From 8549817648561001bbe3e71f5210e59e69594c27 Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Fri, 2 Feb 2024 14:31:04 +0000 Subject: [PATCH] chore: add CLI `fetch` boilerplate Sets up the harness for hosting nested CLI commands with `go-flags`[1]. Each command will be defined in a separate `go` file. The structured logging is set up with the JSON outputter. That can be controlled with `--log-level=` The `bazel-git fetch` usage mirrors an extreme subset of `git fetch` but includes the `--reference` argument to provide references the tool can use to find a single SHA when a server does not advertise the SHA. The tool does nothing more that output the fetch arguments to the debug logging channel. Try it out with: go run \ ./cmd/bazel-git \ --log-level debug \ fetch \ --reference one \ --reference two \ abc def The output should be: { "time": "2024-02-02T14:35:14.478250053Z", "level": "DEBUG", "msg": "fetch", "FetchCommand": { "RecurseSubmodules": false, "References": [ "one", "two" ], "Args": { "Remote": "abc", "Committish": [ "def" ] } } } [1]: https://pkg.go.dev/github.com/jessevdk/go-flags --- cmd/bazel-git/fetch.go | 33 ++++++++++++++++++++++++++++ cmd/bazel-git/main.go | 50 ++++++++++++++++++++++++++++++++++++++++-- go.mod | 5 +++++ go.sum | 4 ++++ 4 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 cmd/bazel-git/fetch.go create mode 100644 go.sum diff --git a/cmd/bazel-git/fetch.go b/cmd/bazel-git/fetch.go new file mode 100644 index 0000000..bf62efb --- /dev/null +++ b/cmd/bazel-git/fetch.go @@ -0,0 +1,33 @@ +package main + +import ( + "log/slog" +) + +type FetchCommand struct { + RecurseSubmodules bool `long:"recurse-submodules" description:"Recursively fetch submodule objects."` + References []string `long:"reference" value-name:"" description:"References to use to retrieve objects from when a single SHA cannot be retrieved."` + Args struct { + Remote string `positional-arg-name:"repository" description:"The remote to retrieve objects from."` + Committish []string `positional-arg-name:"refspec" description:"The committish to retrieve from the server. Usually a commit SHA but can be a resolvable reference."` + } `positional-args:"yes" required:"yes"` +} + +var fetchCommand FetchCommand + +func (x *FetchCommand) Execute(_ []string) error { + log := slog.With("FetchCommand", x) + log.Debug("fetch") + return nil +} + +func init() { + parser.AddCommand("fetch", + "Download objects from another repository.", + `Fetches objects. + +Initially, the fetch will attempt to request the objects for the single SHA. + +When a server repository does not advertise single SHAs, if a reference is provided, a depth expansion of the reference is performed.`, + &fetchCommand) +} diff --git a/cmd/bazel-git/main.go b/cmd/bazel-git/main.go index b7d2a32..61a3c6c 100644 --- a/cmd/bazel-git/main.go +++ b/cmd/bazel-git/main.go @@ -1,7 +1,53 @@ package main -import "fmt" +import ( + "log/slog" + "os" + + "github.com/jessevdk/go-flags" +) + +type Options struct { + Dir []bool `long:"git-dir" description:"Path to store objects." env:"GIT_DIR"` + WorkTree []bool `long:"work-tree" description:"Path to the working tree." env:"GIT_WORK_TREE"` + LogLevel func(string) `long:"log-level" description:"Set the structured logging level." choice:"debug" choice:"info" choice:"warning" choice:"error" default:"error"` +} + +var options Options + +var parser = flags.NewParser(&options, flags.Default) func main() { - fmt.Println("Hello, World!") + var level = new(slog.LevelVar) + + handler := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: level}) + + slog.SetDefault(slog.New(handler)) + + options.LogLevel = func(v string) { + switch v { + case "debug": + level.Set(slog.LevelDebug) + case "info": + level.Set(slog.LevelInfo) + case "warning": + level.Set(slog.LevelWarn) + case "error": + level.Set(slog.LevelError) + default: + panic("unreachable") + } + } + + if _, err := parser.Parse(); err != nil { + switch flagsErr := err.(type) { + case flags.ErrorType: + if flagsErr == flags.ErrHelp { + os.Exit(0) + } + os.Exit(2) + default: + os.Exit(1) + } + } } diff --git a/go.mod b/go.mod index 517bf55..6e6fb99 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,8 @@ module gitlab.arm.com/bazel/git go 1.21.3 + +require ( + github.com/jessevdk/go-flags v1.5.0 // indirect + golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..df31363 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4 h1:EZ2mChiOa8udjfp6rRmswTbtZN/QzUQp4ptM4rnjHvc= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -- GitLab