feat(workspace): shareable repo workspace policy - #21
Merged
Conversation
The shared repo workspace policy needs real TOML parsing (with a toml::Value pre-pass for forward-compatible version detection) rather than the hand-rolled parser used for the personal profile. Add the `toml` crate as a dependency for that loader.
Add an optional, committable repo-level config that lets a team define a
shared workspace setup, replacing the personal-only model where repo
setup lived outside the repo.
New `repo_config` module:
- Loads `.gx/workspace.toml` (committable) and `.gx/workspace.local.toml`
(git-ignored override) via serde + the `toml` crate, with upward
directory discovery so the config is found from nested paths.
- Merges config layers into one resolved WorkspacePolicy with the
precedence: built-in defaults < global user config < personal profile
< shared repo config < local override. copy_files unions across layers
(mirroring the existing setup pipeline); scalars replace.
- A forward-compatible version pre-pass warns (not panics) on an unknown
future `version` and still loads the known subset of fields.
- Hook support: pre_create / post_create shell commands with
{workspace}, {workspace_path}, {main_root} and {branch} expansion,
also exported as GX_* env vars. Hook stdout is redirected to stderr so
gx's own stdout stays clean for shell navigation.
- Helpers to scaffold `.gx` (config file, `.gitignore`, local override)
for the onboarding flow.
Expose `repo_setup::stderr_stdio` to `pub(crate)` so hook and repo-config
script execution reuse the existing stdout-clean convention.
Wire the resolved WorkspacePolicy into workspace creation and setup so the shared repo config takes effect: - `workspace new` resolves the policy and uses its unioned copy_files, runs pre-create hooks before `git worktree add` (a failure aborts creation and leaves nothing behind), and runs post-create hooks plus the repo-config `.gx` setup script afterward (failures warn but keep the workspace). The repo-config script is skipped when it resolves to the personal profile's script, which run_setup_pipeline already runs, so the same script never runs twice. - `workspace setup` resolves the policy for the repo and applies its copy_files, honoring the shared config too. - Hook execution is gated behind a run_hooks parameter, leaving the seam for section 4's future `--no-hooks` flag.
`gx onboarding` now asks where the setup should live: personal-only (the existing behavior, kept for secrets and machine-specific scripts) or shared repo config. Choosing shared writes `.gx/workspace.toml`, a `.gx/.gitignore`, an optional `.gx/setup-workspace.sh`, and an optional `.gx/workspace.local.toml` override, giving a team a committable default while still supporting personal overrides.
…space-config # Conflicts: # src/commands/workspace.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds an optional, committable repo-level workspace config so workspace setup can belong to the repository, not just to one developer. This implements section 3 (Shareable Repo Workspace Policy) of the GX Workspace Improvement Plan.
New files a repo may carry:
.gx/workspace.toml— committable shared defaults.gx/workspace.local.toml— git-ignored, machine-specific override.gx/.gitignore— ignores the local override,state.toml, andtmp/Config precedence (lowest to highest)
.gx/workspace.toml.gx/workspace.local.tomlCLI flags layer on top via the caller.
copy_filesis unioned across layers (and deduped), mirroring the existing setup pipeline; scalar fields replace.New
repo_configmoduleWorkspacePolicy, with upward.gx/discovery so the config is found from nested directories.versionpre-pass: an unknown future version warns on stderr and still loads the known subset of fields (serde ignores unknown fields) — no panic.pre_create/post_createshell commands with{workspace},{workspace_path},{main_root},{branch}expansion (also exported asGX_*env vars). Pre-create failure aborts creation; post-create failure warns but keeps the workspace. Hook stdout is redirected to stderr to keep gx's stdout clean for shell navigation.Command integration
workspace newresolves the policy, uses its unionedcopy_files, runs pre-create hooks beforegit worktree add, and runs post-create hooks plus the repo-config.gxsetup script afterward. The repo-config script is skipped when it resolves to the personal profile's script (already run by the setup pipeline), so it never runs twice.workspace setupresolves the repo policy and applies itscopy_files.run_hooksgate, leaving the seam for section 4's future--no-hooksflag.Onboarding
gx onboardingnow asks where setup should live: personal-only (existing behavior, kept for secrets and local-only scripts) or shared repo config. Choosing shared scaffolds.gx/workspace.toml,.gx/.gitignore, an optional setup script, and an optional local override.Why
Today repo setup lives outside the repo, which is useful for personal secrets and local scripts but gives a team no shared default. This adds that shared default while preserving the personal-only path as an override source.
Testing
cargo build— clean, no warnings.cargo test— 142 passed, 0 failed.New
repo_configtests cover the plan's required cases: shared config discovered from nested directories, local override winning over shared, global config working with no repo config, unknown future version warning (not panicking), hook variable expansion, and post-create hook failure not removing the workspace.