Skip to content

feat: dynamic environment scaffolding and human-readable config parsing#56

Merged
JacksonFergusonDev merged 9 commits intomainfrom
feat/env-config
Feb 25, 2026
Merged

feat: dynamic environment scaffolding and human-readable config parsing#56
JacksonFergusonDev merged 9 commits intomainfrom
feat/env-config

Conversation

@JacksonFergusonDev
Copy link
Owner

Description

This PR overhauls the configuration engine to provide a more flexible, user-friendly, and secure experience. It abstracts hardcoded environment variables into the configuration hierarchy, introduces human-readable string parsing for intervals/limits, and gives power users strict control over their .gitignore files.

Key Changes

1. Dynamic Environment Scaffolding (--env)

  • EnvConfig Dataclass: Added to config.py to expose python_version, venv_dir, generate_vscode_settings, and generate_direnv.
  • Refactored bootstrap_env: Replaced hardcoded strings ("3.12", ".venv") with dynamic injections from the active Config payload.

2. Safety & Index Bloat Prevention

  • Dynamic Ignore: bootstrap_env now dynamically injects the configured venv_dir into .gitignore upon creation to prevent the daemon from staging thousands of Python binaries into the shadow index.
  • Default Fallback: Appended ".venv/" to DEFAULT_IGNORES in constants.py for standard repository initialization.
  • Opt-Out .gitignore Management: Added a manage_gitignore boolean to FilesConfig. If set to false, the daemon will completely bypass writing to .gitignore during setup_repo and add_ignore, respecting user boundaries.

3. Human-Readable Configuration & Validation

  • Regex Parsers: Added parse_time (e.g., "10m", "1 hr") and parse_size (e.g., "100mb", "1.5gb") to config.py.
  • Robust Fallbacks: The configuration engine now intercepts unknown keys, logs targeted warnings, and safely falls back to defaults if parsing fails, rather than silently dropping data or crashing.

4. CLI Observability

  • Config Reference Table: Added the --list (-l) flag to the git pulsar config command. This renders a comprehensive Rich table outlining all configuration sections, keys, accepted types, defaults, and descriptions.

Testing

  • Updated test_ops.py to mock Config and assert dynamic directory injections.
  • Added strict regex-matching assertions (pytest.raises(ValueError, match=...)) to test_config.py to validate byte/second conversions and ensure Ruff (PT011) compliance.
  • Verified configuration fallback logic on invalid inputs.

Extends the global configuration model to support customizable parameters
for the `--env` bootstrap command. Introduces the `EnvConfig` dataclass
to handle Python version targeting, virtual environment directory naming,
and boolean flags for opting out of VS Code and direnv generation.

This ensures the environment scaffolding is decoupled from hardcoded
strings and can participate in the cascading TOML configuration hierarchy.
Updates `bootstrap_env` to load the active `Config` instance and utilize
the new `EnvConfig` parameters.

- Dynamically injects `config.env.python_version` into the `uv init` call.
- Dynamically injects `config.env.venv_dir` into the `.envrc` and VS Code
  settings generation templates.
- Wraps the direnv and VS Code generation blocks in conditionals based on
  the respective boolean flags in `EnvConfig`.
Injects a dynamic call to `add_ignore()` in the `--env` bootstrap sequence
to automatically untrack the configured virtual environment directory
(`config.env.venv_dir`).

Additionally appends `".venv/"` to `DEFAULT_IGNORES` in `constants.py` as a
fallback safety measure for standard repository initialization.
Refactors `test_bootstrap_env_scaffolds_files` to mock the active
`Config` state rather than relying on hardcoded defaults.

- Asserts that the dynamically assigned `venv_dir` is correctly
  injected into the generated `.envrc` and VS Code settings files.
- Verifies that `add_ignore` is successfully called with the custom
  virtual environment directory path to prevent index bloat.
Introduces the `manage_gitignore` boolean flag in `FilesConfig` to allow
users to opt out of automated `.gitignore` modifications.

- Wraps the default ignore scaffolding in `cli.py`'s `setup_repo()`
  behind the flag constraint.
- Conditionally bypasses the file write step in `ops.py`'s `add_ignore()`
  while preserving the index tracking checks.

This ensures Git Pulsar operates non-destructively for power users
who prefer strict, manual control over their repository ignore state.
Introduces `git pulsar config --list` to provide a zero-friction way
to view the configuration schema directly in the terminal.

- Renders a rich table containing all sections, keys, types, defaults,
  and descriptions.
- Keeps the primary `git pulsar help` output clean by isolating the
  verbose configuration matrix to a specific subcommand flag.
Introduces flexible string parsing for configuration values, allowing
users to define intervals (e.g., "10 min", "1 hr") and file limits
(e.g., "100mb", "1.5gb") intuitively.

- Adds `parse_size` and `parse_time` regex-based helper functions.
- Refactors `_update_dataclass` to intercept updates, warn on unknown
  keys, and safely fall back to defaults if parsing fails.
- Modifies the `.gitignore` parsing logic in `_merge_from_file` to cleanly
  separate list extension from dataclass field updates.
Introduces unit tests for the new `parse_time` and `parse_size` helpers
to ensure human-readable formats and whitespace variations are correctly
converted to operational integers.

- Verifies conversion logic for bytes (KB, MB, GB) and seconds (s, m, h).
- Implements strict `pytest.raises` matching to satisfy Ruff's PT011 rule
  and prevent false positives on generic ValueErrors.
- Adds `test_config_invalid_keys_and_values` to verify the configuration
  engine successfully intercepts garbage data, logs targeted warnings,
  and preserves safe defaults without crashing.
Updates the `git pulsar config --list` output to accurately reflect the
new parsing capabilities introduced in the configuration engine.

- Changes type hints for interval and threshold settings to `int | str`.
- Updates the displayed defaults to their human-readable equivalents
  (e.g., `"10m"`, `"100mb"`).
- Expands descriptions to include syntax examples for the time and size
  parsers.
@JacksonFergusonDev JacksonFergusonDev merged commit 9eea9e3 into main Feb 25, 2026
4 checks passed
@JacksonFergusonDev JacksonFergusonDev deleted the feat/env-config branch February 25, 2026 06:23
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