diff options
| author | emmett1 <me@emmett1.my> | 2026-05-29 23:40:06 +0800 |
|---|---|---|
| committer | emmett1 <me@emmett1.my> | 2026-05-29 23:40:06 +0800 |
| commit | 49717b9544bacbcd38a10b791adcb4a4aa2e9162 (patch) | |
| tree | d032595b7f70de43df9e485ce7da196bb125aee3 | |
| parent | 53900763c5574fe60beb877dda57ea76941f7cec (diff) | |
| download | autils-49717b9544bacbcd38a10b791adcb4a4aa2e9162.tar.gz autils-49717b9544bacbcd38a10b791adcb4a4aa2e9162.zip | |
updates
| -rw-r--r-- | INSTALL.sh | 11 | ||||
| -rw-r--r-- | Makefile | 30 | ||||
| -rw-r--r-- | README.md | 215 | ||||
| -rwxr-xr-x | apkg | 73 | ||||
| -rwxr-xr-x | apkg-bin | 233 | ||||
| -rwxr-xr-x[-rw-r--r--] | apkg-genabuild | 0 | ||||
| -rwxr-xr-x | apkg-outdated | 32 | ||||
| -rwxr-xr-x | apkg-reposync | 73 | ||||
| -rw-r--r-- | man/apkg-chroot.8 | 42 | ||||
| -rw-r--r-- | man/apkg-clean.8 | 36 | ||||
| -rw-r--r-- | man/apkg-deps.8 | 33 | ||||
| -rw-r--r-- | man/apkg-foreign.8 | 29 | ||||
| -rw-r--r-- | man/apkg-genabuild.8 | 35 | ||||
| -rw-r--r-- | man/apkg-orphan.8 | 29 | ||||
| -rw-r--r-- | man/apkg-purge.8 | 32 | ||||
| -rw-r--r-- | man/apkg-redundantdeps.8 | 35 | ||||
| -rw-r--r-- | man/apkg.8 | 368 | ||||
| -rw-r--r-- | man/apkg.conf.md | 45 | ||||
| -rw-r--r-- | man/apkg.md | 72 | ||||
| -rw-r--r-- | man/make-man.sh | 32 | ||||
| -rw-r--r-- | man/man5/apkg.conf.5 | 86 | ||||
| -rw-r--r-- | man/man8/apkg.8 | 181 | ||||
| -rw-r--r-- | man/man8/revdep.8 | 34 | ||||
| -rw-r--r-- | man/reposync.8 | 51 | ||||
| -rw-r--r-- | man/revdep.8 | 38 | ||||
| -rw-r--r-- | man/revdep.md | 29 | ||||
| -rw-r--r-- | man/updateconf.8 | 49 | ||||
| -rwxr-xr-x | reposync | 63 |
28 files changed, 1087 insertions, 899 deletions
diff --git a/INSTALL.sh b/INSTALL.sh deleted file mode 100644 index d569215..0000000 --- a/INSTALL.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -BINDIR=${DESTDIR}${BINDIR:-/usr/bin} -CONFDIR=${DESTDIR}${CONFDIR:-/etc} - -mkdir -p ${BINDIR} ${CONFDIR} - -install -m755 apkg ${BINDIR} -install -m755 apkg-* ${BINDIR} -install -m755 revdep updateconf reposync ${BINDIR} -install -m644 doc/apkg.conf.readme ${CONFDIR}/apkg.conf diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..303714f --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +PREFIX ?= /usr +BINDIR ?= $(PREFIX)/bin +MANDIR ?= $(PREFIX)/share/man/man8 + +SCRIPTS = apkg \ + apkg-chroot \ + apkg-clean \ + apkg-deps \ + apkg-foreign \ + apkg-genabuild \ + apkg-orphan \ + apkg-purge \ + apkg-redundantdeps \ + reposync \ + revdep \ + updateconf + +.PHONY: all install uninstall + +all: + @echo "Run 'make install' to install autils." + +install: + mkdir -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR) + install -m755 $(SCRIPTS) $(DESTDIR)$(BINDIR) + install -m644 man/*.8 $(DESTDIR)$(MANDIR) + +uninstall: + for f in $(SCRIPTS); do rm -f $(DESTDIR)$(BINDIR)/$$f; done + for f in man/*.8; do rm -f $(DESTDIR)$(MANDIR)/$$(basename $$f); done @@ -1,2 +1,215 @@ # autils -Alice Linux Utilities + +Alice Linux Utilities — a collection of POSIX shell scripts for source-based package management on [Alice Linux](https://codeberg.org/emmett1/alicelinux). + +## Overview + +**apkg** is the core package manager. It reads an `abuild` recipe (a POSIX shell snippet defining the package name, version, sources, and optional build hooks), downloads and verifies source tarballs, auto-detects one of 6 supported build systems, compiles the software, post-processes the result (strip binaries, compress man pages, install runit services), packages it into the `.spm` format, and installs or upgrades the package via the **spm**(8) backend. + +A set of `apkg-*` helper scripts handle binary package management, dependency analysis, repo syncing, orphan detection, cleanup, and more. Standalone utilities cover reverse-dependency checking (`revdep`), configuration file merging (`updateconf`), and environment-driven git repository synchronization (`reposync`). + +## Installation + +```sh +make install +``` + +Installs all scripts into `/usr/bin` and man pages into `/usr/share/man/man8`. +Override with `DESTDIR`, `PREFIX`, `BINDIR`, or `MANDIR`. Individual scripts are +self-contained and can be run directly from the source tree for testing. + +## Quick start + +```sh +# Build and install a package (from inside its recipe directory) +cd /path/to/repo/mypkg +apkg -i + +# Install with automatic dependency resolution +apkg -I firefox + +# Search available packages +apkg -s icon + +# List outdated packages on the system +apkg -l + +# Full system upgrade +apkg -U + +# Remove a package and its unneeded dependencies +apkg-purge -p mypkg + +# Find broken library links after an upgrade +revdep + +# Merge .new config files after an upgrade +updateconf +``` + +## Tools + +### Core + +| Tool | Description | +|---|---| +| `apkg` | Build packages from source, resolve dependencies, install/upgrade/remove, search repos, system upgrade | +| `spm` | Low-level `.spm` package installer (external, not in this repo) | + +### Helpers + +| Script | Purpose | +|---|---| +| `apkg-chroot` | Enter a chroot with `/dev`, `/proc`, `/sys`, `/run` bind-mounted | +| `apkg-clean` | List stale `.spm` files and orphaned source tarballs (pipe to `xargs rm`) | +| `apkg-deps` | Show runtime library dependencies of an installed package via `ldd` | +| `apkg-foreign` | List installed packages not found in any configured repo | +| `apkg-genabuild` | Scaffold an `abuild` recipe file from a source URL | +| `apkg-orphan` | List installed packages that have no dependents installed | +| `apkg-purge` | Remove a package and its dependencies that are no longer needed by others (`-p` to actually remove) | +| `apkg-redundantdeps` | Detect transitive dependencies explicitly listed in `depends` files (`-f` to fix) | + +### Standalone utilities + +| Tool | Description | +|---|---| +| `revdep` | Scan system binaries and libraries for missing library links (run after major upgrades) | +| `updateconf` | Interactive `.new` config file merge tool — diff, keep, discard, or edit | +| `reposync` | Git repo sync driven by `REPOSYNC_*` environment variables (no `/etc/apkg.conf` dependency) | + +## The abuild recipe + +An `abuild` file is a POSIX shell snippet sourced by apkg. The directory containing it must have the same name as the `name` variable. + +A minimal recipe: + +```sh +name=mypkg +version=1.2.3 +release=1 +source="https://example.com/$name-$version.tar.gz" +``` + +### Source formats + +The `source` variable accepts five formats: + +| Format | Description | +|---|---| +| `https://example.com/pkg-1.0.tar.gz` | A remote URL | +| `mypkg-1.0.tar.gz::https://example.com/v1.0.tar.gz` | Custom local filename for a remote URL | +| `https://example.com/pkg.tar.gz::noextract` | Download but do not unpack | +| `my-file` | A local file in the recipe directory | +| (empty) | Create a dummy/meta package with only `/usr` | + +### Optional recipe variables + +| Variable | Purpose | +|---|---| +| `build_opt` | Extra flags appended to the auto-detected build system | +| `build_type` | Force a specific build system (`meson_build`, `configure_build`, `cmake_build`, `python_build`, `perlmodule_build`, `makefile_build`) | +| `build_dir` | Subdirectory within the extracted source to enter before building | +| `sv` | Runit service files to install into `/etc/sv` | +| `skip_patch` | Skip automatic `.patch` / `.diff` application | +| `patch_opt` | Options for `patch` (default: `-p1`) | +| `keep_static` | Keep `*.a` static libraries | +| `keep_libtool` | Keep `*.la` libtool archives | +| `keep_locale` | Keep locale files | +| `keep_doc` | Keep documentation | +| `no_strip` | Skip ELF binary stripping | + +### Build hooks + +If a `build()` function is defined, it replaces the auto-detected build system entirely. Use `$SRC` (source extraction directory) and `$PKG` (fakeroot staging directory) to compile and install files. Several `DESTDIR`-style variables are pre-exported: `DESTDIR`, `DEST_DIR`, `INSTALLROOT`, `install_root`, `INSTALL_ROOT`. + +```sh +build() { + ./configure --prefix=/usr + make + make DESTDIR=$PKG install +} +``` + +Without `build()`, optional `prebuild()` and `postbuild()` hooks run before and after the auto-detected build system. + +### Other recipe files + +| File | Purpose | +|---|---| +| `depends` | Dependencies, one per line (`#` for comments) | +| `preinstall` | Script run before the package is built (only during `-i` or `-u`) | +| `postinstall` | Script run after the package is installed or upgraded | +| `.shasum` | Source checksums (auto-generated, regenerate with `apkg -g`) | +| `.files` | Package file list (auto-generated, regenerate with `apkg -k`) | + +## Build systems + +When no `build()` function is defined, apkg auto-detects the build system by checking for these files in order: + +1. **meson.build** — `meson setup` with LTO, PIE, `wrap_mode=nodownload`, `buildtype=plain` +2. **configure** — `./configure --prefix=/usr --sysconfdir=/etc ...` +3. **CMakeLists.txt** — `cmake` with `Release` build type, prefers `ninja` +4. **setup.py** — `python3 setup.py build && install --root=$PKG` +5. **Makefile.PL** — `perl Makefile.PL && make && make install` +6. **Makefile / makefile / GNUmakefile** — raw `make` with standard prefix variables + +See `doc/defaultbuildopts` for the exact flags used by each build system. + +### Post-build processing + +After compilation, apkg automatically: +- Compresses man pages (man1–man8, gzip) and info pages +- Removes common conflict files (`fonts.dir`, `fonts.scale`, `perllocal.pod`, `charset.alias`) +- Removes static libraries (`*.a`), libtool archives (`*.la`), locales, and docs (unless kept via `keep_*`) +- Strips ELF binaries (`--strip-all`), shared objects (`--strip-unneeded`), and static archives (`--strip-debug`) +- Merges `/bin`, `/sbin`, `/usr/sbin` into `/usr/bin` if `APKG_BINMERGE` is set + +## Triggers + +After install or upgrade, apkg can automatically refresh system caches when the package provides relevant files: + +- **fontconfig** — `fc-cache -sf` +- **GDK-Pixbuf** — `gdk-pixbuf-query-loaders --update-cache` +- **GIO modules** — `gio-querymodules /usr/lib/gio/modules` +- **GSettings schemas** — `glib-compile-schemas /usr/share/glib-2.0/schemas` +- **GTK2/GTK3 input methods** — `gtk-query-immodules-2.0/3.0 --update-cache` +- **Icon themes** — `gtk-update-icon-cache` +- **udev hardware database** — `udevadm hwdb --update` +- **X font indices** — `mkfontdir` / `mkfontscale` +- **Desktop MIME cache** — `update-desktop-database` +- **Shared MIME database** — `update-mime-database /usr/share/mime` + +Run `apkg -t` to trigger these manually for all installed packages. + +## Environment variables + +### apkg + +| Variable | Default | Purpose | +|---|---|---| +| `APKG_REPO` | `$PWD` | Space-separated repo directories (first match wins) | +| `APKG_PACKAGE_DIR` | `$PWD` | Where built `.spm` files are stored | +| `APKG_SOURCE_DIR` | `$PWD` | Source tarball cache directory | +| `APKG_WORK_DIR` | `$PWD` | Build working tree (extraction + fakeroot) | +| `APKG_ROOT` | `/` | Alternative install root | +| `APKG_NOPROMPT` | (unset) | Skip confirmation prompt (for scripting) | +| `APKG_KEEP_WORKDIR` | (unset) | Keep build tree on failure (for debugging) | +| `APKG_ALIAS` | (unset) | Dependency substitution: `real:alias` pairs | +| `APKG_MASK` | (unset) | Packages to skip during `-l` and `-U` | +| `APKG_BINMERGE` | (unset) | Merge bin/sbin dirs into `/usr/bin` | +| `APKG_LOG` | (unset) | Enable build logging | +| `APKG_LOG_DIR` | (unset) | Log file directory (filename: `$name.log`) | + +### reposync + +| Variable | Format | Purpose | +|---|---|---| +| `REPOSYNC_<name>` | `url\|branch\|path` | Define a git repo to sync | + +## Bugs + +Issue tracker: [codeberg.org/emmett1/autils/issues](https://codeberg.org/emmett1/autils/issues) + +## License + +See [LICENSE](./LICENSE). @@ -5,12 +5,13 @@ # \ \_\ \_\\ \_\ \ \_\ \_\\ \_____\ # \/_/\/_/ \/_/ \/_/\/_/ \/_____/ # -# APKG - Alice Package Manager (C) 2023-2025 Emmett1 +# APKG - Alice Package Manager (C) 2023-2026 Emmett1 # fetch_src() { [ "$source" ] || return 0 for i in $source; do + unset resume i=${i%::noextract} case $i in *::*) sn=${i%::*};; @@ -239,8 +240,9 @@ build_src() { fi elif [ -d $name-$version ]; then build_dir=$name-$version - elif [ -d "$(ls -1 --group-directories-first | head -n1)" ]; then - build_dir=$(ls -1 --group-directories-first | head -n1) + elif [ -d "$(ls -1d */ 2>/dev/null | head -n1)" ]; then + build_dir=$(ls -1d */ 2>/dev/null | head -n1) + build_dir=${build_dir%/} fi # cd into extracted source directory @@ -291,13 +293,14 @@ build_src() { esac rm -rf $m done - for i in $(find $PKG/usr/share/man -type f); do - [ $i = ${i%%.gz} ] || continue - gzip -9 $i + find $PKG/usr/share/man -type f | while IFS= read -r i; do + [ "$i" = "${i%%.gz}" ] || continue + gzip -9 "$i" done - for i in $(find $PKG/usr/share/man -type l) ; do - ln -s $(readlink $i).gz ${i%.gz}.gz - rm $i + find $PKG/usr/share/man -type l | while IFS= read -r i; do + [ "$i" = "${i%%.gz}" ] || continue + ln -s "$(readlink "$i").gz" "${i%.gz}.gz" + rm "$i" done fi @@ -333,9 +336,14 @@ build_src() { # strip binaries and libraries if [ ! "$no_strip" ]; then - find $PKG | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs ${CROSS_COMPILE}strip --strip-all 2>/dev/null - find $PKG | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs ${CROSS_COMPILE}strip --strip-unneeded 2>/dev/null - find $PKG | xargs file | grep "current ar archive" | cut -f 1 -d : | xargs ${CROSS_COMPILE}strip --strip-debug 2>/dev/null + find $PKG -type f -exec file {} + | while read -r line; do + f=${line%%: *} + case $line in + *ELF*executable*) ${CROSS_COMPILE}strip --strip-all "$f" 2>/dev/null;; + *ELF*shared\ object*) ${CROSS_COMPILE}strip --strip-unneeded "$f" 2>/dev/null;; + *current\ ar\ archive*) ${CROSS_COMPILE}strip --strip-debug "$f" 2>/dev/null;; + esac + done fi # usrmerge @@ -369,28 +377,17 @@ build_src() { ret 1 fi - # temporary: for backward compatibility - if [ "$(grep '#MARKER' /usr/bin/spm)" ]; then - cd $PKG - spm -b $packagefile || { - msg "Failed packaging $packagefile" - ret 1 - } - else - cd $APKG_PACKAGE_DIR - spm -b $PKG && { - mv package.spm $packagefile - } || { - msg "Failed packaging $packagefile" - ret 1 - } - fi + cd $PKG + spm -b $packagefile || { + msg "Failed packaging $packagefile" + ret 1 + } + cd - >/dev/null - if [ ! -f "$apkg_list" ] || [ "$apkg_build" -nt "$apkg_list" ]; then + if [ ! -f "$apkg_list" ] || [ -n "$(find "$apkg_build" -newer "$apkg_list")" ]; then pkg_updatefiles fi - cd $HERE remove_workdir } @@ -429,11 +426,11 @@ checkdep() { [ -s $SPM_PKGDB/$ii ] && continue fi # if deps already in process list, skip, cycle deps detected - printf "%s\n" $process | tr ' ' '\n' | grep -qx $ii && continue + printf "%s\n" $process | tr ' ' '\n' | grep -Fxq "$ii" && continue # skip if itself in depends list [ "$ii" = "$1" ] && continue # skip if pkg already in deps list - printf "%s\n" $DEPS | tr ' ' '\n' | grep -x $ii && continue + printf "%s\n" $DEPS | tr ' ' '\n' | grep -Fx "$ii" && continue # check deps checkdep $ii done @@ -444,7 +441,7 @@ checkdep() { pkg_deplist() { for i in $@; do # if already have in list deps, dont check again - if [ ! $(printf "%s\n" $DEPS | tr ' ' '\n' | grep -x $i) ]; then + if [ ! $(printf "%s\n" $DEPS | tr ' ' '\n' | grep -Fx "$i") ]; then checkdep $i fi done @@ -462,7 +459,7 @@ pkg_dependents() { for r in $APKG_REPO; do rr="$rr $r/*/depends" done - grep -x $1 $rr 2>/dev/null | rev | cut -d / -f 2 | rev + grep -Fx "$1" $rr 2>/dev/null | rev | cut -d / -f 2 | rev } pkg_depends() { @@ -487,7 +484,7 @@ pkg_outdate() { verbose=1 pkg_allinstalled | while read -r n v; do if [ "$mask" ]; then [ "$APKG_MASK" ] && { - printf "%s\n" "$APKG_MASK" | tr ' ' '\n' | grep -xq $n && continue + printf "%s\n" "$APKG_MASK" | tr ' ' '\n' | grep -Fxq "$n" && continue } fi [ "$(pkg_path $n)" ] || continue @@ -515,7 +512,7 @@ pkg_sysup() { msg "Solving dependencies..." for p in $(pkg_deplist $od); do [ -s $SPM_PKGDB/$p ] || ni="$ni $p" - printf "%s\n" $od | tr ' ' '\n' | grep -qx $p && pu="$pu $p" + printf "%s\n" $od | tr ' ' '\n' | grep -Fxq "$p" && pu="$pu $p" done if [ "$ni" ]; then newpkg=$(printf "%s\n" $ni | tr ' ' '\n' | wc -l) @@ -551,7 +548,7 @@ pkg_search() { } } -pkg_depinstalll() { +pkg_depinstall() { needroot for p in $@; do if [ -s $SPM_PKGDB/$p ]; then @@ -822,7 +819,7 @@ updateopts() { parseopts() { while [ "$1" ]; do case $1 in - -I) pkg_depinstalll "$(parsesubopt "$@")"; exit 0;; + -I) pkg_depinstall "$(parsesubopt "$@")"; exit 0;; -D) pkg_deplist "$(parsesubopt "$@")"; exit 0;; -r) pkg_remove "$(parsesubopt "$@")"; exit 0;; -p) pkg_path "$(parsesubopt "$@")"; exit 0;; diff --git a/apkg-bin b/apkg-bin deleted file mode 100755 index 75bac29..0000000 --- a/apkg-bin +++ /dev/null @@ -1,233 +0,0 @@ -#!/bin/sh -# apkg-bin - a simple binary package manager helper script - -REMOTE="${REMOTE:-https://emmett1.my/pub/alice/packages}" -PKGDIR="${PKGDIR:-/var/cache/apkg-bin}" -REPODB="${REPODB:-REPO}" -DBFILE="$PKGDIR/$REPODB" - -usage() { - echo "Usage: $0 [options]" - echo " g <path> Generate database from package dir" - echo " S Sync database from remote server" - echo " l List packages" - echo " s <pattern> Search packages" - echo " a <pkg> Show package info" - echo " d <pkg...> Download package(s)" - echo " i <pkg...> Install package(s)" - echo " u <pkg...> Upgrade/reinstall package(s)" - echo " c Clean mismatched/unknown packages" - exit 0 -} - -msg() { - m=${pkg%#*} - echo "[${m:-...}] $*" -} - -pkg_existence() { - need_db - [ "$(cut -d '#' -f1 "$DBFILE" | grep -x "$1" | uniq)" ] || return 1 - return 0 -} - -get_pkg() { - for p in $@; do - pkg_existence $p && pkg="$pkg $p" || msg "No package found matching: $p" - done -} - -get_entry() { - entry=$(grep ^$1# "$DBFILE" | sort -V -t'#' -k2 | tail -n1) -} - -need_db() { - [ -f "$DBFILE" ] || { msg "Run '$0 S' first to sync database."; exit 1; } -} - -need_root() { - [ $(id -u) = 0 ] || { msg "This option need root access."; exit 1; } -} - -fetch_pkg() { - get_entry $1 - expected_sha=$(echo "$entry" | cut -d'|' -f4) - pkg=$(echo "$entry" | cut -d'|' -f1) - - mkdir -p "$PKGDIR" - if [ -f "$PKGDIR/$pkg" ]; then - msg "$PKGDIR/$pkg found." - else - url="$REMOTE/$(echo "$pkg" | sed 's/#/%23/g')" - msg "Downloading $url..." - curl -fsSLo "$PKGDIR/$pkg" "$url" || { msg "Download failed: $pkg" >&2; return 1; } - fi - - actual_sha=$(sha256sum "$PKGDIR/$pkg" | awk '{print $1}') - if [ "$expected_sha" = "$actual_sha" ]; then - msg "Verification PASSED: $pkg" - else - msg "Verification FAILED: $pkg" >&2 - rm -f "$pkg" - return 1 - fi - - if [ "$mode" ]; then - spm $mode "$PKGDIR/$pkg" - fi -} - -generate_db() { - [ -d "$1" ] || { msg "Invalid path: $1"; exit 1; } - > "$1/$REPODB" - msg "Generating database, please wait..." - for f in "$1"/*.spm; do - [ -f "$f" ] || continue - size=$(stat -c%s "$f") - mtime=$(stat -c%Y "$f") - sha=$(sha256sum "$f" | awk '{print $1}') - name=$(basename "$f") - echo "$name|$size|$mtime|$sha" >> "$1/$REPODB" - done - msg "Database generated at $1/$REPODB" -} - -sync_db() { - need_root - mkdir -p "${DBFILE%/*}" - msg "Downloading database $REMOTE/$REPODB" - curl -fsSo "$DBFILE" "$REMOTE/$REPODB" || { msg "Failed to sync $REPODB"; exit 1; } - msg "Database synced to $DBFILE" -} - -list_pkg() { - need_db - cut -d'|' -f1 "$DBFILE" | sed 's/#/ /g;s/.spm//g' -} - -search_pkg() { - need_db - cut -d '|' -f1 "$DBFILE" | grep -i "$1" | sed 's/#/ /g;s/.spm//g' - exit 0 -} - -info_pkg() { - need_db - get_pkg $@ - for p in $pkg; do - get_entry $p - name=$p - verrel=$(echo "$entry" | cut -d '#' -f2 | sed 's/\.spm.*//') - size=$(echo "$entry" | cut -d '|' -f2) - mtime=$(echo "$entry" | cut -d '|' -f3) - sha=$(echo "$entry" | cut -d '|' -f4) - - # convert size - if [ "$size" -lt 1024 ]; then - hsize="${size} B" - elif [ "$size" -lt 1048576 ]; then - hsize="$(awk "BEGIN{printf \"%.1f\", $size/1024}") KB" - else - hsize="$(awk "BEGIN{printf \"%.1f\", $size/1048576}") MB" - fi - - # convert date - hdate=$(date -d @"$mtime" '+%Y-%m-%d %H:%M:%S') - - echo "Package: $name" - echo "Version: $verrel" - echo "Size: $hsize" - echo "Date: $hdate" - echo "SHA256: $sha" - done -} - -download_pkg() { - need_db - get_pkg $@ - for p in $pkg; do - fetch_pkg $p - done -} - -install_pkg() { - need_root - need_db - get_pkg $@ - for p in $pkg; do - [ "$(spm -a | grep -x $p)" ] && { - msg "Package '$p' is installed, skipped." - } || { - pkg2="$pkg2 $p" - } - done - for p in $pkg2; do - mode='-i' fetch_pkg $p - done -} - -upgrade_pkg() { - need_root - need_db - get_pkg $@ - for p in $pkg; do - [ "$(spm -a | grep -x $p)" ] || { - msg "Package '$p' not installed, skipped." - } && { - pkg2="$pkg2 $p" - } - done - for p in $pkg2; do - mode='-u' fetch_pkg $p - done -} - -clean_pkg() { - need_db - need_root - msg "Checking local packages in $PKGDIR..." - known_pkgs=$(cut -d '|' -f1 "$DBFILE") - for f in "$PKGDIR"/*.spm; do - [ -f "$f" ] || continue - fname=${f##*/} - if echo "$known_pkgs" | grep -qx "$fname"; then - entry=$(grep "^$fname|" "$DBFILE") - expected_size=$(echo "$entry" | cut -d'|' -f2) - expected_sha=$(echo "$entry" | cut -d'|' -f4) - actual_size=$(stat -c%s "$f") - actual_sha=$(sha256sum "$f" | awk '{print $1}') - if [ "$expected_size" != "$actual_size" ] || [ "$expected_sha" != "$actual_sha" ]; then - msg "Mismatch: $fname (removed)" - rm -f "$f" - fi - else - msg "Unknown package: $fname (removed)" - rm -f "$f" - fi - done - msg "Cleanup done." -} - -main() { - if [ ! "$1" ]; then - usage - else - case $1 in - g) generate_db $2 ;; - S) sync_db ;; - l) list_pkg ;; - s) search_pkg $2 ;; - a) shift; info_pkg $@ ;; - d) shift; download_pkg $@ ;; - i) shift; install_pkg $@ ;; - u) shift; upgrade_pkg $@ ;; - c) clean_pkg ;; - *) usage ;; - esac - exit 0 - fi -} - -main $@ - -exit 0 diff --git a/apkg-genabuild b/apkg-genabuild index 1882ec7..1882ec7 100644..100755 --- a/apkg-genabuild +++ b/apkg-genabuild diff --git a/apkg-outdated b/apkg-outdated deleted file mode 100755 index 9963f08..0000000 --- a/apkg-outdated +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - -[ "$1" ] || { - echo "script to check outdated package from repology" - echo " usage: $0 <port path> <port path> ..." - echo - exit 1 -} - -while [ "$1" ]; do - unset curver port - [ -f $1/abuild ] && port=$(realpath $1) - [ "$port" ] || { shift; continue; } - repo=${port%/*}; repo=${repo##*/} - pname=${1##*/} - curver=$(grep ^version= $port/abuild | awk -F = '{print $2}') - [ "$curver" ] || { shift; continue; } - if [ -s $1/outdated ]; then - pname=$(tail -n1 $1/outdated) - else - case $pname in - python-*) pname=python:${pname#python-};; - esac - fi - newver=$(curl -s -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" https://repology.org/badge/latest-versions/$pname.svg | grep middle | sed 's/.*middle">//;s/<.*//;s/,//' | tr ' ' '\n' | tail -n1) - if [ "$newver" = "-" ]; then - echo "$repo/${1##*/} 404 ($curver)" - elif [ "$curver" != "$newver" ]; then - echo "$repo/${1##*/} $newver ($curver)" - fi - shift -done diff --git a/apkg-reposync b/apkg-reposync deleted file mode 100755 index 6b275c1..0000000 --- a/apkg-reposync +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/sh - -APKG_CONF="${APKG_CONF:-/etc/apkg.conf}" -temp_repos_file=$(mktemp) -write_permission=0 - -die() { - [ "$1" ] && echo "error: $1" - rm -f "$temp_repos_file" - exit 1 -} - -find_default_remote() { - cd "${1}" || die "cannot cd to <${1}> the repo" - default_remote=$(git branch --list "$(git branch --show-current)" \ - "--format=%(upstream:remotename)") -} - -find_current_branch() { - cd "${1}" || die "cannot cd to the <${1}> repo" - current_branch=$(git remote show "${default_remote}" | sed -n '/HEAD branch/s/.*: //p') -} - -check_write_permissions() { - random_file=$(find "${1}" -type f -print0 | shuf -z -n 1) - test -w "$random_file" || write_permission=$((write_permission+1)) -} - -source_and_sanity_checks() { -[ ! -e "$(realpath "${APKG_CONF}")" ] && die "There is no configuration file in ${APKG_CONF}! Exiting..." - -. "${APKG_CONF}" - -[ -z "${APKG_REPO}" ] && die "There are no repos configured in $APKG_CONF, exiting..." - -for r in ${APKG_REPO}; do -printf "%s\n" "$r" >> "$temp_repos_file" -check_write_permissions "$r"; done -[ "$write_permission" = 0 ] || die "You need to execute the script as root!" -printf "%s\n" "Configured repos:" && awk ' {print $0} ' "$temp_repos_file" -grep -q "alicelinux/repos/core" "$temp_repos_file" || die "No official repos configured in $APKG_CONF" -} - -sync_official() { - # This assumes the current repo structure. - dir_for_official_repo=$(grep alicelinux/repos/core "$temp_repos_file") - [ -d "$dir_for_official_repo" ] || die "No $dir_for_official_repo exists, exiting..." - dir_for_official_repo=$(echo "$dir_for_official_repo" | sed "s/repos\/core//") - printf "%s\n" "[~> Syncing official repos in <$dir_for_official_repo> ...]" - find_default_remote "$dir_for_official_repo" - find_current_branch "$dir_for_official_repo" - git pull "$default_remote" "$current_branch" || die "Cannot pull from $default_remote/$current_branch for the ofixial repos" - [ "$?" = 0 ] && printf "%s\n" "[~> Successfully synced the <official> repo!]" -} - -sync_or_skip() { - # Remove all official repo lines from the temp_repos_file - unofficial_repos=$(grep -v alicelinux/repos "$temp_repos_file" | tr "\n" " ") - for r in $unofficial_repos; do - if [ -d "$r"/.git ]; then - find_default_remote "$r" - find_current_branch "$r" - git pull "$default_remote" "$current_branch" || die "Cannot pull from $default_remote/$current_branch" - else - printf "%s\n" "[~>Repo in <$r> is not a git repo, skipping...]" - fi - done -} - -source_and_sanity_checks -sync_official -sync_or_skip -[ "$?" = 0 ] && echo "[~> Repo(s) succesfully synced!]" && rm -f "temp_repos_file" diff --git a/man/apkg-chroot.8 b/man/apkg-chroot.8 new file mode 100644 index 0000000..65bdd1d --- /dev/null +++ b/man/apkg-chroot.8 @@ -0,0 +1,42 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.TH APKG-CHROOT 8 +.SH NAME +apkg-chroot \- enter a chroot environment for package building +.SH DESCRIPTION +.LP +\fBapkg-chroot\fR enters a chroot environment suitable for package building and +system maintenance. It mounts the required virtual filesystems (\fI/dev\fR, +\fI/proc\fR, \fI/sys\fR, \fI/run\fR), copies the host's \fI/etc/resolv.conf\fR, +and executes a command inside the chroot (default: \fI/bin/sh\fR). All mounts are +cleaned up on exit. +.SH USAGE +.LP +\f(CRapkg-chroot <chroot-dir> [command]\fR +.PP +If \fIcommand\fR is not specified, \fB/bin/sh\fR is launched. +The script must be run as root. +.SH ENVIRONMENT +.TP +\fBHOME\fR +Set to \fI/root\fR inside the chroot. +.TP +\fBTERM\fR +Passed through from the host. +.TP +\fBPATH\fR +Set to \fI/bin:/usr/bin:/sbin:/usr/sbin\fR. +.SH EXAMPLES +.LP +\f(CRapkg-chroot /mnt/alice\fR - Enter a chroot and launch an interactive shell. +.PP +\f(CRapkg-chroot /mnt/alice apkg -i mypkg\fR - Run apkg inside the chroot. +.SH AUTHORS +.LP +emmett1 \c +.MT me@emmett1.my +.ME +.SH REPORTING BUGS +.LP +Please report bugs and issues in the project issue tracker: \c +.UR https://codeberg.org/emmett1/autils/issues +.UE diff --git a/man/apkg-clean.8 b/man/apkg-clean.8 new file mode 100644 index 0000000..6cca0f2 --- /dev/null +++ b/man/apkg-clean.8 @@ -0,0 +1,36 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.TH APKG-CLEAN 8 +.SH NAME +apkg-clean \- clean up unreferenced package and source files +.SH DESCRIPTION +.LP +\fBapkg-clean\fR scans the package and source directories and prints paths to +files that are no longer referenced by any current package recipe. Output is +intended to be piped to \fBxargs rm\fR for cleanup. +.SH OPTIONS +.TP +\fB-p\fR +Print unreferenced package files (\fI*.spm\fR) only. +.TP +\fB-s\fR +Print unreferenced source files only. +.TP +\fB-h\fR +Print help message. +.SH EXAMPLES +.LP +\f(CRapkg-clean\fR - Print all unreferenced files (packages and sources). +.PP +\f(CRapkg-clean | xargs rm -v\fR - Remove all unreferenced package and source files. +.PP +\f(CRapkg-clean -p | xargs rm\fR - Remove only unreferenced package files. +.SH AUTHORS +.LP +emmett1 \c +.MT me@emmett1.my +.ME +.SH REPORTING BUGS +.LP +Please report bugs and issues in the project issue tracker: \c +.UR https://codeberg.org/emmett1/autils/issues +.UE diff --git a/man/apkg-deps.8 b/man/apkg-deps.8 new file mode 100644 index 0000000..20098f9 --- /dev/null +++ b/man/apkg-deps.8 @@ -0,0 +1,33 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.TH APKG-DEPS 8 +.SH NAME +apkg-deps \- show runtime library dependencies of an installed package +.SH DESCRIPTION +.LP +\fBapkg-deps\fR examines the runtime library dependencies of an installed package. +It uses \fBldd\fR to find shared libraries required by the package's binaries and +libraries, then maps those libraries back to the packages that provide them. +Useful for discovering implicit runtime dependencies that may not be listed +in the package's formal dependency list. +.SH USAGE +.LP +\f(CRapkg-deps <package>\fR +.PP +The package must already be installed on the system. +.SH OUTPUT +.LP +Lists packages that provide shared libraries used by the specified package, +excluding the package itself and common base packages (gcc, musl, binutils, glibc). +.SH EXAMPLES +.LP +\f(CRapkg-deps mypkg\fR - Show runtime library dependencies for mypkg. +.SH AUTHORS +.LP +emmett1 \c +.MT me@emmett1.my +.ME +.SH REPORTING BUGS +.LP +Please report bugs and issues in the project issue tracker: \c +.UR https://codeberg.org/emmett1/autils/issues +.UE diff --git a/man/apkg-foreign.8 b/man/apkg-foreign.8 new file mode 100644 index 0000000..0a2fbe9 --- /dev/null +++ b/man/apkg-foreign.8 @@ -0,0 +1,29 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.TH APKG-FOREIGN 8 +.SH NAME +apkg-foreign \- list installed packages not found in any repository +.SH DESCRIPTION +.LP +\fBapkg-foreign\fR lists all installed packages that are not present in any +configured repository. These "foreign" packages may have been installed +from an external source or whose build recipes have since been removed. +.SH USAGE +.LP +\f(CRapkg-foreign\fR +.PP +The script takes no arguments and produces one package name per line. +.SH EXAMPLES +.LP +\f(CRapkg-foreign\fR - List all foreign packages. +.PP +\f(CRapkg-foreign | wc -l\fR - Count the number of foreign packages. +.SH AUTHORS +.LP +emmett1 \c +.MT me@emmett1.my +.ME +.SH REPORTING BUGS +.LP +Please report bugs and issues in the project issue tracker: \c +.UR https://codeberg.org/emmett1/autils/issues +.UE diff --git a/man/apkg-genabuild.8 b/man/apkg-genabuild.8 new file mode 100644 index 0000000..69124b7 --- /dev/null +++ b/man/apkg-genabuild.8 @@ -0,0 +1,35 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.TH APKG-GENABUILD 8 +.SH NAME +apkg-genabuild \- generate an abuild recipe template from a source URL +.SH DESCRIPTION +.LP +\fBapkg-genabuild\fR generates an \fIabuild\fR template file from a source URL. +It attempts to parse the package name and version from the URL and creates +a directory with a skeleton \fIabuild\fR recipe. +.SH USAGE +.LP +\f(CRapkg-genabuild <url> [name]\fR +.PP +If \fIname\fR is not provided, it is derived from the URL. +Special handling is included for GitHub tag archives, PyPI packages, and +CPAN/Perl packages, which get the appropriate prefix (\fIpython-\fR or \fIperl-\fR). +.SH OUTPUT +.LP +Creates a directory named after the package containing an \fIabuild\fR file +with \fIname\fR, \fIversion\fR, \fIrelease\fR, and \fIsource\fR fields populated. +.SH EXAMPLES +.LP +\f(CRapkg-genabuild https://example.com/pkg-1.2.3.tar.gz\fR - Generate template for a tarball. +.PP +\f(CRapkg-genabuild https://github.com/user/repo/archive/v1.0.tar.gz\fR - Generate template from a GitHub tag archive. +.SH AUTHORS +.LP +emmett1 \c +.MT me@emmett1.my +.ME +.SH REPORTING BUGS +.LP +Please report bugs and issues in the project issue tracker: \c +.UR https://codeberg.org/emmett1/autils/issues +.UE diff --git a/man/apkg-orphan.8 b/man/apkg-orphan.8 new file mode 100644 index 0000000..26b132c --- /dev/null +++ b/man/apkg-orphan.8 @@ -0,0 +1,29 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.TH APKG-ORPHAN 8 +.SH NAME +apkg-orphan \- list orphan packages with no dependents installed +.SH DESCRIPTION +.LP +\fBapkg-orphan\fR lists orphan packages: packages that are installed and +exist in a repository, but have no other installed package depending on them. +These may be safe to remove. +.SH USAGE +.LP +\f(CRapkg-orphan\fR +.PP +The script takes no arguments and produces one package name per line. +.SH EXAMPLES +.LP +\f(CRapkg-orphan\fR - List all orphaned packages. +.PP +\f(CRapkg-orphan | while read p; do apkg -r "$p"; done\fR - Remove all orphaned packages. +.SH AUTHORS +.LP +emmett1 \c +.MT me@emmett1.my +.ME +.SH REPORTING BUGS +.LP +Please report bugs and issues in the project issue tracker: \c +.UR https://codeberg.org/emmett1/autils/issues +.UE diff --git a/man/apkg-purge.8 b/man/apkg-purge.8 new file mode 100644 index 0000000..cbc92cf --- /dev/null +++ b/man/apkg-purge.8 @@ -0,0 +1,32 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.TH APKG-PURGE 8 +.SH NAME +apkg-purge \- remove a package and its unused dependencies +.SH DESCRIPTION +.LP +\fBapkg-purge\fR removes a package and all its dependencies that are no longer +required by any other installed package. This is a "deep" removal compared to +\fBapkg -r\fR which only removes the specified package. +.SH OPTIONS +.TP +\fB-p\fR +Purge (remove from system). Without this flag, the script prints what would be +removed without taking action (dry-run mode). +.TP +\fB-h\fR +Print help message. +.SH EXAMPLES +.LP +\f(CRapkg-purge mypkg\fR - Show what would be removed when purging mypkg. +.PP +\f(CRapkg-purge -p mypkg\fR - Actually purge mypkg and its now-unused dependencies. +.SH AUTHORS +.LP +emmett1 \c +.MT me@emmett1.my +.ME +.SH REPORTING BUGS +.LP +Please report bugs and issues in the project issue tracker: \c +.UR https://codeberg.org/emmett1/autils/issues +.UE diff --git a/man/apkg-redundantdeps.8 b/man/apkg-redundantdeps.8 new file mode 100644 index 0000000..5169e07 --- /dev/null +++ b/man/apkg-redundantdeps.8 @@ -0,0 +1,35 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.TH APKG-REDUNDANTDEPS 8 +.SH NAME +apkg-redundantdeps \- find and fix redundant dependencies +.SH DESCRIPTION +.LP +\fBapkg-redundantdeps\fR finds redundant entries in package dependency files. +A dependency is considered redundant if it is already pulled in by another +listed dependency (transitive dependency). This helps keep \fIdepends\fR files +clean by listing only direct dependencies. +.SH OPTIONS +.TP +\fB-f\fR +Fix mode: remove the redundant dependencies from the \fIdepends\fR files. +Without this flag, the script prints redundant entries without modifying anything. +.TP +\fB-h\fR +Print help message. +.SH EXAMPLES +.LP +\f(CRapkg-redundantdeps mypkg\fR - Check mypkg for redundant dependencies. +.PP +\f(CRapkg-redundantdeps\fR - Check all packages in configured repos. +.PP +\f(CRapkg-redundantdeps -f mypkg\fR - Remove redundant dependencies from mypkg. +.SH AUTHORS +.LP +emmett1 \c +.MT me@emmett1.my +.ME +.SH REPORTING BUGS +.LP +Please report bugs and issues in the project issue tracker: \c +.UR https://codeberg.org/emmett1/autils/issues +.UE diff --git a/man/apkg.8 b/man/apkg.8 new file mode 100644 index 0000000..b810666 --- /dev/null +++ b/man/apkg.8 @@ -0,0 +1,368 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.TH APKG 8 +.SH NAME +apkg \- Alice Linux package build and install tool +.SH DESCRIPTION +.LP +\fBapkg\fR is the package manager for Alice Linux. It builds packages from source +using \fIabuild\fR recipe files and installs them through the \fBspm\fR(8) backend. + +It operates in two modes: when given a package name, it locates the recipe in +\fBAPKG_REPO\fR and processes it; when run from inside a package directory, it +uses the \fIabuild\fR file in the current directory directly. + +The build pipeline is: fetch sources \f[R] checksum verification \f[R] extract +\f[R] auto-detect build system \f[R] patch \f[R] compile \f[R] post-process +(strip, compress man pages, remove conflicts) \f[R] package into \fI.spm\fR +format \f[R] install/upgrade via \fBspm\fR. + +.SH OPTIONS +.TP +\fB\-h\fR +Print help and exit. +.TP +\fB\-i\fR \fI<pkg...>\fR +Build and install package(s). Skips packages already installed. Does not +resolve dependencies; use \fB\-I\fR for that. +.TP +\fB\-I\fR \fI<pkg...>\fR +Install package(s) with all dependencies resolved recursively. Prompts for +confirmation unless \fBAPKG_NOPROMPT\fR is set. +.TP +\fB\-u\fR \fI<pkg...>\fR +Upgrade (rebuild and reinstall) package(s). Skips packages not currently installed. +.TP +\fB\-U\fR +System upgrade. Checks all installed packages for outdated versions, resolves +dependencies for the full upgrade set, installs new packages first, then +upgrades existing ones. Respects \fBAPKG_MASK\fR. +.TP +\fB\-f\fR +Force rebuild even if an existing \fI.spm\fR package file is found. +.TP +\fB\-r\fR \fI<pkg...>\fR +Remove (uninstall) package(s) via \fBspm \-r\fR. Requires root. +.TP +\fB\-o\fR \fI<pkg...>\fR +Download sources only; do not build or install. +.TP +\fB\-d\fR \fI<pkg>\fR +List direct dependencies of a package (from its \fIdepends\fR file). +Respects \fBAPKG_ALIAS\fR. +.TP +\fB\-D\fR \fI<pkg...>\fR +List all dependencies recursively in install order (dependencies before +dependents). Detects and skips dependency cycles. +.TP +\fB\-j\fR \fI<pkg>\fR +List reverse dependencies \-- packages that list the given package in their +\fIdepends\fR file. +.TP +\fB\-p\fR \fI<pkg>\fR +Print the filesystem path to the package's recipe directory. Searches each +directory in \fBAPKG_REPO\fR in order; the first match wins. +.TP +\fB\-s\fR \fI<pattern>\fR +Search for packages by name across all configured repos. With \fB\-v\fR, also +prints the version from the \fIabuild\fR file. +.TP +\fB\-S\fR \fI<pattern>\fR +Search package file lists (the \fI.files\fR files in each repo) for a pattern. +Prints the repo path and matching filename. +.TP +\fB\-a\fR +List all installed packages. With \fB\-v\fR, also prints the installed version. +.TP +\fB\-l\fR +List outdated packages by comparing each installed package's version against +the version available in the repo. Respects \fBAPKG_MASK\fR. +.TP +\fB\-g\fR \fI<pkg>\fR +Generate or update the \fI.shasum\fR checksum file for the package's source files. +Uses \fBsha3sum\fR by default. +.TP +\fB\-k\fR \fI<pkg>\fR +Regenerate the \fI.files\fR file listing from the built \fI.spm\fR package. +.TP +\fB\-t\fR \fI<pkg...>\fR +Run post-install triggers: fontconfig cache, GDK-Pixbuf loaders, GIO modules, +GSettings schemas, GTK2/GTK3 input method modules, icon theme cache, udev +hardware database, X font indices, desktop MIME cache, and shared MIME database. +Only triggers that are relevant to the package's installed files are executed. +With no arguments, triggers all installed packages. +.TP +\fB\-v\fR +Verbose output. Affects \fB\-s\fR (show versions), \fB\-a\fR (show versions), +and \fB\-l\fR (internal use). + +.SH ABUILD RECIPE FORMAT +.LP +An \fIabuild\fR file is a POSIX shell snippet sourced by \fBapkg\fR. The +directory containing it must be named identically to the \fBname\fR variable. + +.SS Required variables +.TP +\fBname\fR +Package name. Must match the parent directory name. +.TP +\fBversion\fR +Upstream version string. Used in source URLs via \fB$name\fR and \fB$version\fR. +.TP +\fBrelease\fR +Integer starting at 1. Increment on each rebuild; reset to 1 when \fBversion\fR +changes. + +.SS Optional variables +.TP +\fBsource\fR +Whitespace-separated list of source files. Five formats are accepted: +.RS +.IP \- 2 +\fI<url>\fR \-- a source tarball URL (e.g. \fIhttps://example.com/$name-$version.tar.gz\fR) +.IP \- 2 +\fI<filename>::<url>\fR \-- custom local filename for the downloaded source +.IP \- 2 +\fI<url>::noextract\fR \-- download but do not unpack +.IP \- 2 +\fI<filename>\fR \-- a local file in the recipe directory (not downloaded) +.IP \- 2 +\fI<filename>::noextract\fR \-- a local file, not extracted +.RE +.IP +If \fBsource\fR is empty, a dummy (meta) package is created containing only +\fI/usr\fR. +.TP +\fBbuild_opt\fR +Extra flags passed to the build system (appended after the defaults). +.TP +\fBsv\fR +Runit service files to install into \fI/etc/sv\fR. Accepts names like \fIrun\fR, +\fIfinish\fR, \fI<name>.run\fR, \fI<name>.finish\fR. +.TP +\fBbuild_type\fR +Force a specific build system. Normally auto-detected; set to one of: +\fImeson_build\fR, \fIconfigure_build\fR, \fIcmake_build\fR, \fIpython_build\fR, +\fIperlmodule_build\fR, \fImakefile_build\fR. +.TP +\fBbuild_dir\fR +Subdirectory within the extracted source to enter before building. +.TP +\fBskip_patch\fR +If set to 1, skip automatic patch application (so \fIbuild()\fR can call +\fBapply_patch\fR manually). +.TP +\fBpatch_opt\fR +Options passed to \fBpatch\fR(1). Default: \fB\-p1\fR. +.TP +\fBkeep_static\fR +If set, keep \fI*.a\fR static libraries (removed by default). +.TP +\fBkeep_libtool\fR +If set, keep \fI*.la\fR libtool archives (removed by default). +.TP +\fBkeep_locale\fR +If set, keep locale files in \fI/usr/share/locale\fR and \fI/usr/lib/locale\fR. +.TP +\fBkeep_doc\fR +If set, keep documentation in \fI/usr/share/doc\fR and \fI/usr/doc\fR. +.TP +\fBno_strip\fR +If set, skip ELF binary and library stripping. + +.SS Build function hooks +.LP +If a \fBbuild()\fR function is defined, it is called directly (in \fBset \-ex\fR +mode) and the auto-detection pipeline is bypassed. \fB$SRC\fR and \fB$PKG\fR +point to the source extraction and fakeroot directories respectively. Several +\fBDESTDIR\fR-style variables are pre-exported for common build systems: +\fBDESTDIR\fR, \fBDEST_DIR\fR, \fBINSTALLROOT\fR, \fBinstall_root\fR, and +\fBINSTALL_ROOT\fR. + +If no \fBbuild()\fR function is present, \fBprebuild()\fR (if any) runs first, +then the auto-detected build system, then \fBpostbuild()\fR (if any). + +.SS Other files in the recipe directory +.TP +\fBdepends\fR +One dependency per line. Lines starting with \fB#\fR are comments. +.TP +\fBpreinstall\fR +Executable script run before the package is built (only during \fB\-i\fR or +\fB\-u\fR). +.TP +\fBpostinstall\fR +Executable script run after the package is installed or upgraded. +.TP +\fB.shasum\fR +Auto-generated checksum file. Regenerate with \fB\-g\fR. +.TP +\fB.files\fR +Auto-generated sorted file list from the package contents. Regenerate with +\fB\-k\fR. + +.SH BUILD SYSTEMS +.LP +When no \fBbuild()\fR function is defined, the build type is auto-detected by +checking for these files in order: +.IP 1. 3 +\fBmeson.build\fR \-- \fBmeson setup\fR with LTO and PIE enabled, +\fBwrap_mode=nodownload\fR, \fBbuildtype=plain\fR +.IP 2. 3 +\fBconfigure\fR \-- \fB./configure --prefix=/usr --sysconfdir=/etc ...\fR +.IP 3. 3 +\fBCMakeLists.txt\fR \-- \fBcmake\fR with \fBRelease\fR build type, +\fBninja\fR preferred over \fBmake\fR +.IP 4. 3 +\fBsetup.py\fR \-- \fBpython3 setup.py build && install --root=$PKG\fR +.IP 5. 3 +\fBMakefile.PL\fR \-- \fBperl Makefile.PL && make && make install\fR +.IP 6. 3 +\fBMakefile\fR, \fBmakefile\fR, or \fBGNUmakefile\fR \-- \fBmake\fR with +standard prefix/sysconfdir variables + +.SS Post-build processing +.LP +After compilation, \fBapkg\fR automatically: +.IP \- 2 +Compresses man pages (gzip, keeps only man[1-8] sections) and info pages +.IP \- 2 +Removes common conflict files (\fIfonts.dir\fR, \fIfonts.scale\fR, +\fIperllocal.pod\fR, \fIcharset.alias\fR) +.IP \- 2 +Removes static libraries (\fI*.a\fR), libtool archives (\fI*.la\fR), +locales, and docs unless the corresponding \fBkeep_*\fR variable is set +.IP \- 2 +Strips ELF executables (\fB\-\-strip-all\fR), shared objects +(\fB\-\-strip-unneeded\fR), and static archives (\fB\-\-strip-debug\fR) +unless \fBno_strip\fR is set +.IP \- 2 +Merges \fI/bin\fR, \fI/sbin\fR, \fI/usr/sbin\fR into \fI/usr/bin\fR if +\fBAPKG_BINMERGE\fR is set +.IP \- 2 +Installs runit service files from the \fBsv\fR variable into \fI/etc/sv\fR + +.SH ENVIRONMENT +.TP +\fBAPKG_REPO\fR +Space-separated list of directories containing package recipes. Searched in +order; the first match wins. Default: current directory. +.TP +\fBAPKG_PACKAGE_DIR\fR +Directory where built \fI.spm\fR packages are stored. Default: current directory. +.TP +\fBAPKG_SOURCE_DIR\fR +Directory for downloaded source tarballs. Default: current directory. +.TP +\fBAPKG_WORK_DIR\fR +Directory for build working trees (subdirectories \fIapkg-src-<name>\fR and +\fIapkg-pkg-<name>\fR are created and cleaned automatically). Default: current +directory. +.TP +\fBAPKG_ROOT\fR +Alternative root directory for installation (e.g. for cross-compilation or +staged installs). Sets \fBSPM_ROOT\fR. Default: \fI/\fR. +.TP +\fBAPKG_KEEP_WORKDIR\fR +If set, do not remove the work directory on build failure (useful for debugging). +.TP +\fBAPKG_NOPROMPT\fR +If set, skip the confirmation prompt in \fB\-I\fR and \fB\-U\fR operations. +.TP +\fBAPKG_ALIAS\fR +Space-separated list of \fIreal:alias\fR pairs for dependency substitution +(e.g. \fIopenssl:libressl\fR makes packages depending on openssl pull libressl). +.TP +\fBAPKG_MASK\fR +Space-separated list of packages to exclude from \fB\-l\fR and \fB\-U\fR. +.TP +\fBAPKG_BINMERGE\fR +If set, merge \fI/bin\fR, \fI/sbin\fR, and \fI/usr/sbin\fR into +\fI/usr/bin\fR during packaging. +.TP +\fBAPKG_LOG\fR +If set, enable build logging. +.TP +\fBAPKG_LOG_DIR\fR +Directory for build log files (log filename is \fI$name.log\fR). +.TP +\fBCFLAGS\fR, \fBCXXFLAGS\fR +Compiler flags used by the cmake build system. +.TP +\fBCROSS_COMPILE\fR +Prefix for the \fBstrip\fR command (e.g. \fIx86_64-linux-musl-\fR). +.TP +\fBCARGO_HOME\fR, \fBGOCACHE\fR +Set inside the build environment for Rust and Go builds respectively. + +.SH FILES +.TP +\fI/var/lib/spm/db/\fR +SPM package database. Each installed package has a file here whose first line +is the installed version-release string. + +.SH EXAMPLES +.LP +Build and install a package: +.RS +\f(CRapkg \-i mypkg\fR +.RE +.LP +Install with automatic dependency resolution: +.RS +\f(CRapkg \-I firefox\fR +.RE +.LP +Full system upgrade: +.RS +\f(CRapkg \-U\fR +.RE +.LP +Search for packages: +.RS +\f(CRapkg \-s icon\fR +.RE +.LP +Find which package owns a file: +.RS +\f(CRapkg \-S libpng.so\fR +.RE +.LP +List outdated packages: +.RS +\f(CRapkg \-l\fR +.RE +.LP +Force rebuild: +.RS +\f(CRapkg \-f jupp\fR +.RE +.LP +Check direct dependencies: +.RS +\f(CRapkg \-d mypkg\fR +.RE + +.SH SEE ALSO +.BR apkg-chroot (8), +.BR apkg-clean (8), +.BR apkg-deps (8), +.BR apkg-foreign (8), +.BR apkg-genabuild (8), +.BR apkg-orphan (8), +.BR apkg-purge (8), +.BR apkg-redundantdeps (8), +.BR reposync (8), +.BR revdep (8), +.BR updateconf (8), +.BR spm (8) + +.SH AUTHORS +.LP +emmett1 \c +.MT me@emmett1.my +.ME + +.SH REPORTING BUGS +.LP +.UR https://codeberg.org/emmett1/autils/issues +.UE diff --git a/man/apkg.conf.md b/man/apkg.conf.md deleted file mode 100644 index d4aa590..0000000 --- a/man/apkg.conf.md +++ /dev/null @@ -1,45 +0,0 @@ -# NAME - -**apkg.conf** - configuration file for apkg - -# DESCRIPTION - -**apkg.conf** is the configuration file for the **apkg** package manager for the alice linux distribution. -It resides by default under `/etc` in an alice linux installation. -The contents are sourced by the **apkg** program and are in the posix shell `key="value"` format. - -# CONFIGURATION KEYS - -- `APKG_NOPROMPT` If set, it enables non-interactive use by disabling user confirmation prompt. -- `APKG_PACKAGE_DIR` Directory where the compiled packages will reside. -- `APKG_SOURCE_DIR` Directory that will hold the downloaded sources. -- `APKG_WORK_DIR` Directory where the actual building process will take place. This happens in subdirectories which are cleaned after completion. -- `APKG_LOG` If set, it enables the creation of a log for the program output. -- `export CFLAGS="<cflags>"` Default <cflags> are *-O3 -march=x86-64 -pipe* -- `export CXXFLAGS="$CFLAGS"` -- `export NINJAJOBS="<-x>"` Replace <-x> with the number of jobs the ninja build system with use. Without this it will use the maximum amount of threads the processor suports. -- `export MAKEFLAGS="-jx"` Replace <x> with the number of jobs the make build system with use. - -EXAMPLES - -``` -### example of a valid apkg.conf ### -export CFLAGS="-O3 -march=x86-64 -pipe" -export CXXFLAGS="$CFLAGS" -export MAKEFLAGS="-j12" -export NINJAJOBS="12" -APKG_REPO="/var/lib/alicelinux/repos/core /var/lib/alicelinux/repos/extra /var/lib/alicelinux/repos/xorg /var/lib/alicelinux/repos/wayland" -APKG_PACKAGE_DIR=/var/cache/pkg -APKG_SOURCE_DIR=/var/cache/src -APKG_WORK_DIR=/var/cache/work -``` - -# AUTHORS - -emmett1 <emmett1.2miligrams@protonmail.com> Author of the program and creator of alice linux. - -mobinmob <mobinmob@disroot.org> Author of the man page. - -# REPORTING BUGS - -**apkg** is in a working stage but also under heavy development. Please report and bugs/issues in the project issue tracker: https://codeberg.org/emmett1/autils/issues diff --git a/man/apkg.md b/man/apkg.md deleted file mode 100644 index a692d1e..0000000 --- a/man/apkg.md +++ /dev/null @@ -1,72 +0,0 @@ -# NAME - -**apkg** - package building tool and package manager for alice linux - -# SYNOPSIS - -**apkg** [-i] [-I] [-d] [-D] [-j] [-u] [-r] [-t] [-U ] [-f] [-o] [-p] [-s] [-g] [-h] [*pkg(s)*] - -# DESCRIPTION - -**apkg** is the package build tool and package installer, along with **spm** for the alice linux distribution. -It is written in posix shell with the goal to be simple and effective. It can consume package building templates in the abuild format -and automate the building and installing of packages. - -# OPTIONS - -Arguments for apkg are as follows: - -- **-h** Print help. -- **-i** *<pkg(s)>* Install package(s) without taking dependencies into account. Building will fail if the dependencies are not present in the system. -- **-I** *<pkg(s)>* Install package(s) with dependencies. -- **-d** *<pkg>* List only direct package dependencies -- **-D** *<pkg(s)>* List all dependencies for package(s) -- **-j** *<pkg>* List all reverse dependencies for the package (packages that depend on it). -- **-u** *<pkg(s)>* Upgrade package(s) -- **-r** *<pkg(s)>* Remove package(s) -- **-t** *<pkg(s)>* Run scripts for package(s) that update cache or dbs (mime, font cache e.t.c) -- **-U** Update system -- **-f** Force rebuild a package. -- **-o** *<pkg(s)>* Only download source for package(s), do not build and install -- **-p** *<pkg(s)>* Print full path to the package build template directory -- **-s** *<pattern>* Search for packages -- **-g** *<pkg>* Update or generate checksum(s) for the package source files. - -# ENVIRONMENT VARIABLES - -- `APKG_ROOT` Overrides default root location (/), where sw is installed -- `APKG_CONF` Overrides default location for the configuration file apkg.conf. The default is under /etc on an installed alice linux system. -- `APKG_NOPROMPT` If set, it enabled non-interactive use by disabling user confirmation prompt. -- `APKG_REPO` Double-quoted, space-separated list for the local directories that contain build templates. -- `APKG_PACKAGE_DIR` Directory where the compiled packages will reside. -- `APKG_SOURCE_DIR` Directory that will hold the downloaded sources. -- `APKG_WORK_DIR` Directory where the actual building process will take place. This happens in subdirectories which are cleaned after completion. -- `APKG_LOG` If set, it enables the creation of a log for the program output. - -**Note:** Usually, APKG_REPO, APKG_PACKAGE_DIR, APKG_SOURCE_DIR and APKG_WORK_DIR are declared in the apkg.conf configuration file. For more information, please see apkg.conf(5). - -# FILES - -- **apkg.conf(5)** is the default configuration file, it resides by default under /etc. -- **abuild** is the name of the package templates that apkg uses, along with relevant files in order to -build and installed packages. For example, one can look to the alice linux repos, under https://codeberg.org/emmett1/alicelinux/src/branch/main/repos - -# EXAMPLES - -`apkg -i linux` - Install the *linux* package - -`apkg -f jupp` - Force rebuild the *jupp* package. If someone tries with just `-i`, `apkg` will produce the following message -if the package is already installed: `[...] Package 'jupp' already installed.` - -`apkg -s icon` - Search for packages names that contain "icon", it will produce a list with one -package per line. - -# AUTHORS - -emmett1 <emmett1.2miligrams@protonmail.com> Author of the program and creator of alice linux. - -mobinmob <mobinmob@disroot.org> Author of the man page. - -# REPORTING BUGS - -**apkg** is in a working stage but also under heavy development. Please report and bugs/issues in the project issue tracker: https://codeberg.org/emmett1/autils/issues diff --git a/man/make-man.sh b/man/make-man.sh deleted file mode 100644 index dd0a8c5..0000000 --- a/man/make-man.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh - -# This script is derives from the original, written for Obarun Linux distribution by Eric Vidal. -# The original is released under BSD Zero Clause licence (BSD0), and can be found at https://git.obarun.org/Obarun/66/-/blob/master/doc/make-man.sh?ref_type=heads. - - -man8='apkg revdep' -man5='apkg.conf' - -for i in 5 8;do - if [ ! -d man${i} ]; then - mkdir -p -m 0755 man"${i}" || exit 1 - fi -done - -for i in ${man5}; do - lowdown -s -Tman "${i}".md -o man5/"${i}".5 || exit 1 - var=$( sed -n -e '/^.TH/p' < man5/"${i}".5) - var=$(printf '%s' "$var" | tr '7' '5') - sed -i "s!^.TH.*!${var}!" man5/"${i}".5 || exit 1 - sed -i '4,8d' man5/"${i}".5 || exit 1 -done - -for i in ${man8}; do - lowdown -s -Tman "${i}".md -o man8/"${i}".8 || exit 1 - var=$( sed -n -e '/^.TH/p' < man8/"${i}".8) - var=$(printf '%s' "$var" | tr '7' '8') - sed -i "s!^.TH.*!${var}!" man8/"${i}".8 || exit 1 - sed -i '4,8d' man8/"${i}".8 || exit 1 -done - -exit 0 diff --git a/man/man5/apkg.conf.5 b/man/man5/apkg.conf.5 deleted file mode 100644 index e4bb96d..0000000 --- a/man/man5/apkg.conf.5 +++ /dev/null @@ -1,86 +0,0 @@ -.\" -*- mode: troff; coding: utf-8 -*- -.TH "" "5" "" -.SH NAME -It resides by default under \f(CR/etc\fR in an alice linux installation. -The contents are sourced by the \fBapkg\fR program and are in the posix shell \f(CRkey=\(dqvalue\(dq\fR format. -.SH CONFIGURATION KEYS -.IP "\(bu" 3 -\f(CRAPKG_NOPROMPT\fR If set, it enables non-interactive use by disabling user confirmation prompt. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRAPKG_PACKAGE_DIR\fR Directory where the compiled packages will reside. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRAPKG_SOURCE_DIR\fR Directory that will hold the downloaded sources. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRAPKG_WORK_DIR\fR Directory where the actual building process will take place. This happens in subdirectories which are cleaned after completion. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRAPKG_LOG\fR If set, it enables the creation of a log for the program output. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRexport CFLAGS=\(dq<cflags>\(dq\fR Default are \fI-O3 -march=x86-64 -pipe\fR -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRexport CXXFLAGS=\(dq$CFLAGS\(dq\fR -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRexport NINJAJOBS=\(dq<-x>\(dq\fR Replace <-x> with the number of jobs the ninja build system with use. Without this it will use the maximum amount of threads the processor suports. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRexport MAKEFLAGS=\(dq-jx\(dq\fR Replace with the number of jobs the make build system with use. -.LP -EXAMPLES -.LP -.EX -### example of a valid apkg.conf ### -export CFLAGS=\(dq-O3 -march=x86-64 -pipe\(dq -export CXXFLAGS=\(dq$CFLAGS\(dq -export MAKEFLAGS=\(dq-j12\(dq -export NINJAJOBS=\(dq12\(dq -APKG_REPO=\(dq/var/lib/alicelinux/repos/core /var/lib/alicelinux/repos/extra /var/lib/alicelinux/repos/xorg /var/lib/alicelinux/repos/wayland\(dq -APKG_PACKAGE_DIR=/var/cache/pkg -APKG_SOURCE_DIR=/var/cache/src -APKG_WORK_DIR=/var/cache/work -.EE -.SH AUTHORS -.LP -emmett1 \c -.MT emmett1.2miligrams@protonmail.com -.ME -Author of the program and creator of alice linux. -.PP -mobinmob \c -.MT mobinmob@disroot.org -.ME -Author of the man page. -.SH REPORTING BUGS -.LP -\fBapkg\fR is in a working stage but also under heavy development. Please report and bugs/issues in the project issue tracker: \c -.UR https://codeberg.org/emmett1/autils/issues -.UE diff --git a/man/man8/apkg.8 b/man/man8/apkg.8 deleted file mode 100644 index 2727207..0000000 --- a/man/man8/apkg.8 +++ /dev/null @@ -1,181 +0,0 @@ -.\" -*- mode: troff; coding: utf-8 -*- -.TH "" "8" "" -.SH NAME -.SH DESCRIPTION -.LP -\fBapkg\fR is the package build tool and package installer, along with \fBspm\fR for the alice linux distribution. -It is written in posix shell with the goal to be simple and effective. It can consume package building templates in the abuild format -and automate the building and installing of packages. -.SH OPTIONS -.LP -Arguments for apkg are as follows: -.IP "\(bu" 3 -\fB-h\fR Print help. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-i\fR \fI\fR Install package(s) without taking dependencies into account. Building will fail if the dependencies are not present in the system. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-I\fR \fI\fR Install package(s) with dependencies. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-d\fR \fI\fR List only direct package dependencies -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-D\fR \fI\fR List all dependencies for package(s) -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-j\fR \fI\fR List all reverse dependencies for the package (packages that depend on it). -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-u\fR \fI\fR Upgrade package(s) -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-r\fR \fI\fR Remove package(s) -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-t\fR \fI\fR Run scripts for package(s) that update cache or dbs (mime, font cache e.t.c) -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-U\fR Update system -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-f\fR Force rebuild a package. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-o\fR \fI\fR Only download source for package(s), do not build and install -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-p\fR \fI\fR Print full path to the package build template directory -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-s\fR \fI\fR Search for packages -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-g\fR \fI\fR Update or generate checksum(s) for the package source files. -.SH ENVIRONMENT VARIABLES -.IP "\(bu" 3 -\f(CRAPKG_ROOT\fR Overrides default root location (/), where sw is installed -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRAPKG_CONF\fR Overrides default location for the configuration file apkg.conf. The default is under /etc on an installed alice linux system. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRAPKG_NOPROMPT\fR If set, it enabled non-interactive use by disabling user confirmation prompt. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRAPKG_REPO\fR Double-quoted, space-separated list for the local directories that contain build templates. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRAPKG_PACKAGE_DIR\fR Directory where the compiled packages will reside. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRAPKG_SOURCE_DIR\fR Directory that will hold the downloaded sources. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRAPKG_WORK_DIR\fR Directory where the actual building process will take place. This happens in subdirectories which are cleaned after completion. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\f(CRAPKG_LOG\fR If set, it enables the creation of a log for the program output. -.LP -\fBNote:\fR Usually, APKG\fIREPO, APKG\fRPACKAGE\fIDIR, APKG\fRSOURCE\fIDIR and APKG\fRWORK_DIR are declared in the apkg.conf configuration file. For more information, please see apkg.conf(5). -.SH FILES -.IP "\(bu" 3 -\fBapkg.conf(5)\fR is the default configuration file, it resides by default under /etc. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fBabuild\fR is the name of the package templates that apkg uses, along with relevant files in order to -build and installed packages. For example, one can look to the alice linux repos, under \c -.UR https://codeberg.org/emmett1/alicelinux/src/branch/main/repos -.UE -.SH EXAMPLES -.LP -\f(CRapkg -i linux\fR - Install the \fIlinux\fR package -.PP -\f(CRapkg -f jupp\fR - Force rebuild the \fIjupp\fR package. If someone tries with just \f(CR-i\fR, \f(CRapkg\fR will produce the following message -if the package is already installed: \f(CR[...] Package 'jupp' already installed.\fR -.PP -\f(CRapkg -s icon\fR - Search for packages names that contain \(lqicon\(rq, it will produce a list with one -package per line. -.SH AUTHORS -.LP -emmett1 \c -.MT emmett1.2miligrams@protonmail.com -.ME -Author of the program and creator of alice linux. -.PP -mobinmob \c -.MT mobinmob@disroot.org -.ME -Author of the man page. -.SH REPORTING BUGS -.LP -\fBapkg\fR is in a working stage but also under heavy development. Please report and bugs/issues in the project issue tracker: \c -.UR https://codeberg.org/emmett1/autils/issues -.UE diff --git a/man/man8/revdep.8 b/man/man8/revdep.8 deleted file mode 100644 index 52d32fd..0000000 --- a/man/man8/revdep.8 +++ /dev/null @@ -1,34 +0,0 @@ -.\" -*- mode: troff; coding: utf-8 -*- -.TH "" "8" "" -.SH NAME -it can discover programs that need to be rebuilt after library upgrades or are missing libraries. -It should probably run after any big upgrade, especially those that feature lib version bumps. -.SH OPTIONS -.IP "\(bu" 3 -\fB-h\fR Show program help. -.if n \ -.sp -1 -.if t \ -.sp -0.25v -.IP "\(bu" 3 -\fB-v\fR Verbose output of the operation. -.SH NOTE -.LP -\fBrevdep\fR does not automatically rebuild broken packages or their dependencies. You need to -use apkg for these operations. -.SH REPORTING BUGS -.LP -\fBapkg\fR is in a working stage but also under heavy development. Please report and bugs/issues in the project issue tracker: \c -.UR https://codeberg.org/emmett1/autils/issues -.UE -.SH AUTHORS -.LP -emmett1 \c -.MT emmett1.2miligrams@protonmail.com -.ME -Author of the program and creator of alice linux. -.PP -mobinmob \c -.MT mobinmob@disroot.org -.ME -Author of the man page. diff --git a/man/reposync.8 b/man/reposync.8 new file mode 100644 index 0000000..bed67c3 --- /dev/null +++ b/man/reposync.8 @@ -0,0 +1,51 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.TH REPOSYNC 8 +.SH NAME +reposync \- synchronize git-based package repositories +.SH DESCRIPTION +.LP +\fBreposync\fR synchronizes git-based package repositories using environment +variables for configuration. It does not depend on an \fIapkg.conf\fR file. +.SH OPTIONS +.TP +\fB-n\fR +Dry-run: print actions without executing them. +.TP +\fB-l\fR +Enable logging to \fI/var/log/reposync.log\fR. +.TP +\fB-f\fR +Force sync: remove existing repo directories before cloning fresh. +.TP +\fB-h\fR +Print usage message. +.SH ENVIRONMENT VARIABLES +.LP +Repository configuration is provided via variables with the \fBREPOSYNC_\fR prefix. +Each variable's value uses the pipe-delimited format: +\fI<url>|<branch>|<local-path>\fR. +.PP +For example: +.PP +\f(CRREPOSYNC_CORE="https://codeberg.org/emmett1/alicelinux.git|main|/var/lib/alicelinux"\fR +.PP +\f(CRREPOSYNC_EXTRA="https://codeberg.org/emmett1/alicelinux.git|extra|/var/lib/alicelinux/extra"\fR +.SH EXAMPLES +.LP +\f(CRreposync\fR - Sync all repos configured via REPOSYNC_* variables. +.PP +\f(CRreposync -n\fR - Dry-run to see what actions would be taken. +.PP +\f(CRreposync -l\fR - Sync with logging enabled. +.PP +\f(CRreposync -f\fR - Force fresh clones of all repositories. +.SH AUTHORS +.LP +emmett1 \c +.MT me@emmett1.my +.ME +.SH REPORTING BUGS +.LP +Please report bugs and issues in the project issue tracker: \c +.UR https://codeberg.org/emmett1/autils/issues +.UE diff --git a/man/revdep.8 b/man/revdep.8 new file mode 100644 index 0000000..be93f32 --- /dev/null +++ b/man/revdep.8 @@ -0,0 +1,38 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.TH REVDEP 8 +.SH NAME +revdep \- discover broken library dependencies +.SH DESCRIPTION +.LP +\fBrevdep\fR scans system binaries and shared libraries for missing library links. +It can discover programs that need to be rebuilt after library upgrades or are +missing libraries. It should probably be run after any big upgrade, especially +those that feature library version bumps. +.SH OPTIONS +.TP +\fB-h\fR +Show program help. +.TP +\fB-v\fR +Verbose output of the operation. +.SH NOTE +.LP +\fBrevdep\fR does not automatically rebuild broken packages or their dependencies. +You need to use \fBapkg\fR for these operations. +.SH REPORTING BUGS +.LP +\fBapkg\fR is in a working stage but also under heavy development. Please report +bugs and issues in the project issue tracker: \c +.UR https://codeberg.org/emmett1/autils/issues +.UE +.SH AUTHORS +.LP +emmett1 \c +.MT me@emmett1.my +.ME +Author of the program and creator of Alice Linux. +.PP +mobinmob \c +.MT mobinmob@disroot.org +.ME +Author of the man page. diff --git a/man/revdep.md b/man/revdep.md deleted file mode 100644 index 6f23ee3..0000000 --- a/man/revdep.md +++ /dev/null @@ -1,29 +0,0 @@ -# NAME - -**revdep** - utility to discover and rebuild reverse deps - -# DESCRIPTION - -**revdep** is a utility inspired by the gentoo program revdep-rebuild. It is written in posix shell and -it can discover programs that need to be rebuilt after library upgrades or are missing libraries. -It should probably run after any big upgrade, especially those that feature lib version bumps. - -# OPTIONS - -- **-h** Show program help. -- **-v** Verbose output of the operation. - -# NOTE - -**revdep** does not automatically rebuild broken packages or their dependencies. You need to -use apkg for these operations. - -# REPORTING BUGS - -**apkg** is in a working stage but also under heavy development. Please report and bugs/issues in the project issue tracker: https://codeberg.org/emmett1/autils/issues - -# AUTHORS - -emmett1 <emmett1.2miligrams@protonmail.com> Author of the program and creator of alice linux. - -mobinmob <mobinmob@disroot.org> Author of the man page. diff --git a/man/updateconf.8 b/man/updateconf.8 new file mode 100644 index 0000000..d73e4e1 --- /dev/null +++ b/man/updateconf.8 @@ -0,0 +1,49 @@ +.\" -*- mode: troff; coding: utf-8 -*- +.TH UPDATECONF 8 +.SH NAME +updateconf \- interactive .new configuration file merge tool +.SH DESCRIPTION +.LP +\fBupdateconf\fR is an interactive tool for handling \fI.new\fR configuration +files. When packages are upgraded, new default configuration files are installed +with a \fI.new\fR suffix to avoid overwriting locally modified files. +\fBupdateconf\fR helps merge, discard, or keep these files. +.SH USAGE +.LP +\f(CRupdateconf\fR +.PP +Must be run as root. The script scans \fI/etc\fR for files ending in \fI.new\fR +and presents each one interactively. +.SH INTERACTIVE PROMPT +.LP +For each \fI.new\fR file, a unified diff between the current and new version is +shown, and the user is prompted: +.TP +\fBU\fR +Update: replace the current file with the new one. +.TP +\fBD\fR +Discard: delete the \fI.new\fR file, keeping the current version. +.TP +\fBE\fR +Edit: open the current file in the editor (\fB$EDITOR\fR, defaults to \fIvi\fR). +.TP +\fBK\fR +Keep: keep both files, no changes. +.SH ENVIRONMENT +.TP +\fBEDITOR\fR +Editor to use (default: \fIvi\fR). +.SH EXAMPLES +.LP +\f(CRupdateconf\fR - Run the interactive config file updater. +.SH AUTHORS +.LP +emmett1 \c +.MT me@emmett1.my +.ME +.SH REPORTING BUGS +.LP +Please report bugs and issues in the project issue tracker: \c +.UR https://codeberg.org/emmett1/autils/issues +.UE @@ -1,19 +1,15 @@ #!/bin/sh -e # -# script to sync repos -# required /etc/reposync.conf -# -# /etc/reposync.conf format: -# <git url>|<branch>|<local path to sync> +# repo sync script (env-based: REPOSYNC_*) # log() { msg="$1" if [ "$LOG" ]; then - echo "$(date +'%Y-%m-%d %H:%M:%S') $msg" | tee -a "$LOGFILE" - else - echo "$msg" - fi + echo "$(date +'%Y-%m-%d %H:%M:%S') $msg" | tee -a "$LOGFILE" + else + echo "$msg" + fi } run_cmd() { @@ -29,27 +25,21 @@ syncrepo() { url=$1 branch=$2 path=$3 - - # if url is empty, do nothing - if [ ! "$url" ]; then - exit 0 - fi - - # if $path empty, your format is wrong - if [ ! "$path" ]; then - echo "/etc/reposync.conf format: <git url>|<branch>|<local path to sync>" - exit - fi - - if [ "$FORCE" ]; then - if [ -d "$path" ]; then - log "=> Force removing repo directory $path..." - run_cmd "rm -rf \"$path\"" - fi + + [ -z "$url" ] && return 0 + + if [ -z "$path" ]; then + log "error: invalid repo format (missing path)" + return 1 + fi + + if [ "$FORCE" ] && [ -d "$path" ]; then + log "=> Force removing repo directory $path..." + run_cmd "rm -rf \"$path\"" fi if [ ! -d "$path/.git" ]; then - log "=> Sync repo $path..." + log "=> Cloning repo into $path..." run_cmd "mkdir -p \"$path\"" run_cmd "git clone --branch \"$branch\" --single-branch \"$url\" \"$path\"" else @@ -68,6 +58,7 @@ usage() { exit 1 } +# --- args --- while [ "$1" ]; do case "$1" in -n) DRY_RUN=1;; @@ -78,20 +69,28 @@ while [ "$1" ]; do shift done +# --- checks --- command -v git >/dev/null 2>&1 || { echo "error: git is not installed." >&2 exit 1 } LOGFILE="/var/log/reposync.log" -CONFFILE="/etc/reposync.conf" -if [ ! -f "$CONFFILE" ]; then - echo "error: config file not found: $CONFFILE" >&2 - exit 1 +REPOS=$(env | grep '^REPOSYNC_' | sort || true) + +if [ -z "$REPOS" ]; then + echo "error: no REPOSYNC_* variables found." >&2 + exit 1 fi -grep -Ev '^#|^$' "$CONFFILE" | while IFS='|' read -r url branch path _; do +echo "$REPOS" | while IFS='=' read -r name value; do + IFS='|' read -r url branch path _ <<EOF +$value +EOF + + [ -z "$url" ] && continue + syncrepo "$url" "$branch" "$path" done |