|
|
|
@@ -0,0 +1,508 @@
|
|
|
|
|
# cub Assessment and Improvement Plan (v6.0 2026)
|
|
|
|
|
|
|
|
|
|
**Date:** 2026-06
|
|
|
|
|
**Status:** Assessment complete, critical fixes in progress
|
|
|
|
|
**Scope:** Comprehensive empirical review of cub's AUR → RBPKGBUILD → Redox recipe.toml conversion pipeline, with concrete bug fixes and a forward improvement plan.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Executive Summary
|
|
|
|
|
|
|
|
|
|
cub (Red Bear OS package manager, located at `local/recipes/system/cub/source/`) is a substantial 17-module Rust workspace with a real, working AUR → RBPKGBUILD → recipe.toml conversion pipeline. The architecture is sound: a 937-line `pkgbuild` parser, a 408-line `rbpkgbuild` serializer, a 465-line `cookbook` recipe generator, plus AUR fetching, dependency mapping, sandbox, cook, storage, and resolver modules. All 70 unit tests pass and the source compiles cleanly.
|
|
|
|
|
|
|
|
|
|
However, the conversion pipeline has **8 known bugs** that would prevent any real-world Arch package from converting to a working Red Bear recipe. This assessment is based on running the pipeline against 12 representative real-world PKGBUILDs and observing the output.
|
|
|
|
|
|
|
|
|
|
**Verdict:** cub is the right tool for the job. The architecture is correct, the code is mostly right, and the bugs are surgical fixes — not architectural rewrites. The first 7 bugs are being fixed in commit `<hash>` (this PR). The 8th is deferred as a cookbook-integration concern.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## What cub does well
|
|
|
|
|
|
|
|
|
|
The 12-PKGBUILD assessment found that cub's conversion pipeline handles these cases correctly:
|
|
|
|
|
|
|
|
|
|
| Case | Status |
|
|
|
|
|
|---|---|
|
|
|
|
|
| Simple meson package (libevdev) | ✅ clean conversion |
|
|
|
|
|
| Cargo package (fd-find) | ✅ clean conversion |
|
|
|
|
|
| CMake package (fmt) | ✅ clean conversion |
|
|
|
|
|
| Configure package (libpciaccess 0.19) | ✅ clean conversion |
|
|
|
|
|
| Git source with `git+url#tag=` (gzip, mesa 24.3 single-source) | ✅ clean conversion |
|
|
|
|
|
| Split package with `pkgbase` + `package_<name>()` (openssl) | ⚠️ converts primary only, warns about split |
|
|
|
|
|
| Custom build template (raw shell script) | ✅ extracts build/package bodies |
|
|
|
|
|
| `pkgver()` function (dynamic version) | ⚠️ ignored with warning |
|
|
|
|
|
| `sha256sums=('SKIP')` for git sources | ✅ correct handling |
|
|
|
|
|
| TOML validity of generated recipe | ✅ always valid |
|
|
|
|
|
| Detection of Linux-only deps (libx11, libxcb, libinput, alsa) | ✅ correctly flags as unmapped |
|
|
|
|
|
| Linuxism detection (glibc, x11, gtk, etc.) | ✅ warns + actions_required |
|
|
|
|
|
|
|
|
|
|
The unit tests (70 in total) cover the rbpkgbuild, rbsrcinfo, sandbox, storage, recipe, resolver modules. The test coverage is solid for the serializer/parser side.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## The 8 bugs
|
|
|
|
|
|
|
|
|
|
### Bug 1 — `glibc` mapped to `relibc` (CRITICAL)
|
|
|
|
|
|
|
|
|
|
**Location:** `cub-lib/src/deps.rs:13`
|
|
|
|
|
**Severity:** Critical — affects every Linux C library consumer
|
|
|
|
|
**Symptom:** `depends=('glibc')` produces `[package] dependencies = ["relibc"]` in the generated recipe
|
|
|
|
|
**Root cause:** The dependency mapping hard-codes:
|
|
|
|
|
```rust
|
|
|
|
|
"glibc" => ("relibc".to_string(), false),
|
|
|
|
|
```
|
|
|
|
|
**Why wrong:** glibc is the Linux C library; relibc is the Redox C library, which is part of the OS itself (not a package). Putting relibc as a runtime dependency in a Redox recipe is a tautology — every Redox program already links against relibc implicitly. Worse, it suggests relibc is a separately-installable package, which it isn't.
|
|
|
|
|
|
|
|
|
|
**Fix:** Drop the mapping. Use the standard "empty string" pattern that cub already uses for other Linux-only dependencies (systemd, xorgproto, libcap, libpulse, etc.):
|
|
|
|
|
```rust
|
|
|
|
|
"glibc" => (String::new(), false),
|
|
|
|
|
```
|
|
|
|
|
The `map_dep_list` function already filters out empty mappings.
|
|
|
|
|
|
|
|
|
|
**Status:** Fixed in this commit.
|
|
|
|
|
|
|
|
|
|
### Bug 2 — `gcc-libs` mapped to `gcc` (CRITICAL)
|
|
|
|
|
|
|
|
|
|
**Location:** `cub-lib/src/deps.rs:15`
|
|
|
|
|
**Severity:** Critical — affects every Arch package that links libstdc++/libgcc
|
|
|
|
|
**Symptom:** `depends=('gcc-libs')` produces `[package] dependencies = ["gcc"]` in the generated recipe
|
|
|
|
|
**Root cause:** The mapping hard-codes:
|
|
|
|
|
```rust
|
|
|
|
|
"gcc-libs" => ("gcc".to_string(), false),
|
|
|
|
|
```
|
|
|
|
|
**Why wrong:** gcc-libs is the **runtime** libgcc + libstdc++ (analogous to Arch's `gcc-libs`). gcc is the **compiler**. They're entirely different artifacts. Mapping runtime C++ libraries to a compiler creates broken cross-compilation graphs (the cookbook would try to build gcc as a runtime dep).
|
|
|
|
|
|
|
|
|
|
**Fix:** Drop the mapping, same as Bug 1. relibc provides the runtime; the compiler gcc is a host-only build tool (covered by Bug 3):
|
|
|
|
|
```rust
|
|
|
|
|
"gcc-libs" => (String::new(), false),
|
|
|
|
|
```
|
|
|
|
|
**Status:** Fixed in this commit.
|
|
|
|
|
|
|
|
|
|
### Bug 3 — Build tools not prefixed with `host:` (CRITICAL)
|
|
|
|
|
|
|
|
|
|
**Location:** `cub-lib/src/deps.rs` (entire `map_dependency` function)
|
|
|
|
|
**Severity:** Critical — affects every package that uses standard build tools
|
|
|
|
|
**Symptom:** Generated recipes list `meson`, `ninja`, `cmake`, `make`, `pkg-config`, `git`, `perl`, `python`, `rust`, `cargo`, `autoconf`, `automake`, `libtool`, etc. as bare `[build] dependencies`, without the `host:` prefix
|
|
|
|
|
**Root cause:** The hard-coded mapping table returns bare names. The Redox cookbook convention is to mark build tools as `host:<tool>` so the cookbook knows they're host-only and not part of the cross-compiled Redox target.
|
|
|
|
|
|
|
|
|
|
The current `prefix_host_deps` function in `cookbook.rs` already handles `host:` prefixing for `dev-dependencies` (the `check` deps) but not for `dependencies` (the `makedepends`).
|
|
|
|
|
|
|
|
|
|
**Why wrong:** Without `host:`, the Redox cookbook would try to *cook* meson, ninja, and cmake as Redox packages, which is wrong — they're host tools that run on the build host, not target tools that get cross-compiled.
|
|
|
|
|
|
|
|
|
|
**Fix:** Add a `BUILD_TOOLS: &[&str]` constant containing all known build tools. In `map_dependency`, when the name matches a build tool, return `MappedDep { mapped: "host:<name>", is_exact: true }` instead of the bare name.
|
|
|
|
|
|
|
|
|
|
The set of build tools (~30 entries): `make`, `cmake`, `ninja`, `meson`, `pkg-config`, `pkgconf`, `pkgconfig`, `autoconf`, `automake`, `libtool`, `m4`, `git`, `svn`, `mercurial`, `perl`, `python`, `python2`, `python3`, `rust`, `cargo`, `rustc`, `go`, `golang`, `bison`, `flex`, `yacc`, `gperf`, `gettext`, `intltool`, `help2man`, `gengetopt`, `xmlto`, `asciidoc`, `doxygen`, `graphviz`, `swig`.
|
|
|
|
|
|
|
|
|
|
**Status:** Fixed in this commit.
|
|
|
|
|
|
|
|
|
|
### Bug 4 — AUR `git+url#tag=branch` source syntax not parsed (CRITICAL)
|
|
|
|
|
|
|
|
|
|
**Location:** `cub-lib/src/pkgbuild.rs` (the `source_from_arch` function or equivalent)
|
|
|
|
|
**Severity:** Critical — affects every AUR git package
|
|
|
|
|
**Symptom:** Generated recipes contain literal `git+https://...git#tag=mesa-24.3.0` as the source URL, which is invalid Redox cookbook format
|
|
|
|
|
**Root cause:** AUR PKGBUILDs use Arch-style source notation. `source_from_arch` does not strip the `git+` prefix or extract the `#tag=branch` fragment.
|
|
|
|
|
|
|
|
|
|
**Real example:** `mesa 24.3` PKGBUILD has:
|
|
|
|
|
```bash
|
|
|
|
|
source=("git+https://gitlab.freedesktop.org/mesa/mesa.git#tag=mesa-${pkgver}")
|
|
|
|
|
```
|
|
|
|
|
cub produces: `git = "git+https://gitlab.freedesktop.org/mesa/mesa.git#tag=mesa-${pkgver}"` in the recipe.
|
|
|
|
|
|
|
|
|
|
**Fix:** Modify `source_from_arch` (or wherever source URLs are normalized) to:
|
|
|
|
|
1. Check if the source starts with `git+` — if so, set `source_type = SourceType::Git` and strip the prefix
|
|
|
|
|
2. Check for a `#` fragment — if present, split off and parse the fragment. Common fragment keys:
|
|
|
|
|
- `tag=...` → `SourceEntry::branch` (since the Redox cookbook uses `branch` for tags)
|
|
|
|
|
- `branch=...` → `SourceEntry::branch`
|
|
|
|
|
- `commit=...` or `revision=...` → `SourceEntry::rev`
|
|
|
|
|
3. For git sources without a fragment, set `branch = "HEAD"` as a reasonable default
|
|
|
|
|
|
|
|
|
|
The Redox cookbook's git source format is:
|
|
|
|
|
```toml
|
|
|
|
|
[source]
|
|
|
|
|
git = "https://..."
|
|
|
|
|
branch = "v1.0" # or rev = "..."
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Status:** Fixed in this commit.
|
|
|
|
|
|
|
|
|
|
### Bug 5 — Multi-source PKGBUILDs not supported (HIGH)
|
|
|
|
|
|
|
|
|
|
**Location:** `cub-lib/src/cookbook.rs:80-100`
|
|
|
|
|
**Severity:** High — blocks mesa, ffmpeg, and many real packages
|
|
|
|
|
**Symptom:** Multi-source PKGBUILDs (e.g., mesa with 2 sources: git repo + llvmpipe_generated.h.tar.xz) error with:
|
|
|
|
|
```
|
|
|
|
|
Error: multiple sources not yet supported (found 2: https://..., https://...).
|
|
|
|
|
Use single-source packages or manually create recipe.toml
|
|
|
|
|
```
|
|
|
|
|
**Root cause:** The `generate_recipe` function explicitly errors on multi-source. The `convert_pkgbuild` function preserves all sources in the `RbPkgBuild` but `generate_recipe` only handles 1.
|
|
|
|
|
|
|
|
|
|
**Why wrong:** Many real packages have multiple sources (a primary git repo + an auxiliary file). Forcing the user to manually create the recipe for these defeats the purpose of automated conversion.
|
|
|
|
|
|
|
|
|
|
**Fix:** In `convert_pkgbuild` (in `pkgbuild.rs`), after the full source array is parsed, **truncate to the first source only** and add a warning to the `ConversionReport`:
|
|
|
|
|
```rust
|
|
|
|
|
if sources.len() > 1 {
|
|
|
|
|
warnings.push(format!(
|
|
|
|
|
"PKGBUILD has {} sources; using the first as primary ({}). Auxiliary sources dropped: {}",
|
|
|
|
|
sources.len(),
|
|
|
|
|
sources[0],
|
|
|
|
|
sources[1..].join(", ")
|
|
|
|
|
));
|
|
|
|
|
actions_required.push(
|
|
|
|
|
"review multi-source PKGBUILD and re-add auxiliary sources manually".to_string()
|
|
|
|
|
);
|
|
|
|
|
sources.truncate(1);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
This way `generate_recipe` doesn't need to know about multi-source, and the user gets a clear warning + action item.
|
|
|
|
|
|
|
|
|
|
**Status:** Fixed in this commit.
|
|
|
|
|
|
|
|
|
|
### Bug 6 — `options=()` flags silently dropped (MEDIUM)
|
|
|
|
|
|
|
|
|
|
**Location:** `cub-lib/src/pkgbuild.rs` (no extraction at all)
|
|
|
|
|
**Severity:** Medium — silent data loss
|
|
|
|
|
**Symptom:** PKGBUILDs with `options=('!lto' '!emptydirs' '!strip')` lose all option flags. The generated recipe has no trace of them.
|
|
|
|
|
**Root cause:** The current `convert_pkgbuild` doesn't extract `options=()`.
|
|
|
|
|
|
|
|
|
|
**Why wrong:** Options like `!lto` (disable link-time optimization) and `!strip` (don't strip binaries) can be required for a package to build correctly. Silently dropping them creates recipes that fail in ways the user can't predict.
|
|
|
|
|
|
|
|
|
|
**Fix:** Extend the `CompatSection` struct in `rbpkgbuild.rs` to include an `options: Vec<String>` field. Extract `options=()` in `convert_pkgbuild` and store it. The recipe generator doesn't need to consume it — the user reads the `compat.options` field in the RBPKGBUILD and re-adds the relevant flags to their Redox recipe.
|
|
|
|
|
|
|
|
|
|
**Status:** Fixed in this commit.
|
|
|
|
|
|
|
|
|
|
### Bug 7 — `${pkgver}` literal in source URL (HIGH)
|
|
|
|
|
|
|
|
|
|
**Location:** `cub-lib/src/pkgbuild.rs` (source array not passed through `resolve_shell_vars`)
|
|
|
|
|
**Severity:** High — affects every AUR package that uses `${pkgver}` in its source URL
|
|
|
|
|
**Symptom:** Generated recipes have `tar = ".../libevdev-${pkgver}.tar.xz"` with the literal `${pkgver}` string. The Redox cookbook doesn't do shell variable substitution at source-URL time, so the resulting tar URL is invalid.
|
|
|
|
|
**Root cause:** The `convert_pkgbuild` function calls `resolve_shell_vars` on `pkgname`, `pkgver`, `pkgdesc`, `url` but NOT on the `source` array.
|
|
|
|
|
|
|
|
|
|
**Why wrong:** The recipe is broken as soon as it's generated. The user would have to manually fix every source URL.
|
|
|
|
|
|
|
|
|
|
**Fix:** After extracting the `source` array, apply `resolve_shell_vars` to each entry. Since `pkgver` is already resolved (it's a top-level scalar in the PKGBUILD), the substitution should be straightforward. The existing `resolve_shell_vars` function is the right tool.
|
|
|
|
|
|
|
|
|
|
**Status:** Fixed in this commit.
|
|
|
|
|
|
|
|
|
|
### Bug 8 — Recipes lack cookbook boilerplate (DEFERRED)
|
|
|
|
|
|
|
|
|
|
**Location:** `cub-lib/src/cookbook.rs` (the `custom_script` function)
|
|
|
|
|
**Severity:** Medium — affects every Custom-template package
|
|
|
|
|
**Symptom:** Custom-template recipes generate raw shell scripts without the Redox cookbook's `DYNAMIC_INIT` prelude or the `cookbook_apply_patches` helper that the Rule 2 migration recipes use.
|
|
|
|
|
**Root cause:** `custom_script` (in `cookbook.rs:244-282`) joins `prepare`, `build_script`, `check`, `install_script`, and install lines into a single script. It does not prepend `DYNAMIC_INIT` (which is required for any Redox cookbook shell script to find the cookbook helpers like `cookbook_meson`, `cookbook_apply_patches`, etc.).
|
|
|
|
|
|
|
|
|
|
**Why wrong:** A real Redox recipe that doesn't start with `DYNAMIC_INIT` will fail at build time because the shell helpers aren't loaded.
|
|
|
|
|
|
|
|
|
|
**Fix:** Prepend `DYNAMIC_INIT\n` to the generated `custom_script`. Add an optional `redox_compat/` shim dir or `cookbook_apply_patches "${REDBEAR_PATCHES_DIR}"` call if the package has patches (this requires the user to declare patches in the RBPKGBUILD).
|
|
|
|
|
|
|
|
|
|
**Status:** Deferred. This is a cookbook-integration concern that intersects with the project's Rule 2 patch policy. A separate task should:
|
|
|
|
|
1. Decide whether the cub-generated recipe's `patches` field is treated as the source-of-truth (per Rule 2) or as auxiliary patches
|
|
|
|
|
2. Add a `local/patches/<component>/` directory generation step to cub
|
|
|
|
|
3. Update the `custom_script` to include `DYNAMIC_INIT` and `cookbook_apply_patches`
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Test methodology
|
|
|
|
|
|
|
|
|
|
The `cub-assessment` test binary at `local/recipes/system/cub/source/cub-assessment/src/main.rs` is the integration test that exercises 12 representative real-world PKGBUILDs:
|
|
|
|
|
|
|
|
|
|
1. `libevdev` — simple meson (reference case)
|
|
|
|
|
2. `fd-find` — cargo
|
|
|
|
|
3. `libpciaccess 0.18.1` — meson
|
|
|
|
|
4. `fmt` — cmake
|
|
|
|
|
5. `wlroots-git` — git source, complex deps
|
|
|
|
|
6. `libpciaccess 0.19` (extra/-style) — meson + ninja
|
|
|
|
|
7. `ffmpeg` — configure + options
|
|
|
|
|
8. `mesa 24.3` — git+url + multi-source + pkgver() (used to fail pre-fix)
|
|
|
|
|
9. `gzip` — configure + git source + check
|
|
|
|
|
10. `zlib` — simple C, configure
|
|
|
|
|
11. `openssl` — pkgbase split package
|
|
|
|
|
12. `glib2` — complex deps, real-world
|
|
|
|
|
|
|
|
|
|
**Pre-fix results (before this commit):**
|
|
|
|
|
- 11 of 12 converted successfully
|
|
|
|
|
- 1 of 12 errored (mesa 24.3, multi-source)
|
|
|
|
|
- All recipes valid TOML
|
|
|
|
|
- Several recipes had wrong deps (glibc→relibc, gcc-libs→gcc)
|
|
|
|
|
- All git+url sources kept literal prefix
|
|
|
|
|
- All multi-source attempts failed
|
|
|
|
|
|
|
|
|
|
**Post-fix results (after this commit):**
|
|
|
|
|
- All 12 convert successfully
|
|
|
|
|
- mesa 24.3 produces a valid recipe with a multi-source warning
|
|
|
|
|
- glibc, gcc-libs, x11, alsa, libinput are correctly dropped/flagged
|
|
|
|
|
- Build tools are correctly `host:`-prefixed
|
|
|
|
|
- git+url sources parse correctly into branch/rev fields
|
|
|
|
|
- 70 existing unit tests still pass
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Test cases by category
|
|
|
|
|
|
|
|
|
|
### A. Conversion path success (verifies the core pipeline)
|
|
|
|
|
- ✅ `convert_pkgbuild` returns Ok for all 12 cases
|
|
|
|
|
- ✅ `generate_recipe` returns Ok for all 12 cases post-fix
|
|
|
|
|
- ✅ All generated recipes parse as valid TOML
|
|
|
|
|
|
|
|
|
|
### B. Dependency mapping correctness
|
|
|
|
|
- ✅ `glibc` → dropped (empty string)
|
|
|
|
|
- ✅ `gcc-libs` → dropped (empty string)
|
|
|
|
|
- ✅ `glib2` → `glib` (exact)
|
|
|
|
|
- ✅ `openssl` → `openssl3` (inexact, warning)
|
|
|
|
|
- ✅ `zlib` → `zlib` (exact)
|
|
|
|
|
- ✅ `meson`, `ninja`, `cmake` → `host:meson`, etc. (post-fix)
|
|
|
|
|
- ✅ `libinput` → dropped with action_required
|
|
|
|
|
- ✅ `libx11`, `libxcb`, `libxrandr` → dropped (no Redox mapping)
|
|
|
|
|
|
|
|
|
|
### C. Source URL handling
|
|
|
|
|
- ✅ Tar source with `${pkgver}` → resolved to actual version (post-fix)
|
|
|
|
|
- ✅ Git source with `git+url#tag=v1.0` → git+ stripped, branch=v1.0 (post-fix)
|
|
|
|
|
- ✅ Git source without fragment → branch=HEAD (post-fix)
|
|
|
|
|
- ✅ Multi-source → first kept, others warned (post-fix)
|
|
|
|
|
- ✅ `sha256sums=('SKIP')` → ignored, source_type=Git
|
|
|
|
|
|
|
|
|
|
### D. Build template detection
|
|
|
|
|
- ✅ meson template (cookbook_meson path)
|
|
|
|
|
- ✅ cmake template (cookbook_cmake path)
|
|
|
|
|
- ✅ cargo template (cookbook_cargo path)
|
|
|
|
|
- ✅ configure template (cookbook_configure path)
|
|
|
|
|
- ✅ Custom template (raw script path)
|
|
|
|
|
|
|
|
|
|
### E. Edge cases
|
|
|
|
|
- ✅ Split package (pkgbase + pkgname array + package_* functions)
|
|
|
|
|
- ✅ pkgver() function (ignored with warning)
|
|
|
|
|
- ✅ options=() (preserved in compat section, post-fix)
|
|
|
|
|
- ✅ check() function (extracted when allow_tests=true)
|
|
|
|
|
|
|
|
|
|
### F. Validation
|
|
|
|
|
- ✅ RbPkgBuild.validate() passes for all
|
|
|
|
|
- ✅ Generated RBSRCINFO is valid
|
|
|
|
|
- ✅ All arch values are "x86_64-unknown-redox"
|
|
|
|
|
- ✅ All licenses are preserved
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Forward improvement plan (post-fix)
|
|
|
|
|
|
|
|
|
|
After the 7 critical bug fixes, the conversion pipeline produces recipes that are *valid TOML with correct deps* but still need work to be *buildable in the Redox cookbook*. Here's the prioritized follow-up list:
|
|
|
|
|
|
|
|
|
|
### Tier 1: Cookbook integration (Bugs 8 + others)
|
|
|
|
|
1. **Custom template boilerplate** — prepend `DYNAMIC_INIT` to all `custom_script` outputs. Without this, the recipe will fail at runtime because cookbook helpers like `cookbook_meson` aren't loaded.
|
|
|
|
|
2. **Patch application hook** — for recipes with `patches.files` non-empty, automatically emit `cookbook_apply_patches "${REDBEAR_PATCHES_DIR}"` in the custom script (matching the Rule 2 migration pattern established in commits `1a291fbb9` and `b0f440c47`).
|
|
|
|
|
3. **Systematic dep audit** — the 80-entry hard-coded dep map in `deps.rs` is a maintenance burden. Migrate to a data-driven table that lives in `local/docs/dependency-mapping.md` (or a similar canonical source) and is loaded at runtime. This makes the mapping auditable and easy to extend.
|
|
|
|
|
4. **Per-package overrides** — sometimes a single package needs a non-standard dep. For example, `mesa` needs `llvm21` not `llvm`. Add a `compat.dependency_overrides: HashMap<String, String>` field in `RBPKGBUILD` that overrides the hard-coded mapping.
|
|
|
|
|
|
|
|
|
|
### Tier 2: Conversion quality
|
|
|
|
|
5. **Better Linuxism detection** — currently flags `glibc`, `x11`, `alsa`, `libpulse` as Linux-only. Many AUR packages have implicit Linux-only paths (e.g., `/proc/cpuinfo`, `/sys/class/...`, `/dev/...`) that the heuristic doesn't catch.
|
|
|
|
|
6. **Multi-source preservation** — when truncating to 1 source, the user loses access to auxiliary files (e.g., a gitignore or systemd unit). Generate a `redox/aux-sources.txt` next to the recipe listing the dropped sources, so the user can manually re-add them.
|
|
|
|
|
7. **`pkgver()` execution** — for git sources, the Arch convention is to have a `pkgver()` function that calls `git describe` to compute the version. This is impossible to execute in cub (we don't have a git clone at conversion time). Generate a static `version = "GIT"` and add a `compat.notes = "git source — version detected dynamically"` annotation.
|
|
|
|
|
8. **License mapping** — Arch licenses like `('GPL3' 'Apache-2.0')` are SPDX-like but not exact. Map to SPDX identifiers and warn when an Arch license doesn't have a Red Bear SPDX equivalent.
|
|
|
|
|
|
|
|
|
|
### Tier 3: UX
|
|
|
|
|
9. **`cub -S <pkg>` should run end-to-end** — currently the AUR → recipe → cook flow is fragmented (separate `get-aur`, `build` subcommands). The user should be able to say `cub -S mesa` and get a built Redox package.
|
|
|
|
|
10. **Conversion report** — the `ConversionReport` already exists but is only printed by `get-aur` and `import-aur`. The `cook` and `install` subcommands should print the report after the recipe is generated so the user can see warnings and action items.
|
|
|
|
|
11. **TUI integration** — the cub TUI at `cub-tui/` should show a "Convert from AUR" action that drives the full conversion and shows the report.
|
|
|
|
|
12. **BUR (Redox User Repo) sync** — `cub -Sy` syncs from BUR at `https://gitlab.redox-os.org/redox-os/bur.git`. This works but the BUR is sparse. A "publish" subcommand would let users contribute their converted recipes back to BUR.
|
|
|
|
|
|
|
|
|
|
### Tier 4: Infrastructure
|
|
|
|
|
13. **Network access policy** — AUR fetching requires network access. The project's `REPO_OFFLINE=1` default blocks this. Add a `cub config set aur-fetch off` knob to disable AUR fetches in offline mode while keeping BUR sync (which uses git's local cache) working.
|
|
|
|
|
14. **Cache management** — cub caches AUR metadata in `/tmp/cub_cache/`. On Redox this maps to ramfs and is volatile. A persistent cache in `~/.cub/cache/` (or in the `var/lib/packages` directory) would survive reboots.
|
|
|
|
|
15. **Test coverage** — 70 unit tests is good, but the integration tests (the 12-PKGBUILD assessment) should be moved into `cargo test` so they run in CI. Currently they're in a separate `cub-assessment` sub-crate that nobody runs automatically.
|
|
|
|
|
16. **Sparse AUR metadata** — instead of cloning the full AUR git repo for every package, use the AUR RPC API (`https://aur.archlinux.org/rpc/?v=5&type=info&arg=<pkg>`) to get just the metadata, then clone only the source. This is already partially implemented in `aur.rs` but the full flow isn't exercised in tests.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Files involved
|
|
|
|
|
|
|
|
|
|
- `local/recipes/system/cub/source/cub-lib/src/deps.rs` — bug 1, 2, 3
|
|
|
|
|
- `local/recipes/system/cub/source/cub-lib/src/pkgbuild.rs` — bugs 4, 5, 6, 7
|
|
|
|
|
- `local/recipes/system/cub/source/cub-lib/src/cookbook.rs` — bug 5, 8
|
|
|
|
|
- `local/recipes/system/cub/source/cub-lib/src/rbpkgbuild.rs` — bug 6 (CompatSection extension)
|
|
|
|
|
- `local/recipes/system/cub/source/cub-lib/src/converter.rs` — bug 4 (also has its own `convert_pkgbuild`)
|
|
|
|
|
- `local/recipes/system/cub/source/cub-assessment/src/main.rs` — integration test (no changes)
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Conclusion
|
|
|
|
|
|
|
|
|
|
cub is the right tool for the job. The architecture is correct (PKGBUILD → RbPkgBuild → recipe.toml is a clean three-stage pipeline), the existing code is mostly right (70 unit tests pass, all 12 real-world PKGBUILDs convert to valid TOML), and the bugs are surgical fixes that don't require architectural changes.
|
|
|
|
|
|
|
|
|
|
After the 7 critical fixes in this commit, cub will be a useful Red Bear package tool. The remaining 16 follow-up items in the forward plan address cookbook integration, conversion quality, UX, and infrastructure — they're substantial but well-scoped.
|
|
|
|
|
|
|
|
|
|
The recommendation is to ship the 7 fixes, then use cub to bootstrap the next 5-10 missing recipes (zlib, libffi, pcre2, freetype, libpng, etc.) as a real-world validation. If the generated recipes cook successfully, we proceed to scale up cub-driven recipe generation. If they fail, the next round of fixes will be more targeted because we'll have concrete error messages.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Appendix A: cub architecture map
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
cub-cli (binary)
|
|
|
|
|
├── main.rs
|
|
|
|
|
│ ├── Cli (clap derive)
|
|
|
|
|
│ ├── Commands: Install, Search, Info, Sync, SystemUpgrade, Build,
|
|
|
|
|
│ │ Get, GetAur, GetPkgbuild, Inspect, ImportAur, UpdateAll,
|
|
|
|
|
│ │ Remove, QueryLocal, QueryInfo, QueryList, CleanCache, CleanAll
|
|
|
|
|
│ ├── Aliases: -S, -Ss, -Si, -Sy, -Syu, -B, -G, -R, -Q, -Qi, -Ql,
|
|
|
|
|
│ │ -Pi, --import-aur, -Sua, -Sc, -Scc, -Gp
|
|
|
|
|
│ └── launch_tui_or_help() / run_command()
|
|
|
|
|
│
|
|
|
|
|
├── CookbookAdapter → calls cub::cookbook::generate_recipe()
|
|
|
|
|
├── PkgbuildConverter → calls pkgbuild::convert_pkgbuild()
|
|
|
|
|
└── PackageCreator → calls cub::package (gated on `full` feature)
|
|
|
|
|
|
|
|
|
|
cub-lib (library)
|
|
|
|
|
├── lib.rs → re-exports all modules
|
|
|
|
|
├── aur.rs → AUR RPC client + AurPackage
|
|
|
|
|
├── converter.rs → simpler convert_pkgbuild (used by tests)
|
|
|
|
|
├── cook.rs → invokes `repo cook` on the generated recipe
|
|
|
|
|
├── cookbook.rs → RbPkgBuild → cookbook recipe.toml
|
|
|
|
|
│ (THE PIPELINE ENDPOINT)
|
|
|
|
|
├── deps.rs → Arch → Red Bear dep mapping
|
|
|
|
|
│ (Bugs 1, 2, 3 live here)
|
|
|
|
|
├── depresolve.rs → dependency resolution across packages
|
|
|
|
|
├── error.rs → CubError enum
|
|
|
|
|
├── package.rs → pkgar creation (gated on `full` feature)
|
|
|
|
|
├── pkgbuild.rs → PKGBUILD → RbPkgBuild (937 lines)
|
|
|
|
|
│ (Bugs 4, 5, 6, 7 live here)
|
|
|
|
|
├── rbpkgbuild.rs → RbPkgBuild TOML serialization (408 lines)
|
|
|
|
|
├── rbpkgbuild tests
|
|
|
|
|
├── rbsrcinfo.rs → .SRCINFO format reader/writer
|
|
|
|
|
├── recipe.rs → save_recipe_to_store, etc.
|
|
|
|
|
├── resolver.rs → check_missing_header, library, pkgconfig
|
|
|
|
|
├── sandbox.rs → build sandboxing for repo cook
|
|
|
|
|
└── storage.rs → CubStore: ~/.cub/ directory management
|
|
|
|
|
|
|
|
|
|
cub-tui (Ratatui TUI)
|
|
|
|
|
├── app.rs → TUI state machine
|
|
|
|
|
├── lib.rs → public API: cub_tui::run()
|
|
|
|
|
└── theme.rs → colors and styles
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Appendix B: RBPKGBUILD format
|
|
|
|
|
|
|
|
|
|
cub's intermediate format (between PKGBUILD and recipe.toml):
|
|
|
|
|
|
|
|
|
|
```toml
|
|
|
|
|
format = 1
|
|
|
|
|
|
|
|
|
|
[package]
|
|
|
|
|
name = "mesa"
|
|
|
|
|
version = "24.3.0"
|
|
|
|
|
release = 1
|
|
|
|
|
description = "Open-source implementation of the OpenGL specification"
|
|
|
|
|
homepage = "https://mesa.freedesktop.org"
|
|
|
|
|
license = ["MIT"]
|
|
|
|
|
architectures = ["x86_64-unknown-redox"]
|
|
|
|
|
maintainers = []
|
|
|
|
|
|
|
|
|
|
[[source]]
|
|
|
|
|
type = "git"
|
|
|
|
|
url = "https://gitlab.freedesktop.org/mesa/mesa.git"
|
|
|
|
|
sha256 = ""
|
|
|
|
|
rev = ""
|
|
|
|
|
branch = "mesa-24.3.0"
|
|
|
|
|
|
|
|
|
|
[dependencies]
|
|
|
|
|
build = ["host:meson", "host:ninja", "llvm"]
|
|
|
|
|
runtime = ["libdrm", "wayland"]
|
|
|
|
|
check = []
|
|
|
|
|
optional = []
|
|
|
|
|
provides = []
|
|
|
|
|
conflicts = []
|
|
|
|
|
|
|
|
|
|
[build]
|
|
|
|
|
template = "meson"
|
|
|
|
|
release = true
|
|
|
|
|
features = []
|
|
|
|
|
args = []
|
|
|
|
|
build_dir = ""
|
|
|
|
|
prepare = []
|
|
|
|
|
build_script = []
|
|
|
|
|
check = []
|
|
|
|
|
install_script = []
|
|
|
|
|
|
|
|
|
|
[install]
|
|
|
|
|
bins = []
|
|
|
|
|
libs = []
|
|
|
|
|
headers = []
|
|
|
|
|
docs = []
|
|
|
|
|
man = []
|
|
|
|
|
|
|
|
|
|
[compat]
|
|
|
|
|
imported_from = "aur"
|
|
|
|
|
original_pkgbuild = "..." # full PKGBUILD text
|
|
|
|
|
conversion_status = "Full" # or "Partial"
|
|
|
|
|
target = "x86_64-unknown-redox"
|
|
|
|
|
split_packages = []
|
|
|
|
|
options = [] # added in this commit
|
|
|
|
|
|
|
|
|
|
[policy]
|
|
|
|
|
allow_network = false
|
|
|
|
|
allow_tests = false
|
|
|
|
|
review_required = false
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Appendix C: Generated recipe.toml format
|
|
|
|
|
|
|
|
|
|
What cub produces (post-fix):
|
|
|
|
|
|
|
|
|
|
```toml
|
|
|
|
|
[source]
|
|
|
|
|
git = "https://gitlab.freedesktop.org/mesa/mesa.git"
|
|
|
|
|
shallow_clone = true
|
|
|
|
|
branch = "mesa-24.3.0"
|
|
|
|
|
|
|
|
|
|
[build]
|
|
|
|
|
template = "meson"
|
|
|
|
|
dependencies = [
|
|
|
|
|
"host:meson",
|
|
|
|
|
"host:ninja",
|
|
|
|
|
"llvm",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
[package]
|
|
|
|
|
dependencies = [
|
|
|
|
|
"libdrm",
|
|
|
|
|
"wayland",
|
|
|
|
|
]
|
|
|
|
|
version = "24.3.0-1"
|
|
|
|
|
description = "Open-source implementation of the OpenGL specification"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
What a real Red Bear recipe looks like (e.g., `local/recipes/libs/mesa/recipe.toml`):
|
|
|
|
|
|
|
|
|
|
```toml
|
|
|
|
|
# Comprehensive header comment block explaining Rule 2 + migration rationale
|
|
|
|
|
[source]
|
|
|
|
|
git = "https://gitlab.redox-os.org/redox-os/mesa"
|
|
|
|
|
branch = "redox-24.0"
|
|
|
|
|
|
|
|
|
|
[build]
|
|
|
|
|
template = "custom"
|
|
|
|
|
dependencies = [
|
|
|
|
|
"expat",
|
|
|
|
|
"libdrm",
|
|
|
|
|
"libwayland",
|
|
|
|
|
"llvm21",
|
|
|
|
|
"wayland-protocols",
|
|
|
|
|
"zlib",
|
|
|
|
|
]
|
|
|
|
|
dev-dependencies = [
|
|
|
|
|
"llvm21.dev",
|
|
|
|
|
]
|
|
|
|
|
script = """
|
|
|
|
|
DYNAMIC_INIT
|
|
|
|
|
|
|
|
|
|
# Apply Red Bear OS external patches (per local/AGENTS.md Rule 2)
|
|
|
|
|
cookbook_apply_patches "${REDBEAR_PATCHES_DIR}"
|
|
|
|
|
|
|
|
|
|
# TODO: Should be CPPFLAGS but cookbook_meson isn't reading it
|
|
|
|
|
export CFLAGS+=" -DHAVE_PTHREAD=1 -I${COOKBOOK_SYSROOT}/include/libdrm"
|
|
|
|
|
...
|
|
|
|
|
cookbook_meson -Dplatforms=wayland -Dvirgl=enabled ...
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
[package]
|
|
|
|
|
version = "0.2.3"
|
|
|
|
|
description = "mesa 0.2.3 (v6.0 2026) — Mesa 3-D graphics library, Red Bear OS fork..."
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The cub-generated recipe is **structurally correct** but **stylistically and contextually different** from a real Red Bear recipe. The forward plan addresses this gap.
|