208 lines
5.1 KiB
Markdown
208 lines
5.1 KiB
Markdown
# angela
|
|
|
|
A fast CLI tool that updates Python dependencies in `pyproject.toml` and scans for known vulnerabilities using [OSV.dev](https://osv.dev).
|
|
|
|
Built in Go for speed — parallel HTTP requests, local caching with ETag support, and a single binary with zero runtime dependencies.
|
|
|
|
---
|
|
|
|
## Why
|
|
|
|
The Python ecosystem lacks a single tool that updates all dependencies in `pyproject.toml` the way `pnpm update` works for JavaScript. Existing options either show outdated packages without updating them (`pip list --outdated`), upgrade one at a time (`pip install --upgrade`), or require CI infrastructure (Dependabot, Renovate).
|
|
|
|
**angela** fills this gap: one command updates everything, with built-in CVE scanning.
|
|
|
|
---
|
|
|
|
## Install
|
|
|
|
```bash
|
|
go install github.com/CarterPerez-dev/angela@latest
|
|
```
|
|
|
|
Or build from source:
|
|
|
|
```bash
|
|
git clone https://github.com/CarterPerez-dev/angela.git
|
|
cd angela
|
|
go build -o bin/angela ./cmd/angela
|
|
```
|
|
|
|
---
|
|
|
|
## Usage
|
|
|
|
### Update all dependencies
|
|
|
|
```bash
|
|
angela update
|
|
```
|
|
|
|
Reads `pyproject.toml` in the current directory, queries PyPI for the latest stable versions, and writes the updates back to the file.
|
|
|
|
### Dry run (show what would change)
|
|
|
|
```bash
|
|
angela check
|
|
```
|
|
|
|
Shows available updates and vulnerabilities without modifying any files.
|
|
|
|
### Scan for vulnerabilities only
|
|
|
|
```bash
|
|
angela scan
|
|
```
|
|
|
|
Checks all pinned dependencies against the OSV.dev vulnerability database.
|
|
|
|
### Update with vulnerability scan
|
|
|
|
```bash
|
|
angela update --scan-vulns
|
|
```
|
|
|
|
Updates dependencies and reports any known CVEs in your current versions.
|
|
|
|
### Skip major version bumps
|
|
|
|
```bash
|
|
angela update --safe
|
|
```
|
|
|
|
Only applies minor and patch updates, skipping anything that crosses a major version boundary.
|
|
|
|
### Include pre-release versions
|
|
|
|
```bash
|
|
angela update --include-prerelease
|
|
```
|
|
|
|
Considers alpha, beta, release candidate, and dev versions when resolving the latest.
|
|
|
|
### Specify a different file
|
|
|
|
```bash
|
|
angela update --file path/to/pyproject.toml
|
|
```
|
|
|
|
### Clear the local cache
|
|
|
|
```bash
|
|
angela cache clear
|
|
```
|
|
|
|
Removes all cached PyPI responses from `~/.angela/cache/`.
|
|
|
|
---
|
|
|
|
## Example output
|
|
|
|
```
|
|
Scanning 9 dependencies...
|
|
|
|
Updates available:
|
|
django 3.2.0 -> 5.1.5 (major)
|
|
requests 2.28.0 -> 2.32.3 (minor)
|
|
click 8.0.0 -> 8.1.8 (patch)
|
|
pydantic 2.0.0 -> 2.10.6 (minor)
|
|
flask 2.0.0 -> 3.1.0 (major)
|
|
pytest 7.0.0 -> 8.3.4 (major)
|
|
black 23.0.0 -> 25.1.0 (major)
|
|
ruff 0.1.0 -> 0.9.4 (minor)
|
|
mypy 1.0.0 -> 1.14.1 (minor)
|
|
|
|
Vulnerabilities found:
|
|
django
|
|
GHSA-2hrw-hx67-34x6 [CRITICAL] Potential denial-of-service in django.utils.text.Truncator
|
|
Fixed in: 4.2.16
|
|
requests
|
|
GHSA-9wx4-h78v-vm56 [MEDIUM] Requests `Session` object does not verify requests after making first request with verify=False
|
|
Fixed in: 2.32.0
|
|
|
|
Updated pyproject.toml
|
|
9 packages checked
|
|
9 updated
|
|
36 vulnerabilities found
|
|
Done in 2.4s
|
|
```
|
|
|
|
---
|
|
|
|
## How it works
|
|
|
|
```
|
|
1. Parse pyproject.toml
|
|
Extract all [project.dependencies] and [project.optional-dependencies]
|
|
|
|
2. Query PyPI Simple API (parallel)
|
|
Fetch version lists using the lightweight JSON format
|
|
ETag-based caching avoids redundant downloads
|
|
|
|
3. Resolve updates
|
|
Parse versions per PEP 440 (epochs, pre-releases, post-releases)
|
|
Filter to stable releases by default
|
|
Classify changes as major, minor, or patch
|
|
|
|
4. Scan for vulnerabilities (optional)
|
|
Batch query OSV.dev for all dependencies
|
|
Hydrate results with full advisory details
|
|
Deduplicate overlapping CVE/GHSA identifiers
|
|
|
|
5. Write updates
|
|
Regex-based surgery preserves comments and formatting
|
|
Atomic write via temp file + rename
|
|
```
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
```
|
|
cmd/angela/main.go CLI entry point
|
|
internal/
|
|
cli/
|
|
update.go Command definitions and orchestration
|
|
output.go Terminal formatting with color
|
|
pypi/
|
|
version.go PEP 440 parser and comparator
|
|
client.go PyPI Simple API client with retry
|
|
cache.go File-backed ETag cache
|
|
osv/
|
|
client.go OSV.dev batch vulnerability scanner
|
|
pyproject/
|
|
parser.go TOML parsing and PEP 508 splitting
|
|
writer.go Comment-preserving regex updater
|
|
pkg/types/
|
|
types.go Shared domain types
|
|
```
|
|
|
|
---
|
|
|
|
## Development
|
|
|
|
Requires Go 1.24+ and [just](https://github.com/casey/just).
|
|
|
|
```bash
|
|
just test # Run all tests with race detector
|
|
just lint # Run golangci-lint
|
|
just build # Build binary to bin/angela
|
|
just cover # Generate HTML coverage report
|
|
just check # Lint + test in one step
|
|
just run check # Run angela check via go run
|
|
```
|
|
|
|
---
|
|
|
|
## Part of Cybersecurity-Projects
|
|
|
|
This tool is project #1 in the [Cybersecurity-Projects](https://github.com/CarterPerez-dev/Cybersecurity-Projects) repository — a collection of 60 security-focused projects built for learning and reference. The code is written to be educational: clear structure, proper error handling, and thorough testing.
|
|
|
|
See the [`learn/`](learn/) directory for deep dives into the techniques used here.
|
|
|
|
---
|
|
|
|
## License
|
|
|
|
MIT
|