on main help sign in
refactor: move run to its own file
867484bCarlos Alexandro Becker
internal/cmd/root.go+3−50
@@ -6,7 +6,6 @@ import (
6 "io"
6 "io"
7 "log/slog"
7 "log/slog"
8 "os"
8 "os"
9− "strings"
10
9
11 tea "github.com/charmbracelet/bubbletea/v2"
10 tea "github.com/charmbracelet/bubbletea/v2"
12 "github.com/charmbracelet/crush/internal/app"
11 "github.com/charmbracelet/crush/internal/app"
@@ -26,7 +25,6 @@ func init() {
26 rootCmd.Flags().BoolP("help", "h", false, "Help")
25 rootCmd.Flags().BoolP("help", "h", false, "Help")
27 rootCmd.Flags().BoolP("yolo", "y", false, "Automatically accept all permissions (dangerous mode)")
26 rootCmd.Flags().BoolP("yolo", "y", false, "Automatically accept all permissions (dangerous mode)")
28
27
29− runCmd.Flags().BoolP("quiet", "q", false, "Hide spinner")
30 rootCmd.AddCommand(runCmd)
28 rootCmd.AddCommand(runCmd)
31}
29}
32
30
@@ -81,51 +79,6 @@ crush -y
81 },
79 },
82}
80}
83
81
84−var runCmd = &cobra.Command{
85− Use: "run [prompt...]",
86− Short: "Run a single non-interactive prompt",
87− Long: `Run a single prompt in non-interactive mode and exit.
88−The prompt can be provided as arguments or piped from stdin.`,
89− Example: `
90−# Run a simple prompt
91−crush run Explain the use of context in Go
92−
93−# Pipe input from stdin
94−echo "What is this code doing?" | crush run
95−
96−# Run with quiet mode (no spinner)
97−crush run -q "Generate a README for this project"
98− `,
99− RunE: func(cmd *cobra.Command, args []string) error {
100− quiet, _ := cmd.Flags().GetBool("quiet")
101−
102− app, err := setupApp(cmd)
103− if err != nil {
104− return err
105− }
106− defer app.Shutdown()
107−
108− if !app.Config().IsConfigured() {
109− return fmt.Errorf("no providers configured - please run 'crush' to set up a provider interactively")
110− }
111−
112− prompt := strings.Join(args, " ")
113−
114− prompt, err = maybePrependStdin(prompt)
115− if err != nil {
116− slog.Error("Failed to read from stdin", "error", err)
117− return err
118− }
119−
120− if prompt == "" {
121− return fmt.Errorf("no prompt provided")
122− }
123−
124− // Run non-interactive flow using the App method
125− return app.RunNonInteractive(cmd.Context(), prompt, quiet)
126− },
127−}
128−
129func Execute() {
82func Execute() {
130 if err := fang.Execute(
83 if err := fang.Execute(
131 context.Background(),
84 context.Background(),
@@ -144,7 +97,7 @@ func setupApp(cmd *cobra.Command) (*app.App, error) {
144 yolo, _ := cmd.Flags().GetBool("yolo")
97 yolo, _ := cmd.Flags().GetBool("yolo")
145 ctx := cmd.Context()
98 ctx := cmd.Context()
146
99
147− cwd, err := resolveCwd(cmd)
100+ cwd, err := ResolveCwd(cmd)
148 if err != nil {
101 if err != nil {
149 return nil, err
102 return nil, err
150 }
103 }
@@ -174,7 +127,7 @@ func setupApp(cmd *cobra.Command) (*app.App, error) {
174 return appInstance, nil
127 return appInstance, nil
175}
128}
176
129
177−func maybePrependStdin(prompt string) (string, error) {
130+func MaybePrependStdin(prompt string) (string, error) {
178 if term.IsTerminal(os.Stdin.Fd()) {
131 if term.IsTerminal(os.Stdin.Fd()) {
179 return prompt, nil
132 return prompt, nil
180 }
133 }
@@ -192,7 +145,7 @@ func maybePrependStdin(prompt string) (string, error) {
192 return string(bts) + "\n\n" + prompt, nil
145 return string(bts) + "\n\n" + prompt, nil
193}
146}
194
147
195−func resolveCwd(cmd *cobra.Command) (string, error) {
148+func ResolveCwd(cmd *cobra.Command) (string, error) {
196 cwd, _ := cmd.Flags().GetString("cwd")
149 cwd, _ := cmd.Flags().GetString("cwd")
197 if cwd != "" {
150 if cwd != "" {
198 err := os.Chdir(cwd)
151 err := os.Chdir(cwd)
internal/cmd/run.gonew file+58
@@ -0,0 +1,58 @@
1+package cmd
2+
3+import (
4+ "fmt"
5+ "log/slog"
6+ "strings"
7+
8+ "github.com/spf13/cobra"
9+)
10+
11+var runCmd = &cobra.Command{
12+ Use: "run [prompt...]",
13+ Short: "Run a single non-interactive prompt",
14+ Long: `Run a single prompt in non-interactive mode and exit.
15+The prompt can be provided as arguments or piped from stdin.`,
16+ Example: `
17+# Run a simple prompt
18+crush run Explain the use of context in Go
19+
20+# Pipe input from stdin
21+echo "What is this code doing?" | crush run
22+
23+# Run with quiet mode (no spinner)
24+crush run -q "Generate a README for this project"
25+ `,
26+ RunE: func(cmd *cobra.Command, args []string) error {
27+ quiet, _ := cmd.Flags().GetBool("quiet")
28+
29+ app, err := setupApp(cmd)
30+ if err != nil {
31+ return err
32+ }
33+ defer app.Shutdown()
34+
35+ if !app.Config().IsConfigured() {
36+ return fmt.Errorf("no providers configured - please run 'crush' to set up a provider interactively")
37+ }
38+
39+ prompt := strings.Join(args, " ")
40+
41+ prompt, err = MaybePrependStdin(prompt)
42+ if err != nil {
43+ slog.Error("Failed to read from stdin", "error", err)
44+ return err
45+ }
46+
47+ if prompt == "" {
48+ return fmt.Errorf("no prompt provided")
49+ }
50+
51+ // Run non-interactive flow using the App method
52+ return app.RunNonInteractive(cmd.Context(), prompt, quiet)
53+ },
54+}
55+
56+func init() {
57+ runCmd.Flags().BoolP("quiet", "q", false, "Hide spinner")
58+}