Repository navigation
fix(scripts): prevent nested scaffolding and fix target resolution - #15
Conversation
There was a problem hiding this comment.
Code Review Summary
Needs Attention (1 issue)
- [Correctness] Bash pattern matching bug in path resolution condition - scripts/create-project.sh:177
The condition uses quoted glob pattern"$TEMPLATE_REAL_DIR"/*which prevents bash from recognizing it as a pattern. The second part of the OR condition will never match. Change to unquoted pattern:$CURRENT_DIR == $TEMPLATE_REAL_DIR/*for proper glob expansion.
Suggestions (3 items)
-
[Maintainability] Extract path validation logic into separate functions (HIGH impact, MED effort)
Lines 145-219 contain complex interrelated validation logic. Breaking this into functions likevalidate_nested_git(),resolve_target_path(), andvalidate_target_containment()would improve readability and testability. -
[Simplification] Reconsider necessity of dual-stage validation (MED impact, MED effort)
The combination of pre-validation (lines 181-205) and post-creation fallback check (lines 211-219) adds complexity. Evaluate whether the post-creation check is actually necessary given the thorough pre-validation logic, or if it could be consolidated. -
[Documentation] Add comments clarifying the exact scenarios being prevented (LOW impact, LOW effort)
While comments explain the technical issues (Git submodule errors, nested git corruption), a brief note about the specific user scenarios (e.g., accidental scaffolding inside template repo) would help maintainers understand the threat model.
All Clear
- Pass 1 (Correctness & Logic): Nested git detection, sibling resolution logic, and ancestor validation are sound (modulo the pattern matching issue).
- Pass 4 (Security): No credentials, injection vulnerabilities, or sensitive information leaks detected. Path validation prevents directory traversal.
- Pass 6 (Test Quality): Good edge case coverage including filesystem mutation prevention and nested git detection.
- Pass 7 (Performance): Appropriate use of find exclusions and bounded loop logic.
- Pass 10 (PII Detection): No personally identifiable information found.
Verdict: Needs Work
The bash pattern matching bug on line 177 is a correctness issue that will cause the sibling directory resolution feature to fail silently in its intended use case (when running from within the template directory). This must be fixed before merging.
When create-project.sh was executed from within the template directory with a bare project name (e.g. 'wisprflow-muteme-ptt-bridge'), it resolved the target path directly inside the template repository. This left stray nested git repositories that caused Copier to fail on subsequent invocations with 'fatal: No url found for submodule path in .gitmodules'. This change: - Resolves bare target names to the template's sibling directory. - Excludes '.' and '..' and normalizes target path formatting. - Validates target containment prior to creating directories on disk. - Runs pre-flight checks with pruning for nested git repos. - Expands Justfile test assertions and updates README and CLI help. AI-Reasoning: https://github.com/menil/project-template/blob/ai-reasoning/fix-scaffolding-target-resolution.md
19b0ac4 to
c7eec26
Compare
|
Addressed review feedback: the glob pattern matching on line 177 has been fixed in commit c7eec26. Sibling resolution and path containment validation are tested and verified via |
Summary
When
scripts/create-project.shwas invoked from within the template repository with a bare project name (e.g../scripts/create-project.sh wisprflow-muteme-ptt-bridge), it resolved target destinations relative to$PWD, creating downstream repositories nested directly inside the template repository.This created stray nested
.gitrepositories (such as./sandbox), which broke subsequent Copier invocations: Copier's VCS cloning logic attempted to stage dirty changes viagit add -A, adding untracked nested repos as gitlinks without.gitmodulesentries, fatally crashing ongit submodule update:Key Changes
.and..), automatically resolves the target to a sibling directory (../<name>), aligning with standard multi-repo workspace structures.my-app/->my-app).mkdir -p../nested/sub) on invalid target paths without relying on post-creation rollback.-e "$TEMPLATE_SRC/.git").-prunefor.git,.direnv,.venv, andnode_modulesto avoid deep object graph traversals.Justfile(test-templaterecipe) to verify rejection of., shallow paths, and multi-level paths inside the template repository without leaving disk artifacts, and verified that pre-flight scans catch nested.gitfolders.--helptext andREADME.mdto document sibling resolution behavior.Verification
nix-shell --run "just validate"passed all linters, formatting, and Copier generation tests../scripts/create-project.sh --dry-run wisprflow-muteme-ptt-bridge.