Skip to content

Commit b97acfc

Browse files
authored
Merge pull request #10 from taggedzi/tree_maker
Added tree_maker script to help with dev, AND modified labeler to bet…
2 parents d02c11d + 3fe2036 commit b97acfc

3 files changed

Lines changed: 144 additions & 21 deletions

File tree

.github/labeler.yml

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,75 @@
1-
# Documentation
1+
# Docs (includes repo docs + user docs)
22
docs:
33
- changed-files:
44
- any-glob-to-any-file:
5-
- "**/*.md"
5+
- "README.md"
66
- "docs/**"
7+
- "**/*.md"
78

8-
# GitHub / meta
9+
# GitHub meta (templates, workflows, configs)
910
github:
1011
- changed-files:
1112
- any-glob-to-any-file:
1213
- ".github/**"
1314

14-
# CI / automation
15+
# CI / automation tooling
1516
ci:
1617
- changed-files:
1718
- any-glob-to-any-file:
1819
- ".github/workflows/**"
1920
- "noxfile.py"
20-
- "pyproject.toml"
21-
- "requirements*.txt"
21+
- "make_release.py"
2222
- "tools/**"
23-
- "scripts/**"
23+
24+
# Core library code (engine + public API)
25+
core:
26+
- changed-files:
27+
- any-glob-to-any-file:
28+
- "src/simplicitypress/**"
29+
- "!src/simplicitypress/gui.py"
30+
- "!src/simplicitypress/cli.py"
31+
- "!src/simplicitypress/scaffold/**"
32+
33+
# CLI-specific changes
34+
cli:
35+
- changed-files:
36+
- any-glob-to-any-file:
37+
- "src/simplicitypress/cli.py"
38+
- "src/simplicitypress/__main__.py"
39+
40+
# GUI-specific changes
41+
gui:
42+
- changed-files:
43+
- any-glob-to-any-file:
44+
- "src/simplicitypress/gui.py"
45+
46+
# Scaffolding (theme/templates/static assets)
47+
scaffold:
48+
- changed-files:
49+
- any-glob-to-any-file:
50+
- "src/simplicitypress/scaffold/**"
2451

2552
# Tests
2653
tests:
2754
- changed-files:
2855
- any-glob-to-any-file:
2956
- "tests/**"
30-
- "**/*test*.py"
3157

32-
# Core source (adjust if your src layout differs)
33-
core:
58+
# Packaging / licensing / release artifacts
59+
packaging:
3460
- changed-files:
3561
- any-glob-to-any-file:
36-
- "src/**"
37-
- "**/*.py"
62+
- "pyproject.toml"
63+
- "SimplicityPress.spec"
64+
- "LICENSE"
65+
- "LICENSES/**"
66+
- "THIRD-PARTY-NOTICES.txt"
67+
- "QT-ATTRIBUTION.txt"
3868

39-
# Packaging / release
40-
packaging:
69+
# Generated files
70+
generated:
4171
- changed-files:
4272
- any-glob-to-any-file:
43-
- "pyproject.toml"
44-
- "MANIFEST.in"
45-
- "setup.cfg"
46-
- "setup.py"
47-
- "LICENSE*"
48-
- "CHANGELOG*"
49-
- "RELEASE*"
73+
- "!src/simplicitypress.egg-info/**"
74+
- "!build/**"
75+
- "!dist/**"

.treeignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
__pycache__/
2+
.mypy_cache/
3+
.nox/
4+
.pytest_cache/
5+
.ruff_cache/
6+
.venv/
7+
htmlcov/
8+
nonwordgen.egg-info
9+
.git/
10+
build/
11+
dist/

tools/tree_maker.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# SPDX-License-Identifier: MIT
2+
# Path: scripts/tree_maker.py
3+
"""Print a tree of a project's files and directories, using a custom .treeignore style filter."""
4+
from pathlib import Path
5+
import argparse
6+
import pathspec
7+
8+
9+
def find_project_root(script_location: Path) -> Path:
10+
"""Assumes the script is inside 'scripts/' and returns the project root."""
11+
return script_location.parent.parent.resolve()
12+
13+
14+
def load_pathspec_file(file_path: Path) -> pathspec.PathSpec:
15+
"""Load pathspec-compatible ignore rules from a file."""
16+
if not file_path.exists():
17+
return pathspec.PathSpec.from_lines('gitwildmatch', [])
18+
with file_path.open('r') as f:
19+
return pathspec.PathSpec.from_lines('gitwildmatch', f)
20+
21+
22+
def should_ignore(path: Path, base_path: Path, ignore_spec: pathspec.PathSpec) -> bool:
23+
"""Return True if path should be ignored."""
24+
relative = path.relative_to(base_path).as_posix()
25+
return ignore_spec.match_file(relative)
26+
27+
28+
def print_tree(
29+
path: Path,
30+
prefix: str = '',
31+
base_path: Path = None,
32+
ignore_spec: pathspec.PathSpec = None) -> None:
33+
"""
34+
Recursively print a visual tree of files and directories starting from the given path.
35+
36+
Directories are printed with a trailing slash ('/'). Entries that match the ignore_spec
37+
(e.g., from a .treeignore file) are excluded from the output.
38+
39+
Args:
40+
path (Path): The current directory or file path to start printing from.
41+
prefix (str, optional): The visual indentation prefix used to align tree branches.
42+
base_path (Path, optional): The root of the tree for computing relative ignore paths.
43+
Defaults to `path` on first call.
44+
ignore_spec (PathSpec, optional): A compiled PathSpec object used to filter out
45+
ignored files and folders. Can be empty.
46+
47+
Returns:
48+
None: This function prints directly to stdout.
49+
"""
50+
base_path = base_path or path
51+
ignore_spec = ignore_spec or pathspec.PathSpec.from_lines('gitwildmatch', [])
52+
53+
entries = [
54+
p for p in sorted(path.iterdir())
55+
if not should_ignore(p, base_path, ignore_spec)
56+
]
57+
58+
for i, entry in enumerate(entries):
59+
connector = '└── ' if i == len(entries) - 1 else '├── '
60+
display_name = entry.name + '\\' if entry.is_dir() else entry.name
61+
print(prefix + connector + display_name)
62+
63+
if entry.is_dir():
64+
extension = ' ' if i == len(entries) - 1 else '│ '
65+
print_tree(entry, prefix + extension, base_path, ignore_spec)
66+
67+
68+
69+
def main():
70+
"""The main function to run the script."""
71+
script_location = Path(__file__).resolve()
72+
project_root = find_project_root(script_location)
73+
74+
parser = argparse.ArgumentParser(description='Project Tree Viewer (respects .treeignore)')
75+
parser.add_argument('--treeignore', type=str, default='.treeignore',
76+
help='Path to treeignore-style file (default: .treeignore)')
77+
args = parser.parse_args()
78+
79+
treeignore_file = project_root / args.treeignore
80+
ignore_spec = load_pathspec_file(treeignore_file)
81+
82+
print_tree(project_root, ignore_spec=ignore_spec)
83+
84+
85+
if __name__ == '__main__':
86+
main()

0 commit comments

Comments
 (0)