Skip to content

Commit 58bdec8

Browse files
authored
Merge pull request #775 from entireio/soph/do-content-check-for-opencode-plugin
rewrite opencode plugin if content differs
2 parents 90a260e + 4df06ee commit 58bdec8

2 files changed

Lines changed: 55 additions & 11 deletions

File tree

cmd/entire/cli/agent/opencode/hooks.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,14 @@ func getPluginPath(ctx context.Context) (string, error) {
4040
}
4141

4242
// InstallHooks writes the Entire plugin file to .opencode/plugins/entire.ts.
43-
// Returns 1 if the plugin was installed, 0 if already present (idempotent).
43+
// Returns 1 if the plugin was written, 0 if already up-to-date (idempotent).
44+
// If the file exists but content differs (e.g., localDev vs production), it is rewritten.
4445
func (a *OpenCodeAgent) InstallHooks(ctx context.Context, localDev bool, force bool) (int, error) {
4546
pluginPath, err := getPluginPath(ctx)
4647
if err != nil {
4748
return 0, err
4849
}
4950

50-
// Check if already installed (idempotent) unless force
51-
if !force {
52-
if _, err := os.Stat(pluginPath); err == nil {
53-
data, readErr := os.ReadFile(pluginPath) //nolint:gosec // Path constructed from repo root
54-
if readErr == nil && strings.Contains(string(data), entireMarker) {
55-
return 0, nil // Already installed
56-
}
57-
}
58-
}
59-
6051
// Build the command prefix
6152
var cmdPrefix string
6253
if localDev {
@@ -68,6 +59,15 @@ func (a *OpenCodeAgent) InstallHooks(ctx context.Context, localDev bool, force b
6859
// Generate plugin content from template
6960
content := strings.ReplaceAll(pluginTemplate, entireCmdPlaceholder, cmdPrefix)
7061

62+
// Check if already installed with identical content (idempotent) unless force
63+
if !force {
64+
if existing, readErr := os.ReadFile(pluginPath); readErr == nil { //nolint:gosec // Path constructed from repo root
65+
if string(existing) == content {
66+
return 0, nil // Already up-to-date
67+
}
68+
}
69+
}
70+
7171
// Ensure directory exists
7272
pluginDir := filepath.Dir(pluginPath)
7373
//nolint:gosec // G301: Plugin directory needs standard permissions

cmd/entire/cli/agent/opencode/hooks_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,50 @@ func TestInstallHooks_ForceReinstall(t *testing.T) {
160160
}
161161
}
162162

163+
func TestInstallHooks_RewritesWhenContentDiffers(t *testing.T) {
164+
dir := t.TempDir()
165+
t.Chdir(dir)
166+
ag := &OpenCodeAgent{}
167+
168+
// Install with localDev=true
169+
count, err := ag.InstallHooks(context.Background(), true, false)
170+
if err != nil {
171+
t.Fatalf("first install failed: %v", err)
172+
}
173+
if count != 1 {
174+
t.Errorf("first install: expected 1, got %d", count)
175+
}
176+
177+
pluginPath := filepath.Join(dir, ".opencode", "plugins", "entire.ts")
178+
before, err := os.ReadFile(pluginPath)
179+
if err != nil {
180+
t.Fatalf("failed to read plugin file: %v", err)
181+
}
182+
if !strings.Contains(string(before), "go run") {
183+
t.Fatal("expected localDev content with 'go run'")
184+
}
185+
186+
// Reinstall with localDev=false (content differs) — should rewrite
187+
count, err = ag.InstallHooks(context.Background(), false, false)
188+
if err != nil {
189+
t.Fatalf("second install failed: %v", err)
190+
}
191+
if count != 1 {
192+
t.Errorf("second install with different content: expected 1, got %d", count)
193+
}
194+
195+
after, err := os.ReadFile(pluginPath)
196+
if err != nil {
197+
t.Fatalf("failed to read plugin file after rewrite: %v", err)
198+
}
199+
if strings.Contains(string(after), "go run") {
200+
t.Error("expected production content after rewrite, but still contains 'go run'")
201+
}
202+
if !strings.Contains(string(after), `const ENTIRE_CMD = 'entire'`) {
203+
t.Error("expected production command constant after rewrite")
204+
}
205+
}
206+
163207
func TestUninstallHooks(t *testing.T) {
164208
dir := t.TempDir()
165209
t.Chdir(dir)

0 commit comments

Comments
 (0)