Skip to content

feat(workspace): shareable repo workspace policy - #21

Merged
reckerp merged 5 commits into
mainfrom
feat/shared-repo-workspace-config
Jun 29, 2026
Merged

feat(workspace): shareable repo workspace policy#21
reckerp merged 5 commits into
mainfrom
feat/shared-repo-workspace-config

Conversation

@reckerp

@reckerp reckerp commented Jun 29, 2026

Copy link
Copy Markdown
Owner

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, and tmp/

Config precedence (lowest to highest)

  1. Built-in defaults
  2. Global user config (confy)
  3. Personal repo-setup profile (kept as an override source)
  4. Shared .gx/workspace.toml
  5. Local .gx/workspace.local.toml

CLI flags layer on top via the caller. copy_files is unioned across layers (and deduped), mirroring the existing setup pipeline; scalar fields replace.

New repo_config module

  • Loads and merges the layers into one resolved WorkspacePolicy, with upward .gx/ discovery so the config is found from nested directories.
  • Forward-compatible version pre-pass: an unknown future version warns on stderr and still loads the known subset of fields (serde ignores unknown fields) — no panic.
  • Hook model: pre_create / post_create shell commands with {workspace}, {workspace_path}, {main_root}, {branch} expansion (also exported as GX_* 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 new resolves the policy, uses its unioned copy_files, runs pre-create hooks before git worktree add, and runs post-create hooks plus the repo-config .gx setup 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 setup resolves the repo policy and applies its copy_files.
  • Hook execution sits behind a run_hooks gate, leaving the seam for section 4's future --no-hooks flag.

Onboarding

gx onboarding now 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_config tests 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.

reckerp added 5 commits June 29, 2026 21:52
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
@reckerp
reckerp merged commit b75b557 into main Jun 29, 2026
6 checks passed
@reckerp
reckerp deleted the feat/shared-repo-workspace-config branch June 29, 2026 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant