diff options
| -rw-r--r-- | .go.mod.sri | 2 | ||||
| -rw-r--r-- | cmd/tshello/main.go | 52 | ||||
| -rw-r--r-- | cmd/yeet/.gitignore | 1 | ||||
| -rw-r--r-- | cmd/yeet/README.md | 380 | ||||
| -rw-r--r-- | cmd/yeet/internal/mkrpm/mkrpm.go | 173 | ||||
| -rw-r--r-- | cmd/yeet/main.go | 81 | ||||
| -rw-r--r-- | cmd/yeet/yeetfile.js | 13 | ||||
| -rw-r--r-- | flake.nix | 2 | ||||
| -rw-r--r-- | go.mod | 42 | ||||
| -rw-r--r-- | go.sum | 173 | ||||
| -rw-r--r-- | internal/yeet/yeet.go | 2 |
11 files changed, 847 insertions, 74 deletions
diff --git a/.go.mod.sri b/.go.mod.sri index 1d6815a..496d3dc 100644 --- a/.go.mod.sri +++ b/.go.mod.sri @@ -1 +1 @@ -sha256-O3pH0hQ/WmXWO3bO/xQqX2kRfFEdTLeB4q9g+uVkJX4= +sha256-wXchFhghtSn4JAS4spJhTcwM1axDIaQuCEBs29XXxkA= diff --git a/cmd/tshello/main.go b/cmd/tshello/main.go deleted file mode 100644 index 59c688f..0000000 --- a/cmd/tshello/main.go +++ /dev/null @@ -1,52 +0,0 @@ -// The tshello server demonstrates how to use Tailscale as a library. -package main - -import ( - "flag" - "fmt" - "html" - "log" - "net/http" - "strings" - - "tailscale.com/tsnet" -) - -var ( - addr = flag.String("addr", ":80", "address to listen on") - hostname = flag.String("hostname", "tshello", "hostname to use on the tailnet") -) - -func main() { - flag.Parse() - s := new(tsnet.Server) - defer s.Close() - ln, err := s.Listen("tcp", *addr) - if err != nil { - log.Fatal(err) - } - defer ln.Close() - - lc, err := s.LocalClient() - if err != nil { - log.Fatal(err) - } - - log.Fatal(http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - who, err := lc.WhoIs(r.Context(), r.RemoteAddr) - if err != nil { - http.Error(w, err.Error(), 500) - return - } - fmt.Fprintf(w, "<html><body><h1>Hello, world!</h1>\n") - fmt.Fprintf(w, "<p>You are <b>%s</b> from <b>%s</b> (%s)</p>", - html.EscapeString(who.UserProfile.LoginName), - html.EscapeString(firstLabel(who.Node.ComputedName)), - r.RemoteAddr) - }))) -} - -func firstLabel(s string) string { - s, _, _ = strings.Cut(s, ".") - return s -} diff --git a/cmd/yeet/.gitignore b/cmd/yeet/.gitignore new file mode 100644 index 0000000..e7a9c13 --- /dev/null +++ b/cmd/yeet/.gitignore @@ -0,0 +1 @@ +*.rpm diff --git a/cmd/yeet/README.md b/cmd/yeet/README.md new file mode 100644 index 0000000..4e61d6f --- /dev/null +++ b/cmd/yeet/README.md @@ -0,0 +1,380 @@ +# yeet + +Yeet out actions with maximum haste! Declare your build instructions as small JavaScript snippets and let er rip! + +## Usage + +To install the current program with `go install`: + +```js +// yeetfile.js +go.install(); +``` + +## Available functions + +Yeet uses [goja](https://pkg.go.dev/github.com/dop251/goja#section-readme) to execute JavaScript. As such, it does not have access to NPM or other external JavaScript libraries. You also cannot import code/data from other files. These are not planned for inclusion into yeet. If functionality is required, it should be added to yeet itself. + +To make it useful, yeet exposes a bunch of helper objects full of tools. These tools fall in a few categories, each has its own section. + +### `docker` + +Aliases for `docker` commands. + +#### `docker.build` + +An alias for the `docker build` command. Builds a docker image in the current working directory's Dockerfile. + +Usage: + +`docker.build(tag);` + +```js +docker.build("ghcr.io/xe/site/bin"); +docker.push("ghcr.io/xe/site/bin"); +``` + +#### `docker.load` + +Loads an exported docker image by path into the local docker daemon. This is most useful when combined with tools like `nix.build`. + +Usage: + +`docker.load(path)` + +```js +nix.build(".#docker.xedn"); +docker.load("./result"); +docker.push("registry.fly.io/xedn:latest"); +fly.deploy(); +``` + +#### `docker.push` + +Pushes a docker image to a registry. Analogous to `docker push` in the CLI. + +Usage: + +`docker.push(tag);` + +```js +docker.build("ghcr.io/xe/site/bin"); +docker.push("ghcr.io/xe/site/bin"); +``` + +### `file` + +Helpers for filesystem access. + +#### `file.copy` + +Copies a file from one place to another. Analogous to the `cp` command on Linux. Automatically creates directories in the `dest` path if they don't exist. + +Usage: + +`file.copy(src, dest);` + +```js +file.copy("LICENSE", `${out}/usr/share/doc/LICENSE`); +``` + +#### `file.read` + +Reads a file into memory and returns it as a string. + +Usage: + +`file.read(path);` + +```js +const version = file.read("VERSION"); +``` + +#### `file.write` + +Writes the contents of the `data` string to a file with mode `0660`. + +Usage: + +`file.write(path, data);` + +```js +file.write("VERSION", git.tag()); +``` + +### `fly` + +Automation for [flyctl](https://github.com/superfly/flyctl). Soon this will also let you manage Machines with the [Machines API](https://docs.machines.dev). + +#### `fly.deploy` + +Runs the `fly deploy` command for you. + +Usage: + +`fly.deploy();` + +```js +docker.build("registry.fly.io/foobar"); +docker.push("registry.fly.io/foobar"); +fly.deploy(); +``` + +### `git` + +Helpers for the Git version control system. + +#### `git.repoRoot` + +Returns the repository root as a string. + +`git.repoRoot();` + +```js +const repoRoot = git.repoRoot(); + +file.copy(`${repoRoot}/LICENSE`, `${out}/usr/share/doc/yeet/LICENSE`); +``` + +#### `git.tag` + +Returns the output of `git describe --tags`. Useful for getting the "current version" of the repo, where the current version will likely be different forward in time than it is backwards in time. + +Usage: + +`git.tag();` + +```js +const version = git.tag(); +``` + +### `go` + +Helpers for the Go programming language. + +#### `go.build` + +Runs `go build` in the current working directory with any extra arguments passed in. This is useful for building and installing Go programs in an RPM build context. + +Usage: + +`go.build(args);` + +```js +go.build("-o", `${out}/usr/bin/`); +``` + +#### `go.install` + +Runs `go install`. Not useful for cross-compilation. + +Usage: + +`go.install();` + +```js +go.install(); +``` + +### `nix` + +Automation for running Nix ecosystem tooling. + +#### `nix.build` + +Runs `nix build` against a given flakeref. + +Usage: + +`nix.build(flakeref);` + +```js +nix.build(".#docker"); +docker.load("./result"); +``` + +#### `nix.eval` + +A tagged template that helps you build Nix expressions safely from JavaScript and then evaluates them. See my [nixexpr blogpost](https://xeiaso.net/blog/nixexpr/) for more information about how this works. + +Usage: + +```js +const glibcPath = nix.eval`let pkgs = import <nixpkgs>; in pkgs.glibc`; +``` + +#### `nix.expr` + +A tagged template that helps you build Nix expressions safely from JavaScript. See my [nixexpr blogpost](https://xeiaso.net/blog/nixexpr/) for more information about how this works. + +Usage: + +```js +go.build(); +const fname = slug.build("todayinmarch2020"); + +const url = slug.push(fname); +const hash = nix.hashURL(url); + +const expr = nix.expr`{ stdenv }: + +stdenv.mkDerivation { + name = "todayinmarch2020"; + src = builtins.fetchurl { + url = ${url}; + sha256 = ${hash}; + }; + + phases = "installPhase"; + + installPhase = '' + tar xf $src + mkdir -p $out/bin + cp bin/main $out/bin/todayinmarch2020 + ''; +} +`; + +file.write(`${repoRoot}/pkgs/x/todayinmarch2020.nix`, expr); +``` + +#### `nix.hashURL` + +Hashes the contents of a given URL and returns the `sha256` SRI form. Useful when composing Nix expressions with the `nix.expr` tagged template. + +Usage: + +`nix.hashURL(url);` + +```js +const hash = nix.hashURL("https://whatever.com/some_file.tgz"); +``` + +### `rpm` + +Helpers for building RPM packages and docker images out of a constellation of RPM packages. + +#### `rpm.build` + +Builds an RPM package with a descriptor object. See the RPM packages section for more information. The important part of this is your `build` function. The `build` function is what will turn your package source code into an executable in `out` somehow. Everything in `out` corresponds 1:1 with paths in the resulting RPM. + +The resulting RPM path will be returned as a string. + +Usage: + +`rpm.build(package);` + +```js +["amd64", "arm64"].forEach((goarch) => + rpm.build({ + name: "yeet", + description: "Yeet out actions with maximum haste!", + homepage: "https://within.website", + license: "CC0", + goarch, + + build: (out) => { + go.build("-o", `${out}/usr/bin/`); + }, + }) +); +``` + +### `yeet` + +This contains various "other" functions that don't have a good place to put them. + +#### `yeet.cwd` + +The current working directory. This is a constant value and is not updated at runtime. + +Usage: + +```js +log.println(yeet.cwd); +``` + +#### `yeet.dateTag` + +A constant string representing the time that yeet was started in UTC. It is formatted in terms of `YYYYmmDDhhMM`. This is not updated at runtime. You can use it for a "unique" value per invocation of yeet (assuming you aren't a time traveler). + +Usage: + +```js +docker.build(`ghcr.io/xe/site/bin:${git.tag()}-${yeet.dateTag}`); +``` + +#### `yeet.run` / `yeet.runcmd` + +Runs an arbitrary command and returns any output as a string. + +Usage: + +`yeet.run(cmd, arg1, arg2, ...);` + +```js +yeet.run( + "protoc", + "--proto-path=.", + `--proto-path=${git.repoRoot()}/proto`, + "foo.proto" +); +``` + +#### `yeet.setenv` + +Sets an environment variable for the process yeet is running in and all children. + +Usage: + +`yeet.setenv(key, val);` + +```js +yeet.setenv("GOOS", "linux"); +``` + +#### `yeet.goos` / `yeet.goarch` + +The GOOS/GOARCH value that yeet was built for. This typically corresponds with the OS and CPU architecture that yeet is running on. + +## Building RPM Packages + +When using the `rpm.build` function, you can create RPM packages from arbitrary yeet expressions. This allows you to create RPM packages from a macOS or other Linux system. As an example, here is how the yeet RPMs are built: + +```js +["amd64", "arm64"].forEach((goarch) => + rpm.build({ + name: "yeet", + description: "Yeet out actions with maximum haste!", + homepage: "https://within.website", + license: "CC0", + goarch: goarch, + + build: (out) => { + go.build("-o", `${out}/usr/bin/`); + }, + }) +); +``` + +### Build settings + +The following settings are supported: + +| Name | Example | Description | +| :------------ | :----------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | `xeiaso.net-yeet` | The unique name of the package. | +| `version` | `1.0.0` | The version of the package, if not set then it will be inferred from the git version. | +| `description` | `Yeet out scripts with haste!` | The human-readable description of the package. | +| `homepage` | `https://xeiaso.net` | The URL for the homepage of the package. | +| `group` | `Network` | If set, the RPM group that this package belongs to. | +| `license` | `MIT` | The license that the contents of this package is under. | +| `goarch` | `amd64` / `arm64` | The GOARCH value corresponding to the architecture that the RPM is being built for. If you want to build a `noarch` package, put `any` here. | +| `replaces` | `["foo", "bar"]` | Any packages that this package conflicts with or replaces. | +| `depends` | `["foo", "bar"]` | Any packages that this package depends on (such as C libraries for CGo code). | +| `emptyDirs` | `["/var/lib/yeet"]` | Any empty directories that should be created when the package is installed. | +| `configFiles` | `{"./.env.example": "/var/lib/yeet/.env"}` | Any configuration files that should be copied over on install, but managed by administrators after installation. | + +## Support + +For support, please [subscribe to me on Patreon](https://patreon.com/cadey) and ask in the `#yeet` channel. You may open GitHub issues if you wish, but I do not often look at them. diff --git a/cmd/yeet/internal/mkrpm/mkrpm.go b/cmd/yeet/internal/mkrpm/mkrpm.go new file mode 100644 index 0000000..71c48fd --- /dev/null +++ b/cmd/yeet/internal/mkrpm/mkrpm.go @@ -0,0 +1,173 @@ +package mkrpm + +import ( + "context" + "flag" + "fmt" + "log/slog" + "os" + "path/filepath" + "runtime" + + "github.com/Songmu/gitconfig" + "github.com/goreleaser/nfpm/v2" + "github.com/goreleaser/nfpm/v2/files" + _ "github.com/goreleaser/nfpm/v2/rpm" + "within.website/x/internal/yeet" +) + +var ( + userName = flag.String("git-user-name", gitUserName(), "user name in Git") + userEmail = flag.String("git-user-email", gitUserEmail(), "user email in Git") +) + +const ( + fallbackName = "Mimi Yasomi" + fallbackEmail = "mimi@xeserv.us" +) + +func gitUserName() string { + name, err := gitconfig.User() + if err != nil { + return fallbackName + } + + return name +} + +func gitUserEmail() string { + email, err := gitconfig.Email() + if err != nil { + return fallbackEmail + } + + return email +} + +func gitVersion() string { + vers, err := yeet.GitTag(context.Background()) + if err != nil { + panic(err) + } + return vers[1:] +} + +type Package struct { + Name string `json:"name"` + Version string `json:"version"` + Description string `json:"description"` + Homepage string `json:"homepage"` + Group string `json:"group"` + License string `json:"license"` + Goarch string `json:"goarch"` + Replaces []string `json:"replaces"` + Depends []string `json:"depends"` + Recommends []string `json:"recommends"` + + EmptyDirs []string `json:"emptyDirs"` // rpm destination path + ConfigFiles map[string]string `json:"configFiles"` // repo-relative source path, rpm destination path + + Build func(out string) `json:"build"` +} + +func Build(p Package) (foutpath string, err error) { + defer func() { + if r := recover(); r != nil { + switch r.(type) { + case error: + err = r.(error) + default: + err = fmt.Errorf("mkrpm: error while building: %v", r) + } + } + }() + + if p.Version == "" { + p.Version = gitVersion() + } + + dir, err := os.MkdirTemp("", "yeet-mkrpm") + if err != nil { + return "", fmt.Errorf("mkrpm: can't make temporary directory") + } + defer os.RemoveAll(dir) + + defer func() { + os.Setenv("GOARCH", runtime.GOARCH) + os.Setenv("GOOS", runtime.GOOS) + }() + os.Setenv("GOARCH", p.Goarch) + os.Setenv("GOOS", "linux") + + p.Build(dir) + + var contents files.Contents + + for _, d := range p.EmptyDirs { + if d == "" { + continue + } + + contents = append(contents, &files.Content{Type: files.TypeDir, Destination: d}) + } + + for repoPath, rpmPath := range p.ConfigFiles { + contents = append(contents, &files.Content{Type: files.TypeConfig, Source: repoPath, Destination: rpmPath}) + } + + if err := filepath.Walk(dir, func(path string, stat os.FileInfo, err error) error { + if err != nil { + return err + } + + if stat.IsDir() { + return nil + } + + contents = append(contents, &files.Content{Type: files.TypeFile, Source: path, Destination: path[len(dir)+1:]}) + + return nil + }); err != nil { + return "", fmt.Errorf("mkrpm: can't walk output directory: %w", err) + } + + info := nfpm.WithDefaults(&nfpm.Info{ + Name: p.Name, + Version: p.Version, + Arch: p.Goarch, + Platform: "linux", + Description: p.Description, + Maintainer: fmt.Sprintf("%s <%s>", *userName, *userEmail), + Homepage: p.Homepage, + License: p.License, + Overridables: nfpm.Overridables{ + Contents: contents, + Depends: p.Depends, + Recommends: p.Recommends, + Replaces: p.Replaces, + Conflicts: p.Replaces, + }, + }) + + info.Overridables.RPM.Group = p.Group + + pkg, err := nfpm.Get("rpm") + if err != nil { + return "", fmt.Errorf("mkrpm: can't get RPM packager: %w", err) + } + + foutpath = fmt.Sprintf("%s-%s-%s.rpm", p.Name, p.Version, p.Goarch) + fout, err := os.Create(foutpath) + if err != nil { + return "", fmt.Errorf("mkrpm: can't create output file: %w", err) + } + defer fout.Close() + + if err := pkg.Package(info, fout); err != nil { + return "", fmt.Errorf("mkrpm: can't build package: %w", err) + } + + slog.Debug("built package", "name", p.Name, "version", p.Version, "path", foutpath) + + return foutpath, err +} diff --git a/cmd/yeet/main.go b/cmd/yeet/main.go index b143597..dd18d33 100644 --- a/cmd/yeet/main.go +++ b/cmd/yeet/main.go @@ -5,6 +5,7 @@ import ( "encoding/json" "flag" "fmt" + "io" "log" "log/slog" "os" @@ -15,6 +16,7 @@ import ( "strings" "github.com/dop251/goja" + "within.website/x/cmd/yeet/internal/mkrpm" "within.website/x/internal" "within.website/x/internal/appsluggr" "within.website/x/internal/kahless" @@ -23,8 +25,8 @@ import ( ) var ( - fname = flag.String("fname", "yeetfile.js", "filename for the yeetfile") - flyctl = flag.String("flyctl-path", flyctlPath(), "path to flyctl binary") + fname = flag.String("fname", "yeetfile.js", "filename for the yeetfile") + flyctl = flag.String("flyctl-path", flyctlPath(), "path to flyctl binary") protocPath = flag.String("protoc-path", "protoc", "path to protoc binary") ) @@ -46,7 +48,7 @@ func flyctlPath() string { func runcmd(cmdName string, args ...string) string { ctx := context.Background() - slog.Info("running command", "cmd", cmdName, "args", args) + slog.Debug("running command", "cmd", cmdName, "args", args) result, err := yeet.Output(ctx, cmdName, args...) if err != nil { @@ -74,10 +76,6 @@ func dockerload(fname string) { yeet.DockerLoadResult(context.Background(), fname) } -func dockertag(org, repo, image string) string { - return yeet.DockerTag(context.Background(), org, repo, image) -} - func dockerbuild(tag string, args ...string) { yeet.DockerBuild(context.Background(), yeet.WD, tag, args...) } @@ -150,11 +148,11 @@ func hostname() string { } type protocInput struct { - Input string `json:"input"` + Input string `json:"input"` Output string `json:"output"` - Kinds []struct { + Kinds []struct { Kind string `json:"kind"` - Opt string `json:"opt"` + Opt string `json:"opt"` } `json:"kinds"` } @@ -182,15 +180,52 @@ func main() { "build": dockerbuild, "load": dockerload, "push": dockerpush, - "tag": dockertag, }) vm.Set("file", map[string]any{ + "read": func(fname string) string { + data, err := os.ReadFile(fname) + if err != nil { + panic(err) + } + return string(data) + }, "write": func(fname, data string) { if err := os.WriteFile(fname, []byte(data), 0660); err != nil { panic(err) } }, + "copy": func(from, to string) { + st, err := os.Stat(from) + if err != nil { + panic(err) + } + + fin, err := os.Open(from) + if err != nil { + panic(err) + } + defer fin.Close() + + dir := filepath.Dir(to) + os.MkdirAll(dir, 0777) + + fout, err := os.OpenFile(to, os.O_CREATE, st.Mode()) + if err != nil { + panic(err) + } + defer fout.Close() + + n, err := io.Copy(fout, fin) + if err != nil { + panic(err) + } + + if n != st.Size() { + slog.Error("wrong number of bytes written", "from", from, "to", to, "want", st.Size(), "got", n) + panic("copy failed") + } + }, }) vm.Set("fly", map[string]any{ @@ -201,17 +236,17 @@ func main() { "repoRoot": func() string { return runcmd("git", "rev-parse", "--show-toplevel") }, + "tag": gittag, }) vm.Set("go", map[string]any{ - "build": func() { runcmd("go", "build") }, + "build": func(args ...string) { + args = append([]string{"build"}, args...) + runcmd("go", args...) + }, "install": func() { runcmd("go", "install") }, }) - vm.Set("git", map[string]any{ - "tag": gittag, - }) - vm.Set("log", map[string]any{ "info": lg.Println, "println": fmt.Println, @@ -219,9 +254,19 @@ func main() { vm.Set("nix", map[string]any{ "build": nixbuild, - "hashURL": func(fileURL string) string { return strings.TrimSpace(runcmd("nix-prefetch-url", fileURL)) }, - "expr": buildNixExpr, "eval": evalNixExpr, + "expr": buildNixExpr, + "hashURL": func(fileURL string) string { return strings.TrimSpace(runcmd("nix-prefetch-url", fileURL)) }, + }) + + vm.Set("rpm", map[string]any{ + "build": func(p mkrpm.Package) string { + foutpath, err := mkrpm.Build(p) + if err != nil { + panic(err) + } + return foutpath + }, }) vm.Set("slug", map[string]any{ diff --git a/cmd/yeet/yeetfile.js b/cmd/yeet/yeetfile.js index 312fd4f..ebf7acf 100644 --- a/cmd/yeet/yeetfile.js +++ b/cmd/yeet/yeetfile.js @@ -1,2 +1,13 @@ -yeet.setenv("CGO_ENABLED", "0"); go.install(); + +["amd64", "arm64"].forEach(goarch => rpm.build({ + name: "yeet", + description: "Yeet out actions with maximum haste!", + homepage: "https://within.website", + license: "CC0", + goarch, + + build: (out) => { + go.build("-o", `${out}/usr/bin/`); + }, +}));
\ No newline at end of file @@ -1,4 +1,4 @@ -# nix-direnv cache busting line: sha256-O3pH0hQ/WmXWO3bO/xQqX2kRfFEdTLeB4q9g+uVkJX4= +# nix-direnv cache busting line: sha256-peNzrjlmFqFFgp+0UgIriHl21j1a8Y1F1zIu7RO5NaY= { description = "/x/perimental code"; @@ -9,6 +9,7 @@ require ( entgo.io/ent v0.13.1 github.com/Marcel-ICMC/graw v0.0.0-20230411090719-e24cd8592d25 github.com/McKael/madon/v2 v2.4.0 + github.com/Songmu/gitconfig v0.2.0 github.com/aws/aws-sdk-go v1.51.13 github.com/aws/aws-sdk-go-v2/service/s3 v1.53.0 github.com/bwmarrin/discordgo v0.27.1 @@ -26,6 +27,7 @@ require ( github.com/google/go-github v17.0.0+incompatible github.com/google/subcommands v1.2.0 github.com/google/uuid v1.6.0 + github.com/goreleaser/nfpm/v2 v2.33.1 github.com/hullerob/go.farbfeld v0.0.0-20181222022525-3661193c725f github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43 github.com/joho/godotenv v1.5.1 @@ -62,7 +64,14 @@ require ( require ( ariga.io/atlas v0.19.1-0.20240203083654-5948b60a8e43 // indirect + dario.cat/mergo v1.0.0 // indirect + github.com/AlekSi/pointer v1.2.0 // indirect github.com/Khan/genqlient v0.6.0 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect github.com/PuerkitoBio/rehttp v1.3.0 // indirect github.com/agext/levenshtein v1.2.1 // indirect github.com/andybalholm/brotli v1.1.0 // indirect @@ -74,34 +83,61 @@ require ( github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.6 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.4 // indirect github.com/bytedance/sonic v1.11.3 // indirect + github.com/cavaliergopher/cpio v1.0.1 // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.1 // indirect + github.com/cli/go-gh v0.1.0 // indirect + github.com/cloudflare/circl v1.3.7 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa // indirect github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e // indirect github.com/dustin/go-humanize v1.0.1 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/evanw/esbuild v0.19.11 // indirect github.com/fasthttp/router v1.5.0 // indirect + github.com/fatih/color v1.15.0 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-git/go-git/v5 v5.11.0 // indirect github.com/go-openapi/inflect v0.19.0 // indirect github.com/go-shiori/dom v0.0.0-20210627111528-4e4722cd0d65 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/goccy/go-yaml v1.9.5 // indirect github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f // indirect github.com/google/nftables v0.1.1-0.20230115205135-9aa6fdf5a28c // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect + github.com/google/rpmpack v0.5.0 // indirect + github.com/goreleaser/chglog v0.5.0 // indirect + github.com/goreleaser/fileglob v1.3.0 // indirect github.com/gorilla/csrf v1.7.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect github.com/grbit/go-json v0.11.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl/v2 v2.13.0 // indirect + github.com/huandu/xstrings v1.4.0 // indirect + github.com/imdario/mergo v0.3.16 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/klauspost/cpuid/v2 v2.2.6 // indirect + github.com/klauspost/pgzip v1.2.6 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/miekg/dns v1.1.58 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/safchain/ethtool v0.3.0 // indirect github.com/savsgio/gotils v0.0.0-20240303185622-093b76447511 // indirect + github.com/sergi/go-diff v1.3.1 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/skeema/knownhosts v1.2.1 // indirect + github.com/spf13/cast v1.6.0 // indirect github.com/superfly/graphql v0.2.4 // indirect github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 // indirect github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a // indirect @@ -109,13 +145,19 @@ require ( github.com/tailscale/web-client-prebuilt v0.0.0-20240226180453-5db17b287bf1 // indirect github.com/turnage/redditproto v0.0.0-20151223012412-afedf1b6eddb // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.52.0 // indirect github.com/valyala/fastjson v1.6.4 // indirect github.com/vektah/gqlparser/v2 v2.5.1 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/zclconf/go-cty v1.8.0 // indirect + gitlab.com/digitalxero/go-conventional-commit v1.0.7 // indirect golang.org/x/arch v0.6.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect modernc.org/libc v1.41.0 // indirect modernc.org/mathutil v1.6.0 // indirect @@ -57,6 +57,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= entgo.io/ent v0.13.1 h1:uD8QwN1h6SNphdCCzmkMN3feSUzNnVvV/WIkHKMbzOE= entgo.io/ent v0.13.1/go.mod h1:qCEmo+biw3ccBn9OyL4ZK5dfpwg++l1Gxwac5B1206A= @@ -64,21 +66,44 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= filippo.io/mkcert v1.4.4 h1:8eVbbwfVlaqUM7OwuftKc2nuYOoTDQWqsoXmzoXZdbc= filippo.io/mkcert v1.4.4/go.mod h1:VyvOchVuAye3BoUsPUOOofKygVwLV2KQMVFJNRq+1dA= +github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w= +github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Khan/genqlient v0.6.0 h1:Bwb1170ekuNIVIwTJEqvO8y7RxBxXu639VJOkKSrwAk= github.com/Khan/genqlient v0.6.0/go.mod h1:rvChwWVTqXhiapdhLDV4bp9tz/Xvtewwkon4DpWWCRM= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Marcel-ICMC/graw v0.0.0-20230411090719-e24cd8592d25 h1:2y0Jf51U3toefyF80qgCNfd8qZEjkmWSvBX/DNhM6Mw= github.com/Marcel-ICMC/graw v0.0.0-20230411090719-e24cd8592d25/go.mod h1:Tc1Bv6CivnFGhW5kjO2ZN9/PMlGJ6O4cVFYkaTNWSY8= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/McKael/madon/v2 v2.4.0 h1:u5bwEs7r3ek2L1KFOZ27wzHY1vY9bnG4oQDzcrbJyK4= github.com/McKael/madon/v2 v2.4.0/go.mod h1:fSjqeQzvbKPjWQOv0VV3SPKvPCmj6Y+meOqkvQbXEnU= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k= +github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw= +github.com/ProtonMail/gopenpgp/v2 v2.7.1 h1:Awsg7MPc2gD3I7IFac2qE3Gdls0lZW8SzrFZ3k1oz0s= +github.com/ProtonMail/gopenpgp/v2 v2.7.1/go.mod h1:/BU5gfAVwqyd8EfC3Eu7zmuhwYQpKs+cGD8M//iiaxs= github.com/PuerkitoBio/rehttp v1.3.0 h1:w54Pb72MQn2eJrSdPsvGqXlAfiK1+NMTGDrOJJ4YvSU= github.com/PuerkitoBio/rehttp v1.3.0/go.mod h1:LUwKPoDbDIA2RL5wYZCNsQ90cx4OJ4AWBmq6KzWZL1s= +github.com/Songmu/gitconfig v0.2.0 h1:pX2++u4KUq+K2k/ZCzGXLtkD3ceCqIdi0tDyb+IbSyo= +github.com/Songmu/gitconfig v0.2.0/go.mod h1:cB5bYJer+pl7W8g6RHFwL/0X6aJROVrYuHlvc7PT+hE= github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= @@ -102,6 +127,8 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuW github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aws/aws-sdk-go v1.51.13 h1:j6lgtz9E/XFRiYYnGNrAfWvyyTsuYvWvo2RCt0zqAIs= github.com/aws/aws-sdk-go v1.51.13/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn |
