Metadata-Version: 2.4
Name: dependaman
Version: 1.0.1
Summary: Understand your Python dependencies. Find cycles, dead modules, and architecture problems.
Author-email: Jacobo Bedoya <jacobobedoya@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://codeberg.org/jacobitosuperstar/DependaMan
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# DependaMan

Understand your Python project's internal structure. Find cycles, dead modules,
hotspots, and architecture problems — visualized as an interactive graph.

No external Python dependencies. Pure stdlib only.

---

## Goal

Given a Python project directory, DependaMan produces an interactive HTML graph
showing:

- Which modules import which (directed dependency graph)
- Which modules are never imported (dead code candidates)
- Circular import chains
- Modules with high fan-in (many dependents) or high fan-out (many dependencies)
- Module size (lines of code, number of functions/classes)
- Git churn: how often each module changes

---

## Architecture

### Phase 1 — File Discovery
Walk the project directory, collect all `.py` files, and determine the package
root. Distinguish internal modules from external ones (stdlib + third-party are
ignored).

### Phase 2 — Import Parsing
Use `ast` to parse each file and extract `import` and `from ... import`
statements. Resolve relative imports. Filter to internal-only imports.

### Phase 3 — Graph Construction
Build a directed graph as an adjacency structure:
- Node = internal module
- Edge A → B = "module A imports module B"

Attach metadata to each node: file path, line count, function/class count.

### Phase 4 — Analysis
Run these passes on the graph:

- **Dead code**: nodes with no incoming edges and not an entry point
- **Circular imports**: detect cycles (DFS-based)
- **Hotspots**: nodes ranked by fan-in (most imported)
- **Coupling**: nodes ranked by fan-out (imports the most)

### Phase 5 — Git Integration
Use `subprocess` + `git log` to compute per-file:
- Commit frequency (how often it changes)
- Lines added/removed over time (churn)
- Last author that changed the file

Attach this data to graph nodes. Optional: skipped if the project is not a git
repo.

### Phase 6 — HTML Output
Generate a self-contained `.html` file (or return HTML as a string for web
integration).

The HTML template is a static string embedded in Python. Only the data changes
between runs. Python serializes the graph to JSON and injects it into the
template — no templating library needed:

```python
import json

data = json.dumps({"nodes": [...], "edges": [...]})
html = TEMPLATE.replace("__GRAPH_DATA__", data)
```

The template contains a `<script>` block that reads the injected data and
renders the graph using the browser's `<canvas>` or SVG API. No external JS
libraries required.

The graph supports:
- **Hover tooltips**: quick summary (import count, churn score)
- **Click modals**: full detail panel (git log, list of dependents/dependencies,
  size metrics)

The output function signature is designed to be framework-agnostic:

```python
def render(graph, analysis) -> str:  # returns HTML string
    ...
```

This makes it trivial to plug into FastAPI, Flask, or any other framework:

```python
# FastAPI example
@app.get("/graph", response_class=HTMLResponse)
def dependency_graph():
    graph = build_graph(".")
    analysis = analyze(graph)
    return render(graph, analysis)
```

---

## Package Structure

DependaMan is distributed as a Python package (`dependaman`). The current layout:

```
dependaman/
    __init__.py        # public API: dependaman()
    __main__.py        # CLI entry point
    core.py            # orchestration
    discovery.py       # Phase 1 — file discovery
    parser.py          # Phase 2 — import parsing
    graph.py           # Phase 3 — graph construction
    analysis.py        # Phase 4 — analysis passes
    git.py             # Phase 5 — git integration
    renderer.py        # Phase 6 — HTML output
    pool.py            # GIL-aware executor selection
```

Entry point via `pyproject.toml`:
```
[project.scripts]
dependaman = "dependaman.__main__:dependaman"
```

### Usage

**CLI:**
```bash
dependaman              # analyzes current directory, opens browser
dependaman /path/to/project
```

**Python API:**
```python
from dependaman import dependaman

html = dependaman(".", in_memory=True)   # returns HTML string
dependaman(".")                          # writes output.html + opens browser
```

---

## Roadmap

- [X] Phase 1: File discovery
- [X] Phase 2: Import parsing (`ast`)
- [X] Phase 3: Graph construction
- [X] Phase 4: Analysis (dead code, cycles, hotspots)
- [X] Phase 5: Git integration
- [X] Phase 6: HTML renderer
- [X] Phase 7: Unused symbol detection (functions, classes, methods never imported)
- [X] Phase 8: Installable package (`uv pip install -e .`)
- [X] Phase 9: CLI entry point with auto project root detection and browser open
- [X] Phase 10: Performance — parallel git stats (ThreadPoolExecutor), GIL-aware pool for parsing and graph construction
