diff --git a/cmd/core/cmd/api.go b/cmd/core/cmd/api.go new file mode 100644 index 00000000..2a2e5410 --- /dev/null +++ b/cmd/core/cmd/api.go @@ -0,0 +1,14 @@ +package cmd + +import ( + "github.com/leaanthony/clir" +) + +// AddAPICommands adds the 'api' command and its subcommands to the given parent command. +func AddAPICommands(parent *clir.Command) { + // Create the 'api' command + apiCmd := parent.NewSubCommand("api", "Tools for managing service APIs") + + // Add the 'sync' command to 'api' + AddSyncCommand(apiCmd) +} diff --git a/cmd/core/cmd/build.go b/cmd/core/cmd/build.go index 3695d374..d5f85289 100644 --- a/cmd/core/cmd/build.go +++ b/cmd/core/cmd/build.go @@ -10,9 +10,22 @@ import ( "strings" tea "github.com/charmbracelet/bubbletea" - "github.com/spf13/cobra" + "github.com/leaanthony/clir" ) +// AddBuildCommand adds the build command to the clir app. +func AddBuildCommand(app *clir.Cli) { + buildCmd := app.NewSubCommand("build", "Build a Wails application") + buildCmd.LongDescription("This command allows you to build a Wails application, optionally selecting a custom HTML entry point.") + buildCmd.Action(func() error { + p := tea.NewProgram(initialModel()) + if _, err := p.Run(); err != nil { + return fmt.Errorf("Alas, there's been an error: %w", err) + } + return nil + }) +} + // viewState represents the current view of the TUI. type viewState int @@ -284,20 +297,3 @@ func buildWailsCmd(htmlPath string) tea.Cmd { return buildFinishedMsg(fmt.Sprintf("Wails build successful!\n%s", string(out))) } } - -var buildCmd = &cobra.Command{ - Use: "build", - Short: "Build a Wails application", - Long: `This command allows you to build a Wails application, optionally selecting a custom HTML entry point.`, - Run: func(cmd *cobra.Command, args []string) { - p := tea.NewProgram(initialModel()) - if _, err := p.Run(); err != nil { - fmt.Printf("Alas, there's been an error: %v", err) - os.Exit(1) - } - }, -} - -func init() { - rootCmd.AddCommand(buildCmd) -} diff --git a/cmd/core/cmd/root.go b/cmd/core/cmd/root.go index a5002afc..e43f6a88 100644 --- a/cmd/core/cmd/root.go +++ b/cmd/core/cmd/root.go @@ -2,25 +2,14 @@ package cmd import ( "fmt" - "os" - "strings" - "github.com/AlecAivazis/survey/v2" - "github.com/c-bata/go-prompt" "github.com/charmbracelet/lipgloss" - "mvdan.cc/sh/v3/syntax" - // "github.com/rivo/tview" // Disabled for now due to console issues "github.com/common-nighthawk/go-figure" - "github.com/spf13/cobra" + "github.com/leaanthony/clir" ) // Define some global lipgloss styles for a Tailwind dark theme var ( - headerStyle = lipgloss.NewStyle(). - Foreground(lipgloss.Color("#e2e8f0")). // Tailwind gray‑200 - Bold(true). - Padding(0, 1) - coreStyle = lipgloss.NewStyle(). Foreground(lipgloss.Color("#3b82f6")). // Tailwind blue-500 Bold(true) @@ -31,8 +20,7 @@ var ( descriptionStyle = lipgloss.NewStyle(). Foreground(lipgloss.Color("#e2e8f0")). // Tailwind gray-200 - //Background(lipgloss.Color("#1a202c")). // Tailwind gray-900 - Padding(1, 2) + Padding(1, 2) linkStyle = lipgloss.NewStyle(). Foreground(lipgloss.Color("#3b82f6")). // Tailwind blue-500 @@ -40,43 +28,51 @@ var ( taglineStyle = lipgloss.NewStyle(). Foreground(lipgloss.Color("#e2e8f0")). - PaddingTop(2).PaddingLeft(8).PaddingBottom(1). // vertical spacing around the tagline - Align(lipgloss.Center) // centre it under the big words - + PaddingTop(2).PaddingLeft(8).PaddingBottom(1). + Align(lipgloss.Center) ) -var rootCmd = &cobra.Command{ - Use: "core", - Short: coreStyle.Render("Core") + subPkgStyle.Render(".Framework") + " is a CLI tool for managing applications", - Long: descriptionStyle.Render( - "\n" + - " " + coreStyle.Render("Core") + subPkgStyle.Render(".Framework") + " " + coreStyle.Render("Version V0.0.1") + "\n\n\n" + - "For more information: " + linkStyle.Render("https://core.help") + " and " + linkStyle.Render("https://lt.hn") + "\n\n" + - "managing various aspects of Core.Framework applications."), - Run: func(cmd *cobra.Command, args []string) { - // Default behaviour if no subcommand is given - if len(args) == 0 { - showBanner() - } - err := cmd.Help() - if err != nil { - return - } - }, -} +// Execute creates the root CLI application and runs it. +func Execute() error { + // Create a new clir instance, removing the description and version to avoid the default header. + app := clir.NewCli("core", "", "") -func Execute() { - if err := rootCmd.Execute(); err != nil { - _, _ = fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(1) - } -} + // Recreate the header with better alignment. + title := coreStyle.Render("Core") + subPkgStyle.Render(".Framework") + version := coreStyle.Render("Version V0.0.1") + titleLine := lipgloss.JoinHorizontal(lipgloss.Top, title, lipgloss.NewStyle().Width(4).Render(""), version) -func init() { - // Here you can define global flags and command setup. - if os.Getenv("CORE_DEV_TOOLS") == "true" { - initDevTools() - } + linksLine := "For more information: " + linkStyle.Render("https://core.help") + " and " + linkStyle.Render("https://lt.hn") + descLine := "managing various aspects of Core.Framework applications." + + headerBlock := lipgloss.JoinVertical(lipgloss.Center, + titleLine, + "", // blank line + "", // blank line + linksLine, + "", // blank line + descLine, + ) + + // Set the long description using a centered container. + app.LongDescription(lipgloss.NewStyle().Padding(1, 2).Align(lipgloss.Center).Render(headerBlock)) + + // Default action when no command is given is to show the banner and then the help. + app.Action(func() error { + showBanner() + app.PrintHelp() + return nil + }) + + // Add the top-level commands + devCmd := app.NewSubCommand("dev", "Development tools for Core Framework") + AddAPICommands(devCmd) + + AddBuildCommand(app) + AddTviewCommand(app) + + // Run the application + return app.Run() } // showBanner generates and prints the ASCII art banner. @@ -84,7 +80,6 @@ func showBanner() { coreFig := figure.NewFigure("Core", "big", true) frameworkFig := figure.NewFigure("Framework", "big", true) - // Apply the colour styles to the Figlet output. coreBlock := coreStyle.Render(coreFig.String()) frameworkBlock := subPkgStyle.Render(frameworkFig.String()) @@ -95,69 +90,9 @@ func showBanner() { ) output := lipgloss.JoinVertical(lipgloss.Left, - bigWords, // big “Core Framework” - tagline, // bottom tagline, centred + bigWords, + tagline, ) - // Print the whole thing. + fmt.Print(output) } - -func initDevTools() { - // Example usage for survey - name := "" - surveyPrompt := &survey.Input{ - Message: "What is your name?", - } - _ = survey.AskOne(surveyPrompt, &name) - fmt.Printf("Hello, %s (from survey)!\n", name) - - // Example usage for go-prompt - fmt.Println("Starting go-prompt (type 'exit' to quit)...") - executor := func(in string) { - fmt.Printf("You typed: %s\n", in) - if in == "exit" { - os.Exit(0) - } - } - completer := func(d prompt.Document) []prompt.Suggest { - s := []prompt.Suggest{ - {Text: "hello", Description: "Say hello"}, - {Text: "world", Description: "Say world"}, - {Text: "exit", Description: "Exit the prompt"}, - } - return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true) - } - // go-prompt will now run synchronously for the demo. - prompt.New(executor, completer, prompt.OptionPrefix(">>> ")).Run() - - // Example usage for lipgloss - // Using the global descriptionStyle for consistency - fmt.Println(descriptionStyle.Render("Hello from Lipgloss!")) - - // Example usage for mvdan.cc/sh/v3/syntax - parser := syntax.NewParser() - word, err := parser.Parse(strings.NewReader("echo hello world"), "") - if err != nil { - fmt.Printf("Error parsing shell command: %v\n", err) - } else { - // For demonstration, just print the parsed statement. - fmt.Printf("Parsed shell command: %v\n", word.Stmts[0]) - } - - // The tview example is disabled for now due to console issues. - // Uncomment the following block to re-enable it. - /* - app := tview.NewApplication() - box := tview.NewBox(). - SetBorder(true). - SetTitle("Hello from tview!") - - go func() { - if err := app.SetRoot(box, true).Run(); err != nil { - panic(err) - } - }() - - time.Sleep(2 * time.Second) - */ -} diff --git a/cmd/core/cmd/sync.go b/cmd/core/cmd/sync.go new file mode 100644 index 00000000..2c9fe24e --- /dev/null +++ b/cmd/core/cmd/sync.go @@ -0,0 +1,160 @@ +package cmd + +import ( + "bytes" + "fmt" + "go/ast" + "go/parser" + "go/token" + "os" + "path/filepath" + "text/template" + + "github.com/leaanthony/clir" + "golang.org/x/text/cases" + "golang.org/x/text/language" +) + +// AddSyncCommand adds the 'sync' command to the given parent command. +func AddSyncCommand(parent *clir.Command) { + syncCmd := parent.NewSubCommand("sync", "Synchronizes the public service APIs with their internal implementations.") + syncCmd.LongDescription("This command scans the 'pkg' directory for services and ensures that the\ntop-level public API for each service is in sync with its internal implementation.\nIt automatically generates the necessary Go files with type aliases.") + syncCmd.Action(func() error { + if err := runSync(); err != nil { + return fmt.Errorf("Error: %w", err) + } + fmt.Println("Public APIs synchronized successfully.") + return nil + }) +} + +type symbolInfo struct { + Name string + Kind string // "var", "func", "type", "const" +} + +func runSync() error { + pkgDir := "pkg" + internalDirs, err := os.ReadDir(pkgDir) + if err != nil { + return fmt.Errorf("failed to read pkg directory: %w", err) + } + + for _, dir := range internalDirs { + if !dir.IsDir() || dir.Name() == "core" { + continue + } + + serviceName := dir.Name() + internalFile := filepath.Join(pkgDir, serviceName, serviceName+".go") + publicDir := serviceName + publicFile := filepath.Join(publicDir, serviceName+".go") + + if _, err := os.Stat(internalFile); os.IsNotExist(err) { + continue + } + + symbols, err := getExportedSymbols(internalFile) + if err != nil { + return fmt.Errorf("error getting symbols for service '%s': %w", serviceName, err) + } + + if err := generatePublicAPIFile(publicDir, publicFile, serviceName, symbols); err != nil { + return fmt.Errorf("error generating public API file for service '%s': %w", serviceName, err) + } + } + + return nil +} + +func getExportedSymbols(path string) ([]symbolInfo, error) { + fset := token.NewFileSet() + node, err := parser.ParseFile(fset, path, nil, parser.ParseComments) + if err != nil { + return nil, err + } + + var symbols []symbolInfo + for name, obj := range node.Scope.Objects { + if ast.IsExported(name) { + kind := "unknown" + switch obj.Kind { + case ast.Con: + kind = "const" + case ast.Var: + kind = "var" + case ast.Fun: + kind = "func" + case ast.Typ: + kind = "type" + } + if kind != "unknown" { + symbols = append(symbols, symbolInfo{Name: name, Kind: kind}) + } + } + } + return symbols, nil +} + +const publicAPITemplate = `// package {{.ServiceName}} provides the public API for the {{.ServiceName}} service. +package {{.ServiceName}} + +import ( + // Import the internal implementation with an alias. + impl "github.com/Snider/Core/pkg/{{.ServiceName}}" + + // Import the core contracts to re-export the interface. + "github.com/Snider/Core/pkg/core" +) + +{{range .Symbols}} +{{- if eq .Kind "type"}} +// {{.Name}} is the public type for the {{.Name}} service. It is a type alias +// to the underlying implementation, making it transparent to the user. +type {{.Name}} = impl.{{.Name}} +{{else if eq .Kind "const"}} +// {{.Name}} is a public constant that points to the real constant in the implementation package. +const {{.Name}} = impl.{{.Name}} +{{else if eq .Kind "var"}} +// {{.Name}} is a public variable that points to the real variable in the implementation package. +var {{.Name}} = impl.{{.Name}} +{{else if eq .Kind "func"}} +// {{.Name}} is a public function that points to the real function in the implementation package. +var {{.Name}} = impl.{{.Name}} +{{end}} +{{end}} + +// {{.InterfaceName}} is the public interface for the {{.ServiceName}} service. +type {{.InterfaceName}} = core.{{.InterfaceName}} +` + +func generatePublicAPIFile(dir, path, serviceName string, symbols []symbolInfo) error { + if err := os.MkdirAll(dir, os.ModePerm); err != nil { + return err + } + + tmpl, err := template.New("publicAPI").Parse(publicAPITemplate) + if err != nil { + return err + } + + tcaser := cases.Title(language.English) + interfaceName := tcaser.String(serviceName) + + data := struct { + ServiceName string + Symbols []symbolInfo + InterfaceName string + }{ + ServiceName: serviceName, + Symbols: symbols, + InterfaceName: interfaceName, + } + + var buf bytes.Buffer + if err := tmpl.Execute(&buf, data); err != nil { + return err + } + + return os.WriteFile(path, buf.Bytes(), 0644) +} diff --git a/cmd/core/cmd/tview.go b/cmd/core/cmd/tview.go index 306b88c7..be954d2f 100644 --- a/cmd/core/cmd/tview.go +++ b/cmd/core/cmd/tview.go @@ -4,20 +4,15 @@ import ( "fmt" "os" + "github.com/leaanthony/clir" "github.com/rivo/tview" - "github.com/spf13/cobra" ) -func init() { - rootCmd.AddCommand(tviewCmd) -} - -var tviewCmd = &cobra.Command{ - Use: "tview-example", - Short: "Runs a tview example to demonstrate its capabilities", - Long: `This command launches a simple tview application to showcase its full-screen terminal UI features.`, - Run: func(cmd *cobra.Command, args []string) { - // Removed: fmt.Println("Starting tview example...") to prevent visual artifacts +// AddTviewCommand adds the tview-example command to the clir app. +func AddTviewCommand(app *clir.Cli) { + tviewCmd := app.NewSubCommand("tview-example", "Runs a tview example to demonstrate its capabilities") + tviewCmd.LongDescription("This command launches a simple tview application to showcase its full-screen terminal UI features.") + tviewCmd.Action(func() error { app := tview.NewApplication() box := tview.NewBox(). SetBorder(true). @@ -26,5 +21,6 @@ var tviewCmd = &cobra.Command{ fmt.Fprintf(os.Stderr, "Error running tview app: %v\n", err) os.Exit(1) } - }, + return nil + }) } diff --git a/cmd/core/go.mod b/cmd/core/go.mod index c2894875..373b6079 100644 --- a/cmd/core/go.mod +++ b/cmd/core/go.mod @@ -3,14 +3,13 @@ module github.com/Snider/Core/cmd/core go 1.23.0 require ( - github.com/AlecAivazis/survey/v2 v2.3.7 - github.com/c-bata/go-prompt v0.2.6 github.com/charmbracelet/bubbletea v0.26.6 github.com/charmbracelet/lipgloss v1.1.0 github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be + github.com/leaanthony/clir v1.7.0 github.com/rivo/tview v0.42.0 github.com/spf13/cobra v1.8.0 - mvdan.cc/sh/v3 v3.12.0 + golang.org/x/text v0.21.0 ) require ( @@ -23,23 +22,17 @@ require ( github.com/gdamore/encoding v1.0.1 // indirect github.com/gdamore/tcell/v2 v2.8.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/mattn/go-colorable v0.1.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/mattn/go-tty v0.0.3 // indirect - github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.16.0 // indirect - github.com/pkg/term v1.2.0-beta.2 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect golang.org/x/sync v0.10.0 // indirect golang.org/x/sys v0.33.0 // indirect golang.org/x/term v0.32.0 // indirect - golang.org/x/text v0.21.0 // indirect ) diff --git a/cmd/core/go.sum b/cmd/core/go.sum index 21c0c8fb..3c101e6c 100644 --- a/cmd/core/go.sum +++ b/cmd/core/go.sum @@ -1,11 +1,5 @@ -github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= -github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= -github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= -github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= -github.com/c-bata/go-prompt v0.2.6 h1:POP+nrHE+DfLYx370bedwNhsqmpCUynWPxuHi0C5vZI= -github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY= github.com/charmbracelet/bubbletea v0.26.6 h1:zTCWSuST+3yZYZnVSvbXwKOPRSNZceVeqpzOLN2zq1s= github.com/charmbracelet/bubbletea v0.26.6/go.mod h1:dz8CWPlfCCGLFbBlTY4N7bjLiyOGDJEnd2Muu7pOWhk= github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= @@ -21,80 +15,42 @@ github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNE github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ= github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= -github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -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/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw= github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo= github.com/gdamore/tcell/v2 v2.8.1 h1:KPNxyqclpWpWQlPLx6Xui1pMk8S+7+R37h3g07997NU= github.com/gdamore/tcell/v2 v2.8.1/go.mod h1:bj8ori1BG3OYMjmb3IklZVWfZUJ1UBQt9JXrOCOhGWw= -github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= -github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= -github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leaanthony/clir v1.7.0 h1:xiAnhl7ryPwuH3ERwPWZp/pCHk8wTeiwuAOt6MiNyAw= +github.com/leaanthony/clir v1.7.0/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw= -github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= -github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI= -github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= -github.com/pkg/term v1.2.0-beta.2 h1:L3y/h2jkuBVFdWiJvNfYfKmzcCnILw7mJWm2JQuMppw= -github.com/pkg/term v1.2.0-beta.2/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= -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/rivo/tview v0.42.0 h1:b/ftp+RxtDsHSaynXTbJb+/n/BxDEi+W3UfF5jILK6c= github.com/rivo/tview v0.42.0/go.mod h1:cSfIYfhpSGCjp3r/ECJb+GKS7cGJnqV8vfjQPwoXyfY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= -github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= 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= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -119,7 +75,6 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= @@ -128,13 +83,6 @@ golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -163,7 +111,6 @@ golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= @@ -179,8 +126,4 @@ golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58 golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -mvdan.cc/sh/v3 v3.12.0 h1:ejKUR7ONP5bb+UGHGEG/k9V5+pRVIyD+LsZz7o8KHrI= -mvdan.cc/sh/v3 v3.12.0/go.mod h1:Se6Cj17eYSn+sNooLZiEUnNNmNxg0imoYlTu4CyaGyg= diff --git a/cmd/core/main.go b/cmd/core/main.go index 0a5d69c7..ec387c86 100644 --- a/cmd/core/main.go +++ b/cmd/core/main.go @@ -5,5 +5,8 @@ import ( ) func main() { - cmd.Execute() + err := cmd.Execute() + if err != nil { + return + } }