CRUX Package Keeper is a toolset designed to efficiently manage packages and their sources in CRUX environments.
- Centralized and standardized package + source management.
- Safe reuse of pre-built packages across different machines.
- Clear metadata about the source and build process of each package.
- Native multi-architecture support with explicit architecture identifiers.
In CRUX, binary packages (.pkg.tar.gz, .pkg.tar.bz2, .pkg.tar.xz) are intentionally minimal. While this design keeps packages lightweight, it also comes with some drawbacks:
- No record of the build-time dependencies used during compilation.
- No inclusion of the local sources provided by the port, which are sometimes required to build or properly configure the package.
- No pre-install or post-install scripts that may be required for proper setup.
- No inclusion of the README file that often provides important usage or configuration notes.
- No explicit reference to the target architecture, which makes it harder to manage multi-architecture environments (e.g.,
x86_64,arm64,armhf).
Because of these limitations, binary packages alone are not fully self-descriptive. Installing them without access to the corresponding port source may reduce portability and reliability, as important contextual information is missing.
cpk addresses these issues by embedding the complete port source within the package and extending the package format to include the target architecture in its name. This makes packages:
- Self-contained — all relevant metadata and sources are included.
- Reproducible — rebuilds can be performed reliably using the embedded port.
- Auditable — users can inspect the exact sources and instructions used to build the package.
- Multi-architecture aware — different builds of the same package (e.g.,
pkgname#1.0-1.x86_64.cpk,pkgname#1.0-1.arm64.cpk).
cpk is not a replacement for pkgutils but an extension built on top of it.
All low-level package management tasks (installation, removal, querying, etc.) are still handled by pkgadd, pkgrm, pkginfo, pkgmk and related tools from pkgutils.
What cpk adds on top is:
- A richer package format (
.cpk) that embeds port sources, metadata, and architecture information. - Higher-level commands (
cpk search,cpk verify,cpk diff, etc.) that extend the functionality ofpkgutils. - Improved portability and reproducibility while maintaining full compatibility with the existing CRUX ecosystem.
In short, pkgutils does the heavy lifting, while cpk provides the missing context and metadata.
cpk <command> [options]
Commands:
update Update the index of available packages
info <package> Show information about installed or available packages
search <keyword> Search for packages by name or keyword
list List all installed packages
diff Show differences between installed and available packages
verify <package> Verify integrity of package source files
build <package> Build a package from source files
install <package> Install or upgrade packages on the system
uninstall <package> Remove packages from the system
upgrade Upgrade all installed packages to the latest versions
clean Clean up package source files and temporary directories
index <repo> Create a CPKINDEX file for a local repository
archive <prtdir> <repo> Create .cpk archive(s) from a directory containing ports
help Show this help message
version Show version information
Options:
-c, --config <file> Set an alternative configuration file (default: /etc/cpk.conf)
-r, --root <path> Set an alternative installation root (default: /)
-C, --color Show colorized output messages
-v, --verbose Show verbose output messages
-h, --help Print this help information
-V, --version Print version information
Usage: (no arguments)
- Ensures
CPK_HOME_DIRexists; otherwise prints an error. - Downloads
CPKINDEXfrom${CPK_REPO_URL}/CPKINDEXintoCPK_HOME_DIR. - Counts available packages and prints the total.
Usage: one argument (package name or key)
- Finds the package in
CPKINDEX. - If not yet downloaded, fetches and extracts the
.cpkarchive. - Parses the
Pkgfileand displays fields like Name, Version, Arch, Description, URL, and Dependencies.
Usage: one argument (substring to match)
- Opens
CPKINDEXand searches all lines containing the given term. - Displays all matches in a formatted list, or shows a “no matches found” message.
Usage: (no arguments)
- Runs
pkginfo -ito list installed packages on the system. - Prints a formatted table of package names and versions.
Usage: (no arguments)
- Loads installed packages using
pkginfo -i. - For each one, looks up the version in the remote index (
CPKINDEX). - Shows all entries where the local version differs from the repository version.
Usage: one argument (package name or key)
- Locates the package in the index and downloads it if missing.
- Runs
pkgmk -doto ensure all source files are fetched. - Attempts to verify the
.signatureusing public keys found under/etc/ports/. - Reports success if any key verifies, otherwise shows an error.
Usage: one argument (package name or key)
- Finds the package and downloads/extracts it if needed.
- Runs
pkgmk -dinside the source directory to build the package. - Prints a success message or an error if the build fails.
Usage: one required argument (package name or key), optional --upgrade
- Finds the package in the repository index.
- If already installed:
- Continues only if
--upgradeis specified; otherwise prints a warning. - Ensures the package archive exists locally.
- Executes pre-install and post-install scripts when present.
- Runs
pkgadd -r <CPK_INSTALL_ROOT> [ -u ] <package_file>to install or upgrade. - Displays the README (if available) after installation.
Usage: one argument (package name or key)
- Checks if the package is installed; exits if not.
- Executes
pkgrm -r <CPK_INSTALL_ROOT> <pkgname>to remove it. - Reports errors or success accordingly.
Usage: zero or more package names
- If no arguments: loads all installed packages (bulk upgrade not fully implemented).
- For each package:
- Checks if an update exists in the repo and calls
cpk install --upgradewhen needed. - Skips missing or uninstalled packages and logs them in verbose mode.
- Checks if an update exists in the repo and calls
Usage: (no arguments)
- Scans
CPK_HOME_DIRand removes all files and directories exceptCPKINDEX. - Prints status messages for each deletion and confirms cleanup completion.
Usage: one argument (local repository path)
- Validates that the argument is a directory.
- Rebuild or update the local
CPKINDEX.
Usage: two arguments ( )
- Recursively scans
<portsdir>for built packages (*.pkg.tar.gz, .bz2, .xz). - Reads Pkgfile in each directory to extract name, version, release, and source fields.
- Validates package filename format (
name#version-release.pkg.tar.*). - Copies files and metadata into
<repo>/<name>/<version-release>and creates.cpkarchives. - Prints progress and summary messages (verbose mode supported).
If you want to contribute to this project, feel free to fork the repository, make your changes, and submit a pull request. Contributions from the community are always welcome! See the CONTRIBUTING file for details.
This project is licensed under the GPL-3.0 License. See the LICENSE file for details.