From ca101da0b2eb2a9bbabf3096e9d41e96a2059c6e Mon Sep 17 00:00:00 2001 From: voidint Date: Mon, 20 Nov 2023 23:07:37 +0800 Subject: [PATCH] feat: added --output option for ls and ls-remote subcommands. #119 --- cli/cli.go | 49 ++++++++++++++++++++++++++++++++++++++-------- cli/cli_test.go | 2 +- cli/commands.go | 18 +++++++++++++++-- cli/ls.go | 12 ++++++++++-- cli/ls_remote.go | 10 +++++++++- version/version.go | 18 ++++++++--------- 6 files changed, 86 insertions(+), 23 deletions(-) diff --git a/cli/cli.go b/cli/cli.go index 966c4f6..c8b2b93 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -1,6 +1,7 @@ package cli import ( + "encoding/json" "fmt" "io" "os" @@ -123,17 +124,49 @@ func installed() (versions map[string]bool) { return } +type versionResp struct { + Version string `json:"version"` + Default bool `json:"default"` + Installed bool `json:"installed"` + Packages []version.Package `json:"packages"` +} + +const ( + rawMode = 0 + jsonMode = 1 +) + // render 渲染go版本列表 -func render(installed map[string]bool, items []*version.Version, out io.Writer) { - for _, v := range items { - if inused, found := installed[v.Name()]; found { - if inused { - color.New(color.FgGreen).Fprintf(out, "* %s\n", v.Name()) +func render(mode uint8, installed map[string]bool, items []*version.Version, out io.Writer) { + switch mode { + case jsonMode: + vs := make([]versionResp, 0, len(items)) + + for _, item := range items { + v := versionResp{ + Version: item.Name(), + Packages: item.Packages(), + } + if inused, found := installed[item.Name()]; found { + v.Default = inused + v.Installed = found + } + vs = append(vs, v) + } + + _ = json.NewEncoder(out).Encode(&vs) + + default: + for _, item := range items { + if inused, found := installed[item.Name()]; found { + if inused { + color.New(color.FgGreen).Fprintf(out, "* %s\n", item.Name()) + } else { + color.New(color.FgGreen).Fprintf(out, " %s\n", item.Name()) + } } else { - color.New(color.FgGreen).Fprintf(out, " %s\n", v.Name()) + fmt.Fprintf(out, " %s\n", item.Name()) } - } else { - fmt.Fprintf(out, " %s\n", v.Name()) } } } diff --git a/cli/cli_test.go b/cli/cli_test.go index f9bc23c..d85cd78 100644 --- a/cli/cli_test.go +++ b/cli/cli_test.go @@ -51,7 +51,7 @@ func Test_render(t *testing.T) { } sort.Sort(version.Collection(items)) - render(map[string]bool{"1.8.1": true}, items, &buf) + render(rawMode, map[string]bool{"1.8.1": true}, items, &buf) assert.Equal(t, " 1.7\n* 1.8.1\n 1.10beta2\n 1.19beta1\n 1.21rc4\n 1.21.0\n", buf.String()) }) } diff --git a/cli/commands.go b/cli/commands.go index b25d6a9..193f6bc 100644 --- a/cli/commands.go +++ b/cli/commands.go @@ -9,14 +9,28 @@ var ( Aliases: []string{"l"}, Usage: "List installed versions", UsageText: "g ls", - Action: list, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "output", + Aliases: []string{"o"}, + Usage: "Output format. One of: (raw, json).", + }, + }, + Action: list, }, { Name: "ls-remote", Aliases: []string{"lr", "lsr"}, Usage: "List remote versions available for install", UsageText: "g ls-remote [stable|archived|unstable]", - Action: listRemote, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "output", + Aliases: []string{"o"}, + Usage: "Output format. One of: (raw, json).", + }, + }, + Action: listRemote, }, { Name: "use", diff --git a/cli/ls.go b/cli/ls.go index e0ba99c..a941913 100644 --- a/cli/ls.go +++ b/cli/ls.go @@ -10,7 +10,7 @@ import ( "github.com/voidint/g/version" ) -func list(*cli.Context) (err error) { +func list(ctx *cli.Context) (err error) { dirs, err := os.ReadDir(versionsDir) if err != nil || len(dirs) <= 0 { fmt.Printf("No version installed yet\n\n") @@ -30,6 +30,14 @@ func list(*cli.Context) (err error) { sort.Sort(version.Collection(items)) } - render(installed(), items, ansi.NewAnsiStdout()) + var renderMode uint8 + switch ctx.String("output") { + case "json": + renderMode = jsonMode + default: + renderMode = rawMode + } + + render(renderMode, installed(), items, ansi.NewAnsiStdout()) return nil } diff --git a/cli/ls_remote.go b/cli/ls_remote.go index ba3b7f5..76cb3b3 100644 --- a/cli/ls_remote.go +++ b/cli/ls_remote.go @@ -42,6 +42,14 @@ func listRemote(ctx *cli.Context) (err error) { return cli.Exit(errstring(err), 1) } - render(installed(), vs, ansi.NewAnsiStdout()) + var renderMode uint8 + switch ctx.String("output") { + case "json": + renderMode = jsonMode + default: + renderMode = rawMode + } + + render(renderMode, installed(), vs, ansi.NewAnsiStdout()) return nil } diff --git a/version/version.go b/version/version.go index 296417d..f73022f 100644 --- a/version/version.go +++ b/version/version.go @@ -117,15 +117,15 @@ func (v *Version) FindPackages(kind, goos, goarch string) (pkgs []*Package, err // Package go版本安装包 type Package struct { - FileName string - URL string - Kind string - OS string - Arch string - Size string - Checksum string - ChecksumURL string - Algorithm string // checksum algorithm + FileName string `json:"filename"` + URL string `json:"url"` + Kind string `json:"kind"` + OS string `json:"os"` + Arch string `json:"arch"` + Size string `json:"size"` + Checksum string `json:"checksum"` + ChecksumURL string `json:"-"` + Algorithm string `json:"algorithm"` // checksum algorithm } const (