Skip to content

Commit 4b868e1

Browse files
nikolay-eclaude
andcommitted
feat: add Python library API and refactor architecture
- Add map_directory(), to_yaml(), to_json(), to_text() public API - Refactor with TreeBuildContext and ParsedArgs dataclasses - Improve README with badges, examples, and use cases - Extend tests to verify library API alongside CLI - Remove obsolete .flake8 and test_logging.py 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 083f428 commit 4b868e1

16 files changed

Lines changed: 470 additions & 722 deletions

.flake8

Lines changed: 0 additions & 2 deletions
This file was deleted.

CLAUDE.md

Lines changed: 58 additions & 269 deletions
Original file line numberDiff line numberDiff line change
@@ -1,301 +1,90 @@
1-
# CLAUDE.md - TreeMapper
1+
# TreeMapper
22

3-
## Project Overview
3+
[![PyPI](https://img.shields.io/pypi/v/treemapper)](https://pypi.org/project/treemapper/)
4+
[![Downloads](https://img.shields.io/pypi/dm/treemapper)](https://pypi.org/project/treemapper/)
5+
[![License](https://img.shields.io/github/license/nikolay-e/treemapper)](https://github.com/nikolay-e/treemapper/blob/main/LICENSE)
46

5-
treemapper is a Python tool that converts directory structures to YAML format, designed specifically for use with Large Language Models (LLMs). It maps entire codebases into structured YAML files, making it easy to analyze code, document projects, and work with AI tools.
6-
7-
## Installation
8-
9-
Requires Python 3.9+:
7+
**Export your codebase for AI/LLM context in one command.**
108

119
```bash
1210
pip install treemapper
11+
treemapper . -o context.yaml # paste into ChatGPT/Claude
1312
```
1413

15-
## Development Environment
16-
17-
- Python 3.9+ required
18-
- Package dependencies: pathspec, pyyaml
19-
20-
## Building and Installation
21-
22-
```bash
23-
# Install in development mode
24-
pip install -e .
25-
26-
# Install with development dependencies
27-
pip install -e ".[dev]"
28-
29-
# Build distribution package
30-
python -m build
31-
32-
# Install from PyPI
33-
pip install treemapper
34-
```
14+
## Why TreeMapper?
3515

36-
## Testing
37-
38-
```bash
39-
# Run all tests
40-
pytest
41-
42-
# Run specific test file
43-
pytest tests/test_basic.py
44-
45-
# Run specific test
46-
pytest tests/test_basic.py::test_basic_mapping
47-
48-
# Run tests with coverage
49-
pytest --cov=src/treemapper
50-
51-
# Run tests in verbose mode
52-
pytest -v
53-
```
54-
55-
## Linting and Formatting
56-
57-
```bash
58-
# Run flake8 linter
59-
flake8 src/treemapper
16+
Unlike `tree` or `find`, TreeMapper exports **structure + file contents** in a format optimized for LLM context windows:
6017

61-
# Run black formatter
62-
black src/treemapper
63-
64-
# Run type checking with mypy
65-
mypy src/treemapper
66-
67-
# Run autoflake to remove unused imports
68-
autoflake --remove-all-unused-imports -i src/treemapper/*.py
69-
70-
# Run pre-commit hooks on all files
71-
pre-commit run --all-files
72-
73-
# Run isort (import sorting)
74-
isort src/treemapper tests
75-
```
76-
77-
## Code Quality Tools
78-
79-
The project includes comprehensive code quality checks via CI and pre-commit hooks:
80-
81-
```bash
82-
# Complexity analysis
83-
radon cc src/treemapper/ --min B # Cyclomatic complexity
84-
radon mi src/treemapper/ --min B # Maintainability index
85-
86-
# Mutation testing (test effectiveness)
87-
mutmut run --paths-to-mutate=src/treemapper/
88-
89-
# Architecture checks (import contracts)
90-
lint-imports
91-
92-
# Coverage reporting
93-
pytest --cov=src/treemapper --cov-report=html
94-
open htmlcov/index.html
18+
```yaml
19+
name: myproject
20+
type: directory
21+
children:
22+
- name: main.py
23+
type: file
24+
content: |
25+
def hello():
26+
print("Hello, World!")
27+
- name: utils/
28+
type: directory
29+
children:
30+
- name: helpers.py
31+
type: file
32+
content: |
33+
def add(a, b):
34+
return a + b
9535
```
9636
97-
### CI/CD Workflows
98-
99-
The project has two CI/CD workflows:
100-
101-
1. **Main CI** (`.github/workflows/ci.yml`): Comprehensive quality checks
102-
- Pre-commit hook validation (all hooks)
103-
- Linting and type checking (flake8, black, mypy)
104-
- Cross-platform testing (Linux, macOS, Windows)
105-
- Python version matrix (3.9, 3.10, 3.11, 3.12)
106-
- PyPy compatibility testing (pypy-3.9, pypy-3.10)
107-
- Test coverage with 80% threshold and branch analysis
108-
- Mutation testing (test effectiveness validation)
109-
- Complexity and maintainability metrics (radon)
110-
- Architecture/import contract validation (import-linter)
111-
- SonarCloud quality gate (code quality analysis)
112-
113-
2. **CD (Release)** (`.github/workflows/cd.yml`): Atomic releases
114-
- Version bump with git bundles
115-
- Multi-platform binary builds (Linux, macOS, Windows)
116-
- PyPI publishing (optional)
117-
- GitHub release creation with assets
118-
119-
## Project Architecture
120-
121-
The codebase is organized as follows:
122-
123-
- `src/treemapper/`: Main package
124-
- `treemapper.py`: Entry point and main orchestration
125-
- `cli.py`: Command-line argument parsing
126-
- `ignore.py`: Logic for handling ignore patterns (gitignore, treemapperignore)
127-
- `tree.py`: Core tree building functionality
128-
- `writer.py`: YAML output formatting and file writing
129-
- `logger.py`: Logging configuration
130-
131-
The application flow is:
132-
1. Parse command-line arguments (`cli.py`)
133-
2. Set up logging based on verbosity level (`logger.py`)
134-
3. Load ignore patterns from various sources (`ignore.py`)
135-
4. Build the directory tree structure (`tree.py`)
136-
5. Write the tree structure to a YAML file (`writer.py`)
137-
13837
## Usage
13938
140-
Generate a structured representation of a directory:
141-
14239
```bash
143-
# Map current directory to stdout (YAML format)
144-
treemapper .
145-
146-
# Map specific directory to stdout
147-
treemapper /path/to/dir
148-
149-
# Save to a file
150-
treemapper . -o my-tree.yaml
151-
152-
# Use "-" to explicitly output to stdout
153-
treemapper . -o -
154-
155-
# Output in JSON format
156-
treemapper . --format json
157-
158-
# Output in plain text format
159-
treemapper . --format text -o output.txt
160-
161-
# Limit directory traversal depth
162-
treemapper . --max-depth 3
163-
164-
# Skip file contents (structure only)
165-
treemapper . --no-content
166-
167-
# Limit file size for content reading
168-
treemapper . --max-file-bytes 10000
169-
170-
# Custom ignore patterns
171-
treemapper . -i ignore.txt
172-
173-
# Disable all default ignores
174-
treemapper . --no-default-ignores
175-
176-
# Combine multiple options
177-
treemapper . -o tree.json --format json --max-depth 5 --max-file-bytes 50000
178-
179-
# Set verbosity level (0=ERROR, 1=WARNING, 2=INFO, 3=DEBUG)
180-
treemapper . -v 3
40+
treemapper . # YAML to stdout
41+
treemapper . -o tree.yaml # save to file
42+
treemapper . --format json # JSON format
43+
treemapper . --format text # tree-style text
44+
treemapper . --no-content # structure only (no file contents)
45+
treemapper . --max-depth 3 # limit directory depth
46+
treemapper . --max-file-bytes 10000 # skip files larger than 10KB
47+
treemapper . -i custom.ignore # custom ignore patterns
18148
```
18249

183-
### Options
50+
## Python API
18451

185-
```
186-
treemapper [OPTIONS] [DIRECTORY]
52+
```python
53+
from treemapper import map_directory, to_yaml, to_json, to_text
18754

188-
Arguments:
189-
DIRECTORY Directory to analyze (default: current directory)
55+
# Get tree as dict
56+
tree = map_directory("./myproject")
57+
tree = map_directory("./src", max_depth=2, no_content=True)
19058

191-
Options:
192-
-o, --output-file PATH Output file (default: stdout)
193-
Use "-" to force stdout output
194-
--format {yaml,json,text} Output format (default: yaml)
195-
-i, --ignore-file PATH Custom ignore patterns file
196-
--no-default-ignores Disable all default ignores (.gitignore, .treemapperignore, etc.)
197-
--max-depth N Maximum depth to traverse (default: unlimited)
198-
--no-content Skip reading file contents (structure-only mode)
199-
--max-file-bytes N Maximum file size to read in bytes (default: unlimited)
200-
Larger files will show a placeholder
201-
-v, --verbosity [0-3] Logging verbosity (default: 0)
202-
0=ERROR, 1=WARNING, 2=INFO, 3=DEBUG
203-
--version Show version and exit
204-
-h, --help Show this help
59+
# Serialize to string
60+
yaml_str = to_yaml(tree)
61+
json_str = to_json(tree)
62+
text_str = to_text(tree)
20563
```
20664

207-
### Ignore Patterns
208-
209-
By default, treemapper ignores:
65+
## Ignore Patterns
21066

211-
- The output file itself (when using `-o`)
212-
- All `.git` directories
213-
- Python cache directories (`__pycache__`, `.pytest_cache`, `.mypy_cache`, etc.)
214-
- Python build artifacts (`*.pyc`, `*.egg-info`, `dist/`, `build/`, etc.)
215-
- Patterns from `.gitignore` files (in the scanned directory and subdirectories)
216-
- Patterns from `.treemapperignore` file (in the scanned root directory)
217-
- Symbolic links (always skipped)
67+
Respects `.gitignore` and `.treemapperignore` automatically. Use `--no-default-ignores` to include everything.
21868

219-
Use `--no-default-ignores` to disable all default ignores and only use patterns from `-i/--ignore-file`.
69+
## Development
22070

221-
### Example Output
222-
223-
**YAML format (default):**
224-
```yaml
225-
name: my-project
226-
type: directory
227-
children:
228-
- name: src
229-
type: directory
230-
children:
231-
- name: main.py
232-
type: file
233-
content: |
234-
def main():
235-
print("Hello World")
236-
- name: README.md
237-
type: file
238-
content: |
239-
# My Project
240-
Documentation here...
241-
```
242-
243-
**JSON format (`--format json`):**
244-
```json
245-
{
246-
"name": "my-project",
247-
"type": "directory",
248-
"children": [
249-
{
250-
"name": "src",
251-
"type": "directory",
252-
"children": [
253-
{
254-
"name": "main.py",
255-
"type": "file",
256-
"content": "def main():\n print(\"Hello World\")\n"
257-
}
258-
]
259-
},
260-
{
261-
"name": "README.md",
262-
"type": "file",
263-
"content": "# My Project\nDocumentation here...\n"
264-
}
265-
]
266-
}
267-
```
268-
269-
**Text format (`--format text`):**
71+
```bash
72+
pip install -e ".[dev]"
73+
pytest
74+
pre-commit run --all-files
27075
```
271-
================================================================================
272-
Directory Tree: my-project
273-
================================================================================
27476

275-
src/ (directory)
276-
main.py (file)
277-
--- BEGIN CONTENT ---
278-
def main():
279-
print("Hello World")
280-
--- END CONTENT ---
77+
## Architecture
28178

282-
README.md (file)
283-
--- BEGIN CONTENT ---
284-
# My Project
285-
Documentation here...
286-
--- END CONTENT ---
28779
```
288-
289-
## Creating a Distribution Package
290-
291-
```bash
292-
# Build package
293-
python -m build
294-
295-
# Create executable with PyInstaller
296-
pyinstaller treemapper.spec
80+
src/treemapper/
81+
├── cli.py # argument parsing
82+
├── ignore.py # gitignore/treemapperignore handling
83+
├── tree.py # directory traversal
84+
├── writer.py # YAML/JSON/text output
85+
└── treemapper.py # main entry point
29786
```
29887

29988
## License
30089

301-
Apache License 2.0 - see [LICENSE](LICENSE) for details.
90+
Apache 2.0

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ dynamic = ["version"] # Version is still managed in version.py
1717
authors = [
1818
{ name = "Nikolay Eremeev", email = "nikolay.eremeev@outlook.com" },
1919
]
20-
description = "A tool for mapping directory structures"
20+
description = "Export codebase structure and contents for AI/LLM context"
2121
readme = "README.md"
2222
requires-python = ">=3.9"
2323
license = { file = "LICENSE" }

0 commit comments

Comments
 (0)