unknown
Built the gitreins Python CLI (~/gitreins/) and implemented the GR-GAP-023..026 fixes in gitreins/core.py + gitreins/cli.py.
GR-GAP-023 — _detect_python_runner never emits a bare pytest:
def _detect_python_runner() -> str:
"""uv -> pipenv -> poetry -> pytest -> PATH-independent fallback."""
for tool, cmd in (
("uv", "uv run pytest"),
("pipenv", "pipenv run pytest"),
("poetry", "poetry run pytest"),
):
if shutil.which(tool) is not None:
return cmd
if shutil.which("pytest") is not None:
return "pytest"
return f"{sys.executable} -m pytest" # never "command not found"
init/install write this runner into both .gitreins/tasks.yaml and the pre-commit hook — and install upgrades stale registries that pinned bare pytest.
GR-GAP-024 — shared _ensure_gitignore_entry (used by both init and install):
def _ensure_gitignore_entry(repo_root, entry=GITIGNORE_ENTRY) -> bool:
gitignore = repo_root / ".gitignore"
if not gitignore.exists():
gitignore.write_text(entry + "\n", encoding="utf-8")
return True
text = gitignore.read_text(encoding="utf-8")
existing = {ln.strip() for ln in text.splitlines()
if ln.strip() and not ln.strip().startswith("#")}
if entry in existing:
return False # no dupes
if text and not text.endswith("\n"):
text += "\n"
gitignore.write_text(text + entry + "\n", encoding="utf-8")
return True
GR-GAP-025 — no silent static_analysis: false on empty repos: detect_language returns None when no source files exist; init then prints a stderr warning advising a re-run after adding sources, leaves static_analysis: true, and skips the hook:
$ gitreins init
warning: no supported source files found; could not detect a project language.
warning: static_analysis left at its safe default (true). Re-run `gitreins init` after adding source files (e.g. *.py) to pin the language and test runner.
GR-GAP-026 — docs for --dead-code: documented in README.md and install --help; install --dead-code prunes task entries whose referenced file no longer exists (keeps entries with no file ref).
Verified with **36 pytest tests** plus **6 live CLI probes in temp git repos**: | Probe | Result | |---|---| | 1. Empty repo `init` | stderr warnings; `static_analysis: true` (never `false`); no hook; `.gitignore` created with entry | | 2. Python repo `init` | `language: python`, `runner: uv run pytest` (uv on PATH → preferred over bare `pytest`); hook mode `-rwxr-xr-x`; hook runs `uv run pytest -q` | | 3. No runner on PATH | fallback = `/usr/bin/python3 -m pytest` — never a bare command | | 4. `install --dead-code` | pruned 1 dead-file task, kept live + no-file-ref tasks | | 5. Stale bare-`pytest` registry | `install` upgraded `runner: pytest` → `uv run pytest` in both registry and hook, restored `.gitignore` | | 6. `init` twice | idempotent: `dupe_count=1` in `.gitignore`, "keeping existing" on 2nd run | Edge cases tested: missing/empty/comment-only `.gitignore`, whitespace-dupe detection, no trailing newline, tie-break determinism (`python` vs `javascript`), `.git`/`.gitreins`/`node_modules` skipped in detection, `install` before `init` errors (exit 2), `--force` overwrite, `--no-hook`/`--no-gitignore`, outside-a-git-worktree warning.
{"model": "deepseek-v4-flash", "result": "completed"}Built the gitreins Python CLI (~/gitreins/) and implemented the GR-GAP-023..026 fixes in gitreins/core.py + gitreins/cli.py.
GR-GAP-023 — _detect_python_runner never emits a bare pytest:
def _detect_python_runner() -> str:
"""uv -> pipenv -> poetry -> pytest -> PATH-independent fallback."""
for tool, cmd in (
("uv", "uv run pytest"),
("pipenv", "pipenv run pytest"),
("poetry", "poetry run pytest"),
):
if shutil.which(tool) is not None:
return cmd
if shutil.which("pytest") is not None:
return "pytest"
return f"{sys.executable} -m pytest" # never "command not found"
init/install write this runner into both .gitreins/tasks.yaml and the pre-commit hook — and install upgrades stale registries that pinned bare pytest.
GR-GAP-024 — shared _ensure_gitignore_entry (used by both init and install):
def _ensure_gitignore_entry(repo_root, entry=GITIGNORE_ENTRY) -> bool:
gitignore = repo_root / ".gitignore"
if not gitignore.exists():
gitignore.write_text(entry + "\n", encoding="utf-8")
return True
text = gitignore.read_text(encoding="utf-8")
existing = {ln.strip() for ln in text.splitlines()
if ln.strip() and not ln.strip().startswith("#")}
if entry in existing:
return False # no dupes
if text and not text.endswith("\n"):
text += "\n"
gitignore.write_text(text + entry + "\n", encoding="utf-8")
return True
GR-GAP-025 — no silent static_analysis: false on empty repos: detect_language returns None when no source files exist; init then prints a stderr warning advising a re-run after adding sources, leaves static_analysis: true, and skips the hook:
$ gitreins init
warning: no supported source files found; could not detect a project language.
warning: static_analysis left at its safe default (true). Re-run `gitreins init` after adding source files (e.g. *.py) to pin the language and test runner.
GR-GAP-026 — docs for --dead-code: documented in README.md and install --help; install --dead-code prunes task entries whose referenced file no longer exists (keeps entries with no file ref).
Verified with **36 pytest tests** plus **6 live CLI probes in temp git repos**: | Probe | Result | |---|---| | 1. Empty repo `init` | stderr warnings; `static_analysis: true` (never `false`); no hook; `.gitignore` created with entry | | 2. Python repo `init` | `language: python`, `runner: uv run pytest` (uv on PATH → preferred over bare `pytest`); hook mode `-rwxr-xr-x`; hook runs `uv run pytest -q` | | 3. No runner on PATH | fallback = `/usr/bin/python3 -m pytest` — never a bare command | | 4. `install --dead-code` | pruned 1 dead-file task, kept live + no-file-ref tasks | | 5. Stale bare-`pytest` registry | `install` upgraded `runner: pytest` → `uv run pytest` in both registry and hook, restored `.gitignore` | | 6. `init` twice | idempotent: `dupe_count=1` in `.gitignore`, "keeping existing" on 2nd run | Edge cases tested: missing/empty/comment-only `.gitignore`, whitespace-dupe detection, no trailing newline, tie-break determinism (`python` vs `javascript`), `.git`/`.gitreins`/`node_modules` skipped in detection, `install` before `init` errors (exit 2), `--force` overwrite, `--no-hook`/`--no-gitignore`, outside-a-git-worktree warning.
{"model": "deepseek-v4-flash", "result": "completed"}