# zeta-reconstruct zeta-reconstruct — convert Arch Linux packages (binary `.pkg.tar.zst` and source `PKGBUILD`/`.SRCINFO`) into Zeta package format. The tool is a translator. It never runs makepkg, never compiles anything, and never publishes packages. It only converts files and writes them to disk, warning on stderr whenever a dependency or edge case cannot be mapped cleanly. ## Build Requires Go 1.26 or newer. The only external dependency is `github.com/klauspost/compress` (zstd decoding); everything else uses the Go standard library. go build ./cmd/zeta-reconstruct This writes the `zeta-reconstruct` binary into the current directory. To place it next to the sources instead: go build -o ./cmd/zeta-reconstruct/zeta-reconstruct ./cmd/zeta-reconstruct ## Usage ``` $ zeta-reconstruct --help usage: zeta-reconstruct [flags] Commands: arch-binary convert an Arch binary package (.pkg.tar.zst) to Zeta arch-src convert a PKGBUILD/.SRCINFO source recipe to Zeta Flags: --list list registered frontends -h, --help show this help arch-binary flags: --output output directory (default ".") --repo repository base URL (default "https://raw.githubusercontent.com/gretagen/zeta-packages/refs/heads/main") arch-src flags: --output output directory (default ".") --arch target architecture (default "x86_64") ``` `--list` prints the registered frontends: `arch-binary` and `arch-src`. zeta-reconstruct --list zeta-reconstruct arch-binary --output [--repo ] zeta-reconstruct arch-src --output [--arch ] For `arch-binary` the input must end in `.pkg.tar.zst`. For `arch-src` the input may be a `PKGBUILD`, a `.SRCINFO`, or a directory containing either; a `.SRCINFO` is preferred when both are present. ### Outputs - `arch-binary` writes `packages//-.tar.gz` and a `package.lua` manifest beside it, under the `--output` directory. - `arch-src` writes `.recipe` and a generated `build.sh` into the `--output` directory. ### Workflow - The emitted `package.lua` is an archive-mode manifest consumed by `zeta` (the package manager). `zeta` downloads the tarball at the manifest `url`, verifies its `sha256`, and installs it with `strip = 1`. - The emitted `.recipe` plus `build.sh` are consumed by `zeta-makepkg` to build the binary package from source. The recipe declares `build_system = "custom"` and `build_script = "build.sh"`; zeta-makepkg fetches the source, extracts it, and runs the script under `sh` with `DESTDIR` set. ## Field mapping: `.PKGINFO` → `package.lua` | `.PKGINFO` field | `package.lua` field | Notes | | --- | --- | --- | | `pkgname` | `name` | | | `pkgver` | `version` | verbatim, already in epoch+pkgrel form (e.g. `1.0-1`) | | `pkgdesc` | `summary` | | | `url` | n/a | not carried over; the manifest `url` is built from `--repo` plus `packages//-.tar.gz` | | `depend` | `deps` | each relation mapped through the Arch→Zeta name table; dropped deps are skipped with a warning | | n/a | `archive` | `{ strip = 1 }` | | n/a | `sha256` | sha256 of the emitted tarball | Arch metadata members that are not payload (`.BUILDINFO`, `.MTREE`, `.INSTALL`, `.Changelog`) are skipped during extraction. ## Field mapping: `.SRCINFO`/`PKGBUILD` → `.recipe` | source field | recipe field | Notes | | --- | --- | --- | | `pkgname` | `name` | v1 covers exactly one package per recipe | | `pkgver` | `version` | upstream version; `pkgrel` is dropped | | `pkgdesc` | `summary` | falls back to the package name when empty | | `source[0]` | `url` | the text after a `name::` prefix if present, else the whole string; the URL scheme is never stripped | | `sha256sums[0]` | `sha256` | the line is omitted entirely when the value is empty or `SKIP`; a non-hex64 value is dropped with a warning | | `depends` | `deps` | each relation mapped through the Arch→Zeta name table | | n/a | `build_system` | `"custom"` | | n/a | `build_script` | `"build.sh"` | The generated `build.sh` reproduces the PKGBUILD's `prepare()` (if present), `build()` (if present), and `package()` functions with `$pkgdir` pointed at `$DESTDIR`. Function bodies are embedded from the `PKGBUILD` file; a `.SRCINFO`-only input yields stub functions. ## Dependency mapping Each Arch dependency relation is mapped in this order: 1. An optdepend-style description (`name: description`) is stripped back to the name. 2. If the name matches a Zeta package name verbatim (checked against the Zeta package index), it passes through unchanged. Version constraints are preserved; a bare Arch `=` is normalized to `==` (Zeta's canonical form). 3. Otherwise a curated rename table is applied, with a warning. 4. Otherwise, if the name is on the base-system drop list, it is dropped, with a warning. 5. Otherwise it passes through with a warning (nothing is silently lost). ### Renames | Arch | Zeta | | --- | --- | | `zlib` | `libz` | | `xz` | `xz-utils` | | `freetype2` | `freetype` | | `libxkbcommon` | `xkbcommon` | | `libice` | `libICE` | | `libsm` | `libSM` | | `libx11` … `libxxf86vm` | `libX11` … `libXxf86vm` | The X11 family is pure case correction: Arch spells it lowercase (`libx11`, `libxau`, `libxext`, `libxrender`, `libxft`, and the rest of the `libx*` set), while the Zeta index uses `libX*`. Names like `libxcb` and `libxml2` are already correct and are deliberately absent from the table. ### Dropped (base system) These packages are provided outside the package manager, so Zeta has no package for them: `glibc`, `gcc-libs`, `gcc`, `bash`, `coreutils`, `filesystem`, `linux-api-headers`, `systemd`, `util-linux`, `ncurses`, `readline`, `tzdata`, `ca-certificates`. ## Version and epoch - Binary packages keep the `.PKGINFO` `pkgver` verbatim, epoch and pkgrel included (`1.0-1`, or `1:1.0-1` when an epoch exists). - Source recipes use `version = pkgver` (the upstream version); `pkgrel` is dropped, matching how versions appear in the Zeta package index. - An epoch is never folded into the Zeta version. When a `:` epoch is present, a warning is emitted and the version string keeps its epoch form. ## Not yet supported (v1) The following shapes are not yet supported in v1. They produce an explicit error, except where noted: - **Split packages** (more than one `pkgname`): error. - **VCS sources**: `git+`, `svn+`, `hg+`, `bzr+` protocol prefixes, `::` fragments (e.g. `git::https://…`), and dynamic `pkgver()` functions: error. - **Multiple sources** (more than one `source` entry): error. - **Zero sources**: error (a recipe requires a `url`). - **makedepends, optdepends, provides, conflicts, replaces**: parsed but dropped with a warning; Zeta's formats have no fields for them. - **Bash-only constructs in PKGBUILD function bodies** (arrays, `[[ ]]`, `local`, process substitution): the generated `build.sh` carries a warning that it may need manual adjustment. - **Gentoo ebuilds and void-src packages**: not supported. The frontend registry interface is in place, so future converters can be added as new frontends, but no such converter ships in v1.