feat(template): add in_existing_repo for scaffolding into an existing repo - #13
Open
maybebyte wants to merge 4 commits into
Open
feat(template): add in_existing_repo for scaffolding into an existing repo#13maybebyte wants to merge 4 commits into
maybebyte wants to merge 4 commits into
Conversation
`just ci` runs pytest with --cov, which writes .coverage next to the coverage.xml the generated .gitignore already covers. A downstream had to add the line by hand, and every local edit to a template-owned file is a conflict waiting for the next `copier update`.
test_precommit_install_task_runs called copier.run_copy directly without vcs_ref="HEAD", so it rendered copier's default ref, the latest release tag, and could not observe any change to the copy-time _tasks (the same freeze PR #4 fixed for the render fixture). It also failed on any machine whose global git config sets core.hooksPath, because pre-commit refuses to install hooks under it. Route it through the render fixture and add git_global_config, which points GIT_CONFIG_GLOBAL at a throwaway file in both os.environ and plumbum's local.env (copier's git and task channel), so the machine's config cannot leak into a render in either direction.
pre-commit refuses to install hooks while git's core.hooksPath is set in any scope, and a failing _task makes copier delete the whole copy. The task now checks the setting first and skips with a hint on stderr, so a machine with a global hooks directory still gets a complete render; the hooks can be installed by hand once the setting is gone. A generation test pins the skip: the copy succeeds, no hook lands, the hint prints.
Scaffolding into a subdirectory of an existing repository used to need two manual repairs: the unconditional `git init` created a nested repo, and the CI workflows, .pre-commit-config.yaml and renovate.json rendered where GitHub and Renovate never read them. Deleting those locally then conflicts on every later `copier update` that touches them. The new answer (default false) skips `git init` and the hook install and omits the three root-only artifacts, with an after-copy note listing what to recreate at the repository root. Without it, the init task now fails closed when the destination sits inside another work tree and names the answer to re-run with, instead of nesting a repository silently; copier's own `git init && copier copy … .` pattern still passes because the toplevel is the destination there.
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.
Summary
Dogfooding v0.1.1 into a subdirectory of an existing repository needed two manual repairs (a nested
.git, inert CI/pre-commit/Renovate files) and a workaround for the hook-install task, which aborts the whole copy on any machine with git'score.hooksPathset. This adds a first-classin_existing_repoanswer for the nested layout and makes the copy-time tasks fail closed or skip with a hint instead of rolling the copy back.Changes
in_existing_repo(defaultfalse): skipsgit initand the hook install and omits the root-only.github/,.pre-commit-config.yaml, andrenovate.jsonvia path conditions, with an after-copy note listing what to recreate at the repository root. Rendering them nested leaves inert files whose local deletion conflicts on every latercopier update, which is why omission beats documentation here.git inittask now fails closed when the destination sits inside another work tree and names the answer to re-run with. Root cause: a baregit initin a subdirectory of a repository silently creates a nested repository. Copier's documentedgit init && copier copy … .pattern still passes because the toplevel is the destination there.core.hooksPathis set (pre-commit refuses to install under it, in any scope, with no override flag), and the generated.gitignoregains.coverage. The existing install test rendered the release tag rather than HEAD, so it could not see task changes; it now goes through the HEAD-pinned fixture with git's global config isolated.Testing
TMPDIR=<roomy dir> just cion this branch:78 passed,No known vulnerabilities found,ci: all gates passed. The four new or changed generation tests cover the hooksPath skip, the nested happy path (just cigreen from the subdirectory, nothing installed into the parent's hooks), and the fail-closed abort with rollback.main, on a machine whose global git config setscore.hooksPath,uv run pytest tests/test_generation.py::test_precommit_install_task_runsfails with pre-commit'sCowardly refusing to install hooks with core.hooksPath set; on this branch it passes.copier copy --trust --pretend --defaults --data in_existing_repo=true . <dst>lists no.github/,.pre-commit-config.yaml, orrenovate.jsonand prints the nested note; without the answer all three render and the note is absent.Notes for reviewers
copier update; the default keeps their tree unchanged. Decision: the reverse check (answer on, but not inside any repo) is not guarded; Copier's own update precondition reports the missing git repository clearly later.