diff --git a/pkg/dev/registry.go b/pkg/dev/registry.go index f79bb738..8d4b9b8b 100644 --- a/pkg/dev/registry.go +++ b/pkg/dev/registry.go @@ -44,8 +44,8 @@ func loadRegistryWithConfig(registryPath string) (*repos.Registry, string, error registryDir = cwd } } - // Load workspace config to respect packages_dir - if wsConfig, err := workspace.LoadConfig(registryDir); err == nil { + // Load workspace config to respect packages_dir (only if config exists) + if wsConfig, err := workspace.LoadConfig(registryDir); err == nil && wsConfig != nil { if wsConfig.PackagesDir != "" { pkgDir := wsConfig.PackagesDir // Expand ~ diff --git a/pkg/docs/cmd_scan.go b/pkg/docs/cmd_scan.go index 105a133b..9920b5f7 100644 --- a/pkg/docs/cmd_scan.go +++ b/pkg/docs/cmd_scan.go @@ -60,7 +60,7 @@ func loadRegistry(registryPath string) (*repos.Registry, string, error) { basePath := registryDir - if wsConfig.PackagesDir != "" && wsConfig.PackagesDir != "./packages" { + if wsConfig != nil && wsConfig.PackagesDir != "" && wsConfig.PackagesDir != "./packages" { pkgDir := wsConfig.PackagesDir // Expand ~ diff --git a/pkg/i18n/locales/en_GB.json b/pkg/i18n/locales/en_GB.json index 2a85607b..788de6df 100644 --- a/pkg/i18n/locales/en_GB.json +++ b/pkg/i18n/locales/en_GB.json @@ -157,6 +157,18 @@ "no_git_repos": "No git repositories found.", "confirm_claude_commit": "Have Claude commit these repos?", "health.short": "Quick health check across all repos", + "health.long": "Shows a summary of repository health across all repos in the workspace.", + "health.flag.verbose": "Show detailed breakdown", + "health.repos": "repos", + "health.to_push": "to push", + "health.to_pull": "to pull", + "health.errors": "errors", + "health.more": "+{{.Count}} more", + "health.dirty_label": "Dirty:", + "health.ahead_label": "Ahead:", + "health.behind_label": "Behind:", + "health.errors_label": "Errors:", + "status.clean": "clean", "commit.short": "Claude-assisted commits across repos", "push.short": "Push commits across all repos", "push.diverged": "branch has diverged from remote", @@ -293,6 +305,12 @@ } }, "common": { + "status": { + "dirty": "dirty", + "clean": "clean", + "synced": "synced", + "up_to_date": "up to date" + }, "label": { "done": "Done", "error": "Error", @@ -309,7 +327,8 @@ "fix": "Auto-fix issues where possible", "diff": "Show diff of changes", "json": "Output as JSON", - "verbose": "Show detailed output" + "verbose": "Show detailed output", + "registry": "Path to repos.yaml registry file" }, "progress": { "running": "Running {{.Task}}...", diff --git a/pkg/php/cmd.go b/pkg/php/cmd.go index 02531189..6e1af726 100644 --- a/pkg/php/cmd.go +++ b/pkg/php/cmd.go @@ -69,8 +69,8 @@ func AddPHPCommands(root *cobra.Command) { // Load workspace config config, err := workspace.LoadConfig(wsRoot) - if err != nil { - return nil // Failed to load, ignore + if err != nil || config == nil { + return nil // Failed to load or no config, ignore } if config.Active == "" { diff --git a/pkg/setup/cmd_bootstrap.go b/pkg/setup/cmd_bootstrap.go index 96de5bbc..d6e6dfbc 100644 --- a/pkg/setup/cmd_bootstrap.go +++ b/pkg/setup/cmd_bootstrap.go @@ -11,9 +11,11 @@ import ( "fmt" "os" "path/filepath" + "strings" "github.com/host-uk/core/pkg/i18n" "github.com/host-uk/core/pkg/repos" + "github.com/host-uk/core/pkg/workspace" ) // runSetupOrchestrator decides between registry mode and bootstrap mode. @@ -133,6 +135,13 @@ func runBootstrap(ctx context.Context, only string, dryRun, all bool, projectNam // Override base path to target directory reg.BasePath = targetDir + // Check workspace config for default_only if no filter specified + if only == "" { + if wsConfig, err := workspace.LoadConfig(devopsPath); err == nil && wsConfig != nil && len(wsConfig.DefaultOnly) > 0 { + only = strings.Join(wsConfig.DefaultOnly, ",") + } + } + // Now run the regular setup with the loaded registry return runRegistrySetupWithReg(ctx, reg, registryPath, only, dryRun, all, runBuild) } diff --git a/pkg/setup/cmd_registry.go b/pkg/setup/cmd_registry.go index a38a29d2..250cd0f5 100644 --- a/pkg/setup/cmd_registry.go +++ b/pkg/setup/cmd_registry.go @@ -26,6 +26,14 @@ func runRegistrySetup(ctx context.Context, registryPath, only string, dryRun, al return fmt.Errorf("failed to load registry: %w", err) } + // Check workspace config for default_only if no filter specified + if only == "" { + registryDir := filepath.Dir(registryPath) + if wsConfig, err := workspace.LoadConfig(registryDir); err == nil && wsConfig != nil && len(wsConfig.DefaultOnly) > 0 { + only = strings.Join(wsConfig.DefaultOnly, ",") + } + } + return runRegistrySetupWithReg(ctx, reg, registryPath, only, dryRun, all, runBuild) } @@ -39,12 +47,9 @@ func runRegistrySetupWithReg(ctx context.Context, reg *repos.Registry, registryP // Determine base path for cloning basePath := reg.BasePath if basePath == "" { - // Load workspace config to see if packages_dir is set - wsConfig, err := workspace.LoadConfig(registryDir) - if err != nil { - return fmt.Errorf("failed to load workspace config: %w", err) - } - if wsConfig.PackagesDir != "" { + // Load workspace config to see if packages_dir is set (ignore errors, fall back to default) + wsConfig, _ := workspace.LoadConfig(registryDir) + if wsConfig != nil && wsConfig.PackagesDir != "" { basePath = wsConfig.PackagesDir } else { basePath = "./packages" diff --git a/pkg/workspace/cmd_workspace.go b/pkg/workspace/cmd_workspace.go index c61b30cb..a25b1163 100644 --- a/pkg/workspace/cmd_workspace.go +++ b/pkg/workspace/cmd_workspace.go @@ -33,6 +33,9 @@ func runWorkspaceInfo(cmd *cobra.Command, args []string) error { if err != nil { return err } + if config == nil { + return cli.Err("workspace config not found") + } cli.Print("Active: %s\n", cli.ValueStyle.Render(config.Active)) cli.Print("Packages: %s\n", cli.DimStyle.Render(config.PackagesDir)) @@ -53,6 +56,9 @@ func runWorkspaceActive(cmd *cobra.Command, args []string) error { if err != nil { return err } + if config == nil { + config = DefaultConfig() + } // If no args, show active if len(args) == 0 { @@ -60,7 +66,7 @@ func runWorkspaceActive(cmd *cobra.Command, args []string) error { cli.Println("No active package set") return nil } - cli.Println(config.Active) + cli.Text(config.Active) return nil } diff --git a/pkg/workspace/config.go b/pkg/workspace/config.go index d68222ea..fc781b5b 100644 --- a/pkg/workspace/config.go +++ b/pkg/workspace/config.go @@ -25,6 +25,7 @@ func DefaultConfig() *WorkspaceConfig { } // LoadConfig tries to load workspace.yaml from the given directory's .core subfolder. +// Returns nil if no config file exists (caller should check for nil). func LoadConfig(dir string) (*WorkspaceConfig, error) { path := filepath.Join(dir, ".core", "workspace.yaml") data, err := os.ReadFile(path) @@ -35,7 +36,8 @@ func LoadConfig(dir string) (*WorkspaceConfig, error) { if parent != dir { return LoadConfig(parent) } - return DefaultConfig(), nil + // No workspace.yaml found anywhere - return nil to indicate no config + return nil, nil } return nil, fmt.Errorf("failed to read workspace config: %w", err) }