96 lines
4.4 KiB
Markdown
96 lines
4.4 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"), shipped as part
|
|
of the base OS, so a machine can `ccpm install tos-net`, `ccpm uninstall tos-ui`, and
|
|
manage where packages come from. TrapOS itself is **not** becoming a package for now;
|
|
the `wget run .../install.lua` bootstrap stays the recommended entry point.
|
|
|
|
## 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 |
|
|
|
|
### 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`.
|
|
|
|
`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 is package-aware
|
|
|
|
`manifest.json` now lists `packages` instead of `files`. `install.lua` resolves each
|
|
package descriptor (pulling dependencies), downloads the union of their files, and
|
|
writes:
|
|
|
|
- `/trapos/manifest.json` — the aggregated `{ name, version, branch, files, autostart }`
|
|
still consumed verbatim by `startup/motd.lua`, `startup/servers.lua`, and
|
|
`programs/upgrade.lua` (those three are unchanged);
|
|
- `/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.
|
|
|
|
Two install paths follow:
|
|
|
|
- `wget run .../install.lua` — full OS (all packages in `manifest.packages`).
|
|
- `wget run .../install.lua --core` — only `tos-core` (i.e. just `ccpm`); the user then
|
|
cherry-picks with `ccpm install ...`.
|
|
|
|
On a subsequent `upgrade`, `install.lua` prefers the existing lockfile's package set
|
|
over `manifest.packages`, so a cherry-picked machine upgrades only what it actually has.
|
|
|
|
## 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, uninstall dependency
|
|
guard) with an injected `http` stub — no network in tests.
|
|
|
|
## Future Work
|
|
|
|
- Version ranges / `ccpm update` (today a single pinned version per package).
|
|
- Making TrapOS self-update through ccpm rather than the `wget run` bootstrap.
|
|
- http/https registries beyond a plain base URL (auth, caching).
|