Metadata-Version: 2.4
Name: hdl-ip-packager
Version: 0.10.0
Summary: An IP packager and dependency manager for HDL (Verilog/VHDL/SystemVerilog) design reuse.
Project-URL: Homepage, https://github.com/germanbravolopez/hdl-ip-packager
Project-URL: Documentation, https://github.com/germanbravolopez/hdl-ip-packager/tree/main/docs
Project-URL: Repository, https://github.com/germanbravolopez/hdl-ip-packager
Project-URL: Issues, https://github.com/germanbravolopez/hdl-ip-packager/issues
Author-email: German Bravo Lopez <gebralo@hotmail.com>
License: MIT License
        
        Copyright (c) 2026 German Bravo Lopez
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: asic,eda,fpga,hdl,ip,package-manager,systemverilog,verilog,vhdl
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Build Tools
Requires-Python: >=3.11
Provides-Extra: dev
Requires-Dist: hypothesis>=6.100; extra == 'dev'
Requires-Dist: mypy>=1.11; extra == 'dev'
Requires-Dist: pre-commit>=3.7; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest-randomly>=3.15; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: pyyaml>=6.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
Description-Content-Type: text/markdown

# HDL IP Packager

[![CI](https://github.com/germanbravolopez/hdl-ip-packager/actions/workflows/ci.yml/badge.svg)](https://github.com/germanbravolopez/hdl-ip-packager/actions/workflows/ci.yml)
![Python](https://img.shields.io/badge/python-3.11%2B-blue?logo=python&logoColor=white)
[![License: MIT](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
![Status](https://img.shields.io/badge/status-pre--alpha-orange)

A package manager and dependency resolver for **HDL IP cores** — bringing the
ergonomics of `pip` / `npm` / `cargo` / `docker pull` to Verilog, VHDL, and
SystemVerilog design reuse. Built in **Python 3.11+**.

> **Project status: pre-alpha / foundation.** The versioning, identity (VLNV),
> and manifest layers are implemented and tested; resolution, packaging, and
> registries are designed and stubbed. See
> [docs/progress_tracker.md](./docs/progress_tracker.md) for exactly what is done
> versus planned, and [docs/architecture.md](./docs/architecture.md) for the design.

---

## Why

Hardware teams re-use IP constantly, but sharing it is still mostly manual: copy
files, hand-track versions, hope the dependency you vendored matches the one your
colleague used. Software solved this with package managers. The mature HDL
attempts (FuseSoC, Bender, Orbit, IP-XACT/IEEE 1685, vendor catalogs) each got
part of the way. This project distills the state of the art into one tool — see
the research write-up in [docs/research/state_of_the_art.md](./docs/research/state_of_the_art.md).

## Features

Implemented today:

- **VLNV identity** — cores are named `vendor:library:name:version` (the IP-XACT
  convention), so names are globally meaningful and collision-resistant.
- **Semantic versioning** — full SemVer 2.0.0 parsing/precedence plus a
  constraint grammar (`^`, `~`, `>=`, `<`, ranges, `*`) for dependency specs.
- **Manifest (`ip.toml`)** — a TOML manifest per core declaring identity,
  metadata, filesets, dependencies, and build targets.
- **Dependency resolver** — backtracking, newest-compatible resolution that unifies
  SemVer-compatible dependents (Cargo-style) and applies a configurable
  `[resolution] on-conflict` policy to incompatible conflicts
  (`fail_on_conflict`/`use_latest`/`isolate_namespaces`); scheme-aware
  (`semver`/`calver`/`monotonic`/`opaque`), pre-release-aware. Under
  `isolate_namespaces`, `gen` name-mangles coexisting SystemVerilog/VHDL packages so
  two versions build together.
- **Lockfile (`ip.lock`)** — a deterministic, verifiable record of a resolve
  (exact VLNVs + source + SHA-256), written by `hdlpkg resolve`.
- **Content-addressed cache + registries** — a SHA-256-keyed local cache with
  verify-on-read, fed by **local-directory, HTTP, and OCI** registry backends behind one
  `--registry` location (a path, `http(s)://`, or `oci://`); `hdlpkg install` resolves and
  fetches dependencies into it.
- **Private, self-hosted distribution** — publish/consume cores over an internal HTTP server
  or any **OCI registry** (Harbor, Artifactory, Nexus, GitLab, Zot, ECR/ACR) without going
  public; `hdlpkg login` stores per-host credentials (a direct bearer token, or a
  username+secret that drives the OCI token-exchange used by managed registries; a
  `docker login` is reused), so a team shares IP inside its network. A deterministic `.ipkg`
  artifact backs `pack`, append-only `publish` (with `yank`), and `pull` (by VLNV).
- **CLI (`hdlpkg`)** — all commands are implemented: `info`, `validate`, `init`, `add`,
  `resolve`, `install`, `pack`, `publish`, `pull`, `yank`, `login`, `logout`, `gen`, `tree`,
  `export-ipxact`.

Designed and on the roadmap (see the progress tracker):

- A **Git-backed** registry channel.
- Tool-flow **generation** straight from a registry (it builds from local/extracted sources today).

---

## Requirements

| Dependency | Version |
|------------|---------|
| Python | 3.11+ (uses stdlib `tomllib`) |
| OS | Windows, Linux, macOS (pure Python) |
| Runtime deps | none yet (kept minimal by design) |

## Install

```powershell
# From a clone, install in editable mode with the dev/test toolchain:
python -m pip install -e ".[dev]"
```

This puts the `hdlpkg` command on your PATH and installs pytest, ruff, mypy, and
pre-commit. Enable the local git hooks (ruff + mypy on commit) once with:

```powershell
pre-commit install
```

## Usage

```powershell
hdlpkg --help                 # show all commands
hdlpkg init --vendor acme --library comm --name uart   # scaffold a starter ip.toml
hdlpkg info ip.toml           # print the parsed identity, deps, filesets, targets
hdlpkg validate ip.toml       # parse + validate a manifest (exit 0 if OK)
hdlpkg resolve ip.toml --search ../cores   # resolve deps to a deterministic ip.lock
hdlpkg install ip.toml --search ../cores   # resolve + fetch deps into the cache
hdlpkg pack ip.toml                         # build a distributable .ipkg
hdlpkg pack ip.toml --sbom --search ../cores # also emit a CycloneDX SBOM
hdlpkg publish ip.toml --registry ../reg    # publish into a local registry
hdlpkg pull acme:common:fifo:1.0.0 --registry ../reg --output ./fifo
hdlpkg gen sim ip.toml --search ../cores     # generate Verilator/Vivado inputs for a target
hdlpkg tree ip.toml --search ../cores        # print the resolved dependency graph
hdlpkg export-ipxact ip.toml                 # export an IP-XACT (IEEE 1685) component XML
python -m hdl_ip_packager info   # same CLI, invoked as a module

# Private, self-hosted registry (HTTP or OCI) -- log in once, then publish/consume:
hdlpkg login oci://harbor.corp.local/ip            # stores a per-host bearer token
hdlpkg publish ip.toml --registry oci://harbor.corp.local/ip
hdlpkg resolve ip.toml --registry oci://harbor.corp.local/ip   # nothing leaves your network
```

There is also a full `hdlpkg(1)` man page (commands, the typical producer/consumer
workflow, files, registries, examples). View it from a checkout with `man ./man/hdlpkg.1`;
see [`man/README.md`](./man/README.md) to install it so `man hdlpkg` works system-wide.

A minimal `ip.toml`:

```toml
[package]
vendor  = "acme"
library = "comm"
name    = "uart"
version = "1.2.0"

[dependencies]
"acme:common:fifo" = "^1.0.0"

[filesets.rtl]
files = ["rtl/uart_top.sv"]
type  = "systemVerilogSource"

[targets.sim]
toolflow = "verilator"
filesets = ["rtl"]
top      = "uart_top"
```

Optional keys extend this: `[package].scheme` selects the version scheme — `semver`
(default), `calver` (`2024.1`, year-as-major), `monotonic` (`r3`), or `opaque`
(non-SemVer tokens pinned exactly) — and `[resolution] on-conflict = "..."`
(`fail_on_conflict` default / `use_latest` / `isolate_namespaces`, also a
`--on-conflict` flag) for how an incompatible version conflict is handled. See
[docs/modules/manifest.md](docs/modules/manifest.md) and
[resolver.md](docs/modules/resolver.md).

Two complete, working cores live under [`examples/`](examples/) — a FIFO
(`acme:common:fifo`) and a UART (`acme:comm:uart`) that depends on it:

```powershell
hdlpkg info examples/uart/ip.toml
hdlpkg validate examples/fifo/ip.toml
hdlpkg resolve examples/uart/ip.toml --search examples   # writes examples/uart/ip.lock
```

---

## Tests

The suite uses **pytest** with a scalable, marker-based layout and a foldable
summary report. From the repo root:

```powershell
pytest                                   # run everything (with the local summary)
pytest -m unit                           # only fast unit tests
pytest -m "not integration"              # skip filesystem/integration tests
pytest --cov=hdl_ip_packager --cov-report=term-missing   # with coverage

# Produce the JUnit XML + the rendered Markdown report (what CI shows):
pytest --junitxml=test-results.xml
python scripts/render_test_summary.py --title "Test results"
```

See [tests/README.md](./tests/README.md) for how the suite is organized and how
to add new test modules. CI runs the suite on every push/PR and renders the
summary into the GitHub Actions run page.

---

## Documentation

Full technical documentation lives in [`docs/`](./docs/README.md) and is published
as a site at <https://germanbravolopez.github.io/hdl-ip-packager/> (built from
`docs/` by [`.github/workflows/docs.yml`](./.github/workflows/docs.yml) on every
push to `main`). To preview it locally:

```powershell
pip install -e ".[docs]"
mkdocs serve
```

| Document | Description |
|----------|-------------|
| [User guide](./docs/user_guide.md) | **Start here if you are new** — what the tool does and a hands-on walkthrough |
| [Module manual](./docs/modules/README.md) | Per-module reference + the full `hdlpkg` command reference |
| [AI agent instructions](./docs/ai_agent_instructions.md) | **Start here if you are an AI agent or new contributor** — briefing, file map, rules |
| [Architecture](./docs/architecture.md) | Module map, manifest/lockfile design, data flow, roadmap |
| [State of the art](./docs/research/state_of_the_art.md) | Research survey of package managers (pip/npm/cargo/docker) and HDL tools (FuseSoC, IP-XACT, Orbit, Bender) |
| [Progress tracker](./docs/progress_tracker.md) | What is done, in progress, and planned |
| [Quick-find index](./docs/INDEX.md) | Every file, concept, and topic |

---

## Development workflow

Day-to-day work lands on **`develop`**, the working branch; **`main` is the protected
release line**, updated only at release time. **No PR is needed for normal work** —
only a release goes through a PR (see Releasing).

1. **Work on `develop`** (or a short-lived `feature/`/`fix/`/`docs/` branch you merge
   into it). `main` is off-limits for direct commits (ruleset "main": no direct
   commits/pushes, no force-push, no deletion).
2. **Implement with tests.** Keep docs in sync as you go — run the `/update-docs`
   checklist (`docs/progress_tracker.md`, `docs/architecture.md`, `docs/INDEX.md`,
   and this README if user-visible behaviour changed).
3. **Make the gates green** before committing: `pytest`, `ruff check .`,
   `ruff format --check .`, `mypy`. The pre-commit hooks (`pre-commit install`) run
   ruff + mypy on each commit so these are caught locally before CI.
4. **Commit to `develop` and push.** CI runs on the push. No PR — the accumulated
   `develop` diff is reviewed at the next release.

A release is the one flow that uses a PR (`develop` → `main`); the agent reviews it
with `/code-review` and merges it (see Releasing). A **human gate applies only when
the agent cannot safely decide on its own** — the `1.0.0` stability sign-off, a
security-sensitive or hard-to-reverse change, or anything explicitly reserved.

### Releasing

Releases are **tag-driven**, and the `X.Y.Z` tag must sit on the merge commit on
`main` — so a release goes through the same PR flow, not a direct push:

1. On a `release/X.Y.Z` branch cut off **`develop`**, bump the version in **both**
   `pyproject.toml` and `src/hdl_ip_packager/__init__.py`, record the release in
   `docs/progress_tracker.md`, and make the gates green.
2. Open a PR into `main`, **review it (`/code-review`) and merge with a merge commit**
   (the agent owns this — see the workflow above; the `1.0.0` sign-off is the one
   release that needs explicit human go-ahead). Fast-forward `develop` to the merged
   `main` afterwards so the working branch carries the release commit.
3. On the updated `main`, create and push the bare `X.Y.Z` tag (no `v` prefix).
   `.github/workflows/release.yml` then builds the wheel + sdist, publishes to PyPI
   via OIDC trusted publishing, and **creates a GitHub Release** for the tag (a short
   summary from the `docs/progress_tracker.md` entry plus a link to the PyPI page,
   with the wheel + sdist attached). A guard (`scripts/check_release_version.py`)
   fails the run if the tag and the packaged version disagree, so the tag is the
   single source of truth for the published version.

(One-time: register the repo as a PyPI trusted publisher and create the `pypi`
environment.) The `/release` agent command in `.claude/commands/` automates the
mechanics (bump both version files, run the gates, prepare the release PR, review +
merge it, then tag `main` and watch Actions + PyPI to green).

See [docs/ai_agent_instructions.md](./docs/ai_agent_instructions.md) for the full
agent obligations and coding conventions.

## License

[MIT](./LICENSE) © 2026 German Bravo Lopez.
