Portability (Linux distro-agnostic): - Remove hardcoded Clang compiler enforcement; GCC now builds - Add find_package(Threads REQUIRED) for older glibc - Add cmake install() target - FHS 3.0 default root: /kappa -> /usr/local/kappa - fs::path operator/ for all init/bootloader paths (fixes prefix fragility) - Multi-distro zoneinfo search (FHS, NixOS, Guix, alt) - Portable tar extraction (drop GNU-only --no-same-permissions) - Runit enable/disable commands now prefix-aware - --root CLI flag before/after subcommand, lazy directory creation - Shebang constants de-duplicated to types.hpp Correctness (race conditions, UB, corruption): - Fix CWD race in scheduler: per-child chdir() instead of process-global - Fix UB const_cast in exec_cmd/exec_capture: mutable argv buffers - Fix non-atomic installed DB writes: tmp+rename pattern - Fix read_file() no longer calls exit(1), throws instead - Fix silent catch(...) parse errors now print diagnostics - Fix rebuild false positives with config_hash change detection - Fix s6 disable_cmd copy-paste bug (was identical to enable) - Fix runit enable_cmd incomplete, disable_cmd wrong target - Fix dinit env vars: functional env-file + companion .env Quality: - Add -Wall -Wextra -Wpedantic to CMake, fix 2 pre-existing warnings - Move parse_int from error.hpp to parse_util.hpp - Fix hash verification guard checks all three hash types - Check patch return code in fetch.cpp - Add explicit system_dir creation in ensure_directories() - Add resolve to needs_dirs for build_registry() consistency - Update stale /kappa path references in examples - Remove inaccurate -Werror claim in CONTRIBUTING.md - Add build-gcc/ and agent dirs to .gitignore - Suppress clang-tidy portability-avoid-pragma-once - Fix .gitignore /kappa pattern (was matching include/kappa/) - Delete stale vcpkg_installed/ directory 54/54 tests pass. Builds on Clang and GCC with 0 warnings.
138 lines
4.4 KiB
Markdown
138 lines
4.4 KiB
Markdown
# Contributing to kappa
|
|
|
|
We're building a package manager that doesn't care about your init system,
|
|
your bootloader, or your life choices. If that sounds like your kind of
|
|
project, keep reading.
|
|
|
|
## The rules
|
|
|
|
These aren't guidelines. They're the deal.
|
|
|
|
### 1. C++23 or don't bother
|
|
|
|
We compile with Clang, `-std=c++23`, and zero warnings. If your code needs a
|
|
polyfill for `std::format` or can't handle designated initializers, it
|
|
doesn't belong here. The standard library is your only dependency. Zero
|
|
external C++ libraries. Not even Boost.
|
|
|
|
```cpp
|
|
// ✓ yes
|
|
auto msg = std::format("building {} (depth={})", name, depth);
|
|
|
|
// ✗ no
|
|
auto msg = fmt::format("building {} (depth={})", name, depth);
|
|
```
|
|
|
|
### 2. Every new module mirrors the existing structure
|
|
|
|
```
|
|
include/kappa/{module}/
|
|
├── types.hpp # enums, structs, parse/validate declarations
|
|
├── {feature}.hpp # public interface
|
|
src/{module}/
|
|
├── types.cpp # implementations
|
|
├── backend_a.cpp # per-variant generators
|
|
├── backend_b.cpp
|
|
└── install.cpp # dispatch + orchestration
|
|
```
|
|
|
|
If you're adding a feature, look at `src/service/` or `src/boot/` for the
|
|
pattern. If your new module doesn't look like those, you're doing it wrong.
|
|
|
|
### 3. Never suppress type safety
|
|
|
|
There is no `as any`, no `@ts-ignore`, no `reinterpret_cast` abuse, and
|
|
no `void*` unless you're talking to the kernel. If the type system is
|
|
fighting you, you're fighting the design. Fix the design.
|
|
|
|
### 4. Use the namespace. All of it.
|
|
|
|
```cpp
|
|
namespace kappa::module {
|
|
// everything goes here
|
|
} // namespace kappa::module
|
|
```
|
|
|
|
No `using namespace std;` at file scope. No anonymous namespaces for
|
|
functions that are used across files — extract to `util.hpp` instead.
|
|
|
|
### 5. Thread safety is not optional
|
|
|
|
The scheduler is multithreaded. If you touch shared state, you own the
|
|
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`
|
|
means, stay out of the scheduler.
|
|
|
|
### 6. Tests are shell scripts. For now.
|
|
|
|
Integration tests live in `test.sh` and `test-init-switch.sh`. They
|
|
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
|
|
./test.sh # 31 tests, must pass
|
|
./test-init-switch.sh # 23 tests, must pass
|
|
```
|
|
|
|
### 7. Backward compatibility is mandatory
|
|
|
|
The `.kap` DSL is the contract. You can add keywords. You cannot remove
|
|
them. You can extend syntax. You cannot break existing configs. If your
|
|
change means someone's `config.kap` stops parsing, it doesn't ship.
|
|
|
|
## How to contribute
|
|
|
|
### Pick something
|
|
|
|
Good first issues:
|
|
- Adding a 6th init system backend
|
|
- Adding a 3rd bootloader backend
|
|
- C++ unit test framework setup
|
|
- Shell completion scripts
|
|
|
|
Ambitious issues:
|
|
- Binary package support (pre-built caches)
|
|
- Remote build farm (distcc-style)
|
|
- Signed package verification
|
|
- Filesystem overlay activation (like Nix profiles)
|
|
|
|
### Send a PR
|
|
|
|
1. Fork the repo
|
|
2. Create a branch: `feat/my-thing` or `fix/my-bug`
|
|
3. Write code that follows the rules above
|
|
4. Run `./test.sh && ./test-init-switch.sh` — both must pass
|
|
5. Open a PR against `main`
|
|
|
|
### PR requirements
|
|
|
|
- Build must pass: `cmake --build build` with zero warnings
|
|
- Tests must pass: both shell test suites
|
|
- No commented-out code. No dead code. No TODO without a date.
|
|
- Commit messages in imperative: `Add runit backend` not `Added runit backend`
|
|
|
|
## What we won't merge
|
|
|
|
- **`systemd`-only features.** If it can't work on at least two init systems,
|
|
it goes in a `systemd` package definition, not in kappa.
|
|
- **Dependency on a specific distro.** Kappa runs on any Linux kernel. No
|
|
hardcoded paths to `/usr/lib/systemd`, no assumptions about `/etc/os-release`.
|
|
- **Abstract nonsense.** FactoryFactoryBuilder patterns. Premature
|
|
generalization. If you need three layers of indirection to add a feature,
|
|
the feature is too complicated.
|
|
- **AI slop.** If it looks like ChatGPT wrote it, it gets rejected. We can
|
|
tell. Write code like a human who's been doing this for a decade.
|
|
|
|
## Communication
|
|
|
|
We don't have a Discord. We don't have a forum. Open an issue. Write a
|
|
clear title, a reproduction case, and what you expected. We'll respond
|
|
when we respond.
|
|
|
|
If you want to propose a major feature, open an issue first. Surprise PRs
|
|
that rewrite half the codebase get closed without review.
|
|
|
|
---
|
|
|
|
Kappa is 0.1.0. Everything is subject to change except the rules above.
|