Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 0 additions & 62 deletions cmd/entire/cli/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,6 @@ const (
EntireSettingsLocalFile = ".entire/settings.local.json"
)

// StartSettings contains configuration for the 'entire start' command
type StartSettings struct {
// BranchPrefix is prepended to feature names when creating branches
// Default: "feature/"
BranchPrefix string `json:"branchPrefix,omitempty"`

// BaseBranch is the default branch to create features from
// Default: "main"
BaseBranch string `json:"baseBranch,omitempty"`

// RequirementsTemplate is the path to the requirements template file
// Required for --scaffold flag to work
RequirementsTemplate string `json:"requirementsTemplate,omitempty"`

// UseWorktrees controls whether to create git worktrees for parallel work.
// When false (default), creates branch and checks it out in current directory.
// When true, creates branch in a separate worktree at .worktrees/<name>.
UseWorktrees bool `json:"useWorktrees,omitempty"`
}

// EntireSettings represents the .entire/settings.json configuration
type EntireSettings struct {
// Strategy is the name of the git strategy to use
Expand Down Expand Up @@ -76,9 +56,6 @@ type EntireSettings struct {
// AgentOptions contains agent-specific configuration
// Keyed by agent name, e.g., {"claude-code": {"ignore_untracked": false}}
AgentOptions map[string]interface{} `json:"agent_options,omitempty"`

// Start contains configuration for the 'entire start' command
Start *StartSettings `json:"start,omitempty"`
}

// LoadEntireSettings loads the Entire settings from .entire/settings.json,
Expand Down Expand Up @@ -283,45 +260,6 @@ func IsEnabled() (bool, error) {
return settings.Enabled, nil
}

// GetStartSettings returns the start command settings with defaults applied.
// Returns default values if not configured or if settings cannot be loaded.
// Logs a warning if settings file exists but cannot be parsed.
func GetStartSettings() *StartSettings {
defaults := &StartSettings{
BranchPrefix: "feature/",
BaseBranch: "main",
RequirementsTemplate: "",
UseWorktrees: false,
}

settings, err := LoadEntireSettings()
if err != nil {
// Log the error so users know their config file has issues
slog.Warn("failed to load settings, using defaults", slog.Any("error", err))
return defaults
}
if settings.Start == nil {
return defaults
}

// Apply defaults for missing fields
result := &StartSettings{
BranchPrefix: settings.Start.BranchPrefix,
BaseBranch: settings.Start.BaseBranch,
RequirementsTemplate: settings.Start.RequirementsTemplate,
UseWorktrees: settings.Start.UseWorktrees,
}

if result.BranchPrefix == "" {
result.BranchPrefix = defaults.BranchPrefix
}
if result.BaseBranch == "" {
result.BaseBranch = defaults.BaseBranch
}

return result
}

// GetStrategy returns the configured strategy instance.
// Falls back to default if the configured strategy is not found.
//
Expand Down
148 changes: 3 additions & 145 deletions cmd/entire/cli/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ import (
)

const (
testSettingsStrategy = `{"strategy": "manual-commit"}`
testSettingsEnabled = `{"strategy": "manual-commit", "enabled": true}`
testSettingsDisabled = `{"strategy": "manual-commit", "enabled": false}`
testDefaultBranchPrefix = "feature/"
testDefaultBaseBranch = "main"
testSettingsStrategy = `{"strategy": "manual-commit"}`
testSettingsEnabled = `{"strategy": "manual-commit", "enabled": true}`
testSettingsDisabled = `{"strategy": "manual-commit", "enabled": false}`
)

func TestLoadEntireSettings_EnabledDefaultsToTrue(t *testing.T) {
Expand Down Expand Up @@ -135,146 +133,6 @@ func TestSaveEntireSettings_PreservesEnabled(t *testing.T) {
}
}

func TestGetStartSettings_DefaultsWhenNotConfigured(t *testing.T) {
tmpDir := t.TempDir()
t.Chdir(tmpDir)

// No settings file exists - should return defaults
startSettings := GetStartSettings()

if startSettings.BranchPrefix != testDefaultBranchPrefix {
t.Errorf("BranchPrefix = %q, want %q", startSettings.BranchPrefix, testDefaultBranchPrefix)
}
if startSettings.BaseBranch != testDefaultBaseBranch {
t.Errorf("BaseBranch = %q, want %q", startSettings.BaseBranch, testDefaultBaseBranch)
}
if startSettings.RequirementsTemplate != "" {
t.Errorf("RequirementsTemplate = %q, want empty string", startSettings.RequirementsTemplate)
}
if startSettings.UseWorktrees != false {
t.Errorf("UseWorktrees = %v, want false", startSettings.UseWorktrees)
}
}

func TestGetStartSettings_LoadsFromFile(t *testing.T) {
tmpDir := t.TempDir()
t.Chdir(tmpDir)

// Create settings file with start config
settingsDir := filepath.Dir(EntireSettingsFile)
if err := os.MkdirAll(settingsDir, 0o755); err != nil {
t.Fatalf("Failed to create settings dir: %v", err)
}

settingsContent := `{
"strategy": "manual-commit",
"enabled": true,
"start": {
"branchPrefix": "feat/",
"baseBranch": "develop",
"requirementsTemplate": "templates/req.md",
"useWorktrees": true
}
}`
if err := os.WriteFile(EntireSettingsFile, []byte(settingsContent), 0o644); err != nil {
t.Fatalf("Failed to write settings file: %v", err)
}

startSettings := GetStartSettings()

if startSettings.BranchPrefix != "feat/" {
t.Errorf("BranchPrefix = %q, want %q", startSettings.BranchPrefix, "feat/")
}
if startSettings.BaseBranch != "develop" {
t.Errorf("BaseBranch = %q, want %q", startSettings.BaseBranch, "develop")
}
if startSettings.RequirementsTemplate != "templates/req.md" {
t.Errorf("RequirementsTemplate = %q, want %q", startSettings.RequirementsTemplate, "templates/req.md")
}
if startSettings.UseWorktrees != true {
t.Errorf("UseWorktrees = %v, want true", startSettings.UseWorktrees)
}
}

func TestGetStartSettings_PartialConfig(t *testing.T) {
tmpDir := t.TempDir()
t.Chdir(tmpDir)

// Create settings file with partial start config
settingsDir := filepath.Dir(EntireSettingsFile)
if err := os.MkdirAll(settingsDir, 0o755); err != nil {
t.Fatalf("Failed to create settings dir: %v", err)
}

// Only branchPrefix is set, others should use defaults
settingsContent := `{
"strategy": "manual-commit",
"start": {
"branchPrefix": "fix/"
}
}`
if err := os.WriteFile(EntireSettingsFile, []byte(settingsContent), 0o644); err != nil {
t.Fatalf("Failed to write settings file: %v", err)
}

startSettings := GetStartSettings()

if startSettings.BranchPrefix != "fix/" {
t.Errorf("BranchPrefix = %q, want %q", startSettings.BranchPrefix, "fix/")
}
// Should use default for missing fields
if startSettings.BaseBranch != testDefaultBaseBranch {
t.Errorf("BaseBranch = %q, want default %q", startSettings.BaseBranch, testDefaultBaseBranch)
}
if startSettings.RequirementsTemplate != "" {
t.Errorf("RequirementsTemplate = %q, want empty string", startSettings.RequirementsTemplate)
}
if startSettings.UseWorktrees != false {
t.Errorf("UseWorktrees = %v, want false (default)", startSettings.UseWorktrees)
}
}

func TestSaveEntireSettings_PreservesStartSettings(t *testing.T) {
tmpDir := t.TempDir()
t.Chdir(tmpDir)

// Save settings with Start config
settings := &EntireSettings{
Strategy: "manual-commit",
Enabled: true,
Start: &StartSettings{
BranchPrefix: "feature/",
BaseBranch: "main",
RequirementsTemplate: "templates/requirements.md",
UseWorktrees: true,
},
}
if err := SaveEntireSettings(settings); err != nil {
t.Fatalf("SaveEntireSettings() error = %v", err)
}

// Load and verify
loaded, err := LoadEntireSettings()
if err != nil {
t.Fatalf("LoadEntireSettings() error = %v", err)
}
if loaded.Start == nil {
t.Fatal("Start settings should not be nil after loading")
}
if loaded.Start.BranchPrefix != testDefaultBranchPrefix {
t.Errorf("Start.BranchPrefix = %q, want %q", loaded.Start.BranchPrefix, testDefaultBranchPrefix)
}
if loaded.Start.BaseBranch != testDefaultBaseBranch {
t.Errorf("Start.BaseBranch = %q, want %q", loaded.Start.BaseBranch, testDefaultBaseBranch)
}
if loaded.Start.RequirementsTemplate != "templates/requirements.md" {
t.Errorf("Start.RequirementsTemplate = %q, want %q", loaded.Start.RequirementsTemplate, "templates/requirements.md")
}
if loaded.Start.UseWorktrees != true {
t.Errorf("Start.UseWorktrees = %v, want true", loaded.Start.UseWorktrees)
}
}

func TestIsEnabled(t *testing.T) {
tmpDir := t.TempDir()
t.Chdir(tmpDir)
Expand Down
4 changes: 2 additions & 2 deletions cmd/entire/cli/integration_test/setup_claude_hooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func TestSetupClaudeHooks_AddsAllRequiredHooks(t *testing.T) {
env.GitCommit("Initial commit")

// Run entire enable claude-hooks (non-interactive)
output, err := env.runEntireCmd("enable", "claude-hooks")
output, err := env.RunCLIWithError("enable", "claude-hooks")
if err != nil {
t.Fatalf("enable claude-hooks command failed: %v\nOutput: %s", err, output)
}
Expand Down Expand Up @@ -116,7 +116,7 @@ func TestSetupClaudeHooks_PreservesExistingSettings(t *testing.T) {
}

// Run enable claude-hooks
output, err := env.runEntireCmd("enable", "claude-hooks")
output, err := env.RunCLIWithError("enable", "claude-hooks")
if err != nil {
t.Fatalf("enable claude-hooks failed: %v\nOutput: %s", err, output)
}
Expand Down
Loading