Add spec, schema and README for pkgatlas
Specification for a cross-distro file -> package resolver, grounded in verified upstream formats for deb (Contents), rpm (filelists.xml) and pacman (*.files.tar.gz). No implementation: spec only.
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# pkgatlas
|
||||
|
||||
Cross-distro **file → package** resolver. Answers one question well:
|
||||
|
||||
> Given a build-time dependency signal — a linker flag (`-lcurses`), a missing header
|
||||
> (`ncurses.h`), a pkg-config name, or a bare file path — **which package do I install**
|
||||
> on *(distro, release, arch)*?
|
||||
|
||||
Built for build automation. Primary consumer: **saggar** (auto-magic dependency detection),
|
||||
where a `-lcurses not found` error currently has no reliable answer.
|
||||
|
||||
## Why
|
||||
|
||||
That mapping does exist upstream, but only as large per-distro indexes that are slow to
|
||||
query, differently shaped per package manager, and unavailable mid-build:
|
||||
|
||||
| Manager | Source | Size |
|
||||
|---|---|---|
|
||||
| deb | `Contents-<arch>.gz` | 12.7 – 47.6 MB |
|
||||
| rpm | `filelists.xml.zst` | 39.7 – 48.9 MB (→ 875 MB uncompressed) |
|
||||
| pacman | `<repo>.files.tar.gz` | 1.5 – 51 MB |
|
||||
|
||||
pkgatlas precomputes them into one small, uniform, queryable artifact.
|
||||
|
||||
The same mapping is also **distro-dependent**: `-lcurses` is `libncurses-dev` on Debian but
|
||||
`termcap-devel` on openSUSE. So answers cannot be inferred across distros — they must be
|
||||
built per distro.
|
||||
|
||||
## Shape
|
||||
|
||||
```
|
||||
pkgatlas-build ──> snapshot .sqlite ──┬──> pkgatlas-serve (HTTP API)
|
||||
(ETL) (the artifact) └──> published file (offline query)
|
||||
```
|
||||
|
||||
The **artifact is the product**. Consumers can pin a snapshot for reproducible builds, or
|
||||
query locally with no network dependency mid-build.
|
||||
|
||||
## Status
|
||||
|
||||
**Pre-implementation.** Spec and schema are written and grounded in verified upstream
|
||||
formats; the Go implementation is in progress.
|
||||
|
||||
- [`docs/SPEC.md`](docs/SPEC.md) — full specification
|
||||
- [`schema.sql`](schema.sql) — database schema
|
||||
|
||||
## API (planned)
|
||||
|
||||
```
|
||||
GET /v1/resolve?lib=curses&distro=ubuntu&release=24.04&arch=riscv64
|
||||
GET /v1/resolve?header=ncurses.h
|
||||
GET /v1/resolve?pc=ncurses
|
||||
GET /v1/resolve?file=libcurses.so
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"query": { "kind": "lib", "value": "curses" },
|
||||
"resolved": [{
|
||||
"manager": "deb", "distro": "ubuntu", "release": "24.04", "arch": "riscv64",
|
||||
"path": "usr/lib/riscv64-linux-gnu/libcurses.so",
|
||||
"package": "libncurses-dev",
|
||||
"install": "apt-get install -y libncurses-dev"
|
||||
}],
|
||||
"ambiguous": false,
|
||||
"truncated": false
|
||||
}
|
||||
```
|
||||
|
||||
`resolved` is always an array — an empty one means "genuinely unavailable on this distro",
|
||||
which is a real answer. When a flag maps to several packages (`-lcurl` →
|
||||
`libcurl4-openssl-dev` *and* `libcurl4-gnutls-dev`), `ambiguous` is `true` and the consumer
|
||||
chooses; pkgatlas never picks silently.
|
||||
|
||||
## Scope
|
||||
|
||||
v1 covers **deb**, **rpm** and **pacman**. `apk` and `nix` are deferred. Language-registry
|
||||
metadata (npm/cargo/pypi) is explicitly out of scope — that is [deps.dev](https://deps.dev)'s job.
|
||||
|
||||
## Build
|
||||
|
||||
```sh
|
||||
CGO_ENABLED=0 go build ./...
|
||||
go test ./...
|
||||
```
|
||||
|
||||
Requires Go 1.25+. No CGO: SQLite is `modernc.org/sqlite`, zstd is `klauspost/compress`.
|
||||
|
||||
## License
|
||||
|
||||
TBD.
|
||||
Reference in New Issue
Block a user