cc-libs/docs/adrs/adr-0010-ccpm-package-manager.md

103 lines
4.8 KiB
Markdown

# ADR 0010: ccpm Package Manager
## Status
Accepted
## Date
2026-06-08
## Context
ADR 0004 made installs manifest-driven: `install.lua` reads a flat `manifest.json`
file list from a branch and `wget`s every file. That is all-or-nothing. There is no
way to install just networking or just the UI, and no way to add or remove pieces of
the OS after the initial install.
We want a package manager, `ccpm` ("ComputerCraft Package Manager"), installed first
as a standalone user-facing step. After that, a machine can `ccpm update`,
`ccpm install trapos`, `ccpm install tos-net`, `ccpm uninstall tos-ui`, and manage
where packages come from. TrapOS itself is installed through a `trapos` meta-package;
the `wget run .../install-ccpm.lua` bootstrap exists only to install `ccpm`.
## Decision
### Packages are descriptors over the existing tree
Source files stay where they are (`apis/`, `programs/`, `servers/`, `startup/`); their
install targets remain the same absolute CC paths, so `require` paths and the dev
mounts are unchanged. A package is a descriptor that *references* those files:
`packages/<name>/ccpm.json` with `{ name, version, description, dependencies, files,
autostart }`. `packages/index.json` lists the packages a registry offers (for
`ccpm search`). There is no `ccpm.json` at the repo root.
The split is finer-grained than the install examples imply:
| package | contents | deps |
|----------|-----------------------------------------------------------------|----------|
| tos-core | ccpm, libccpm, eventloop, upgrade, events | — |
| tos-test | libtest, runtest | tos-core |
| tos-boot | motd, servers (startup) | tos-core |
| tos-net | net, router, ping, ping-server | tos-core |
| tos-ui | libtui, tuidemo | tos-core |
| trapos | full TrapOS meta-package | tos-boot, tos-net, tos-ui, tos-test |
### Two files for ccpm, "manifest" reserved for the OS
To avoid colliding with the OS `manifest.json`, ccpm never uses the word "manifest".
Local state lives under `/trapos`:
- `ccpm.json` — ordered registry list `{ registries = { { name, type, branch } } }`.
`type` is `github` (resolves to `raw.githubusercontent.com/<name>/<branch>/`) or
`http`/`https` (the `name` is a base URL).
- `ccpm.lock.json` — installed packages `{ packages = { <name> = { version, registry,
files, dependencies, autostart } } }`, used by `ls`, `uninstall`, and `reinstall`.
- `ccpm.cache.json` — packages advertised by configured registries, written by
`ccpm update` from each registry's `packages/index.json`, used by `ccpm search`,
`ccpm available`, and `ccpm upgrade`.
`apis/libccpm.lua` is the testable core (a factory; `http`/`stateDir`/`installRoot`
are injectable for tests). `programs/ccpm.lua` is a thin CLI over it.
### The bootstrap installs only ccpm
`install-ccpm.lua` resolves only the `tos-core` package descriptor (pulling any future
dependencies), downloads its files, and writes:
- `/trapos/manifest.json` — the aggregated `{ name, version, branch, files, autostart }`
still consumed by `startup/motd.lua` and `startup/servers.lua` after boot packages
are installed;
- `/trapos/ccpm.lock.json` — so right after a fresh install `ccpm install tos-core`
correctly reports "already installed";
- `/trapos/ccpm.json` — seeding/refreshing the default `guillaumearm/cc-libs` registry
to track the install branch.
The install path is:
- `wget run .../install-ccpm.lua` — install `ccpm` (`tos-core`) and seed the default
registry.
- `ccpm update` — refresh the local package cache.
- `ccpm install trapos` — install the full OS. During beta, `trapos` includes
`tos-test` by default.
On a subsequent `upgrade`, `programs/upgrade.lua` delegates to `ccpm upgrade`, which
upgrades installed packages using `/trapos/ccpm.cache.json`. Users run `ccpm update`
first to refresh available versions.
## Consequences
- The repo gains a `packages/` descriptor tree; the flat source layout is untouched.
- `just craftos` no longer derives mounts from `manifest.json .files` (it is now
`.packages`); it mounts a fixed list of top-level dirs instead. `just test` was
already on fixed mounts and is unaffected.
- ccpm logic is covered by `tests/ccpm.lua` (URL resolution, dependency ordering,
cycle/missing detection, already-installed, registry CRUD, cache update, available
status, upgrade, uninstall dependency guard) with an injected `http` stub — no
network in tests.
## Future Work
- Version ranges (today a single pinned version per package).
- http/https registries beyond a plain base URL (auth, caching).