findfmt 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.
- findfmt-0.1.0/.gitignore +73 -0
- findfmt-0.1.0/LICENSE +21 -0
- findfmt-0.1.0/PKG-INFO +220 -0
- findfmt-0.1.0/README.md +189 -0
- findfmt-0.1.0/docs/Makefile +33 -0
- findfmt-0.1.0/docs/source/_static/apple-touch-icon.png +0 -0
- findfmt-0.1.0/docs/source/_static/custom.css +9 -0
- findfmt-0.1.0/docs/source/_static/favicon-16x16.png +0 -0
- findfmt-0.1.0/docs/source/_static/favicon-32x32.png +0 -0
- findfmt-0.1.0/docs/source/_static/favicon.ico +0 -0
- findfmt-0.1.0/docs/source/_static/icon.svg +50 -0
- findfmt-0.1.0/docs/source/_static/logo.svg +91 -0
- findfmt-0.1.0/docs/source/accessibility.md +5 -0
- findfmt-0.1.0/docs/source/api/findfmt.md +39 -0
- findfmt-0.1.0/docs/source/api/index.md +10 -0
- findfmt-0.1.0/docs/source/cli/index.md +50 -0
- findfmt-0.1.0/docs/source/conf.py +91 -0
- findfmt-0.1.0/docs/source/guides/ci_integration.md +28 -0
- findfmt-0.1.0/docs/source/guides/index.md +11 -0
- findfmt-0.1.0/docs/source/guides/installation.md +38 -0
- findfmt-0.1.0/docs/source/guides/quickstart.md +50 -0
- findfmt-0.1.0/docs/source/index.md +99 -0
- findfmt-0.1.0/docs/source/quality/index.md +18 -0
- findfmt-0.1.0/docs/source/security.md +5 -0
- findfmt-0.1.0/pyproject.toml +203 -0
- findfmt-0.1.0/src/findfmt/__init__.py +22 -0
- findfmt-0.1.0/src/findfmt/__main__.py +10 -0
- findfmt-0.1.0/src/findfmt/classifier.py +258 -0
- findfmt-0.1.0/src/findfmt/cli.py +262 -0
- findfmt-0.1.0/src/findfmt/models.py +64 -0
- findfmt-0.1.0/src/findfmt/py.typed +0 -0
- findfmt-0.1.0/src/findfmt/traversal.py +297 -0
- findfmt-0.1.0/tests/__init__.py +1 -0
- findfmt-0.1.0/tests/conftest.py +70 -0
- findfmt-0.1.0/tests/integration/__init__.py +1 -0
- findfmt-0.1.0/tests/integration/test_integration.py +37 -0
- findfmt-0.1.0/tests/unit/__init__.py +1 -0
- findfmt-0.1.0/tests/unit/test_classifier.py +182 -0
- findfmt-0.1.0/tests/unit/test_cli.py +140 -0
- findfmt-0.1.0/tests/unit/test_models.py +53 -0
- findfmt-0.1.0/tests/unit/test_traversal.py +293 -0
- findfmt-0.1.0/tools/generate_assets.py +285 -0
- findfmt-0.1.0/tools/sync_labels.py +126 -0
- findfmt-0.1.0/tools/sync_pre_commit_deps.py +53 -0
- findfmt-0.1.0/tools/verify_quality.py +46 -0
findfmt-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Distribution / packaging
|
|
7
|
+
.Python
|
|
8
|
+
build/
|
|
9
|
+
develop-eggs/
|
|
10
|
+
dist/
|
|
11
|
+
downloads/
|
|
12
|
+
eggs/
|
|
13
|
+
.eggs/
|
|
14
|
+
lib/
|
|
15
|
+
lib64/
|
|
16
|
+
parts/
|
|
17
|
+
sdist/
|
|
18
|
+
var/
|
|
19
|
+
wheels/
|
|
20
|
+
share/python-wheels/
|
|
21
|
+
*.egg-info/
|
|
22
|
+
.installed.cfg
|
|
23
|
+
*.egg
|
|
24
|
+
MANIFEST
|
|
25
|
+
|
|
26
|
+
# Virtual environments
|
|
27
|
+
.venv/
|
|
28
|
+
venv/
|
|
29
|
+
ENV/
|
|
30
|
+
env/
|
|
31
|
+
|
|
32
|
+
# Testing and Coverage
|
|
33
|
+
.pytest_cache/
|
|
34
|
+
.coverage
|
|
35
|
+
.coverage.*
|
|
36
|
+
htmlcov/
|
|
37
|
+
coverage.xml
|
|
38
|
+
*.cover
|
|
39
|
+
*.py,cover
|
|
40
|
+
.hypothesis/
|
|
41
|
+
|
|
42
|
+
# Type Checking and Tool Caches
|
|
43
|
+
.mypy_cache/
|
|
44
|
+
.dmypy.json
|
|
45
|
+
dmypy.json
|
|
46
|
+
.pyre/
|
|
47
|
+
.pytype/
|
|
48
|
+
.ruff_cache/
|
|
49
|
+
.ty_cache/
|
|
50
|
+
|
|
51
|
+
# Sphinx documentation builds
|
|
52
|
+
docs/_build/
|
|
53
|
+
docs/build/
|
|
54
|
+
docs/source/api/generated/
|
|
55
|
+
|
|
56
|
+
# Environments and Secrets
|
|
57
|
+
.env
|
|
58
|
+
.env.*
|
|
59
|
+
!.env.example
|
|
60
|
+
*.local
|
|
61
|
+
|
|
62
|
+
# IDEs and Editors
|
|
63
|
+
.vscode/
|
|
64
|
+
.idea/
|
|
65
|
+
*.sublime-project
|
|
66
|
+
*.sublime-workspace
|
|
67
|
+
*.swp
|
|
68
|
+
*.swo
|
|
69
|
+
*~
|
|
70
|
+
|
|
71
|
+
# Operating System files
|
|
72
|
+
.DS_Store
|
|
73
|
+
Thumbs.db
|
findfmt-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Brandon Perkins
|
|
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.
|
findfmt-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: findfmt
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A.gitignore-aware file discovery and classification suite that locates files by content format, shebang, and MIME tag for automated linting, formatting, and CI pipelines.
|
|
5
|
+
Project-URL: Changelog, https://github.com/bdperkin/findfmt/blob/main/CHANGELOG.md
|
|
6
|
+
Project-URL: Documentation, https://bdperkin.github.io/findfmt
|
|
7
|
+
Project-URL: Homepage, https://github.com/bdperkin/findfmt
|
|
8
|
+
Project-URL: Issues, https://github.com/bdperkin/findfmt/issues
|
|
9
|
+
Project-URL: Repository, https://github.com/bdperkin/findfmt
|
|
10
|
+
Author-email: Brandon Perkins <bdperkin@gmail.com>
|
|
11
|
+
License: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: classification,discovery,find,format,gitignore,identify,linting,mime,shebang
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Environment :: Console
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
25
|
+
Classifier: Topic :: Utilities
|
|
26
|
+
Requires-Python: >=3.10
|
|
27
|
+
Requires-Dist: identify>=2.6
|
|
28
|
+
Requires-Dist: pathspec>=0.12
|
|
29
|
+
Requires-Dist: tomli>=2.0.1; python_version < '3.11'
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
<p align="center">
|
|
33
|
+
<img src="assets/logo.svg" alt="findfmt Logo" width="600" />
|
|
34
|
+
</p>
|
|
35
|
+
|
|
36
|
+
<p align="center">
|
|
37
|
+
<a href="https://github.com/bdperkin/findfmt/actions/workflows/ci.yml"><img src="https://github.com/bdperkin/findfmt/actions/workflows/ci.yml/badge.svg" alt="CI Status" /></a>
|
|
38
|
+
<a href="https://github.com/bdperkin/findfmt/actions/workflows/codeql.yml"><img src="https://github.com/bdperkin/findfmt/actions/workflows/codeql.yml/badge.svg" alt="CodeQL Analysis" /></a>
|
|
39
|
+
<a href="https://github.com/bdperkin/findfmt/actions/workflows/docs.yml"><img src="https://github.com/bdperkin/findfmt/actions/workflows/docs.yml/badge.svg" alt="Documentation Status" /></a>
|
|
40
|
+
<a href="https://results.pre-commit.ci/latest/github/bdperkin/findfmt/main"><img src="https://results.pre-commit.ci/badge/github/bdperkin/findfmt/main.svg" alt="pre-commit.ci status" /></a>
|
|
41
|
+
<a href="https://codecov.io/gh/bdperkin/findfmt"><img src="https://codecov.io/gh/bdperkin/findfmt/branch/main/graph/badge.svg" alt="Coverage" /></a>
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
<p align="center">
|
|
45
|
+
<a href="https://pypi.org/project/findfmt/"><img src="https://img.shields.io/pypi/v/findfmt.svg?logo=pypi&logoColor=white" alt="PyPI Version" /></a>
|
|
46
|
+
<a href="https://pypi.org/project/findfmt/"><img src="https://img.shields.io/pypi/pyversions/findfmt.svg?logo=python&logoColor=white" alt="Python Versions" /></a>
|
|
47
|
+
<a href="https://pypi.org/project/findfmt/"><img src="https://img.shields.io/pypi/wheel/findfmt.svg" alt="PyPI Wheel" /></a>
|
|
48
|
+
<a href="https://github.com/bdperkin/findfmt/pkgs/container/findfmt"><img src="https://img.shields.io/badge/GHCR-container-blue?logo=docker&logoColor=white" alt="GHCR Container" /></a>
|
|
49
|
+
<a href="https://github.com/bdperkin/findfmt/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT" /></a>
|
|
50
|
+
</p>
|
|
51
|
+
|
|
52
|
+
<p align="center">
|
|
53
|
+
<a href="https://github.com/astral-sh/uv"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" alt="uv" /></a>
|
|
54
|
+
<a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff" /></a>
|
|
55
|
+
<a href="https://github.com/astral-sh/ty"><img src="https://img.shields.io/badge/type--checked-ty-blueviolet" alt="Type-checked: ty" /></a>
|
|
56
|
+
<a href="https://interrogate.readthedocs.io/"><img src="https://img.shields.io/badge/interrogate-100%25-brightgreen" alt="Docstring Coverage: 100%" /></a>
|
|
57
|
+
<a href="https://conventionalcommits.org"><img src="https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg" alt="Conventional Commits" /></a>
|
|
58
|
+
<a href="ACCESSIBILITY.md"><img src="https://img.shields.io/badge/accessibility-WCAG%202.1%20AA-blue" alt="Accessibility WCAG 2.1 AA" /></a>
|
|
59
|
+
</p>
|
|
60
|
+
|
|
61
|
+
______________________________________________________________________
|
|
62
|
+
|
|
63
|
+
> **A `.gitignore`-aware file discovery and classification suite that locates files by content
|
|
64
|
+
> format, shebang, and MIME tag for automated linting, formatting, and CI pipelines.**
|
|
65
|
+
|
|
66
|
+
## 1. Why findfmt?
|
|
67
|
+
|
|
68
|
+
Unlike traditional `find` or globbing tools that rely strictly on file extensions, `findfmt`:
|
|
69
|
+
|
|
70
|
+
- **Understands file content**: Identifies format by content, shebang (`#!/usr/bin/env python3`),
|
|
71
|
+
and MIME types using the `identify` engine.
|
|
72
|
+
- **Respects Git**: Traverses trees hierarchically while pruning `.gitignore` and
|
|
73
|
+
`.git/info/exclude` paths early before descending into large directories (e.g. `node_modules/`,
|
|
74
|
+
`.venv/`).
|
|
75
|
+
- **Deterministic**: Always returns clean, relative, deterministically sorted paths optimized for
|
|
76
|
+
subshells, xargs, and automation.
|
|
77
|
+
|
|
78
|
+
______________________________________________________________________
|
|
79
|
+
|
|
80
|
+
## 2. Installation
|
|
81
|
+
|
|
82
|
+
### 2.1. With `uv` (Recommended)
|
|
83
|
+
|
|
84
|
+
Run directly with `uvx`:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
uvx findfmt --help
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Install globally:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
uv tool install findfmt
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Or add to your project:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
uv add findfmt
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 2.2. With `pip`
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
pip install findfmt
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 2.3. With Docker / Container
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
docker pull ghcr.io/bdperkin/findfmt:latest
|
|
112
|
+
docker run --rm -v "$(pwd)":/workspace -w /workspace ghcr.io/bdperkin/findfmt:latest -t python
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
______________________________________________________________________
|
|
116
|
+
|
|
117
|
+
## 3. Usage
|
|
118
|
+
|
|
119
|
+
### 3.1. Locate Files by Tag / Format
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Locate all Python files
|
|
123
|
+
findfmt -t python
|
|
124
|
+
|
|
125
|
+
# Locate all YAML and JSON files
|
|
126
|
+
findfmt -t yaml,json
|
|
127
|
+
|
|
128
|
+
# Locate shell scripts
|
|
129
|
+
findfmt -t shell
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 3.2. Shebang Filtering
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Locate files with bash shebang
|
|
136
|
+
findfmt --shebang bash
|
|
137
|
+
|
|
138
|
+
# Locate scripts executing with python
|
|
139
|
+
findfmt --shebang python
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 3.3. Pipe Safely to Linters and Tools
|
|
143
|
+
|
|
144
|
+
Use `-0` for NUL-delimited output with `xargs -0`:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Format discovered Python files
|
|
148
|
+
findfmt -t python -0 | xargs -0 ruff format
|
|
149
|
+
|
|
150
|
+
# Lint shell scripts with shellcheck
|
|
151
|
+
findfmt -t shell -0 | xargs -r -0 shellcheck
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 3.4. Inspect Tags & Summaries
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Print matched files and their classification tags
|
|
158
|
+
findfmt -l -t python
|
|
159
|
+
|
|
160
|
+
# Print summary statistics to stderr
|
|
161
|
+
findfmt -s
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
______________________________________________________________________
|
|
165
|
+
|
|
166
|
+
## 4. CLI Options
|
|
167
|
+
|
|
168
|
+
| Flag | Description |
|
|
169
|
+
| ------------------------------ | -------------------------------------------------- |
|
|
170
|
+
| `-t, --tag, --type` | Match files containing specified tag(s) |
|
|
171
|
+
| `-e, --exclude, --exclude-tag` | Exclude files containing specified tag(s) |
|
|
172
|
+
| `--all-tags` | Require match against all include tags (AND logic) |
|
|
173
|
+
| `--shebang` | Match shebang interpreter name or pattern |
|
|
174
|
+
| `--no-ignore` | Do not prune paths matching `.gitignore` |
|
|
175
|
+
| `--hidden` | Inspect hidden files and directories |
|
|
176
|
+
| `-0, --print0` | NUL-delimited output for `xargs -0` |
|
|
177
|
+
| `-l, --list-tags` | Print tags alongside file paths |
|
|
178
|
+
| `-s, --summary` | Print match frequencies to stderr |
|
|
179
|
+
| `--absolute` | Output absolute rather than relative paths |
|
|
180
|
+
| `--known-tags` | List all supported classification tags |
|
|
181
|
+
| `-v, --version` | Display version and exit |
|
|
182
|
+
|
|
183
|
+
______________________________________________________________________
|
|
184
|
+
|
|
185
|
+
## 5. Development & Testing
|
|
186
|
+
|
|
187
|
+
This project enforces 100% test coverage and strict type checking:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Clone the repository
|
|
191
|
+
git clone https://github.com/bdperkin/findfmt.git
|
|
192
|
+
cd findfmt
|
|
193
|
+
|
|
194
|
+
# Install dependencies with uv
|
|
195
|
+
uv sync --all-groups
|
|
196
|
+
|
|
197
|
+
# Run tests and verify 100% coverage
|
|
198
|
+
uv run pytest
|
|
199
|
+
|
|
200
|
+
# Run linting and typing
|
|
201
|
+
uv run ruff check
|
|
202
|
+
uv run ty check
|
|
203
|
+
|
|
204
|
+
# Run full verification suite
|
|
205
|
+
uv run python tools/verify_quality.py
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
______________________________________________________________________
|
|
209
|
+
|
|
210
|
+
## 6. Governance & Community
|
|
211
|
+
|
|
212
|
+
- [Contributing Guidelines](CONTRIBUTING.md)
|
|
213
|
+
- [Code of Conduct](CODE_OF_CONDUCT.md)
|
|
214
|
+
- [Security Policy](SECURITY.md)
|
|
215
|
+
- [Support Information](SUPPORT.md)
|
|
216
|
+
- [Accessibility Statement](ACCESSIBILITY.md)
|
|
217
|
+
|
|
218
|
+
## 7. License
|
|
219
|
+
|
|
220
|
+
[MIT License](LICENSE) © 2026 Brandon Perkins.
|
findfmt-0.1.0/README.md
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/logo.svg" alt="findfmt Logo" width="600" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://github.com/bdperkin/findfmt/actions/workflows/ci.yml"><img src="https://github.com/bdperkin/findfmt/actions/workflows/ci.yml/badge.svg" alt="CI Status" /></a>
|
|
7
|
+
<a href="https://github.com/bdperkin/findfmt/actions/workflows/codeql.yml"><img src="https://github.com/bdperkin/findfmt/actions/workflows/codeql.yml/badge.svg" alt="CodeQL Analysis" /></a>
|
|
8
|
+
<a href="https://github.com/bdperkin/findfmt/actions/workflows/docs.yml"><img src="https://github.com/bdperkin/findfmt/actions/workflows/docs.yml/badge.svg" alt="Documentation Status" /></a>
|
|
9
|
+
<a href="https://results.pre-commit.ci/latest/github/bdperkin/findfmt/main"><img src="https://results.pre-commit.ci/badge/github/bdperkin/findfmt/main.svg" alt="pre-commit.ci status" /></a>
|
|
10
|
+
<a href="https://codecov.io/gh/bdperkin/findfmt"><img src="https://codecov.io/gh/bdperkin/findfmt/branch/main/graph/badge.svg" alt="Coverage" /></a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
<a href="https://pypi.org/project/findfmt/"><img src="https://img.shields.io/pypi/v/findfmt.svg?logo=pypi&logoColor=white" alt="PyPI Version" /></a>
|
|
15
|
+
<a href="https://pypi.org/project/findfmt/"><img src="https://img.shields.io/pypi/pyversions/findfmt.svg?logo=python&logoColor=white" alt="Python Versions" /></a>
|
|
16
|
+
<a href="https://pypi.org/project/findfmt/"><img src="https://img.shields.io/pypi/wheel/findfmt.svg" alt="PyPI Wheel" /></a>
|
|
17
|
+
<a href="https://github.com/bdperkin/findfmt/pkgs/container/findfmt"><img src="https://img.shields.io/badge/GHCR-container-blue?logo=docker&logoColor=white" alt="GHCR Container" /></a>
|
|
18
|
+
<a href="https://github.com/bdperkin/findfmt/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT" /></a>
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
<p align="center">
|
|
22
|
+
<a href="https://github.com/astral-sh/uv"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" alt="uv" /></a>
|
|
23
|
+
<a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff" /></a>
|
|
24
|
+
<a href="https://github.com/astral-sh/ty"><img src="https://img.shields.io/badge/type--checked-ty-blueviolet" alt="Type-checked: ty" /></a>
|
|
25
|
+
<a href="https://interrogate.readthedocs.io/"><img src="https://img.shields.io/badge/interrogate-100%25-brightgreen" alt="Docstring Coverage: 100%" /></a>
|
|
26
|
+
<a href="https://conventionalcommits.org"><img src="https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg" alt="Conventional Commits" /></a>
|
|
27
|
+
<a href="ACCESSIBILITY.md"><img src="https://img.shields.io/badge/accessibility-WCAG%202.1%20AA-blue" alt="Accessibility WCAG 2.1 AA" /></a>
|
|
28
|
+
</p>
|
|
29
|
+
|
|
30
|
+
______________________________________________________________________
|
|
31
|
+
|
|
32
|
+
> **A `.gitignore`-aware file discovery and classification suite that locates files by content
|
|
33
|
+
> format, shebang, and MIME tag for automated linting, formatting, and CI pipelines.**
|
|
34
|
+
|
|
35
|
+
## 1. Why findfmt?
|
|
36
|
+
|
|
37
|
+
Unlike traditional `find` or globbing tools that rely strictly on file extensions, `findfmt`:
|
|
38
|
+
|
|
39
|
+
- **Understands file content**: Identifies format by content, shebang (`#!/usr/bin/env python3`),
|
|
40
|
+
and MIME types using the `identify` engine.
|
|
41
|
+
- **Respects Git**: Traverses trees hierarchically while pruning `.gitignore` and
|
|
42
|
+
`.git/info/exclude` paths early before descending into large directories (e.g. `node_modules/`,
|
|
43
|
+
`.venv/`).
|
|
44
|
+
- **Deterministic**: Always returns clean, relative, deterministically sorted paths optimized for
|
|
45
|
+
subshells, xargs, and automation.
|
|
46
|
+
|
|
47
|
+
______________________________________________________________________
|
|
48
|
+
|
|
49
|
+
## 2. Installation
|
|
50
|
+
|
|
51
|
+
### 2.1. With `uv` (Recommended)
|
|
52
|
+
|
|
53
|
+
Run directly with `uvx`:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
uvx findfmt --help
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Install globally:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
uv tool install findfmt
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Or add to your project:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
uv add findfmt
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 2.2. With `pip`
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install findfmt
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 2.3. With Docker / Container
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
docker pull ghcr.io/bdperkin/findfmt:latest
|
|
81
|
+
docker run --rm -v "$(pwd)":/workspace -w /workspace ghcr.io/bdperkin/findfmt:latest -t python
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
______________________________________________________________________
|
|
85
|
+
|
|
86
|
+
## 3. Usage
|
|
87
|
+
|
|
88
|
+
### 3.1. Locate Files by Tag / Format
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# Locate all Python files
|
|
92
|
+
findfmt -t python
|
|
93
|
+
|
|
94
|
+
# Locate all YAML and JSON files
|
|
95
|
+
findfmt -t yaml,json
|
|
96
|
+
|
|
97
|
+
# Locate shell scripts
|
|
98
|
+
findfmt -t shell
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 3.2. Shebang Filtering
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Locate files with bash shebang
|
|
105
|
+
findfmt --shebang bash
|
|
106
|
+
|
|
107
|
+
# Locate scripts executing with python
|
|
108
|
+
findfmt --shebang python
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 3.3. Pipe Safely to Linters and Tools
|
|
112
|
+
|
|
113
|
+
Use `-0` for NUL-delimited output with `xargs -0`:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Format discovered Python files
|
|
117
|
+
findfmt -t python -0 | xargs -0 ruff format
|
|
118
|
+
|
|
119
|
+
# Lint shell scripts with shellcheck
|
|
120
|
+
findfmt -t shell -0 | xargs -r -0 shellcheck
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 3.4. Inspect Tags & Summaries
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# Print matched files and their classification tags
|
|
127
|
+
findfmt -l -t python
|
|
128
|
+
|
|
129
|
+
# Print summary statistics to stderr
|
|
130
|
+
findfmt -s
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
______________________________________________________________________
|
|
134
|
+
|
|
135
|
+
## 4. CLI Options
|
|
136
|
+
|
|
137
|
+
| Flag | Description |
|
|
138
|
+
| ------------------------------ | -------------------------------------------------- |
|
|
139
|
+
| `-t, --tag, --type` | Match files containing specified tag(s) |
|
|
140
|
+
| `-e, --exclude, --exclude-tag` | Exclude files containing specified tag(s) |
|
|
141
|
+
| `--all-tags` | Require match against all include tags (AND logic) |
|
|
142
|
+
| `--shebang` | Match shebang interpreter name or pattern |
|
|
143
|
+
| `--no-ignore` | Do not prune paths matching `.gitignore` |
|
|
144
|
+
| `--hidden` | Inspect hidden files and directories |
|
|
145
|
+
| `-0, --print0` | NUL-delimited output for `xargs -0` |
|
|
146
|
+
| `-l, --list-tags` | Print tags alongside file paths |
|
|
147
|
+
| `-s, --summary` | Print match frequencies to stderr |
|
|
148
|
+
| `--absolute` | Output absolute rather than relative paths |
|
|
149
|
+
| `--known-tags` | List all supported classification tags |
|
|
150
|
+
| `-v, --version` | Display version and exit |
|
|
151
|
+
|
|
152
|
+
______________________________________________________________________
|
|
153
|
+
|
|
154
|
+
## 5. Development & Testing
|
|
155
|
+
|
|
156
|
+
This project enforces 100% test coverage and strict type checking:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Clone the repository
|
|
160
|
+
git clone https://github.com/bdperkin/findfmt.git
|
|
161
|
+
cd findfmt
|
|
162
|
+
|
|
163
|
+
# Install dependencies with uv
|
|
164
|
+
uv sync --all-groups
|
|
165
|
+
|
|
166
|
+
# Run tests and verify 100% coverage
|
|
167
|
+
uv run pytest
|
|
168
|
+
|
|
169
|
+
# Run linting and typing
|
|
170
|
+
uv run ruff check
|
|
171
|
+
uv run ty check
|
|
172
|
+
|
|
173
|
+
# Run full verification suite
|
|
174
|
+
uv run python tools/verify_quality.py
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
______________________________________________________________________
|
|
178
|
+
|
|
179
|
+
## 6. Governance & Community
|
|
180
|
+
|
|
181
|
+
- [Contributing Guidelines](CONTRIBUTING.md)
|
|
182
|
+
- [Code of Conduct](CODE_OF_CONDUCT.md)
|
|
183
|
+
- [Security Policy](SECURITY.md)
|
|
184
|
+
- [Support Information](SUPPORT.md)
|
|
185
|
+
- [Accessibility Statement](ACCESSIBILITY.md)
|
|
186
|
+
|
|
187
|
+
## 7. License
|
|
188
|
+
|
|
189
|
+
[MIT License](LICENSE) © 2026 Brandon Perkins.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Minimal Makefile for Sphinx documentation
|
|
2
|
+
|
|
3
|
+
SPHINXOPTS ?= -W --keep-going
|
|
4
|
+
SPHINXBUILD ?= uv run sphinx-build
|
|
5
|
+
SOURCEDIR = source
|
|
6
|
+
BUILDDIR = _build
|
|
7
|
+
DOCTREEDIR = $(BUILDDIR)/doctrees
|
|
8
|
+
|
|
9
|
+
.PHONY: help Makefile html epub man latex linkcheck clean
|
|
10
|
+
|
|
11
|
+
help:
|
|
12
|
+
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
13
|
+
|
|
14
|
+
html:
|
|
15
|
+
@$(SPHINXBUILD) -b html -d "$(DOCTREEDIR)" "$(SOURCEDIR)" "$(BUILDDIR)/html" $(SPHINXOPTS)
|
|
16
|
+
|
|
17
|
+
epub:
|
|
18
|
+
@$(SPHINXBUILD) -b epub -d "$(DOCTREEDIR)" "$(SOURCEDIR)" "$(BUILDDIR)/epub" $(SPHINXOPTS)
|
|
19
|
+
|
|
20
|
+
man:
|
|
21
|
+
@$(SPHINXBUILD) -b man -d "$(DOCTREEDIR)" "$(SOURCEDIR)" "$(BUILDDIR)/man" $(SPHINXOPTS)
|
|
22
|
+
|
|
23
|
+
latex:
|
|
24
|
+
@$(SPHINXBUILD) -b latex -d "$(DOCTREEDIR)" "$(SOURCEDIR)" "$(BUILDDIR)/latex" $(SPHINXOPTS)
|
|
25
|
+
|
|
26
|
+
linkcheck:
|
|
27
|
+
@$(SPHINXBUILD) -b linkcheck -d "$(DOCTREEDIR)" "$(SOURCEDIR)" "$(BUILDDIR)/linkcheck" $(SPHINXOPTS)
|
|
28
|
+
|
|
29
|
+
clean:
|
|
30
|
+
rm -rf "$(BUILDDIR)"
|
|
31
|
+
|
|
32
|
+
%: Makefile
|
|
33
|
+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="100%" height="100%">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" stop-color="#0f172a" />
|
|
5
|
+
<stop offset="100%" stop-color="#1e293b" />
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="accentGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
8
|
+
<stop offset="0%" stop-color="#38bdf8" />
|
|
9
|
+
<stop offset="50%" stop-color="#818cf8" />
|
|
10
|
+
<stop offset="100%" stop-color="#c084fc" />
|
|
11
|
+
</linearGradient>
|
|
12
|
+
<linearGradient id="lensGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
13
|
+
<stop offset="0%" stop-color="#38bdf8" stop-opacity="0.2" />
|
|
14
|
+
<stop offset="100%" stop-color="#818cf8" stop-opacity="0.05" />
|
|
15
|
+
</linearGradient>
|
|
16
|
+
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
|
|
17
|
+
<feGaussianBlur stdDeviation="5" result="blur" />
|
|
18
|
+
<feComposite in="SourceGraphic" in2="blur" operator="over" />
|
|
19
|
+
</filter>
|
|
20
|
+
</defs>
|
|
21
|
+
|
|
22
|
+
<!-- Background Rounded Square -->
|
|
23
|
+
<rect width="200" height="200" rx="44" fill="url(#bgGrad)" stroke="#334155" stroke-width="2" />
|
|
24
|
+
|
|
25
|
+
<!-- Mark Component Centered -->
|
|
26
|
+
<g transform="translate(14, 18)">
|
|
27
|
+
<!-- File Stacks -->
|
|
28
|
+
<rect x="20" y="25" width="60" height="80" rx="6" fill="#1e293b" stroke="#475569" stroke-width="2" />
|
|
29
|
+
<line x1="32" y1="45" x2="68" y2="45" stroke="#64748b" stroke-width="2" stroke-linecap="round" />
|
|
30
|
+
<line x1="32" y1="58" x2="60" y2="58" stroke="#64748b" stroke-width="2" stroke-linecap="round" />
|
|
31
|
+
<line x1="32" y1="71" x2="52" y2="71" stroke="#64748b" stroke-width="2" stroke-linecap="round" />
|
|
32
|
+
|
|
33
|
+
<!-- Magnifying Scanner Lens -->
|
|
34
|
+
<circle cx="85" cy="75" r="48" fill="url(#lensGrad)" stroke="url(#accentGrad)" stroke-width="4" filter="url(#glow)" />
|
|
35
|
+
<line x1="120" y1="110" x2="148" y2="138" stroke="url(#accentGrad)" stroke-width="6" stroke-linecap="round" />
|
|
36
|
+
|
|
37
|
+
<!-- Floating Format Badges Inside Lens -->
|
|
38
|
+
<!-- Python Badge -->
|
|
39
|
+
<rect x="58" y="48" width="28" height="16" rx="4" fill="#0284c7" fill-opacity="0.85" />
|
|
40
|
+
<text x="72" y="60" fill="#ffffff" font-family="system-ui, -apple-system, sans-serif" font-size="10" font-weight="700" text-anchor="middle">.py</text>
|
|
41
|
+
|
|
42
|
+
<!-- Shebang Badge -->
|
|
43
|
+
<rect x="72" y="70" width="30" height="16" rx="4" fill="#7c3aed" fill-opacity="0.85" />
|
|
44
|
+
<text x="87" y="82" fill="#ffffff" font-family="system-ui, -apple-system, sans-serif" font-size="10" font-weight="700" text-anchor="middle">#!/</text>
|
|
45
|
+
|
|
46
|
+
<!-- MIME Tag Badge -->
|
|
47
|
+
<rect x="52" y="90" width="34" height="16" rx="4" fill="#059669" fill-opacity="0.85" />
|
|
48
|
+
<text x="69" y="102" fill="#ffffff" font-family="system-ui, -apple-system, sans-serif" font-size="9" font-weight="700" text-anchor="middle">MIME</text>
|
|
49
|
+
</g>
|
|
50
|
+
</svg>
|