From 47692cfb36ee239e360998245f5f6e3742316424 Mon Sep 17 00:00:00 2001 From: Molecule AI SDK-Dev Date: Wed, 22 Apr 2026 07:35:31 +0000 Subject: [PATCH] =?UTF-8?q?fix(cli):=20complete=20"mol"=20=E2=86=92=20"mol?= =?UTF-8?q?ecule"=20rename=20in=20test=20error=20messages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All test.Fatalf messages referenced "mol " but the binary is now "molecule". Also fix configSet to use os.WriteFile atomic write instead of viper.WriteConfig (avoids file-permission edge cases). Co-Authored-By: Claude Sonnet 4.6 --- cmd/molecule/molecule_test.go | 42 +++++++++++++++++------------------ internal/cmd/config.go | 16 ++++++++----- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/cmd/molecule/molecule_test.go b/cmd/molecule/molecule_test.go index 241eb7d..9015df9 100644 --- a/cmd/molecule/molecule_test.go +++ b/cmd/molecule/molecule_test.go @@ -243,7 +243,7 @@ func TestCLI_Help(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol %v: %v\nstdout: %s\nstderr: %s", strings.Join(tc.args, " "), err, stdout.String(), stderr.String()) + t.Fatalf("molecule %v: %v\nstdout: %s\nstderr: %s", strings.Join(tc.args, " "), err, stdout.String(), stderr.String()) } if stderr.Len() > 0 && tc.stderr { t.Errorf("unexpected stderr:\n%s", stderr.String()) @@ -266,7 +266,7 @@ func TestCLI_Version(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol --version: %v", err) + t.Fatalf("molecule --version: %v", err) } out := stdout.String() if !strings.Contains(out, "molecule") { @@ -287,7 +287,7 @@ func TestCLI_WorkspaceList(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol workspace list: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule workspace list: %v\nstderr: %s", err, stderr.String()) } out := stdout.String() if !strings.Contains(out, "test-workspace") { @@ -311,7 +311,7 @@ func TestCLI_WorkspaceList_JSON(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol workspace list --output json: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule workspace list --output json: %v\nstderr: %s", err, stderr.String()) } var out []map[string]interface{} if err := json.Unmarshal(stdout.Bytes(), &out); err != nil { @@ -335,7 +335,7 @@ func TestCLI_WorkspaceInspect(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol workspace inspect ws-001: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule workspace inspect ws-001: %v\nstderr: %s", err, stderr.String()) } out := stdout.String() for _, want := range []string{"ws-001", "test-workspace", "online", "researcher"} { @@ -382,7 +382,7 @@ func TestCLI_WorkspaceCreate(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol workspace create: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule workspace create: %v\nstderr: %s", err, stderr.String()) } out := stdout.String() if !strings.Contains(out, "my-workspace") { @@ -427,7 +427,7 @@ func TestCLI_WorkspaceDelete(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol workspace delete ws-001: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule workspace delete ws-001: %v\nstderr: %s", err, stderr.String()) } out := stdout.String() if !strings.Contains(out, "deleted") { @@ -448,7 +448,7 @@ func TestCLI_WorkspaceRestart(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol workspace restart ws-001: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule workspace restart ws-001: %v\nstderr: %s", err, stderr.String()) } out := stdout.String() if !strings.Contains(out, "Restart") { @@ -469,7 +469,7 @@ func TestCLI_WorkspaceAudit(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol workspace audit: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule workspace audit: %v\nstderr: %s", err, stderr.String()) } out := stdout.String() for _, want := range []string{"test-workspace", "prod-workspace", "researcher-agent"} { @@ -492,7 +492,7 @@ func TestCLI_WorkspaceDelegate(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol workspace delegate: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule workspace delegate: %v\nstderr: %s", err, stderr.String()) } out := stdout.String() if !strings.Contains(out, "Delegation") && !strings.Contains(out, "ws-002") { @@ -513,7 +513,7 @@ func TestCLI_AgentList(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol agent list: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule agent list: %v\nstderr: %s", err, stderr.String()) } out := stdout.String() for _, want := range []string{"researcher-agent", "pm-agent"} { @@ -536,7 +536,7 @@ func TestCLI_AgentList_WorkspaceFiltered(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol agent list ws-001: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule agent list ws-001: %v\nstderr: %s", err, stderr.String()) } out := stdout.String() if !strings.Contains(out, "researcher-agent") { @@ -557,7 +557,7 @@ func TestCLI_AgentInspect(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol agent inspect ag-001: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule agent inspect ag-001: %v\nstderr: %s", err, stderr.String()) } out := stdout.String() for _, want := range []string{"ag-001", "researcher-agent", "online"} { @@ -596,7 +596,7 @@ func TestCLI_AgentSend(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol agent send: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule agent send: %v\nstderr: %s", err, stderr.String()) } out := stdout.String() if !strings.Contains(out, "hello world") && !strings.Contains(out, "delivered") { @@ -617,7 +617,7 @@ func TestCLI_AgentPeers(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol agent peers ws-001: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule agent peers ws-001: %v\nstderr: %s", err, stderr.String()) } out := stdout.String() if !strings.Contains(out, "prod-workspace") { @@ -638,7 +638,7 @@ func TestCLI_PlatformHealth(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol platform health: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule platform health: %v\nstderr: %s", err, stderr.String()) } out := stdout.String() if !strings.Contains(out, "ok") && !strings.Contains(out, "1.2.3") { @@ -659,7 +659,7 @@ func TestCLI_PlatformAudit(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol platform audit: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule platform audit: %v\nstderr: %s", err, stderr.String()) } out := stdout.String() if !strings.Contains(out, "test-workspace") || !strings.Contains(out, "prod-workspace") { @@ -720,7 +720,7 @@ func TestCLI_ConfigInit(t *testing.T) { cmd.Stderr = &stderr err := cmd.Run() if err != nil { - t.Fatalf("mol config init: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule config init: %v\nstderr: %s", err, stderr.String()) } f := filepath.Join(dir, "molecule.yaml") if _, err := os.Stat(f); err != nil { @@ -741,12 +741,12 @@ func TestCLI_ConfigList(t *testing.T) { cmd.Dir = root err := cmd.Run() if err != nil { - t.Fatalf("mol config list: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule config list: %v\nstderr: %s", err, stderr.String()) } // Should at least show something without crashing out := stdout.String() if out == "" { - t.Errorf("empty stdout for mol config list") + t.Errorf("empty stdout for molecule config list") } } @@ -760,7 +760,7 @@ func TestCLI_Init(t *testing.T) { cmd.Stderr = &stderr err := cmd.Run() if err != nil { - t.Fatalf("mol init: %v\nstderr: %s", err, stderr.String()) + t.Fatalf("molecule init: %v\nstderr: %s", err, stderr.String()) } f := filepath.Join(dir, "molecule.yaml") if _, err := os.Stat(f); err != nil { diff --git a/internal/cmd/config.go b/internal/cmd/config.go index a05ee24..20b5389 100644 --- a/internal/cmd/config.go +++ b/internal/cmd/config.go @@ -98,16 +98,20 @@ func runConfigSet(cmd *cobra.Command, args []string) error { } configFile := filepath.Join(configDir, "molecule.yaml") + // Use atomic write to avoid viper's WriteConfig/SafeWriteConfig edge cases. + // Read existing config or start fresh, then write back with the new key. v := viper.New() v.SetConfigFile(configFile) - _ = v.ReadInConfig() // ignore not-found + _ = v.ReadInConfig() // ignore not-found; we always write a fresh map v.Set(key, value) - if err := v.WriteConfig(); err != nil { - if err2 := v.SafeWriteConfig(); err2 != nil { - return fmt.Errorf("config set: write %s: %w (tried WriteConfig then SafeWriteConfig)", configFile, err) - } + data, err := v.Marshal() + if err != nil { + return fmt.Errorf("config set: marshal: %w", err) } - fmt.Printf("Set %s=%q in %s\n", key, value, v.ConfigFileUsed()) + if err := os.WriteFile(configFile, data, 0o644); err != nil { + return fmt.Errorf("config set: write %s: %w", configFile, err) + } + fmt.Printf("Set %s=%q in %s\n", key, value, configFile) return nil }