git-reaper 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- git_reaper-0.1.0/.github/workflows/ci.yml +50 -0
- git_reaper-0.1.0/.github/workflows/docs.yml +37 -0
- git_reaper-0.1.0/.github/workflows/publish.yml +42 -0
- git_reaper-0.1.0/.gitignore +223 -0
- git_reaper-0.1.0/CHANGELOG.md +70 -0
- git_reaper-0.1.0/LICENSE +21 -0
- git_reaper-0.1.0/Makefile +51 -0
- git_reaper-0.1.0/PKG-INFO +149 -0
- git_reaper-0.1.0/README.md +92 -0
- git_reaper-0.1.0/docs/api.md +25 -0
- git_reaper-0.1.0/docs/commands.md +101 -0
- git_reaper-0.1.0/docs/development.md +45 -0
- git_reaper-0.1.0/docs/index.md +62 -0
- git_reaper-0.1.0/docs/library.md +70 -0
- git_reaper-0.1.0/mkdocs.yml +51 -0
- git_reaper-0.1.0/pyproject.toml +101 -0
- git_reaper-0.1.0/src/git_reaper/__init__.py +8 -0
- git_reaper-0.1.0/src/git_reaper/__main__.py +6 -0
- git_reaper-0.1.0/src/git_reaper/_version.py +24 -0
- git_reaper-0.1.0/src/git_reaper/art.py +60 -0
- git_reaper-0.1.0/src/git_reaper/cache.py +131 -0
- git_reaper-0.1.0/src/git_reaper/cli.py +340 -0
- git_reaper-0.1.0/src/git_reaper/core/__init__.py +1 -0
- git_reaper-0.1.0/src/git_reaper/core/harvest.py +81 -0
- git_reaper-0.1.0/src/git_reaper/core/provenance.py +27 -0
- git_reaper-0.1.0/src/git_reaper/core/pulse.py +75 -0
- git_reaper-0.1.0/src/git_reaper/core/source.py +70 -0
- git_reaper-0.1.0/src/git_reaper/core/tree.py +58 -0
- git_reaper-0.1.0/src/git_reaper/formatters/__init__.py +2 -0
- git_reaper-0.1.0/src/git_reaper/formatters/jsonfmt.py +22 -0
- git_reaper-0.1.0/src/git_reaper/formatters/markdown.py +81 -0
- git_reaper-0.1.0/src/git_reaper/fsutil.py +99 -0
- git_reaper-0.1.0/src/git_reaper/gitio/__init__.py +11 -0
- git_reaper-0.1.0/src/git_reaper/gitio/backend.py +46 -0
- git_reaper-0.1.0/src/git_reaper/gitio/subprocess_git.py +102 -0
- git_reaper-0.1.0/src/git_reaper/ignore.py +60 -0
- git_reaper-0.1.0/src/git_reaper/models.py +123 -0
- git_reaper-0.1.0/src/git_reaper/schemas.py +97 -0
- git_reaper-0.1.0/src/git_reaper/theme.py +51 -0
- git_reaper-0.1.0/tests/conftest.py +76 -0
- git_reaper-0.1.0/tests/test_cache.py +88 -0
- git_reaper-0.1.0/tests/test_cli.py +106 -0
- git_reaper-0.1.0/tests/test_fsutil.py +46 -0
- git_reaper-0.1.0/tests/test_harvest.py +102 -0
- git_reaper-0.1.0/tests/test_ignore.py +59 -0
- git_reaper-0.1.0/tests/test_schemas.py +39 -0
- git_reaper-0.1.0/tests/test_tree.py +61 -0
- git_reaper-0.1.0/uv.lock +1513 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
lint:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
with:
|
|
14
|
+
fetch-depth: 0 # hatch-vcs needs tags to derive the version
|
|
15
|
+
- uses: astral-sh/setup-uv@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
- run: uv sync
|
|
19
|
+
- run: uv run ruff check src tests
|
|
20
|
+
- run: uv run ruff format --check src tests
|
|
21
|
+
- run: uv run mypy
|
|
22
|
+
|
|
23
|
+
test:
|
|
24
|
+
strategy:
|
|
25
|
+
fail-fast: false
|
|
26
|
+
matrix:
|
|
27
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
28
|
+
python: ["3.10", "3.11", "3.12", "3.13"]
|
|
29
|
+
runs-on: ${{ matrix.os }}
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v4
|
|
32
|
+
with:
|
|
33
|
+
fetch-depth: 0
|
|
34
|
+
- uses: astral-sh/setup-uv@v5
|
|
35
|
+
with:
|
|
36
|
+
python-version: ${{ matrix.python }}
|
|
37
|
+
- run: uv sync
|
|
38
|
+
- run: uv run pytest
|
|
39
|
+
|
|
40
|
+
docs:
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v4
|
|
44
|
+
with:
|
|
45
|
+
fetch-depth: 0
|
|
46
|
+
- uses: astral-sh/setup-uv@v5
|
|
47
|
+
with:
|
|
48
|
+
python-version: "3.12"
|
|
49
|
+
- run: uv sync --group docs
|
|
50
|
+
- run: uv run --group docs mkdocs build --strict
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
pages: write
|
|
11
|
+
id-token: write
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: pages
|
|
15
|
+
cancel-in-progress: false
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
deploy:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
environment:
|
|
21
|
+
name: github-pages
|
|
22
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
with:
|
|
26
|
+
fetch-depth: 0 # hatch-vcs needs tags to derive the version
|
|
27
|
+
- uses: astral-sh/setup-uv@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: "3.12"
|
|
30
|
+
- run: uv sync --group docs
|
|
31
|
+
- run: uv run --group docs mkdocs build --strict
|
|
32
|
+
- uses: actions/configure-pages@v5
|
|
33
|
+
- uses: actions/upload-pages-artifact@v3
|
|
34
|
+
with:
|
|
35
|
+
path: site
|
|
36
|
+
- id: deployment
|
|
37
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: publish
|
|
2
|
+
|
|
3
|
+
# Publishes to PyPI via trusted publishing (OIDC) when a GitHub release is
|
|
4
|
+
# published. One-time setup on PyPI: add a trusted publisher for this repo
|
|
5
|
+
# with workflow "publish.yml" and environment "pypi".
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
release:
|
|
9
|
+
types: [published]
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
with:
|
|
17
|
+
fetch-depth: 0 # hatch-vcs derives the version from the release tag
|
|
18
|
+
- uses: astral-sh/setup-uv@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
- run: uv sync
|
|
22
|
+
- run: uv run pytest
|
|
23
|
+
- run: uv build
|
|
24
|
+
- uses: actions/upload-artifact@v4
|
|
25
|
+
with:
|
|
26
|
+
name: dist
|
|
27
|
+
path: dist/
|
|
28
|
+
|
|
29
|
+
publish:
|
|
30
|
+
needs: build
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
environment:
|
|
33
|
+
name: pypi
|
|
34
|
+
url: https://pypi.org/p/git-reaper
|
|
35
|
+
permissions:
|
|
36
|
+
id-token: write
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/download-artifact@v4
|
|
39
|
+
with:
|
|
40
|
+
name: dist
|
|
41
|
+
path: dist/
|
|
42
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
# Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
# poetry.lock
|
|
109
|
+
# poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
# pdm.lock
|
|
116
|
+
# pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
# pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# Redis
|
|
135
|
+
*.rdb
|
|
136
|
+
*.aof
|
|
137
|
+
*.pid
|
|
138
|
+
|
|
139
|
+
# RabbitMQ
|
|
140
|
+
mnesia/
|
|
141
|
+
rabbitmq/
|
|
142
|
+
rabbitmq-data/
|
|
143
|
+
|
|
144
|
+
# ActiveMQ
|
|
145
|
+
activemq-data/
|
|
146
|
+
|
|
147
|
+
# SageMath parsed files
|
|
148
|
+
*.sage.py
|
|
149
|
+
|
|
150
|
+
# Environments
|
|
151
|
+
.env
|
|
152
|
+
.envrc
|
|
153
|
+
.venv
|
|
154
|
+
env/
|
|
155
|
+
venv/
|
|
156
|
+
ENV/
|
|
157
|
+
env.bak/
|
|
158
|
+
venv.bak/
|
|
159
|
+
|
|
160
|
+
# Spyder project settings
|
|
161
|
+
.spyderproject
|
|
162
|
+
.spyproject
|
|
163
|
+
|
|
164
|
+
# Rope project settings
|
|
165
|
+
.ropeproject
|
|
166
|
+
|
|
167
|
+
# mkdocs documentation
|
|
168
|
+
/site
|
|
169
|
+
|
|
170
|
+
# mypy
|
|
171
|
+
.mypy_cache/
|
|
172
|
+
.dmypy.json
|
|
173
|
+
dmypy.json
|
|
174
|
+
|
|
175
|
+
# Pyre type checker
|
|
176
|
+
.pyre/
|
|
177
|
+
|
|
178
|
+
# pytype static type analyzer
|
|
179
|
+
.pytype/
|
|
180
|
+
|
|
181
|
+
# Cython debug symbols
|
|
182
|
+
cython_debug/
|
|
183
|
+
|
|
184
|
+
# PyCharm
|
|
185
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
186
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
187
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
188
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
189
|
+
# .idea/
|
|
190
|
+
|
|
191
|
+
# Abstra
|
|
192
|
+
# Abstra is an AI-powered process automation framework.
|
|
193
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
194
|
+
# Learn more at https://abstra.io/docs
|
|
195
|
+
.abstra/
|
|
196
|
+
|
|
197
|
+
# Visual Studio Code
|
|
198
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
199
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
200
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
201
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
202
|
+
# .vscode/
|
|
203
|
+
# Temporary file for partial code execution
|
|
204
|
+
tempCodeRunnerFile.py
|
|
205
|
+
|
|
206
|
+
# Ruff stuff:
|
|
207
|
+
.ruff_cache/
|
|
208
|
+
|
|
209
|
+
# PyPI configuration file
|
|
210
|
+
.pypirc
|
|
211
|
+
|
|
212
|
+
# Marimo
|
|
213
|
+
marimo/_static/
|
|
214
|
+
marimo/_lsp/
|
|
215
|
+
__marimo__/
|
|
216
|
+
|
|
217
|
+
# Streamlit
|
|
218
|
+
.streamlit/secrets.toml
|
|
219
|
+
|
|
220
|
+
/dev-data
|
|
221
|
+
|
|
222
|
+
# generated by the hatch-vcs build hook
|
|
223
|
+
src/git_reaper/_version.py
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `git-reaper` are recorded here.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] - 2026-07-02
|
|
11
|
+
|
|
12
|
+
The First Harvest. Initial release: the flagship gather-and-concatenate
|
|
13
|
+
workflow, folder trees, a health check, and cache management, on top of a
|
|
14
|
+
library-first core.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
#### Commands
|
|
19
|
+
|
|
20
|
+
- `reaper harvest` - gather files matching a pattern (default `*.md`) from a
|
|
21
|
+
local path or remote repo URL and concatenate them into a single artifact
|
|
22
|
+
with a provenance header and per-file dividers.
|
|
23
|
+
- `reaper tree` - hierarchical file listing as markdown or JSON, with depth
|
|
24
|
+
limits, dirs-only mode, sizes, line counts, and ignore rules. Works on any
|
|
25
|
+
folder, git or not.
|
|
26
|
+
- `reaper pulse` - signs-of-life check: git presence and version, optional
|
|
27
|
+
extras, tty/color detection, cache health.
|
|
28
|
+
- `reaper banish` - clear the catacombs (the clone cache), with
|
|
29
|
+
`--older-than 7d` for partial exorcisms.
|
|
30
|
+
- `reaper boo` - hidden. You did not read this.
|
|
31
|
+
|
|
32
|
+
#### Core behavior
|
|
33
|
+
|
|
34
|
+
- Library-first architecture: all real work lives in `git_reaper.core` and
|
|
35
|
+
returns typed result models; the CLI is a thin presentation layer.
|
|
36
|
+
- The catacombs: remote clones cache under
|
|
37
|
+
`~/.cache/git-reaper/catacombs/<host>/<owner>/<repo>`, shallow by default
|
|
38
|
+
and reused across runs. Local `file://` sources are buried flat as
|
|
39
|
+
`localhost/<name>-<digest>` so deep source paths stay inside Windows
|
|
40
|
+
path limits.
|
|
41
|
+
- Provenance by default: every artifact opens with source, ref and SHA,
|
|
42
|
+
timestamp, tool version, and the exact invocation used to produce it.
|
|
43
|
+
- Deterministic output: same repo state plus same flags yields a
|
|
44
|
+
byte-identical artifact (only the provenance timestamp moves).
|
|
45
|
+
- Ignore rules honored: `.gitignore`, `.reaperignore`, and `--exclude` globs;
|
|
46
|
+
`.git` is never reaped.
|
|
47
|
+
- Binary detection and per-file size caps, with receipts: skipped files are
|
|
48
|
+
reported loudly, never silently.
|
|
49
|
+
- Artifacts go to stdout or `--out`; all themed narration and warnings go to
|
|
50
|
+
stderr, so piping is always safe.
|
|
51
|
+
|
|
52
|
+
#### Output and formats
|
|
53
|
+
|
|
54
|
+
- Markdown and JSON formatters.
|
|
55
|
+
- Published JSON schemas: every JSON-emitting command prints its schema with
|
|
56
|
+
`--schema`.
|
|
57
|
+
- Spooky Rich theming with a shared palette, plus `--plain` / `--no-theme`,
|
|
58
|
+
`NO_COLOR` support, and automatic degradation on non-tty output.
|
|
59
|
+
|
|
60
|
+
#### Packaging and tooling
|
|
61
|
+
|
|
62
|
+
- `src/` layout with hatchling build backend and uv lockfile; VCS-derived
|
|
63
|
+
versioning.
|
|
64
|
+
- Both `reaper` and `git-reaper` console entry points (the long form is the
|
|
65
|
+
fallback if the REAPER DAW owns the short one).
|
|
66
|
+
- Test suite covering the CLI, harvest, tree, ignore matching, cache, and
|
|
67
|
+
schema export; CI workflow; mkdocs documentation site; Makefile.
|
|
68
|
+
|
|
69
|
+
[Unreleased]: https://github.com/jmcmeen/git-reaper/compare/v0.1.0...HEAD
|
|
70
|
+
[0.1.0]: https://github.com/jmcmeen/git-reaper/releases/tag/v0.1.0
|
git_reaper-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 John McMeen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# git-reaper dev rituals. Everything runs through uv.
|
|
2
|
+
|
|
3
|
+
UV ?= uv
|
|
4
|
+
|
|
5
|
+
.DEFAULT_GOAL := help
|
|
6
|
+
|
|
7
|
+
.PHONY: help setup fmt lint typecheck test cov check build clean run pulse docs docs-build
|
|
8
|
+
|
|
9
|
+
help: ## List the available rituals
|
|
10
|
+
@grep -E '^[a-zA-Z_-]+:.*## ' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*## "}; {printf " \033[35m%-12s\033[0m %s\n", $$1, $$2}'
|
|
11
|
+
|
|
12
|
+
setup: ## Create the venv and install all deps (incl. dev group)
|
|
13
|
+
$(UV) sync
|
|
14
|
+
|
|
15
|
+
fmt: ## Auto-format and fix lint findings
|
|
16
|
+
$(UV) run ruff format src tests
|
|
17
|
+
$(UV) run ruff check --fix src tests
|
|
18
|
+
|
|
19
|
+
lint: ## Lint and check formatting (no changes)
|
|
20
|
+
$(UV) run ruff check src tests
|
|
21
|
+
$(UV) run ruff format --check src tests
|
|
22
|
+
|
|
23
|
+
typecheck: ## mypy over the typed core
|
|
24
|
+
$(UV) run mypy
|
|
25
|
+
|
|
26
|
+
test: ## Run the test suite
|
|
27
|
+
$(UV) run pytest
|
|
28
|
+
|
|
29
|
+
cov: ## Tests with coverage report
|
|
30
|
+
$(UV) run pytest --cov=git_reaper --cov-report=term-missing
|
|
31
|
+
|
|
32
|
+
check: lint typecheck test ## The full gauntlet: lint + types + tests
|
|
33
|
+
|
|
34
|
+
docs: ## Serve the docs locally with live reload
|
|
35
|
+
$(UV) run --group docs mkdocs serve
|
|
36
|
+
|
|
37
|
+
docs-build: ## Build the docs strictly (what CI runs)
|
|
38
|
+
$(UV) run --group docs mkdocs build --strict
|
|
39
|
+
|
|
40
|
+
build: ## Build sdist and wheel into dist/
|
|
41
|
+
$(UV) build
|
|
42
|
+
|
|
43
|
+
clean: ## Sweep build artifacts and caches
|
|
44
|
+
rm -rf dist build site .pytest_cache .mypy_cache .ruff_cache .coverage htmlcov
|
|
45
|
+
find . -type d -name __pycache__ -not -path './.venv/*' -exec rm -rf {} +
|
|
46
|
+
|
|
47
|
+
run: ## Run the CLI (ARGS="tree ." to pass arguments)
|
|
48
|
+
$(UV) run reaper $(ARGS)
|
|
49
|
+
|
|
50
|
+
pulse: ## Signs-of-life check via the CLI
|
|
51
|
+
$(UV) run reaper pulse
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: git-reaper
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A spooky utility for data mining git repositories (and any folder foolish enough to hold still).
|
|
5
|
+
Project-URL: Homepage, https://github.com/jmcmeen/git-reaper
|
|
6
|
+
Author: John McMeen
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2026 John McMeen
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Keywords: analysis,cli,git,llm,repository
|
|
30
|
+
Classifier: Development Status :: 3 - Alpha
|
|
31
|
+
Classifier: Environment :: Console
|
|
32
|
+
Classifier: Intended Audience :: Developers
|
|
33
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
34
|
+
Classifier: Operating System :: OS Independent
|
|
35
|
+
Classifier: Programming Language :: Python :: 3
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
41
|
+
Classifier: Topic :: Software Development :: Version Control :: Git
|
|
42
|
+
Requires-Python: >=3.10
|
|
43
|
+
Requires-Dist: pathspec>=0.12
|
|
44
|
+
Requires-Dist: rich>=13.0
|
|
45
|
+
Requires-Dist: typer>=0.12
|
|
46
|
+
Provides-Extra: all
|
|
47
|
+
Requires-Dist: gitpython>=3.1; extra == 'all'
|
|
48
|
+
Requires-Dist: textual>=0.80; extra == 'all'
|
|
49
|
+
Requires-Dist: tiktoken>=0.7; extra == 'all'
|
|
50
|
+
Provides-Extra: git
|
|
51
|
+
Requires-Dist: gitpython>=3.1; extra == 'git'
|
|
52
|
+
Provides-Extra: tokens
|
|
53
|
+
Requires-Dist: tiktoken>=0.7; extra == 'tokens'
|
|
54
|
+
Provides-Extra: tui
|
|
55
|
+
Requires-Dist: textual>=0.80; extra == 'tui'
|
|
56
|
+
Description-Content-Type: text/markdown
|
|
57
|
+
|
|
58
|
+
# git-reaper
|
|
59
|
+
|
|
60
|
+
> A spooky utility for data mining git repositories (and any folder foolish enough to hold still).
|
|
61
|
+
|
|
62
|
+
`git-reaper` reaps structured knowledge from repositories: it clones, gathers,
|
|
63
|
+
concatenates, and packs the contents of a git repo (or a plain directory) into
|
|
64
|
+
clean, portable artifacts. Library first; the CLI is a thin adapter over
|
|
65
|
+
`git_reaper.core`.
|
|
66
|
+
|
|
67
|
+
## Install
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
uv tool install git-reaper # or: pip install git-reaper
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Both `reaper` and `git-reaper` land on your PATH (the long form is the
|
|
74
|
+
fallback if the REAPER DAW already owns the short one).
|
|
75
|
+
|
|
76
|
+
## Commands (v0.1.0)
|
|
77
|
+
|
|
78
|
+
| Command | What it does |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| `harvest` | Gather files matching a pattern (default `*.md`) from a path or repo URL and concatenate them into one artifact with a provenance header and per-file dividers. |
|
|
81
|
+
| `tree` | Hierarchical file listing as markdown or JSON. Depth limits, dirs-only, sizes, line counts, ignore rules. |
|
|
82
|
+
| `pulse` | Signs-of-life check: git present, optional extras, cache health. |
|
|
83
|
+
| `banish` | Clear the catacombs (the clone cache). `--older-than 7d` for partial exorcisms. |
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
reaper harvest https://github.com/Textualize/rich --pattern "*.md" -o RICH.md
|
|
87
|
+
reaper tree . --sizes --lines
|
|
88
|
+
reaper tree . --format json | jq .file_count
|
|
89
|
+
reaper pulse
|
|
90
|
+
reaper banish --older-than 7d
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Behavior you can rely on
|
|
94
|
+
|
|
95
|
+
- **Artifacts to stdout (or `--out`); narration to stderr.** Piping is always safe.
|
|
96
|
+
- **Deterministic output.** Same repo state + same flags = byte-identical
|
|
97
|
+
artifact (only the provenance timestamp moves).
|
|
98
|
+
- **Provenance by default.** Every artifact opens with source, ref/sha,
|
|
99
|
+
timestamp, tool version, and the exact invocation.
|
|
100
|
+
- **Ignore rules honored.** `.gitignore` + `.reaperignore` + `--exclude`
|
|
101
|
+
globs; `.git` is never reaped.
|
|
102
|
+
- **Caps with receipts.** Size caps and binary detection skip files loudly,
|
|
103
|
+
never silently.
|
|
104
|
+
- **The catacombs.** Remote clones cache under
|
|
105
|
+
`~/.cache/git-reaper/catacombs/<host>/<owner>/<repo>`, shallow, reused
|
|
106
|
+
across runs. Local `file://` sources are buried flat
|
|
107
|
+
(`localhost/<name>-<digest>`) to stay inside Windows path limits.
|
|
108
|
+
- **Published schemas.** Every JSON-emitting command prints its JSON schema
|
|
109
|
+
with `--schema`.
|
|
110
|
+
- **`--plain` / `NO_COLOR`** produce clean ASCII; non-tty output auto-disables
|
|
111
|
+
the theatrics.
|
|
112
|
+
- **No telemetry.** The dead tell no tales.
|
|
113
|
+
|
|
114
|
+
## Library use
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
from git_reaper.core.source import resolve_source
|
|
118
|
+
from git_reaper.core.harvest import harvest
|
|
119
|
+
from git_reaper.formatters.markdown import write_harvest
|
|
120
|
+
|
|
121
|
+
repo = resolve_source("https://github.com/Textualize/rich").repo
|
|
122
|
+
result = harvest(repo, patterns=("*.md",))
|
|
123
|
+
with open("RICH.md", "w") as fh:
|
|
124
|
+
write_harvest(result, fh)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Development
|
|
128
|
+
|
|
129
|
+
Everything runs through `uv` and the Makefile:
|
|
130
|
+
|
|
131
|
+
```sh
|
|
132
|
+
make setup # create venv, install deps
|
|
133
|
+
make check # lint + typecheck + tests (the full gauntlet)
|
|
134
|
+
make fmt # auto-format and fix lint findings
|
|
135
|
+
make test # pytest
|
|
136
|
+
make cov # pytest with coverage
|
|
137
|
+
make docs # serve the docs locally
|
|
138
|
+
make run ARGS="tree ."
|
|
139
|
+
make build # sdist + wheel
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The version comes from git tags (`hatch-vcs`); there is nothing to bump.
|
|
143
|
+
Publishing a GitHub release for a `vX.Y.Z` tag builds and uploads to PyPI
|
|
144
|
+
via trusted publishing, and docs deploy to GitHub Pages on every push to
|
|
145
|
+
`main`.
|
|
146
|
+
|
|
147
|
+
## License
|
|
148
|
+
|
|
149
|
+
MIT. Rest in peace.
|