Skip to content

Commit 888c11d

Browse files
authored
Merge pull request #1713 from entireio/fix/1123-local-settings-hooks
fix(settings): recognize local-only setup so hooks run after enable --local
2 parents 2f38e3a + c83cc9b commit 888c11d

2 files changed

Lines changed: 80 additions & 0 deletions

File tree

cmd/entire/cli/integration_test/setup_cmd_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,55 @@ func TestEnableDefaultStrategy(t *testing.T) {
215215
t.Errorf("Expected status to show 'manual-commit', got: %s", stdout)
216216
}
217217
}
218+
219+
// TestHooksRunAfterLocalOnlyEnable is a full-flow reproduction of the
220+
// `entire enable --local` regression: only .entire/settings.local.json
221+
// exists, and the hooks (gated on settings.IsSetUpAndEnabled) silently
222+
// no-op'd because that check only looked at settings.json — so a commit
223+
// produced no checkpoint.
224+
//
225+
// This drives the real hook binary end-to-end: a session, a
226+
// user-prompt-submit, a file change, a stop, and a commit — then asserts the
227+
// commit actually carries an Entire-Checkpoint trailer (i.e. the hooks ran
228+
// and a checkpoint was saved). Complements TestHooksSilentWhenDisabled above,
229+
// which covers the opposite case.
230+
func TestHooksRunAfterLocalOnlyEnable(t *testing.T) {
231+
t.Parallel()
232+
env := NewTestEnv(t)
233+
defer env.Cleanup()
234+
235+
env.InitRepo()
236+
env.WriteFile("README.md", "# Test")
237+
env.GitAdd("README.md")
238+
env.GitCommit("Initial commit")
239+
env.GitCheckoutNewBranch("feature/local-only")
240+
241+
// Simulate `entire enable --local`: only settings.local.json exists.
242+
entireDir := filepath.Join(env.RepoDir, ".entire")
243+
if err := os.MkdirAll(filepath.Join(entireDir, "tmp"), 0o755); err != nil {
244+
t.Fatalf("mkdir .entire/tmp: %v", err)
245+
}
246+
localSettings := `{"enabled":true,"local_dev":true,"strategy_options":{"filtered_fetches":true}}`
247+
if err := os.WriteFile(filepath.Join(entireDir, "settings.local.json"), []byte(localSettings), 0o644); err != nil {
248+
t.Fatalf("write settings.local.json: %v", err)
249+
}
250+
if _, err := os.Stat(filepath.Join(entireDir, "settings.json")); err == nil {
251+
t.Fatal("precondition: settings.json must not exist for the enable --local scenario")
252+
}
253+
254+
session := env.NewSession()
255+
if err := env.SimulateUserPromptSubmitWithPrompt(session.ID, "Create a hello file"); err != nil {
256+
t.Fatalf("user-prompt-submit: %v", err)
257+
}
258+
env.WriteFile("hello.txt", "hello")
259+
session.CreateTranscript("Create a hello file", []FileChange{{Path: "hello.txt", Content: "hello"}})
260+
if err := env.SimulateStop(session.ID, session.TranscriptPath); err != nil {
261+
t.Fatalf("stop: %v", err)
262+
}
263+
env.GitCommitWithShadowHooksAsAgent("add hello", "hello.txt")
264+
265+
cpID := env.GetCheckpointIDFromCommitMessage(env.GetHeadHash())
266+
if cpID == "" {
267+
t.Fatal("commit has no Entire-Checkpoint trailer — hooks silently no-op'd with only settings.local.json")
268+
}
269+
}

cmd/entire/cli/settings/settings_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"testing"
1111
"time"
1212

13+
"github.com/entireio/cli/cmd/entire/cli/paths"
1314
"github.com/entireio/cli/cmd/entire/cli/session"
1415
"github.com/entireio/cli/cmd/entire/cli/testutil"
1516
)
@@ -1330,3 +1331,30 @@ func TestMergeReviewProfiles_PureAndPrecedence(t *testing.T) {
13301331
t.Error("merge(nil, emptyNonNil) should return a non-nil empty map, got nil")
13311332
}
13321333
}
1334+
1335+
// Regression: `entire enable --local` writes only .entire/settings.local.json,
1336+
// but the hook activation check (IsSetUpAndEnabled) only looked for
1337+
// .entire/settings.json, so hooks silently no-op'd. It must recognize a
1338+
// local-only setup.
1339+
func TestIsSetUpAndEnabled_LocalSettingsOnly(t *testing.T) {
1340+
root := t.TempDir()
1341+
testutil.InitRepo(t, root)
1342+
entireDir := filepath.Join(root, ".entire")
1343+
if err := os.MkdirAll(entireDir, 0o755); err != nil {
1344+
t.Fatal(err)
1345+
}
1346+
// Only the local settings file exists (no settings.json), enabled.
1347+
if err := os.WriteFile(filepath.Join(entireDir, "settings.local.json"), []byte(`{"enabled":true}`), 0o644); err != nil {
1348+
t.Fatal(err)
1349+
}
1350+
1351+
t.Chdir(root)
1352+
paths.ClearWorktreeRootCache()
1353+
1354+
if IsSetUp(context.Background()) {
1355+
t.Fatal("precondition: IsSetUp should be false with only settings.local.json")
1356+
}
1357+
if !IsSetUpAndEnabled(context.Background()) {
1358+
t.Fatal("IsSetUpAndEnabled should be true when only settings.local.json exists and is enabled")
1359+
}
1360+
}

0 commit comments

Comments
 (0)