From c3464ea4b95302d1b921098377e2cc7d1f30a19c Mon Sep 17 00:00:00 2001 From: abhinavgautam01 Date: Tue, 30 Jun 2026 13:47:17 +0530 Subject: [PATCH] Clarify scaffold structural folders --- README.md | 5 +++++ src/maxed_cli/schemas/config.schema.json | 2 +- tests/test_cli.py | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index aa53fc8..45fd810 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,11 @@ suite**: `close-checklist` document, valid against the published v0.1 schema; - `configs/workspace.json` — a self-describing copy of the config. +The optional `workspace.folders` setting ensures additional folders exist under +the workspace root. It is not an allowlist: `init` still creates the suite +structural folders needed for the generated config, examples, fixtures, and +pipeline files listed above. + Re-running is safe (idempotent): existing paths are reported as `exists`. ### 2. Validate a workspace config diff --git a/src/maxed_cli/schemas/config.schema.json b/src/maxed_cli/schemas/config.schema.json index 79e2a09..ad89af9 100644 --- a/src/maxed_cli/schemas/config.schema.json +++ b/src/maxed_cli/schemas/config.schema.json @@ -46,7 +46,7 @@ }, "folders": { "type": "array", - "description": "Sub-folders to create under the workspace root.", + "description": "Additional workspace folders to create under the workspace root. maxed init also creates suite structural folders needed for generated config, examples, fixtures, and pipeline files.", "items": { "type": "string", "minLength": 1 }, "uniqueItems": true, "default": ["workpapers", "configs", "fixtures", "exports"] diff --git a/tests/test_cli.py b/tests/test_cli.py index 3c2c765..b5583bf 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -101,6 +101,23 @@ def test_init_scaffolds(tmp_path: Path) -> None: assert (ws / "workpapers" / "example.workpaper.json").is_file() +def test_init_custom_folders_are_not_structural_folder_allowlist(tmp_path: Path) -> None: + config = { + **VALID_CONFIG, + "workspace": {"root": "./ws", "folders": ["exports"]}, + } + cfg = _yaml(tmp_path / "c.yaml", config) + result = runner.invoke(app, ["init", str(cfg), "--base-dir", str(tmp_path)]) + assert result.exit_code == 0 + + ws = tmp_path / "ws" + assert (ws / "exports").is_dir() + assert (ws / "configs" / "workspace.json").is_file() + assert (ws / "fixtures" / "statement.csv").is_file() + assert (ws / "pipeline" / "import_transactions.py").is_file() + assert (ws / "workpapers" / "example.workpaper.json").is_file() + + def test_init_is_idempotent(tmp_path: Path) -> None: cfg = _yaml(tmp_path / "c.yaml", VALID_CONFIG) first = runner.invoke(app, ["init", str(cfg), "--base-dir", str(tmp_path)])