docs: update README and CONTRIBUTING for v0.2 features
README: - Quick Start shows kappa add workflow instead of manual configs - New features: indexed repos, env operators (+=, ?=), conflict reporting - Updated subcommand table (add, remove, index, validate-index) - Repo maintenance section (kappa index) - Link to STYLEGUIDE.md, test counts, CI info CONTRIBUTING: - Updated test counts (30+23+85 instead of 31+23) - Added test-full.sh to mandatory test suite - Referenced STYLEGUIDE.md in PR requirements - Updated good-first/ambitious issues for current state
This commit is contained in:
+20
-14
@@ -63,17 +63,20 @@ lock. `std::mutex`, `std::atomic`, `std::condition_variable` — use them
|
|||||||
correctly or don't use them at all. If you don't know what `memory_order`
|
correctly or don't use them at all. If you don't know what `memory_order`
|
||||||
means, stay out of the scheduler.
|
means, stay out of the scheduler.
|
||||||
|
|
||||||
### 6. Tests are shell scripts. For now.
|
### 6. Tests are shell scripts.
|
||||||
|
|
||||||
Integration tests live in `test.sh` and `test-init-switch.sh`. They
|
Integration tests live in three suites. If you add a subcommand, add a test.
|
||||||
exercise the CLI. If you add a subcommand, add a test. C++ unit tests
|
|
||||||
are welcome — set up Google Test or Catch2 in CMake and we'll merge it.
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./test.sh # 31 tests, must pass
|
./test.sh # 30 tests — DSL parsing, config, services, init systems
|
||||||
./test-init-switch.sh # 23 tests, must pass
|
./test-init-switch.sh # 23 tests — init-switching, rebuild impact, bootloaders
|
||||||
|
./test-full.sh # 85 tests — CLI, all keywords, repos, add/remove,
|
||||||
|
# resolver conflicts, deptrees, build, env ops,
|
||||||
|
# index generation, --root, imports, doctor, and more
|
||||||
```
|
```
|
||||||
|
|
||||||
|
All three must pass. CI enforces this on every push to `main`.
|
||||||
|
|
||||||
### 7. Backward compatibility is mandatory
|
### 7. Backward compatibility is mandatory
|
||||||
|
|
||||||
The `.kap` DSL is the contract. You can add keywords. You cannot remove
|
The `.kap` DSL is the contract. You can add keywords. You cannot remove
|
||||||
@@ -85,29 +88,32 @@ change means someone's `config.kap` stops parsing, it doesn't ship.
|
|||||||
### Pick something
|
### Pick something
|
||||||
|
|
||||||
Good first issues:
|
Good first issues:
|
||||||
- Adding a 6th init system backend
|
- Adding a 6th init system backend (we have 5: systemd, openrc, s6, runit, dinit)
|
||||||
- Adding a 3rd bootloader backend
|
- Adding a 3rd bootloader backend (we have 2: grub, limine)
|
||||||
- C++ unit test framework setup
|
- Improving the `kappa doctor` diagnostics for package recipes
|
||||||
- Shell completion scripts
|
- Adding `--features` / `--config` flags to `kappa add`
|
||||||
|
- Shell completion scripts (bash, zsh, fish)
|
||||||
|
|
||||||
Ambitious issues:
|
Ambitious issues:
|
||||||
- Binary package support (pre-built caches)
|
- Binary package support (pre-built caches)
|
||||||
- Remote build farm (distcc-style)
|
- Remote build farm (distcc-style)
|
||||||
- Signed package verification
|
- Signed package verification with index signing
|
||||||
- Filesystem overlay activation (like Nix profiles)
|
- Filesystem overlay activation (like Nix profiles)
|
||||||
|
- Transitive dependency resolution (auto-including deps not in config)
|
||||||
|
|
||||||
### Send a PR
|
### Send a PR
|
||||||
|
|
||||||
1. Fork the repo
|
1. Fork the repo
|
||||||
2. Create a branch: `feat/my-thing` or `fix/my-bug`
|
2. Create a branch: `feat/my-thing` or `fix/my-bug`
|
||||||
3. Write code that follows the rules above
|
3. Write code that follows the rules above
|
||||||
4. Run `./test.sh && ./test-init-switch.sh` — both must pass
|
4. Run `./test.sh && ./test-init-switch.sh && ./test-full.sh` — all three must pass
|
||||||
5. Open a PR against `main`
|
5. Open a PR against `main`
|
||||||
|
|
||||||
### PR requirements
|
### PR requirements
|
||||||
|
|
||||||
- Build must pass: `cmake --build build` with zero warnings
|
- Build must pass: `cmake --build build` with zero warnings on Clang 17+
|
||||||
- Tests must pass: both shell test suites
|
- Tests must pass: all three shell test suites
|
||||||
|
- Follow the conventions in [STYLEGUIDE.md](STYLEGUIDE.md)
|
||||||
- No commented-out code. No dead code. No TODO without a date.
|
- No commented-out code. No dead code. No TODO without a date.
|
||||||
- Commit messages in imperative: `Add runit backend` not `Added runit backend`
|
- Commit messages in imperative: `Add runit backend` not `Added runit backend`
|
||||||
|
|
||||||
|
|||||||
@@ -72,16 +72,45 @@ kappa rebuild config.kap # boot.init = "openrc" — only 5 packages actually r
|
|||||||
simultaneously, eight jobs each. The scheduler uses depth-based priority
|
simultaneously, eight jobs each. The scheduler uses depth-based priority
|
||||||
grouping so leaf dependencies unblock as much work as possible first.
|
grouping so leaf dependencies unblock as much work as possible first.
|
||||||
|
|
||||||
- **Package recipe caching.** Declare `remotes = ["https://repo.example.com/"]`
|
- **Package recipe caching with indexed repos.** Declare named repos with
|
||||||
in your config. Kappa fetches `.kap` files on demand, caches them, and only
|
channels and mirrors in your config. Kappa fetches `index.kap` from each
|
||||||
re-fetches when the remote version is newer.
|
repo, caches it, and only re-fetches when the remote changes. Package recipes
|
||||||
|
are resolved from the index — fast, offline-tolerant, and mirror-aware.
|
||||||
|
|
||||||
|
```kap
|
||||||
|
repos {
|
||||||
|
kappa-os {
|
||||||
|
url = "https://packages.kappa-os.org/"
|
||||||
|
channels = ["stable"]
|
||||||
|
mirrors = [
|
||||||
|
"https://cdn.kappa-os.org/",
|
||||||
|
"https://eu.kappa-os.org/",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`remotes = [...]` still works. Repos are tried first, then legacy remotes.
|
||||||
|
|
||||||
- **Source tarball caching.** Downloaded once, stored at `$KAPPA_ROOT/cache/`
|
- **Source tarball caching.** Downloaded once, stored at `$KAPPA_ROOT/cache/`
|
||||||
(default: `/usr/local/kappa/cache/`). Rebuilds don't touch the network
|
(default: `/usr/local/kappa/cache/`). Rebuilds don't touch the network
|
||||||
unless versions change.
|
unless versions change.
|
||||||
|
|
||||||
|
- **Env operators.** Three ways to set build environment variables:
|
||||||
|
`=` (hard set), `+=` (append with space), `?=` (soft set — only if not
|
||||||
|
already defined). System-level env propagates to all packages.
|
||||||
|
|
||||||
|
```kap
|
||||||
|
env {
|
||||||
|
CFLAGS = "-O2 -march=native" # overwrite
|
||||||
|
CFLAGS += "-pipe" # append → "-O2 -march=native -pipe"
|
||||||
|
CFLAGS ?= "-g" # soft — only if not set
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
- **Conflicts.** `systemd` declares `conflicts = ["eudev", "elogind"]`. The
|
- **Conflicts.** `systemd` declares `conflicts = ["eudev", "elogind"]`. The
|
||||||
resolver catches mutual incompatibility before a build starts.
|
resolver catches mutual incompatibility before a build starts — and now
|
||||||
|
actually reports it, rather than silently ignoring it.
|
||||||
|
|
||||||
- **Init-agnostic system config.** `groups { wheel { gid = 998 } }` — kappa
|
- **Init-agnostic system config.** `groups { wheel { gid = 998 } }` — kappa
|
||||||
creates the groups. `system { hostname = "mybox" }` — kappa writes
|
creates the groups. `system { hostname = "mybox" }` — kappa writes
|
||||||
@@ -113,41 +142,53 @@ kappa rebuild config.kap # boot.init = "openrc" — only 5 packages actually r
|
|||||||
cmake -B build -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
|
cmake -B build -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
|
||||||
cmake --build build
|
cmake --build build
|
||||||
|
|
||||||
# Write a config
|
# Add packages to your system config
|
||||||
cat > system.kap << 'EOF'
|
build/kappa add make
|
||||||
system { hostname = "kappa.local" }
|
build/kappa add nginx ">=1.24"
|
||||||
packages { nginx {} }
|
build/kappa add zlib
|
||||||
services { nginx { enable = true } }
|
|
||||||
boot {
|
|
||||||
kernel = "linux"; init = "s6"; root = "/dev/sda1"; bootloader = "limine"
|
|
||||||
}
|
|
||||||
users { root { shell = "/bin/zsh" } }
|
|
||||||
remotes = ["https://packages.kappa-os.org/stable/"]
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Parse it
|
# Rebuild — kappa fetches recipes, resolves deps, builds everything
|
||||||
build/kappa parse-config system.kap
|
build/kappa rebuild $KAPPA_ROOT/system/config.kap
|
||||||
|
|
||||||
# Rebuild
|
# Remove packages
|
||||||
build/kappa rebuild system.kap
|
build/kappa remove zlib
|
||||||
```
|
```
|
||||||
|
|
||||||
|
No config files to write by hand. `kappa add` writes the `packages {}` block
|
||||||
|
for you. `kappa rebuild` handles the rest.
|
||||||
|
|
||||||
### Subcommands
|
### Subcommands
|
||||||
|
|
||||||
| Command | What it does |
|
| Command | What it does |
|
||||||
|---------|-------------|
|
|---------|-------------|
|
||||||
| `parse-package <file>` | Validate a `.kap` package definition |
|
| `add <pkg> [version]` | Add a package to system config |
|
||||||
| `parse-config <file>` | Validate a system configuration |
|
| `remove <pkg>` | Remove a package from system config |
|
||||||
| `validate <file>` | Validate any kappa file |
|
| `build <package>` | Build a single package from its `.kap` definition |
|
||||||
| `format <file>` | Pretty-print to canonical style |
|
| `rebuild <config>` | Diff config against installed state, rebuild changed |
|
||||||
| `doctor <file>` | Check for issues and warnings |
|
| `resolve <config>` | Compute a build plan (shows order, deps, conflicts) |
|
||||||
| `resolve <config>` | Compute a build plan |
|
| `doctor <file>` | Check a file for issues and warnings |
|
||||||
| `fetch <package>` | Download and verify source tarballs |
|
| `fetch <package>` | Download and verify source tarballs |
|
||||||
| `fetch-package <name>` | Fetch a package recipe from remotes |
|
| `fetch-package <name>` | Fetch a package recipe from remotes |
|
||||||
| `build <package>` | Build a single package |
|
| `format <file>` | Pretty-print to canonical style |
|
||||||
| `rebuild <config>` | Diff config against installed state, rebuild changed |
|
| `index <dir>` | Build an `index.kap` from `.kap` files in a directory |
|
||||||
| `list` | Show installed packages |
|
| `list` | Show installed packages |
|
||||||
|
| `parse-config <file>` | Validate a system configuration |
|
||||||
|
| `parse-package <file>` | Validate a `.kap` package definition |
|
||||||
| `rollback` | Show available generations |
|
| `rollback` | Show available generations |
|
||||||
|
| `validate <file>` | Validate any kappa file (package, config, or index) |
|
||||||
|
|
||||||
|
### Repo maintenance
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Generate an index from a directory of .kap files
|
||||||
|
kappa index ./packages/
|
||||||
|
# → packages/index.kap
|
||||||
|
|
||||||
|
# Host the directory behind any HTTP server. That's your repo.
|
||||||
|
```
|
||||||
|
|
||||||
|
The index is a tiny text file listing every package and version.
|
||||||
|
Clients fetch it once, cache it, and check for updates via HTTP headers.
|
||||||
|
|
||||||
### License
|
### License
|
||||||
|
|
||||||
@@ -156,4 +197,7 @@ BSD 2-Clause. Do whatever you want. Just don't sue us.
|
|||||||
### Contributing
|
### Contributing
|
||||||
|
|
||||||
See [CONTRIBUTING.md](CONTRIBUTING.md). We're opinionated but we merge good
|
See [CONTRIBUTING.md](CONTRIBUTING.md). We're opinionated but we merge good
|
||||||
code.
|
code. See [STYLEGUIDE.md](STYLEGUIDE.md) for code conventions.
|
||||||
|
|
||||||
|
Tests: 138 integration tests across three suites. CI runs on Arch Linux.
|
||||||
|
Everything passes or nothing merges.
|
||||||
|
|||||||
Reference in New Issue
Block a user