diff options
| author | Xe Iaso <me@xeiaso.net> | 2025-04-01 22:33:36 -0400 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2025-04-01 22:33:36 -0400 |
| commit | f6166a6a9668ed7424514f43d7922990b7db7352 (patch) | |
| tree | 0d1ceeea15974b24ea85591d314c0503e6eac31a /cmd/yeet | |
| parent | 6e622796547d01f59694687decf157a9f09dd51f (diff) | |
| download | x-f6166a6a9668ed7424514f43d7922990b7db7352.tar.xz x-f6166a6a9668ed7424514f43d7922990b7db7352.zip | |
cmd/yeet: build tarball packagesv1.13.0
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'cmd/yeet')
| -rw-r--r-- | cmd/yeet/internal/mkrpm/mkrpm.go | 7 | ||||
| -rw-r--r-- | cmd/yeet/internal/mktarball/mktarball.go | 157 | ||||
| -rw-r--r-- | cmd/yeet/internal/pkgmeta/package.go | 1 | ||||
| -rw-r--r-- | cmd/yeet/main.go | 25 | ||||
| -rw-r--r-- | cmd/yeet/yeetfile.js | 21 |
5 files changed, 198 insertions, 13 deletions
diff --git a/cmd/yeet/internal/mkrpm/mkrpm.go b/cmd/yeet/internal/mkrpm/mkrpm.go index 679e2b3..3816e9c 100644 --- a/cmd/yeet/internal/mkrpm/mkrpm.go +++ b/cmd/yeet/internal/mkrpm/mkrpm.go @@ -34,6 +34,9 @@ func Build(p pkgmeta.Package) (foutpath string, err error) { if p.Version == "" { p.Version = internal.GitVersion() } + if p.Platform == "" { + p.Platform = "linux" + } dir, err := os.MkdirTemp("", "yeet-mkrpm") if err != nil { @@ -49,7 +52,7 @@ func Build(p pkgmeta.Package) (foutpath string, err error) { os.Setenv("CGO_ENABLED", cgoEnabled) }() os.Setenv("GOARCH", p.Goarch) - os.Setenv("GOOS", "linux") + os.Setenv("GOOS", p.Platform) os.Setenv("CGO_ENABLED", "0") p.Build(pkgmeta.BuildInput{ @@ -115,7 +118,7 @@ func Build(p pkgmeta.Package) (foutpath string, err error) { Name: p.Name, Version: p.Version, Arch: p.Goarch, - Platform: "linux", + Platform: p.Platform, Description: p.Description, Maintainer: fmt.Sprintf("%s <%s>", *internal.UserName, *internal.UserEmail), Homepage: p.Homepage, diff --git a/cmd/yeet/internal/mktarball/mktarball.go b/cmd/yeet/internal/mktarball/mktarball.go new file mode 100644 index 0000000..5855403 --- /dev/null +++ b/cmd/yeet/internal/mktarball/mktarball.go @@ -0,0 +1,157 @@ +package mktarball + +import ( + "archive/tar" + "compress/gzip" + "fmt" + "io" + "log/slog" + "os" + "path/filepath" + "runtime" + + "within.website/x/cmd/yeet/internal" + "within.website/x/cmd/yeet/internal/pkgmeta" +) + +func Build(p pkgmeta.Package) (foutpath string, err error) { + defer func() { + if r := recover(); r != nil { + switch r.(type) { + case error: + err = r.(error) + slog.Error("mkrpm: error while building", "err", err) + default: + err = fmt.Errorf("%v", r) + slog.Error("mkrpm: error while building", "err", err) + } + } + }() + + os.MkdirAll("./var", 0755) + os.WriteFile(filepath.Join("./var", ".gitignore"), []byte("*\n!.gitignore"), 0644) + + if p.Version == "" { + p.Version = internal.GitVersion() + } + if p.Platform == "" { + p.Platform = "linux" + } + + dir, err := os.MkdirTemp("", "yeet-mktarball") + if err != nil { + return "", fmt.Errorf("can't make temporary directory") + } + defer os.RemoveAll(dir) + + pkgDir := filepath.Join(dir, fmt.Sprintf("%s-%s-%s-%s", p.Name, p.Version, p.Platform, p.Goarch)) + os.MkdirAll(pkgDir, 0755) + + fname := filepath.Join("var", fmt.Sprintf("%s-%s-%s-%s.tar.gz", p.Name, p.Version, p.Platform, p.Goarch)) + fout, err := os.Create(fname) + if err != nil { + return "", fmt.Errorf("can't make output file: %w", err) + } + defer fout.Close() + + gw, err := gzip.NewWriterLevel(fout, 9) + if err != nil { + return "", fmt.Errorf("can't make gzip writer: %w", err) + } + defer gw.Close() + + tw := tar.NewWriter(gw) + defer tw.Close() + + cgoEnabled := os.Getenv("CGO_ENABLED") + defer func() { + os.Setenv("GOARCH", runtime.GOARCH) + os.Setenv("GOOS", runtime.GOOS) + os.Setenv("CGO_ENABLED", cgoEnabled) + }() + os.Setenv("GOARCH", p.Goarch) + os.Setenv("GOOS", p.Platform) + os.Setenv("CGO_ENABLED", "0") + + os.WriteFile(filepath.Join(pkgDir, "VERSION"), []byte(p.Version+"\n"), 0666) + + bi := pkgmeta.BuildInput{ + Output: pkgDir, + Bin: filepath.Join(pkgDir, "bin"), + Doc: filepath.Join(pkgDir, "doc"), + Etc: filepath.Join(pkgDir, "run"), + Man: filepath.Join(pkgDir, "man"), + Systemd: filepath.Join(pkgDir, "run"), + } + + p.Build(bi) + + for src, dst := range p.ConfigFiles { + if err := Copy(src, filepath.Join(bi.Etc, dst)); err != nil { + return "", fmt.Errorf("can't copy %s to %s: %w", src, dst, err) + } + } + + for src, dst := range p.Documentation { + fname := filepath.Join(bi.Doc, dst) + if filepath.Base(fname) == "README.md" { + fname = filepath.Join(pkgDir, "README.md") + } + + if err := Copy(src, fname); err != nil { + return "", fmt.Errorf("can't copy %s to %s: %w", src, dst, err) + } + } + + root, err := os.OpenRoot(dir) + if err != nil { + return "", fmt.Errorf("can't open root FS %s: %w", dir, err) + } + + if err := tw.AddFS(root.FS()); err != nil { + return "", fmt.Errorf("can't copy built files to tarball: %w", err) + } + + slog.Info("built package", "name", p.Name, "arch", p.Goarch, "version", p.Version, "path", fout.Name()) + + return fname, nil +} + +// Copy copies the contents of the file at srcpath to a regular file +// at dstpath. If the file named by dstpath already exists, it is +// truncated. The function does not copy the file mode, file +// permission bits, or file attributes. +func Copy(srcpath, dstpath string) (err error) { + r, err := os.Open(srcpath) + if err != nil { + return err + } + defer r.Close() // ignore error: file was opened read-only. + + st, err := r.Stat() + if err != nil { + return err + } + + os.MkdirAll(filepath.Dir(dstpath), 0755) + + w, err := os.Create(dstpath) + if err != nil { + return err + } + + if err := w.Chmod(st.Mode()); err != nil { + return err + } + + defer func() { + // Report the error, if any, from Close, but do so + // only if there isn't already an outgoing error. + if c := w.Close(); err == nil { + err = c + } + }() + + _, err = io.Copy(w, r) + return err +} diff --git a/cmd/yeet/internal/pkgmeta/package.go b/cmd/yeet/internal/pkgmeta/package.go index 1aaa5a7..e7a9bb9 100644 --- a/cmd/yeet/internal/pkgmeta/package.go +++ b/cmd/yeet/internal/pkgmeta/package.go @@ -7,6 +7,7 @@ type Package struct { Homepage string `json:"homepage"` Group string `json:"group"` License string `json:"license"` + Platform string `json:"platform"` // if not set, default to linux Goarch string `json:"goarch"` Replaces []string `json:"replaces"` Depends []string `json:"depends"` diff --git a/cmd/yeet/main.go b/cmd/yeet/main.go index 2ad7985..6eca911 100644 --- a/cmd/yeet/main.go +++ b/cmd/yeet/main.go @@ -10,13 +10,13 @@ import ( "os/exec" "path/filepath" "runtime" - "runtime/debug" "strings" "al.essio.dev/pkg/shellescape" "github.com/dop251/goja" "within.website/x/cmd/yeet/internal/mkdeb" "within.website/x/cmd/yeet/internal/mkrpm" + "within.website/x/cmd/yeet/internal/mktarball" "within.website/x/cmd/yeet/internal/pkgmeta" "within.website/x/internal" "within.website/x/internal/appsluggr" @@ -89,10 +89,6 @@ func flydeploy() { runcmd(*flyctl, "deploy", "--now") } -func nixbuild(target string) { - runcmd("nix", "build", target) -} - func slugbuild(bin string, extraFiles map[string]string) string { result := fmt.Sprintf("%s-%s.tar.gz", bin, yeet.DateTag) appsluggr.Must(bin, result, extraFiles) @@ -171,7 +167,6 @@ func main() { defer func() { if r := recover(); r != nil { slog.Error("error in JS", "err", r) - debug.PrintStack() } }() @@ -200,6 +195,14 @@ func main() { "push": dockerpush, }) + vm.Set("file", map[string]any{ + "install": func(src, dst string) { + if err := mktarball.Copy(src, dst); err != nil { + panic(err) + } + }, + }) + vm.Set("fly", map[string]any{ "deploy": flydeploy, }) @@ -239,6 +242,16 @@ func main() { "push": slugpush, }) + vm.Set("tarball", map[string]any{ + "build": func(p pkgmeta.Package) string { + foutpath, err := mktarball.Build(p) + if err != nil { + panic(err) + } + return foutpath + }, + }) + vm.Set("yeet", map[string]any{ "cwd": yeet.WD, "datetag": yeet.DateTag, diff --git a/cmd/yeet/yeetfile.js b/cmd/yeet/yeetfile.js index b8468d5..2f3cfb0 100644 --- a/cmd/yeet/yeetfile.js +++ b/cmd/yeet/yeetfile.js @@ -1,12 +1,23 @@ go.install(); yeet.setenv("GOARM", "7"); -yeet.setenv("CGO_ENABLED", "0"); -$`CGO_ENABLED=0 GOARCH=arm64 GOOS=linux go build -o ./var/yeet -ldflags '-s -w -extldflags "-static" -X "within.website/x.Version=${git.tag()}"'`; - -["amd64", "arm64"].forEach(goarch => { - [deb, rpm].forEach(method => method.build({ +[ + // "386", + "amd64", + // "arm", + "arm64", + // "loong64", + // "mips", + // "mips64", + // "mips64le", + // "mipsle", + // "ppc64", + // "ppc64le", + // "riscv64", + // "s390x", +].forEach(goarch => { + [deb, rpm, tarball].forEach(method => method.build({ name: "yeet", description: "Yeet out actions with maximum haste!", homepage: "https://within.website", |
