Metadata-Version: 2.4
Name: analyze-project
Version: 0.1.0
Summary: Static Python project analyzer with CLI summaries, graphs, and JSON output.
Author: aetsr
License-Expression: MIT
Keywords: analysis,ast,cli,codebase,python,static-analysis
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: matplotlib>=3.8
Requires-Dist: networkx>=3.2
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Dynamic: license-file

# analyze_project

`analyze_project` is a single-file Python utility for statically inspecting a Python codebase and exporting:

- A terminal summary of modules, classes, functions, leaves, entry points, hotspots, warnings, and resolved vs unresolved calls
- A module dependency graph as `project_analysis.png`
- A cross-module call graph as `project_call_graph.png`
- A hotspot chart as `project_hotspots.png`
- A machine-readable report as `project_analysis.json`

It is designed for quick structural analysis without modifying the target repository.

## Requirements

- Python 3.9+
- Runtime dependencies are installed automatically from package metadata

## Installation

```bash
pip install analyze-project
```

For isolated CLI installs, `pipx` is a good fit:

```bash
pipx install analyze-project
```

For a local checkout before publishing to PyPI:

```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -e .[dev]
```

## Usage

Analyze the current working directory:

```bash
analyze-project
```

Analyze a specific project:

```bash
analyze-project /path/to/python-project
```

Only generate JSON:

```bash
analyze-project /path/to/python-project --json-only
```

Only print the terminal summary:

```bash
analyze-project /path/to/python-project --summary-only
```

Show unresolved call examples:

```bash
analyze-project /path/to/python-project --show-unresolved
```

Filter scanned files:

```bash
analyze-project /path/to/python-project --include-glob "pkg/*.py" --exclude-dir generated
```

Module execution is also supported:

```bash
python -m analyze_project /path/to/python-project
```

## CLI

```text
analyze-project [target] [--output-dir PATH] [--depth N] [--max-branches N] [--max-entry-trees N] [--hotspots N] [--non-recursive] [--include-glob PATTERN] [--exclude-dir NAME] [--show-unresolved] [--summary-only | --json-only]
```

- `target`: Directory to analyze. Defaults to the current working directory.
- `--output-dir PATH`: Output directory for generated artifacts. Defaults to `./analysis_output/<project_name>/`.
- `--depth N`: Maximum call tree depth in the terminal summary.
- `--max-branches N`: Maximum number of call branches shown per tree node.
- `--max-entry-trees N`: Maximum number of entry-point call trees printed.
- `--hotspots N`: Number of most-called callables to include.
- `--non-recursive`: Only analyze Python files in the top-level target directory.
- `--include-glob PATTERN`: Repeatable relative-path glob filter for `.py` files.
- `--exclude-dir NAME`: Repeatable directory name to exclude in addition to the built-in skip list.
- `--show-unresolved`: Print unresolved call examples in the terminal summary.
- `--summary-only`: Do not write JSON or image artifacts.
- `--json-only`: Only write `project_analysis.json`; skip image generation.

## Output files

Default runs generate:

- `project_analysis.png`
- `project_call_graph.png`
- `project_hotspots.png`
- `project_analysis.json`

When `--json-only` is used, only `project_analysis.json` is written. When `--summary-only` is used, no artifacts are written.

## JSON report

`project_analysis.json` keeps the original top-level analysis sections and adds structured metadata for downstream tooling.

New top-level fields:

- `schema_version`
- `warnings`
- `stats`
- `unresolved_calls`

The `stats` object currently includes:

- `files_scanned`
- `files_skipped`
- `syntax_error_files`
- `resolved_calls`
- `unresolved_calls`
- `cross_module_edges`

## Resolution behavior

The analyzer now handles these common local patterns more accurately:

- `from pkg import submodule`
- `from pkg.module import symbol`
- aliased imports
- nested relative imports
- package directories with `__init__.py`
- simple instance tracking such as `svc = Service(); svc.work()`
- simple module-backed instance tracking such as `obj = module.Factory(); obj.method()`

## Known limitations

- The analysis is static and AST-based; dynamic imports, monkey-patching, and runtime dispatch cannot always be resolved.
- Deep data-flow and alias tracking are intentionally shallow; only simple same-scope constructor assignments are followed.
- Re-export-heavy package APIs and `from x import *` cannot be resolved with full precision.
- Unknown object calls may appear in `unresolved_calls` even when they are valid at runtime.
- The cross-module call graph and hotspot chart are skipped when the analyzed project does not contain the required edges.

## Development

Install development dependencies and run checks:

```bash
pip install -e .[dev]
python -m py_compile analyze_project.py tests/test_cli.py
ruff check .
pytest
python -m build
python -m twine check dist/*
```

## Publishing

Once the package name has been created on PyPI, the intended install command is:

```bash
pip install analyze-project
```

This repository includes a GitHub Actions publishing workflow that is ready for PyPI Trusted Publishing. Configure the PyPI project to trust this GitHub repository, then publish from GitHub Releases or a manual workflow run.

## License

MIT. See [`LICENSE`](LICENSE).
