From 7ed9fd6368c8d5da8f69210f4a40c312413ff8f4 Mon Sep 17 00:00:00 2001 From: rsteube Date: Sat, 16 Dec 2023 17:56:27 +0100 Subject: [PATCH] export macros --- cmd/carapace/cmd/action/completer.go | 38 ++ cmd/carapace/cmd/codegen.go | 23 + cmd/carapace/cmd/completers/completers.go | 2 + cmd/carapace/cmd/invoke.go | 163 +++++++ cmd/carapace/cmd/invoke_test.go | 44 ++ cmd/carapace/cmd/list.go | 75 ++++ cmd/carapace/cmd/macros.go | 98 +++++ cmd/carapace/cmd/macros_test.go | 18 + cmd/carapace/cmd/root.go | 412 ++++++------------ cmd/carapace/cmd/run.go | 43 ++ cmd/carapace/cmd/schema.go | 26 ++ cmd/carapace/cmd/style.go | 36 ++ cmd/carapace/main.go | 4 +- completers/carapace_completer/cmd/root.go | 187 -------- completers/carapace_completer/main.go | 7 - .../glab_completer/cmd/incident_list.go | 2 +- docs/src/SUMMARY.md | 2 +- docs/src/spec/codegen.md | 9 + docs/src/spec/generate.md | 39 -- docs/src/spec/scrape.md | 40 +- go.mod | 6 +- go.sum | 13 +- 22 files changed, 767 insertions(+), 520 deletions(-) create mode 100644 cmd/carapace/cmd/action/completer.go create mode 100644 cmd/carapace/cmd/codegen.go create mode 100644 cmd/carapace/cmd/invoke.go create mode 100644 cmd/carapace/cmd/invoke_test.go create mode 100644 cmd/carapace/cmd/list.go create mode 100644 cmd/carapace/cmd/macros.go create mode 100644 cmd/carapace/cmd/macros_test.go create mode 100644 cmd/carapace/cmd/run.go create mode 100644 cmd/carapace/cmd/schema.go create mode 100644 cmd/carapace/cmd/style.go delete mode 100644 completers/carapace_completer/cmd/root.go delete mode 100644 completers/carapace_completer/main.go create mode 100644 docs/src/spec/codegen.md delete mode 100644 docs/src/spec/generate.md diff --git a/cmd/carapace/cmd/action/completer.go b/cmd/carapace/cmd/action/completer.go new file mode 100644 index 0000000000..5e1cdad4b6 --- /dev/null +++ b/cmd/carapace/cmd/action/completer.go @@ -0,0 +1,38 @@ +package action + +import ( + "encoding/json" + + "github.com/rsteube/carapace" + "github.com/rsteube/carapace/pkg/style" +) + +func ActionCompleters() carapace.Action { + return carapace.ActionCallback(func(c carapace.Context) carapace.Action { + return carapace.ActionExecCommand("carapace", "--list", "--format", "json")(func(output []byte) carapace.Action { + var completers []struct { + Name string + Description string + Spec string + Overlay string + } + if err := json.Unmarshal(output, &completers); err != nil { + return carapace.ActionMessage(err.Error()) + } + + vals := make([]string, 0, len(completers)) + for _, completer := range completers { + s := style.Default + if completer.Spec != "" { + s = style.Blue + } + if completer.Overlay != "" { + s = style.Of(s, style.Underlined) + } + + vals = append(vals, completer.Name, completer.Description, s) + } + return carapace.ActionStyledValuesDescribed(vals...) + }) + }) +} diff --git a/cmd/carapace/cmd/codegen.go b/cmd/carapace/cmd/codegen.go new file mode 100644 index 0000000000..dd7e5f5491 --- /dev/null +++ b/cmd/carapace/cmd/codegen.go @@ -0,0 +1,23 @@ +package cmd + +import ( + "github.com/rsteube/carapace" + "github.com/spf13/cobra" +) + +var codegenCmd = &cobra.Command{ + Use: "--scrape [spec]", + Short: "", + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + scrape(args[0]) + }, +} + +func init() { + carapace.Gen(codegenCmd).Standalone() + + carapace.Gen(codegenCmd).PositionalCompletion( + carapace.ActionFiles(".yaml"), + ) +} diff --git a/cmd/carapace/cmd/completers/completers.go b/cmd/carapace/cmd/completers/completers.go index e5a583be70..2fe8263465 100644 --- a/cmd/carapace/cmd/completers/completers.go +++ b/cmd/carapace/cmd/completers/completers.go @@ -18,6 +18,8 @@ var ( ) func Names() []string { + names = append(names, "carapace") // TODO add here or in generate? + unique := make(map[string]string) for _, name := range names { unique[name] = name diff --git a/cmd/carapace/cmd/invoke.go b/cmd/carapace/cmd/invoke.go new file mode 100644 index 0000000000..fb493384b3 --- /dev/null +++ b/cmd/carapace/cmd/invoke.go @@ -0,0 +1,163 @@ +package cmd + +import ( + "bytes" + "fmt" + "io" + "os" + "path/filepath" + "strings" + + "github.com/rsteube/carapace" + "github.com/rsteube/carapace-bin/cmd/carapace/cmd/action" + "github.com/rsteube/carapace-bin/cmd/carapace/cmd/completers" + "github.com/rsteube/carapace-bridge/pkg/actions/bridge" + "github.com/spf13/cobra" +) + +var invokeCmd = &cobra.Command{ + Use: "invoke", + Short: "", + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + if overlayPath, err := overlayPath(args[0]); err == nil && len(args) > 2 { // and arg[1] is a known shell + cmd := &cobra.Command{ + DisableFlagParsing: true, + CompletionOptions: cobra.CompletionOptions{ + DisableDefaultCmd: true, + }, + } + + // TODO yuck + command := args[0] + shell := args[1] + args[0] = "_carapace" + args[1] = "export" + os.Args[1] = "_carapace" + os.Args[2] = "export" + os.Setenv("CARAPACE_LENIENT", "1") + + carapace.Gen(cmd).PositionalAnyCompletion( + carapace.ActionCallback(func(c carapace.Context) carapace.Action { + batch := carapace.Batch() + specPath, err := completers.SpecPath(command) + if err != nil { + batch = append(batch, carapace.ActionImport([]byte(invokeCompleter(command)))) + } else { + out, err := specCompletion(specPath, args[1:]...) + if err != nil { + return carapace.ActionMessage(err.Error()) + } + + batch = append(batch, carapace.ActionImport([]byte(out))) + } + + batch = append(batch, overlayCompletion(overlayPath, args[1:]...)) + return batch.ToA() + }), + ) + + cmd.SetArgs(append([]string{"_carapace", shell}, args[2:]...)) + cmd.Execute() + } else { + if specPath, err := completers.SpecPath(args[0]); err == nil { + out, err := specCompletion(specPath, args[1:]...) + if err != nil { + fmt.Fprintln(cmd.ErrOrStderr(), err.Error()) + return + } + + // TODO revert the patching from specCompletion to use the integrated version for overlay to work (should move this somewhere else - best in specCompletion) + // TODO only patch completion script + out = strings.Replace(out, fmt.Sprintf("--spec '%v'", specPath), args[0], -1) + out = strings.Replace(out, fmt.Sprintf("'--spec', '%v'", specPath), fmt.Sprintf("'%v'", args[0]), -1) // xonsh callback + fmt.Fprint(cmd.OutOrStdout(), out) + } else { + fmt.Print(invokeCompleter(args[0])) + } + } + }, +} + +func init() { + carapace.Gen(invokeCmd).Standalone() + invokeCmd.Flags().SetInterspersed(false) + + carapace.Gen(invokeCmd).PositionalCompletion( + action.ActionCompleters(), + bridge.ActionCarapaceBin("_carapace", "export", "", "_carapace").Shift(1). + Filter("macro", "style"), + carapace.ActionCallback(func(c carapace.Context) carapace.Action { + switch c.Args[1] { + case "bash", + "bash-ble", + "elvish", + "export", + "fish", + "ion", + "nushell", + "oil", + "powershell", + "tcsh", + "xonsh", + "zsh": + return carapace.ActionValues(c.Args[0]) + default: + return carapace.ActionValues() + } + }), + ) + + carapace.Gen(invokeCmd).PositionalAnyCompletion( + carapace.ActionCallback(func(c carapace.Context) carapace.Action { + switch c.Args[1] { + case "bash", + "bash-ble", + "elvish", + "export", + "fish", + "ion", + "nushell", + "oil", + "powershell", + "tcsh", + "xonsh", + "zsh": + return bridge.ActionCarapaceBin(c.Args[0]).Shift(3) + default: + return carapace.ActionValues() + } + }), + ) +} + +func invokeCompleter(completer string) string { + old := os.Stdout + r, w, _ := os.Pipe() + os.Stdout = w + + outC := make(chan string) + // copy the output in a separate goroutine so printing can't block indefinitely + go func() { + var buf bytes.Buffer + io.Copy(&buf, r) + outC <- buf.String() + }() + + os.Args[1] = "_carapace" + executeCompleter(completer) + + w.Close() + out := <-outC + os.Stdout = old + + executable, err := os.Executable() + if err != nil { + panic(err.Error()) // TODO exit with error message + } + executableName := filepath.Base(executable) + patched := strings.Replace(string(out), fmt.Sprintf("%v _carapace", executableName), fmt.Sprintf("%v %v", executableName, completer), -1) // general callback + patched = strings.Replace(patched, fmt.Sprintf("'%v', '_carapace'", executableName), fmt.Sprintf("'%v', '%v'", executableName, completer), -1) // xonsh callback + return patched + +} diff --git a/cmd/carapace/cmd/invoke_test.go b/cmd/carapace/cmd/invoke_test.go new file mode 100644 index 0000000000..2e59eff97d --- /dev/null +++ b/cmd/carapace/cmd/invoke_test.go @@ -0,0 +1,44 @@ +package cmd + +import ( + "testing" + + "github.com/rsteube/carapace" + "github.com/rsteube/carapace/pkg/sandbox" + "github.com/rsteube/carapace/pkg/style" +) + +func TestInvokeFlags(t *testing.T) { + sandbox.Package(t, "github.com/rsteube/carapace-bin/cmd/carapace")(func(s *sandbox.Sandbox) { + s.Run("tail", "export", "tail", "--fo"). + Expect(carapace.ActionStyledValuesDescribed( + "--follow", "output appended data as the file grows", style.Yellow, + ).Tag("flags"). + NoSpace('.'). + Usage("carapace [flags] [COMPLETER] [bash|elvish|fish|nushell|oil|powershell|tcsh|xonsh|zsh]")) // TODO fix usage + + s.Run("tail", "export", "tail", "--follow="). + Expect(carapace.ActionValues( + "name", + "descriptor", + ).Prefix("--follow="). + Usage("output appended data as the file grows")) + }) +} + +func TestInvokePositional(t *testing.T) { + sandbox.Package(t, "github.com/rsteube/carapace-bin/cmd/carapace")(func(s *sandbox.Sandbox) { + s.Run("git", "export", "git", "checko"). + Expect(carapace.Batch( + carapace.ActionValuesDescribed( + "checkout", "Switch branches or restore working tree files", + ).Style(style.Blue). + Tag("main commands"), + carapace.ActionValuesDescribed( + "checkout-index", "Copy files from the index to the working tree", + ).Style(style.Of(style.Dim, style.Yellow)). + Tag("low-level manipulator commands"), + ).ToA(). + Usage("carapace [flags] [COMPLETER] [bash|elvish|fish|nushell|oil|powershell|tcsh|xonsh|zsh]")) // TODO fix usage + }) +} diff --git a/cmd/carapace/cmd/list.go b/cmd/carapace/cmd/list.go new file mode 100644 index 0000000000..c79eadca47 --- /dev/null +++ b/cmd/carapace/cmd/list.go @@ -0,0 +1,75 @@ +package cmd + +import ( + "encoding/json" + "fmt" + "strconv" + + "github.com/rsteube/carapace" + "github.com/rsteube/carapace-bin/cmd/carapace/cmd/completers" + "github.com/rsteube/carapace/pkg/style" + "github.com/spf13/cobra" +) + +var listCmd = &cobra.Command{ + Use: "--list", + Short: "", + Run: func(cmd *cobra.Command, args []string) { + switch cmd.Flag("format").Value.String() { + case "json": + printCompletersJson() + default: + printCompleters() + } + }, +} + +func init() { + carapace.Gen(listCmd).Standalone() + + listCmd.Flags().String("format", "plain", "output format") + + carapace.Gen(listCmd).FlagCompletion(carapace.ActionMap{ + "format": carapace.ActionValues("plain", "json").StyleF(func(s string, sc style.Context) string { + return style.ForPathExt("."+s, sc) + }), + }) + +} +func printCompleters() { + maxlen := 0 + for _, name := range completers.Names() { + if len := len(name); len > maxlen { + maxlen = len + } + } + + for _, name := range completers.Names() { + fmt.Printf("%-"+strconv.Itoa(maxlen)+"v %v\n", name, completers.Description(name)) + } +} + +func printCompletersJson() { + // TODO move to completers package + type _completer struct { + Name string + Description string + Spec string `json:",omitempty"` + Overlay string `json:",omitempty"` + } + + _completers := make([]_completer, 0) + for _, name := range completers.Names() { + specPath, _ := completers.SpecPath(name) // TODO handle error (log?) + overlayPath, _ := completers.OverlayPath(name) // TODO handle error (log?) + _completers = append(_completers, _completer{ + Name: name, + Description: completers.Description(name), + Spec: specPath, + Overlay: overlayPath, + }) + } + if m, err := json.Marshal(_completers); err == nil { // TODO handle error (log?) + fmt.Println(string(m)) + } +} diff --git a/cmd/carapace/cmd/macros.go b/cmd/carapace/cmd/macros.go new file mode 100644 index 0000000000..13349eb787 --- /dev/null +++ b/cmd/carapace/cmd/macros.go @@ -0,0 +1,98 @@ +package cmd + +import ( + "fmt" + "path/filepath" + "sort" + "strconv" + "strings" + + "github.com/rsteube/carapace" + "github.com/rsteube/carapace-bin/pkg/actions" + spec "github.com/rsteube/carapace-spec" + "github.com/spf13/cobra" +) + +var macrosCmd = &cobra.Command{ + Use: "--macros [macro] ...", + Short: "", + Args: cobra.ArbitraryArgs, + Run: func(cmd *cobra.Command, args []string) { + switch len(args) { + case 0: + printMacros() + case 1: + printMacro(args[0]) + default: + // TODO macro args + } + }, +} + +func init() { + carapace.Gen(macrosCmd).Standalone() + macrosCmd.Flags().SetInterspersed(false) + + carapace.Gen(macrosCmd).PositionalCompletion( + carapace.ActionMultiPartsN("(", 2, func(c carapace.Context) carapace.Action { + switch len(c.Parts) { + case 0: + return carapace.ActionExecCommand("carapace", "--macros")(func(output []byte) carapace.Action { + lines := strings.Split(string(output), "\n") + + vals := make([]string, 0) + for _, line := range lines[:len(lines)-1] { + if fields := strings.Fields(line); len(fields) > 1 { + vals = append(vals, fields[0], strings.Join(fields[1:], " ")) + } else { + vals = append(vals, fields[0], "") + } + } + return carapace.ActionValuesDescribed(vals...).Invoke(carapace.Context{}).ToMultiPartsA(".") + }) + default: + if m, ok := actions.MacroMap[c.Parts[0]]; ok { + return carapace.ActionValues(m.Signature() + ")") + } + return carapace.ActionValues(")") + } + }), + ) + + carapace.Gen(macrosCmd).PositionalAnyCompletion( + carapace.ActionCallback(func(c carapace.Context) carapace.Action { + return spec.ActionMacro("$carapace." + c.Args[0]).Shift(1) // TODO macro prefix + }), + ) +} + +func printMacros() { + maxlen := 0 + names := make([]string, 0) + for name := range actions.MacroMap { + names = append(names, name) + if len := len(name); len > maxlen { + maxlen = len + } + } + + sort.Strings(names) + for _, name := range names { + fmt.Printf("%-"+strconv.Itoa(maxlen)+"v %v\n", name, actions.MacroDescriptions[name]) + } +} + +func printMacro(name string) { + if m, ok := actions.MacroMap[name]; ok { + path := strings.Replace(name, ".", "/", -1) + signature := "" + if s := m.Signature(); s != "" { + signature = fmt.Sprintf("(%v)", s) + } + + fmt.Printf(`signature: $carapace.%v%v +description: %v +reference: https://pkg.go.dev/github.com/rsteube/carapace-bin/pkg/actions/%v#Action%v +`, name, signature, actions.MacroDescriptions[name], filepath.Dir(path), filepath.Base(path)) + } +} diff --git a/cmd/carapace/cmd/macros_test.go b/cmd/carapace/cmd/macros_test.go new file mode 100644 index 0000000000..36b31a5940 --- /dev/null +++ b/cmd/carapace/cmd/macros_test.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "testing" + + "github.com/rsteube/carapace" + "github.com/rsteube/carapace/pkg/sandbox" +) + +func TestMacros(t *testing.T) { + sandbox.Package(t, "github.com/rsteube/carapace-bin/cmd/carapace")(func(s *sandbox.Sandbox) { + s.Run("--macros", "color.XtermColorNames", "G"). + Expect(carapace.ActionStyledValues( + "Green", "color2", + "Grey", "color8", + ).Usage("--macros [macro] ...")) + }) +} diff --git a/cmd/carapace/cmd/root.go b/cmd/carapace/cmd/root.go index 0363bd14bc..f375d143f7 100644 --- a/cmd/carapace/cmd/root.go +++ b/cmd/carapace/cmd/root.go @@ -3,25 +3,19 @@ package cmd //go:generate go run ../../carapace-generate/gen.go import ( - "bytes" - "encoding/json" "fmt" - "io" "os" - "path/filepath" - "sort" - "strconv" "strings" "time" "github.com/rsteube/carapace" + "github.com/rsteube/carapace-bin/cmd/carapace/cmd/action" "github.com/rsteube/carapace-bin/cmd/carapace/cmd/completers" "github.com/rsteube/carapace-bin/cmd/carapace/cmd/lazyinit" "github.com/rsteube/carapace-bin/cmd/carapace/cmd/shim" "github.com/rsteube/carapace-bin/pkg/actions" spec "github.com/rsteube/carapace-spec" "github.com/rsteube/carapace/pkg/ps" - "github.com/rsteube/carapace/pkg/style" "github.com/rsteube/carapace/pkg/xdg" "github.com/spf13/cobra" ) @@ -60,173 +54,38 @@ var rootCmd = &cobra.Command{ Config is written to [%v/carapace]. Specs are loaded from [%v/carapace/specs]. `, suppressErr(xdg.UserCacheDir), suppressErr(xdg.UserConfigDir), suppressErr(xdg.UserConfigDir)), - Args: cobra.MinimumNArgs(1), - ValidArgs: completers.Names(), + Args: cobra.MinimumNArgs(1), + DisableFlagParsing: true, Run: func(cmd *cobra.Command, args []string) { // since flag parsing is disabled do this manually - // TODO switch to cobra flag parsing with interspersed=false (redirect completion from completers/carapace_completer to here) switch args[0] { case "--macros": - if len(args) > 1 { - printMacro(args[1]) - } else { - printMacros() - } + macrosCmd.SetArgs(args[1:]) + macrosCmd.Execute() case "-h", "--help": cmd.Help() case "-v", "--version": println(cmd.Version) case "--list": - printCompleters() - case "--list=json": - printCompletersJson() + listCmd.SetArgs(args[1:]) + listCmd.Execute() case "--run": - _, spec, err := loadSpec(args[1]) - if err != nil { - fmt.Fprintln(cmd.ErrOrStderr(), err.Error()) - os.Exit(1) - } - - cmd := spec.ToCobra() - cmd.SetArgs(args[2:]) - cmd.Execute() // TODO handle error? + runCmd.SetArgs(args[1:]) + runCmd.Execute() case "--schema": - if schema, err := spec.Schema(); err != nil { - fmt.Fprintln(cmd.ErrOrStderr(), err.Error()) // TODO fail / exit 1 ? - } else { - fmt.Fprintln(cmd.OutOrStdout(), schema) - } - case "--scrape": - if len(args) > 1 { - scrape(args[1]) - } + schemaCmd.SetArgs(args[1:]) + schemaCmd.Execute() + case "--codegen": + codegenCmd.SetArgs(args[1:]) + codegenCmd.Execute() case "--style": - if len(args) > 1 { - if err := setStyle(args[1]); err != nil { - fmt.Fprintln(cmd.ErrOrStderr(), err.Error()) - } - } - case "_carapace": - shell := ps.DetermineShell() - if len(args) > 1 { - shell = args[1] - } - if len(args) <= 2 { - if err := shim.Update(); err != nil { - fmt.Fprintln(cmd.ErrOrStderr(), err.Error()) // TODO fail / exit 1 ? - } - - if err := updateSchema(); err != nil { // TODO do this only if needed - fmt.Fprintln(cmd.ErrOrStderr(), err.Error()) - } - - if err := createOverlayDir(); err != nil { // TODO do this only if needed - fmt.Fprintln(cmd.ErrOrStderr(), err.Error()) - } - } - - completers := completers.Names() - if os.Getenv("CARAPACE_ENV") == "0" { - filtered := make([]string, 0, len(completers)) - for _, name := range completers { - switch name { - case "get-env", "set-env", "unset-env": - default: - filtered = append(filtered, name) - - } - } - completers = filtered - } - - switch shell { - case "bash": - fmt.Fprintln(cmd.OutOrStdout(), lazyinit.Bash(completers)) - case "bash-ble": - fmt.Fprintln(cmd.OutOrStdout(), lazyinit.BashBle(completers)) - case "elvish": - fmt.Fprintln(cmd.OutOrStdout(), lazyinit.Elvish(completers)) - case "fish": - fmt.Fprintln(cmd.OutOrStdout(), lazyinit.Fish(completers)) - case "nushell": - fmt.Fprintln(cmd.OutOrStdout(), lazyinit.Nushell(completers)) - case "oil": - fmt.Fprintln(cmd.OutOrStdout(), lazyinit.Oil(completers)) - case "powershell": - fmt.Fprintln(cmd.OutOrStdout(), lazyinit.Powershell(completers)) - case "tcsh": - fmt.Fprintln(cmd.OutOrStdout(), lazyinit.Tcsh(completers)) - case "xonsh": - fmt.Fprintln(cmd.OutOrStdout(), lazyinit.Xonsh(completers)) - case "zsh": - fmt.Fprintln(cmd.OutOrStdout(), lazyinit.Zsh(completers)) - default: - fmt.Fprintln(os.Stderr, "could not determine shell") - } + styleCmd.SetArgs(args[1:]) + styleCmd.Execute() default: - if overlayPath, err := overlayPath(args[0]); err == nil && len(args) > 2 { // and arg[1] is a known shell - cmd := &cobra.Command{ - DisableFlagParsing: true, - CompletionOptions: cobra.CompletionOptions{ - DisableDefaultCmd: true, - }, - } - - // TODO yuck - command := args[0] - shell := args[1] - args[0] = "_carapace" - args[1] = "export" - os.Args[1] = "_carapace" - os.Args[2] = "export" - os.Setenv("CARAPACE_LENIENT", "1") - - carapace.Gen(cmd).PositionalAnyCompletion( - carapace.ActionCallback(func(c carapace.Context) carapace.Action { - batch := carapace.Batch() - specPath, err := completers.SpecPath(command) - if err != nil { - batch = append(batch, carapace.ActionImport([]byte(invokeCompleter(command)))) - } else { - out, err := specCompletion(specPath, args[1:]...) - if err != nil { - return carapace.ActionMessage(err.Error()) - } - - batch = append(batch, carapace.ActionImport([]byte(out))) - } - - batch = append(batch, overlayCompletion(overlayPath, args[1:]...)) - return batch.ToA() - }), - ) - - cmd.SetArgs(append([]string{"_carapace", shell}, args[2:]...)) - cmd.Execute() - } else { - if specPath, err := completers.SpecPath(args[0]); err == nil { - out, err := specCompletion(specPath, args[1:]...) - if err != nil { - fmt.Fprintln(cmd.ErrOrStderr(), err.Error()) - return - } - - // TODO revert the patching from specCompletion to use the integrated version for overlay to work (should move this somewhere else - best in specCompletion) - // TODO only patch completion script - out = strings.Replace(out, fmt.Sprintf("--spec '%v'", specPath), args[0], -1) - out = strings.Replace(out, fmt.Sprintf("'--spec', '%v'", specPath), fmt.Sprintf("'%v'", args[0]), -1) // xonsh callback - fmt.Fprint(cmd.OutOrStdout(), out) - } else { - fmt.Print(invokeCompleter(args[0])) - } - } + invokeCmd.SetArgs(args) + invokeCmd.Execute() } - }, - FParseErrWhitelist: cobra.FParseErrWhitelist{ - UnknownFlags: true, - }, - DisableFlagParsing: true, CompletionOptions: cobra.CompletionOptions{ DisableDefaultCmd: true, }, @@ -234,19 +93,6 @@ var rootCmd = &cobra.Command{ func suppressErr(f func() (string, error)) string { s, _ := f(); return s } -func printCompleters() { - maxlen := 0 - for _, name := range completers.Names() { - if len := len(name); len > maxlen { - maxlen = len - } - } - - for _, name := range completers.Names() { - fmt.Printf("%-"+strconv.Itoa(maxlen)+"v %v\n", name, completers.Description(name)) - } -} - func createOverlayDir() error { configDir, err := xdg.UserConfigDir() if err != nil { @@ -279,100 +125,6 @@ func overlayCompletion(overlayPath string, args ...string) carapace.Action { }) } -func printCompletersJson() { - // TODO move to completers package - type _completer struct { - Name string - Description string - Spec string `json:",omitempty"` - Overlay string `json:",omitempty"` - } - - _completers := make([]_completer, 0) - for _, name := range completers.Names() { - specPath, _ := completers.SpecPath(name) // TODO handle error (log?) - overlayPath, _ := completers.OverlayPath(name) // TODO handle error (log?) - _completers = append(_completers, _completer{ - Name: name, - Description: completers.Description(name), - Spec: specPath, - Overlay: overlayPath, - }) - } - if m, err := json.Marshal(_completers); err == nil { // TODO handle error (log?) - fmt.Println(string(m)) - } -} - -func printMacros() { - maxlen := 0 - names := make([]string, 0) - for name := range actions.MacroMap { - names = append(names, name) - if len := len(name); len > maxlen { - maxlen = len - } - } - - sort.Strings(names) - for _, name := range names { - fmt.Printf("%-"+strconv.Itoa(maxlen)+"v %v\n", name, actions.MacroDescriptions[name]) - } -} - -func printMacro(name string) { - if m, ok := actions.MacroMap[name]; ok { - path := strings.Replace(name, ".", "/", -1) - signature := "" - if s := m.Signature(); s != "" { - signature = fmt.Sprintf("(%v)", s) - } - - fmt.Printf(`signature: $_%v%v -description: %v -reference: https://pkg.go.dev/github.com/rsteube/carapace-bin/pkg/actions/%v#Action%v -`, name, signature, actions.MacroDescriptions[name], filepath.Dir(path), filepath.Base(path)) - } -} - -func invokeCompleter(completer string) string { - old := os.Stdout - r, w, _ := os.Pipe() - os.Stdout = w - - outC := make(chan string) - // copy the output in a separate goroutine so printing can't block indefinitely - go func() { - var buf bytes.Buffer - io.Copy(&buf, r) - outC <- buf.String() - }() - - os.Args[1] = "_carapace" - executeCompleter(completer) - - w.Close() - out := <-outC - os.Stdout = old - - executable, err := os.Executable() - if err != nil { - panic(err.Error()) // TODO exit with error message - } - executableName := filepath.Base(executable) - patched := strings.Replace(string(out), fmt.Sprintf("%v _carapace", executableName), fmt.Sprintf("%v %v", executableName, completer), -1) // general callback - patched = strings.Replace(patched, fmt.Sprintf("'%v', '_carapace'", executableName), fmt.Sprintf("'%v', '%v'", executableName, completer), -1) // xonsh callback - return patched - -} - -func setStyle(s string) error { - if splitted := strings.SplitN(s, "=", 2); len(splitted) == 2 { - return style.Set(splitted[0], splitted[1]) - } - return fmt.Errorf("invalid format: '%v'", s) -} - func updateSchema() error { confDir, err := xdg.UserConfigDir() if err != nil { @@ -415,16 +167,138 @@ func updateSchema() error { func Execute(version string) error { rootCmd.Version = version + + if len(os.Args) > 1 { + if os.Args[1] == "carapace" { + os.Args[1] = "_carapace" + } else if len(os.Args) < 4 && os.Args[1] == "_carapace" { + shell := ps.DetermineShell() + if len(os.Args) > 2 { + shell = os.Args[2] + } + + if err := shim.Update(); err != nil { + println(err.Error()) // TODO fail / exit 1 ? + } + + if err := updateSchema(); err != nil { // TODO do this only if needed + println(err.Error()) + } + + if err := createOverlayDir(); err != nil { // TODO do this only if needed + println(err.Error()) + } + + completers := completers.Names() + if os.Getenv("CARAPACE_ENV") == "0" { + filtered := make([]string, 0, len(completers)) + for _, name := range completers { + switch name { + case "get-env", "set-env", "unset-env": + default: + filtered = append(filtered, name) + + } + } + completers = filtered + } + + println(shell) + + switch shell { + case "bash": + fmt.Println(lazyinit.Bash(completers)) + case "bash-ble": + fmt.Println(lazyinit.BashBle(completers)) + case "elvish": + fmt.Println(lazyinit.Elvish(completers)) + case "fish": + fmt.Println(lazyinit.Fish(completers)) + case "nushell": + fmt.Println(lazyinit.Nushell(completers)) + case "oil": + fmt.Println(lazyinit.Oil(completers)) + case "powershell": + fmt.Println(lazyinit.Powershell(completers)) + case "tcsh": + fmt.Println(lazyinit.Tcsh(completers)) + case "xonsh": + fmt.Println(lazyinit.Xonsh(completers)) + case "zsh": + fmt.Println(lazyinit.Zsh(completers)) + default: + // TODO + // println("could not determine shell") + return rootCmd.Execute() + } + return nil + } + } return rootCmd.Execute() } func init() { + rootCmd.Flags().Bool("codegen", false, "generate code from spec file") rootCmd.Flags().Bool("list", false, "list completers") - rootCmd.Flags().String("run", "", "run spec") - rootCmd.Flags().String("scrape", "", "scrape spec to go code") - rootCmd.Flags().String("style", "", "set style") + rootCmd.Flags().Bool("macros", false, "list spec macros") + rootCmd.Flags().BoolP("help", "h", false, "help for carapace") + rootCmd.Flags().BoolP("version", "v", false, "version for carapace") + rootCmd.Flags().Bool("run", false, "run spec") + rootCmd.Flags().Bool("schema", false, "json schema for spec files") + rootCmd.Flags().Bool("style", false, "set style") + + rootCmd.MarkFlagsMutuallyExclusive( + "codegen", + "help", + "list", + "macros", + "run", + "schema", + "style", + "version", + ) + + carapace.Gen(rootCmd).PositionalCompletion( + carapace.ActionCallback(func(c carapace.Context) carapace.Action { + if strings.HasPrefix(c.Value, "-") { + cmd := &cobra.Command{} + cmd.Flags().AddFlagSet(rootCmd.Flags()) + return carapace.ActionExecute(cmd) + } + return action.ActionCompleters() + }), + ) + + carapace.Gen(rootCmd).PositionalAnyCompletion( + carapace.ActionCallback(func(c carapace.Context) carapace.Action { + if !strings.HasPrefix(c.Args[0], "-") { + return carapace.ActionExecute(invokeCmd) + } + switch c.Args[0] { + case "--macros": + return carapace.ActionExecute(macrosCmd).Shift(1) + case "--help": + return carapace.ActionValues() + case "-v", "--version": + return carapace.ActionValues() + case "--list": + return carapace.ActionExecute(listCmd).Shift(1).Usage("list") + case "--run": + return carapace.ActionExecute(runCmd).Shift(1) + case "--schema": + return carapace.ActionExecute(schemaCmd).Shift(1) + case "--scrape": + return carapace.ActionExecute(codegenCmd).Shift(1) + case "--style": + return carapace.ActionExecute(styleCmd).Shift(1) + default: + return carapace.ActionValues() + } + }), + ) for m, f := range actions.MacroMap { spec.AddMacro(m, f) } + spec.Register(rootCmd) } diff --git a/cmd/carapace/cmd/run.go b/cmd/carapace/cmd/run.go new file mode 100644 index 0000000000..7421a0e447 --- /dev/null +++ b/cmd/carapace/cmd/run.go @@ -0,0 +1,43 @@ +package cmd + +import ( + "fmt" + "os" + + "github.com/rsteube/carapace" + spec "github.com/rsteube/carapace-spec" + "github.com/spf13/cobra" +) + +var runCmd = &cobra.Command{ + Use: "--run", + Short: "", + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + _, spec, err := loadSpec(args[0]) + if err != nil { + fmt.Fprintln(cmd.ErrOrStderr(), err.Error()) + os.Exit(1) + } + + specCmd := spec.ToCobra() + + specCmd.SetArgs(args[1:]) + specCmd.Execute() // TODO handle error? + }, +} + +func init() { + carapace.Gen(runCmd).Standalone() + runCmd.Flags().SetInterspersed(false) + + carapace.Gen(runCmd).PositionalCompletion( + carapace.ActionFiles(".yaml"), + ) + + carapace.Gen(runCmd).PositionalAnyCompletion( + carapace.ActionCallback(func(c carapace.Context) carapace.Action { + return spec.ActionSpec(c.Args[0]).Shift(1) // TODO + }), + ) +} diff --git a/cmd/carapace/cmd/schema.go b/cmd/carapace/cmd/schema.go new file mode 100644 index 0000000000..2613bd31fb --- /dev/null +++ b/cmd/carapace/cmd/schema.go @@ -0,0 +1,26 @@ +package cmd + +import ( + "fmt" + + "github.com/rsteube/carapace" + spec "github.com/rsteube/carapace-spec" + "github.com/spf13/cobra" +) + +var schemaCmd = &cobra.Command{ + Use: "--codegen", + Short: "", + Run: func(cmd *cobra.Command, args []string) { + if schema, err := spec.Schema(); err != nil { + fmt.Fprintln(cmd.ErrOrStderr(), err.Error()) // TODO fail / exit 1 ? + } else { + fmt.Fprintln(cmd.OutOrStdout(), schema) + } + }, +} + +func init() { + carapace.Gen(schemaCmd).Standalone() + +} diff --git a/cmd/carapace/cmd/style.go b/cmd/carapace/cmd/style.go new file mode 100644 index 0000000000..abc7aa7270 --- /dev/null +++ b/cmd/carapace/cmd/style.go @@ -0,0 +1,36 @@ +package cmd + +import ( + "fmt" + "strings" + + "github.com/rsteube/carapace" + "github.com/rsteube/carapace/pkg/style" + "github.com/spf13/cobra" +) + +var styleCmd = &cobra.Command{ + Use: "--style [config]", + Short: "", + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + if err := setStyle(args[0]); err != nil { + fmt.Fprintln(cmd.ErrOrStderr(), err.Error()) + } + }, +} + +func init() { + carapace.Gen(styleCmd).Standalone() + + carapace.Gen(styleCmd).PositionalCompletion( + carapace.ActionStyleConfig(), + ) +} + +func setStyle(s string) error { + if splitted := strings.SplitN(s, "=", 2); len(splitted) == 2 { + return style.Set(splitted[0], splitted[1]) + } + return fmt.Errorf("invalid format: '%v'", s) +} diff --git a/cmd/carapace/main.go b/cmd/carapace/main.go index c0ab9d2cf6..be4a6a1342 100644 --- a/cmd/carapace/main.go +++ b/cmd/carapace/main.go @@ -1,6 +1,8 @@ package main -import "github.com/rsteube/carapace-bin/cmd/carapace/cmd" +import ( + "github.com/rsteube/carapace-bin/cmd/carapace/cmd" +) var version = "develop" diff --git a/completers/carapace_completer/cmd/root.go b/completers/carapace_completer/cmd/root.go deleted file mode 100644 index dbc2b92473..0000000000 --- a/completers/carapace_completer/cmd/root.go +++ /dev/null @@ -1,187 +0,0 @@ -package cmd - -import ( - "encoding/json" - "strings" - - "github.com/rsteube/carapace" - spec "github.com/rsteube/carapace-spec" - "github.com/rsteube/carapace/pkg/style" - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -var rootCmd = &cobra.Command{ - Use: "carapace", - Short: "multi-shell multi-command argument completer", - Long: "https://github.com/rsteube/carapace-bin", - DisableFlagParsing: true, - CompletionOptions: cobra.CompletionOptions{ - DisableDefaultCmd: true, - }, - Run: func(cmd *cobra.Command, args []string) {}, -} - -func flagCmd(args []string) *cobra.Command { - cmd := &cobra.Command{ - Use: "carapace", - CompletionOptions: cobra.CompletionOptions{ - DisableDefaultCmd: true, - }, - Run: func(cmd *cobra.Command, args []string) {}, - } - - cmd.Flags().BoolP("help", "h", false, "help for carapace") - cmd.Flags().String("list", "", "list completers") - cmd.Flags().String("macros", "test local json schema", "list spec macros") - cmd.Flags().String("run", "", "run spec") - cmd.Flags().Bool("schema", false, "json schema for spec files") - cmd.Flags().String("scrape", "", "scrape spec to go code") - cmd.Flags().String("style", "", "set style") - cmd.Flags().BoolP("version", "v", false, "version for carapace") - - cmd.Flag("list").NoOptDefVal = " " - - if len(args) > 0 { - if f := cmd.Flag(strings.TrimPrefix(args[0], "--")); len(args) > 1 || f != nil && f.Value.Type() == "bool" { - cmd.Flags().VisitAll(func(f *pflag.Flag) { - f.Changed = true // only one flag shall be completed so fake the changed state - }) - } - } - - carapace.Gen(cmd).FlagCompletion(carapace.ActionMap{ - "list": carapace.ActionValues("json"), - "macros": carapace.ActionExecCommand("carapace", "--macros")(func(output []byte) carapace.Action { - lines := strings.Split(string(output), "\n") - - vals := make([]string, 0) - for _, line := range lines[:len(lines)-1] { - if fields := strings.Fields(line); len(fields) > 1 { - vals = append(vals, fields[0], strings.Join(fields[1:], " ")) - } else { - vals = append(vals, fields[0], "") - } - } - return carapace.ActionValuesDescribed(vals...).Invoke(carapace.Context{}).ToMultiPartsA(".") - }), - "run": carapace.ActionFiles(".yaml"), - "scrape": carapace.ActionFiles(".yaml"), - "style": carapace.ActionStyleConfig().NoSpace(), - }) - - carapace.Gen(cmd).PositionalAnyCompletion( - carapace.ActionCallback(func(c carapace.Context) carapace.Action { - if len(args) > 0 && args[0] == "--macros" { - c.Args = args[2:] - return spec.ActionMacro("$_" + args[1]).Invoke(c).ToA() - } - return carapace.ActionValues() - }), - ) - - return cmd -} - -func posCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "carapace", - DisableFlagParsing: true, - CompletionOptions: cobra.CompletionOptions{ - DisableDefaultCmd: true, - }, - Run: func(cmd *cobra.Command, args []string) {}, - } - - carapace.Gen(cmd).PositionalCompletion( - ActionCompleters(), - carapace.ActionStyledValues( - "bash", "#d35673", - "bash-ble", "#c2039a", - "elvish", "#ffd6c9", - "export", style.Default, - "fish", "#7ea8fc", - "ion", "#0e5d6d", - "nushell", "#29d866", - "oil", "#373a36", - "powershell", "#e8a16f", - "spec", style.Default, - "tcsh", "#412f09", - "xonsh", "#a8ffa9", - "zsh", "#efda53", - ), - carapace.ActionCallback(func(c carapace.Context) carapace.Action { - return carapace.ActionValues(c.Args[0]) - }), - ) - - carapace.Gen(cmd).PositionalAnyCompletion( - carapace.ActionCallback(func(c carapace.Context) carapace.Action { - args := []string{c.Args[0], "export", c.Args[0]} - args = append(args, c.Args[3:]...) - args = append(args, c.Value) - return carapace.ActionExecCommand("carapace", args...)(func(output []byte) carapace.Action { - if string(output) == "" { - return carapace.ActionValues() - } - return carapace.ActionImport(output) - }) - }), - ) - - return cmd -} - -func Execute() error { - return rootCmd.Execute() -} - -func init() { - carapace.Gen(rootCmd).Standalone() - - carapace.Gen(rootCmd).PositionalAnyCompletion( - carapace.ActionCallback(func(c carapace.Context) carapace.Action { - if len(c.Args) == 0 { - return carapace.Batch( - carapace.ActionExecute(flagCmd(c.Args)), - carapace.ActionExecute(posCmd()), - ).ToA() - } - - if strings.HasPrefix(c.Args[0], "-") { - return carapace.ActionExecute(flagCmd(c.Args)) - } - return carapace.ActionExecute(posCmd()) - }), - ) -} - -func ActionCompleters() carapace.Action { - return carapace.ActionCallback(func(c carapace.Context) carapace.Action { - return carapace.ActionExecCommand("carapace", "--list=json")(func(output []byte) carapace.Action { - var completers []struct { - Name string - Description string - Spec string - Overlay string - } - if err := json.Unmarshal(output, &completers); err != nil { - return carapace.ActionMessage(err.Error()) - } - - vals := make([]string, 0, len(completers)) - for _, completer := range completers { - s := style.Default - if completer.Spec != "" { - s = style.Blue - } - if completer.Overlay != "" { - s = style.Of(s, style.Underlined) - } - - vals = append(vals, completer.Name, completer.Description, s) - } - return carapace.ActionStyledValuesDescribed(vals...) - }) - }) -} diff --git a/completers/carapace_completer/main.go b/completers/carapace_completer/main.go deleted file mode 100644 index af61b37a5a..0000000000 --- a/completers/carapace_completer/main.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "github.com/rsteube/carapace-bin/completers/carapace_completer/cmd" - -func main() { - cmd.Execute() -} diff --git a/completers/glab_completer/cmd/incident_list.go b/completers/glab_completer/cmd/incident_list.go index 193d59b3da..28a439ef6a 100644 --- a/completers/glab_completer/cmd/incident_list.go +++ b/completers/glab_completer/cmd/incident_list.go @@ -2,7 +2,7 @@ package cmd import ( "github.com/rsteube/carapace" - "github.com/rsteube/carapace-bin/completers_release/glab_completer/cmd/action" + "github.com/rsteube/carapace-bin/completers/glab_completer/cmd/action" "github.com/spf13/cobra" ) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 6a6db6a19f..5c9fe07512 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -11,8 +11,8 @@ - [Embed](./spec/embed.md) - [Run](./spec/run.md) - [Shim](./spec/shim.md) - - [Generate](./spec/generate.md) - [Scrape](./spec/scrape.md) + - [Codegen](./spec/codegen.md) - [Examples](./spec/examples.md) - [Macros](./spec/macros.md) - [Overlay](./overlay.md) diff --git a/docs/src/spec/codegen.md b/docs/src/spec/codegen.md new file mode 100644 index 0000000000..ff10d406f6 --- /dev/null +++ b/docs/src/spec/codegen.md @@ -0,0 +1,9 @@ +# Codegen + +[Specs](../spec.md) can be used to generate go code. + +```sh +carapace --codegen [spec] +``` + +![](./scrape.cast) diff --git a/docs/src/spec/generate.md b/docs/src/spec/generate.md deleted file mode 100644 index 58a594fc4c..0000000000 --- a/docs/src/spec/generate.md +++ /dev/null @@ -1,39 +0,0 @@ -# Generate - -[Specs](../spec.md) can also be generated. - -## Clap - -For [clap](https://github.com/clap-rs/clap) use [carapace-spec-clap](https://github.com/rsteube/carapace-spec-clap). - -![](./generate-clap.cast) - -## Cobra - -For [cobra](https://github.com/spf13/cobra) use [carapace](https://github.com/rsteube/carapace). - -![](./generate-cobra.cast) - -## Kingpin - -For [kingpin](https://github.com/alecthomas/kingpin) use [carapace-spec-kingpin](https://github.com/rsteube/carapace-spec-kingpin). - -![](./generate-kingpin.cast) - -## Kong - -For [kong](https://github.com/alecthomas/kong) use [carapace-spec-kong](https://github.com/rsteube/carapace-spec-kong). - -![](./generate-kong.cast) - -## Man - -For manpages use [carapace-spec-man](https://github.com/rsteube/carapace-spec-man). - -![](./generate-man.cast) - -## Urfavecli - -For [urfavecli](https://github.com/urfave/cli) use [carapce-spec-urfavecli](https://github.com/rsteube/carapace-spec-urfavecli). - -![](./generate-urfavecli.cast) diff --git a/docs/src/spec/scrape.md b/docs/src/spec/scrape.md index 20e689c8d6..ab53171e61 100644 --- a/docs/src/spec/scrape.md +++ b/docs/src/spec/scrape.md @@ -1,9 +1,39 @@ # Scrape -[Specs](../spec.md) can be scraped to go code. +Command structure from various tools can be scraped to [Specs](../spec.md). -```sh -carapace --scrape [spec] -``` +## Clap -![](./scrape.cast) +For [clap](https://github.com/clap-rs/clap) use [carapace-spec-clap](https://github.com/rsteube/carapace-spec-clap). + +![](./generate-clap.cast) + +## Cobra + +For [cobra](https://github.com/spf13/cobra) use [carapace](https://github.com/rsteube/carapace). + +![](./generate-cobra.cast) + +## Kingpin + +For [kingpin](https://github.com/alecthomas/kingpin) use [carapace-spec-kingpin](https://github.com/rsteube/carapace-spec-kingpin). + +![](./generate-kingpin.cast) + +## Kong + +For [kong](https://github.com/alecthomas/kong) use [carapace-spec-kong](https://github.com/rsteube/carapace-spec-kong). + +![](./generate-kong.cast) + +## Man + +For manpages use [carapace-spec-man](https://github.com/rsteube/carapace-spec-man). + +![](./generate-man.cast) + +## Urfavecli + +For [urfavecli](https://github.com/urfave/cli) use [carapce-spec-urfavecli](https://github.com/rsteube/carapace-spec-urfavecli). + +![](./generate-urfavecli.cast) diff --git a/go.mod b/go.mod index 2cb51214c8..00cfcc7bee 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,9 @@ go 1.21 require ( github.com/pelletier/go-toml v1.9.5 github.com/rsteube/carapace v0.47.4 - github.com/rsteube/carapace-bridge v0.1.5 + github.com/rsteube/carapace-bridge v0.1.7 github.com/rsteube/carapace-shlex v0.1.1 - github.com/rsteube/carapace-spec v0.11.1 + github.com/rsteube/carapace-spec v0.12.0 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 golang.org/x/mod v0.14.0 @@ -19,7 +19,7 @@ require ( github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/invopop/jsonschema v0.9.0 // indirect + github.com/invopop/jsonschema v0.12.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect ) diff --git a/go.sum b/go.sum index 1636bfe92a..ceaa93c609 100644 --- a/go.sum +++ b/go.sum @@ -7,8 +7,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/invopop/jsonschema v0.9.0 h1:m1Fe5PN4X9V7P1TCF+pA8Xly3Vj3pY905klC++8oOpM= -github.com/invopop/jsonschema v0.9.0/go.mod h1:uMhbTEOXoPcOKzdYRfk914W6UTGA/cVcgEQxXh1MJ7g= +github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= +github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= @@ -16,17 +16,16 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rsteube/carapace v0.46.2/go.mod h1:4ZC5bulItu9t9sZ5yPcHgPREd8rPf274Q732n+wfl/o= github.com/rsteube/carapace v0.47.4 h1:LwnkFsvRxc2WhZjM63QS7sCi3DlM9XGuATQM5rehgps= github.com/rsteube/carapace v0.47.4/go.mod h1:4ZC5bulItu9t9sZ5yPcHgPREd8rPf274Q732n+wfl/o= -github.com/rsteube/carapace-bridge v0.1.5 h1:7gpvNL5Ci8WieuFo6hLbaRfoBUtqJyn0B9np+oyQrh0= -github.com/rsteube/carapace-bridge v0.1.5/go.mod h1:dvBtSiddmt27551UCS8p7+tWjGgDXDWY1cvZrrA3tPQ= +github.com/rsteube/carapace-bridge v0.1.7 h1:g2Z908p7oZuApGOsfypHhdqG1ZoKk450zEpDsKNqpkg= +github.com/rsteube/carapace-bridge v0.1.7/go.mod h1:acHAKkiojM+ORlijGVvIDJ/DuyiH1Q5eyyga5fA+tFE= github.com/rsteube/carapace-pflag v0.2.0 h1:EYqFO9Haib3NDCPqKu0VxOGi9YQBkXk1IzlHdT0M0vw= github.com/rsteube/carapace-pflag v0.2.0/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/rsteube/carapace-shlex v0.1.1 h1:fRQEBBKyYKm4TXUabm4tzH904iFWSmXJl3UZhMfQNYU= github.com/rsteube/carapace-shlex v0.1.1/go.mod h1:zPw1dOFwvLPKStUy9g2BYKanI6bsQMATzDMYQQybo3o= -github.com/rsteube/carapace-spec v0.11.1 h1:LUNFbGOucWj4C74JMLvPuqKDFNGFGMHunWyiUfTM0BU= -github.com/rsteube/carapace-spec v0.11.1/go.mod h1:1rjCeoupGdnfPaMMfYr7PQDDHk8G8HeL9sSdyHO5UHU= +github.com/rsteube/carapace-spec v0.12.0 h1:ydsHsc0uku6K7DT18TAw4kpooyhbnATc9EIFO6zwrEY= +github.com/rsteube/carapace-spec v0.12.0/go.mod h1:kxUqKja4vvbc7h/8L8gpeDxzGGNL3pD4bu5ipAso/zM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=