Metadata-Version: 2.4
Name: evo-sbom
Version: 0.1.1
Summary: CLI tu dong sinh SBOM cho project Python, Node.js va Docker image (wrap syft)
Project-URL: Homepage, https://github.com/maycuatroi1/evo-sbom
Project-URL: Repository, https://github.com/maycuatroi1/evo-sbom
Project-URL: Issues, https://github.com/maycuatroi1/evo-sbom/issues
Author: maycuatroi
Keywords: cli,cyclonedx,docker,sbom,spdx,supply-chain,syft
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Build Tools
Requires-Python: >=3.10
Requires-Dist: click>=8.1
Requires-Dist: rich>=13.7
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# evo-sbom

A CLI that automatically generates SBOMs (Software Bill of Materials) for Python projects, Node.js projects, and Docker images.

evo-sbom is a UX layer (click + rich) wrapped around [syft](https://github.com/anchore/syft). The syft binary is downloaded automatically into `~/.evo-sbom/bin` on first run (the version is pinned in `src/evo_sbom/config.py`).

## Installation

From PyPI:

```bash
pip install evo-sbom
# or
uv tool install evo-sbom
```

From source:

```bash
uv sync
```

## Usage

```bash
# Auto-detect Python / Node.js and generate both CycloneDX + SPDX
uv run evo-sbom scan .

# Scan a GitHub repo directly (cloned to a temp dir, then removed)
uv run evo-sbom scan maycuatroi1/evo-cli
uv run evo-sbom scan https://github.com/owner/repo
uv run evo-sbom scan owner/repo --branch dev

# Force the project type
uv run evo-sbom python ./my-python-app
uv run evo-sbom node ./my-node-app

# Docker image (image ref, docker-archive:, or oci-archive:)
uv run evo-sbom docker alpine:latest
uv run evo-sbom docker docker-archive:./image.tar

# Check / install the syft engine
uv run evo-sbom doctor
```

### Common flags

- `-b, --branch` branch to clone (GitHub repo input on `scan` only).
- `-f, --format [cyclonedx|spdx|both]` (default `both`).
- `-o, --output PREFIX` (default `sbom`) produces `sbom.cdx.json`, `sbom.spdx.json`.
- `--quiet` prints only the written file paths (for CI).

## Output

- `*.cdx.json` - CycloneDX JSON
- `*.spdx.json` - SPDX 2.3 JSON

## Notes on unpinned dependencies

If a Python project declares its dependencies without pinned versions (no `==`),
leaves `pyproject.toml` dependencies empty, or has no lock file, a source-directory
scan yields no Python packages, because syft needs resolved versions to catalog them.
In that case scan a resolved environment instead:

- Build the project's Docker image (its Dockerfile usually runs `pip install -r requirements.txt`)
  and run `evo-sbom docker <image>`. This also captures OS/apt and base-image packages.
- Or create a fresh virtualenv, install the project into it, and run `evo-sbom python <venv>`.

## Development

```bash
uv run pytest
```

## Releasing

Pushing to `main` triggers `.github/workflows/release.yml`, which bumps the
version, builds, and publishes to PyPI via Trusted Publishing (OIDC, no token).
The bump type is derived from the latest commit message:

- `BREAKING CHANGE` in the message -> major
- message starting with `feat` -> minor
- anything else -> patch

A matching `vX.Y.Z` tag and GitHub Release are created automatically.

One-time PyPI setup (Trusted Publishing): on pypi.org create a pending publisher
for project `evo-sbom` with owner `maycuatroi1`, repo `evo-sbom`, workflow
`release.yml`.
