@ifuryst/harness-cli
Advanced tools
| package cli | ||
| import ( | ||
| "bytes" | ||
| "context" | ||
| "os" | ||
| "path/filepath" | ||
| "strings" | ||
| "testing" | ||
| ) | ||
| func TestRootCommandAcceptsPositionalTarget(t *testing.T) { | ||
| source := testTemplateSource(t) | ||
| target := filepath.Join(t.TempDir(), "project") | ||
| _, _, err := executeRootCommand(t, | ||
| target, | ||
| "--language", "en", | ||
| "--source", source, | ||
| "--git=false", | ||
| ) | ||
| if err != nil { | ||
| t.Fatalf("execute root command: %v", err) | ||
| } | ||
| assertFileContent(t, filepath.Join(target, "README.md"), "hello\n") | ||
| } | ||
| func TestInitCommandAcceptsPositionalTarget(t *testing.T) { | ||
| source := testTemplateSource(t) | ||
| target := filepath.Join(t.TempDir(), "project") | ||
| _, _, err := executeRootCommand(t, | ||
| "init", | ||
| target, | ||
| "--language", "en", | ||
| "--source", source, | ||
| "--git=false", | ||
| ) | ||
| if err != nil { | ||
| t.Fatalf("execute init command: %v", err) | ||
| } | ||
| assertFileContent(t, filepath.Join(target, "README.md"), "hello\n") | ||
| } | ||
| func TestPositionalTargetConflictsWithTargetFlag(t *testing.T) { | ||
| _, _, err := executeRootCommand(t, "project", "--target", "other") | ||
| if err == nil { | ||
| t.Fatal("expected positional target and --target conflict") | ||
| } | ||
| if got, want := err.Error(), "target specified both as positional argument"; !strings.Contains(got, want) { | ||
| t.Fatalf("error = %q, want substring %q", got, want) | ||
| } | ||
| } | ||
| func executeRootCommand(t *testing.T, args ...string) (string, string, error) { | ||
| t.Helper() | ||
| var out bytes.Buffer | ||
| var errOut bytes.Buffer | ||
| cmd := NewRootCommand("test", bytes.NewBuffer(nil), &out, &errOut) | ||
| cmd.SetArgs(args) | ||
| err := cmd.ExecuteContext(context.Background()) | ||
| return out.String(), errOut.String(), err | ||
| } | ||
| func testTemplateSource(t *testing.T) string { | ||
| t.Helper() | ||
| source := t.TempDir() | ||
| if err := os.WriteFile(filepath.Join(source, "README.md"), []byte("hello\n"), 0o644); err != nil { | ||
| t.Fatalf("write template file: %v", err) | ||
| } | ||
| return source | ||
| } | ||
| func assertFileContent(t *testing.T, path, want string) { | ||
| t.Helper() | ||
| got, err := os.ReadFile(path) | ||
| if err != nil { | ||
| t.Fatalf("read %s: %v", path, err) | ||
| } | ||
| if string(got) != want { | ||
| t.Fatalf("%s = %q, want %q", path, string(got), want) | ||
| } | ||
| } |
+22
-2
@@ -5,2 +5,3 @@ package cli | ||
| "context" | ||
| "fmt" | ||
| "io" | ||
@@ -34,3 +35,3 @@ | ||
| rootCmd := &cobra.Command{ | ||
| Use: "harness-cli", | ||
| Use: "harness-cli [target]", | ||
| Short: "Initialize agent-first project repositories from Harness templates", | ||
@@ -40,3 +41,7 @@ Version: version, | ||
| SilenceErrors: true, | ||
| Args: cobra.MaximumNArgs(1), | ||
| RunE: func(cmd *cobra.Command, args []string) error { | ||
| if err := applyTargetArg(cmd, &rootOpts, args); err != nil { | ||
| return err | ||
| } | ||
| return runInit(cmd.Context(), rootOpts, in, out) | ||
@@ -59,5 +64,9 @@ }, | ||
| cmd := &cobra.Command{ | ||
| Use: "init", | ||
| Use: "init [target]", | ||
| Short: "Initialize the current repository from a Harness template", | ||
| Args: cobra.MaximumNArgs(1), | ||
| RunE: func(cmd *cobra.Command, args []string) error { | ||
| if err := applyTargetArg(cmd, &opts, args); err != nil { | ||
| return err | ||
| } | ||
| return runInit(cmd.Context(), opts, in, out) | ||
@@ -70,2 +79,13 @@ }, | ||
| func applyTargetArg(cmd *cobra.Command, opts *initOptions, args []string) error { | ||
| if len(args) == 0 { | ||
| return nil | ||
| } | ||
| if cmd.Flags().Changed("target") { | ||
| return fmt.Errorf("target specified both as positional argument %q and --target", args[0]) | ||
| } | ||
| opts.targetDir = args[0] | ||
| return nil | ||
| } | ||
| func bindInitFlags(cmd *cobra.Command, opts *initOptions) { | ||
@@ -72,0 +92,0 @@ flags := cmd.Flags() |
+1
-1
| { | ||
| "name": "@ifuryst/harness-cli", | ||
| "version": "0.1.1", | ||
| "version": "0.1.2", | ||
| "description": "Initialize agent-first project repositories from Harness templates.", | ||
@@ -5,0 +5,0 @@ "bin": { |
+2
-0
@@ -31,4 +31,6 @@ # harness-cli | ||
| ```sh | ||
| harness-cli ./my-project --language zh | ||
| harness-cli init --language en | ||
| harness-cli init --language zh --target ./my-project | ||
| harness-cli init ./my-project --language zh | ||
| harness-cli init --language zh --force | ||
@@ -35,0 +37,0 @@ harness-cli init --language en --dry-run |
28194
10.67%17
6.25%895
11.6%55
3.77%