aboutsummaryrefslogtreecommitdiff
path: root/apkg
diff options
context:
space:
mode:
authoremmett1 <emmett1.2miligrams@protonmail.com>2024-03-26 00:32:56 +0800
committeremmett1 <emmett1.2miligrams@protonmail.com>2024-03-26 00:32:56 +0800
commitcf41ee19b9776b02b814dfde6bcd5051481d04c2 (patch)
treed8b54aae6f53958af36f27f12143f088ae09b55d /apkg
parent84ec73d5575ac42c88394b49507e09e3af99715a (diff)
downloadautils-cf41ee19b9776b02b814dfde6bcd5051481d04c2.tar.gz
autils-cf41ee19b9776b02b814dfde6bcd5051481d04c2.zip
scripts added
Diffstat (limited to 'apkg')
-rwxr-xr-xapkg598
1 files changed, 598 insertions, 0 deletions
diff --git a/apkg b/apkg
new file mode 100755
index 0000000..776447f
--- /dev/null
+++ b/apkg
@@ -0,0 +1,598 @@
+#!/bin/sh
+
+fetch_src() {
+ [ "$source" ] || return 0
+ for i in $source; do
+ i=${i%::noextract}
+ case $i in
+ *::*) sn=${i%::*};;
+ *) sn=${i##*/};;
+ esac
+ case ${i#*::} in
+ http://*|https://*|ftp://*)
+ if [ ! -f $APKG_SOURCE_DIR/$sn ]; then
+ [ -f $APKG_SOURCE_DIR/$sn.tmp ] && resume="-C -"
+ msg "fetching ${i#*::} to $APKG_SOURCE_DIR/$sn.tmp"
+ curl $resume -L -o $APKG_SOURCE_DIR/$sn.tmp ${i#*::} || {
+ msg "Failed downloading source '$sn'."
+ exit 1
+ }
+ mv $APKG_SOURCE_DIR/$sn.tmp $APKG_SOURCE_DIR/$sn
+ fi;;
+ esac
+ done
+}
+
+extract_src() {
+ rm -rf $PKG $SRC
+ mkdir -p $PKG $SRC
+ [ "$source" ] || return 0
+ for i in $source; do
+ case $i in
+ */*) S=$APKG_SOURCE_DIR;;
+ *) S=$HERE;;
+ esac
+ case ${i%::noextract} in
+ *::*) sn=${i%%::*};;
+ *) sn=${i##*/}; sn=${sn%::noextract};;
+ esac
+ case $i in
+ *::noextract)
+ i=${i%::noextract}
+ cp $S/$sn $SRC || {
+ msg "Failed copy '$S/$sn' to '$SRC'."
+ exit 1
+ };;
+ *.tar.bz2|*.tar.gz|*.tar.lz|*.tar.lzma|*.tar.lzo|*.tar.xz|*.tar.Z|*.tb2|*.tbz|*.tbz2|*.tz2|*.taz|*.tgz|*.tlz|*.txz|*.tZ|*.taZ)
+ msg "Unpacking '$S/$sn'..."
+ tar -p -o -C $SRC -xf $S/$sn || {
+ msg "Failed unpacking source '${i##*/}'."
+ exit 1
+ };;
+ *)
+ i=${i%::noextract}
+ cp $S/$sn $SRC || {
+ msg "Failed copy '$S/$sn' to '$SRC'."
+ exit 1
+ };;
+ esac
+ done
+}
+
+detect_buildtype() {
+ if [ -f meson.build ]; then
+ build_type=meson_build
+ elif [ -f configure ]; then
+ build_type=configure_build
+ elif [ -f CMakeLists.txt ]; then
+ build_type=cmake_build
+ elif [ -f setup.py ]; then
+ build_type=python3_build
+ elif [ -f Makefile.PL ]; then
+ build_type=perlmodule_build
+ elif [ -f Makefile ] || [ -f makefile ]; then
+ build_type=makefile_build
+ else
+ msg "failed to detect buildtype"
+ exit 1
+ fi
+}
+
+_makefile_build() {
+ make
+ make \
+ PREFIX=/usr \
+ prefix=/usr \
+ SYSCONFDIR=/etc \
+ sysconfdir=/etc \
+ MANDIR=/usr/share/man \
+ mandir=/usr/share/man \
+ LIBDIR=/usr/lib \
+ PKGCONFIGDIR=/usr/lib/pkgconfig \
+ DESTDIR=$PKG install
+}
+
+_perlmodule_build() {
+ perl Makefile.PL
+ make
+ make DESTDIR=$PKG install
+}
+
+_cmake_build() {
+ mkdir -p cmakebuild
+ cd cmakebuild
+ cmake \
+ -DCMAKE_INSTALL_PREFIX=/usr \
+ -DCMAKE_INSTALL_SYSCONFDIR=/etc \
+ -DCMAKE_INSTALL_LIBDIR=lib \
+ -DCMAKE_INSTALL_LIBEXECDIR=lib \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DFETCHCONTENT_FULLY_DISCONNECTED=ON \
+ -DCMAKE_C_FLAGS_RELEASE="$CFLAGS" \
+ -DCMAKE_CXX_FLAGS_RELEASE="$CXXFLAGS" \
+ $build_opt $@ \
+ -G Ninja ..
+ if [ -f build.ninja ]; then
+ ninja
+ DESTDIR=$PKG ninja install
+ else
+ cmake --build build
+ DESTDIR=$PKG cmake --install build
+ fi
+}
+
+_python3_build() {
+ python3 setup.py build
+ python3 setup.py install --prefix=/usr --root=$PKG --optimize=1
+}
+
+_configure_build() {
+ ./configure \
+ --prefix=/usr \
+ --sysconfdir=/etc \
+ --localstatedir=/var \
+ --libdir=/usr/lib \
+ --libexecdir=/usr/lib \
+ --infodir=/usr/share/info \
+ --mandir=/usr/share/man \
+ $build_opt $@
+ make
+ make DESTDIR=$PKG install
+}
+
+_meson_build() {
+ meson setup _meson_build \
+ --prefix=/usr \
+ --libdir=/usr/lib \
+ --libexecdir=/usr/lib \
+ --includedir=/usr/include \
+ --datadir=/usr/share \
+ --mandir=/usr/share/man \
+ --infodir=/usr/share/info \
+ --localedir=/usr/share/locale \
+ --sysconfdir=/etc \
+ --localstatedir=/var \
+ --sharedstatedir=/var/lib \
+ --buildtype=plain \
+ --auto-features=auto \
+ --wrap-mode=nodownload \
+ -Db_lto=true \
+ -Db_pie=true \
+ -Db_thinlto_cache=true \
+ $build_opt || return $?
+ meson compile -C _meson_build || return $?
+ DESTDIR=$PKG meson install --no-rebuild -C _meson_build || return $?
+}
+
+apply_patch() {
+ [ "$skip_patch" ] && {
+ unset skip_patch # allowing manual patch in build() using apply_patch
+ return 0
+ }
+ if [ "$source" ]; then
+ for p in $source; do
+ case ${p%::noextract} in
+ *::*) pn=${p%::*};;
+ *) pn=${p##*/};;
+ esac
+ case $pn in
+ *.patch|*.diff)
+ msg "applying path '$SRC/$pn'."
+ patch ${patch_opt:--p1} -t -i $SRC/$pn || exit 1;;
+ esac
+ done
+ fi
+}
+
+msg() {
+ echo "[${name:-...}] $@"
+}
+
+exitonerror() {
+ [ "$?" = 0 ] || { echo "error status $?"; exit 1; }
+}
+
+buildstatus() {
+ [ "$?" = 0 ] || {
+ msg "build package '$name-$version-$release' failed on '$1'."
+ exit 1
+ }
+}
+
+build_src() {
+ cd $SRC
+
+ if [ "$build_dir" ]; then
+ if [ ! -d "$build_dir" ]; then
+ msg "Source directory '$build_dir' not found."
+ exit 1
+ 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)
+ fi
+
+ # cd into extracted source directory
+ if [ "$build_dir" ]; then
+ cd $build_dir
+ fi
+
+ apply_patch
+
+ export DESTDIR=$PKG
+ export DEST_DIR=$PKG # p7zip
+ export INSTALLROOT=$PKG # syslinux
+ export install_root=$PKG # glibc
+ export INSTALL_ROOT=$PKG # qt5
+
+ if [ ! "$source" ]; then
+ # dummy pkg
+ mkdir -p $PKG/usr
+ elif [ "$(command -v pkg_build)" ]; then
+ (set -e -x; pkg_build)
+ buildstatus pkg_build
+ else
+ if [ "$(command -v pre_build)" ]; then
+ (set -e -x; pre_build)
+ buildstatus pre_build
+ fi
+ if [ ! "${build_type}" ]; then
+ detect_buildtype
+ fi
+ (set -e -x; _${build_type})
+ buildstatus _${build_type}
+ if [ "$(command -v post_build)" ]; then
+ (set -e -x; post_build)
+ buildstatus post_build
+ fi
+ fi
+
+ msg "build $name-$version-$release success"
+
+ # compress man pages
+ if [ -d $PKG/usr/share/man ]; then
+ # only keep man[1-8] man pages
+ for m in $PKG/usr/share/man/*; do
+ case ${m##*/} in
+ man[1-8]) continue;;
+ esac
+ rm -rf $m
+ done
+ find $PKG/usr/share/man -type f -exec gzip -9 {} \;
+ for i in $( find $PKG/usr/share/man -type l ) ; do ln -s $( readlink $i ).gz $i.gz ; rm $i ; done
+ fi
+
+ # compress info pages
+ if [ -d $PKG/usr/share/info ]; then
+ rm -f $PKG/usr/share/info/dir
+ find $PKG/usr/share/info -type f -exec gzip -9 {} \;
+ fi
+
+ # possible conflicts
+ find $PKG -name "fonts.dir" -exec rm {} \;
+ find $PKG -name "fonts.scale" -exec rm {} \;
+ find $PKG -name "perllocal.pod" -exec rm {} \;
+ find $PKG -name "charset.alias" -exec rm {} \;
+
+ if [ ! "$keep_static" ]; then
+ find $PKG -name "*.a" -exec rm {} \;
+ fi
+
+ if [ ! "$keep_libtool" ]; then
+ find $PKG -name "*.la" -exec rm {} \;
+ fi
+
+ if [ ! "$keep_locale" ]; then
+ rm -rf $PKG/usr/share/locale
+ rm -rf $PKG/usr/lib/locale
+ fi
+
+ if [ ! "$keep_doc" ]; then
+ rm -rf $PKG/usr/share/doc
+ rm -rf $PKG/usr/doc
+ fi
+
+ # 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
+ fi
+
+ # runit service
+ for s in $sv; do
+ [ -f $SRC/$s ] || exit 1
+ case $s in
+ run) install -Dm755 $SRC/$s $PKG/etc/sv/$name/run
+ ln -s ../../../run/runit/supervise.$name $PKG/etc/sv/$name/supervise;;
+ finish) install -Dm755 $SRC/$s $PKG/etc/sv/$name/finish;;
+ *.run) install -Dm755 $SRC/$s $PKG/etc/sv/${s%.*}/run
+ ln -s ../../../run/runit/supervise.${s%.*} $PKG/etc/sv/${s%.*}/supervise;;
+ *.finish) install -Dm755 $SRC/$s $PKG/etc/sv/${s%.*}/finish;;
+ *.*) install -Dm644 $SRC/$s $PKG/etc/sv/${s%%.*}/${s#*.};;
+ *) install -Dm644 $SRC/$s $PKG/etc/sv/$name/$s;;
+ esac
+ done
+
+ if [ ! "$(ls -1 $PKG)" ]; then
+ msg "\$PKG is empty"
+ exit 1
+ fi
+
+ cd $APKG_PACKAGE_DIR
+ spm -b $PKG && {
+ mv package.spm $packagefile
+ } || {
+ msg "Failed packaging $packagefile"
+ exit 1
+ }
+
+ if [ ! -f "$HERE"/.files ]; then
+ pkg_updatefiles
+ fi
+
+ cd $HERE
+ rm -rf $SRC $PKG
+}
+
+pkg_updatefiles() {
+ if [ ! -f "$packagefile" ]; then
+ msg "Package '$packagefile' not found."
+ exit 1
+ fi
+ msg "'.files' updated."
+ tar -tvf $packagefile | awk '{$3=$4=$5=""; print $0}' | sort -k 3 > "$HERE"/.files
+}
+
+pkg_path() {
+ for r in $APKG_REPO; do
+ [ -f $r/$1/abuild ] && {
+ echo $r/$1
+ break
+ }
+ done
+}
+
+die() {
+ echo "error: $1"
+ exit 1
+}
+
+checkdep() {
+ pkg_path $1 >/dev/null || return
+ # track processed pkg to avoid cycle deps
+ process="$process $1"
+ for ii in $(pkg_depends $1); do
+ # if deps already in process list, skip, cycle deps detected
+ echo $process | tr ' ' '\n' | grep -qx $ii && continue
+ # skip if itself in depends list
+ [ "$ii" = "$1" ] && continue
+ # skip if pkg already in deps list
+ echo $DEPS | tr ' ' '\n' | grep -x $ii && continue
+ # check deps
+ checkdep $ii
+ done
+ # will go here if no deps anymore to check, add it to list deps
+ DEPS="$DEPS $1"
+}
+
+pkg_deplist() {
+ for i in $@; do
+ # if already have in list deps, dont check again
+ if [ ! $(echo $DEPS | tr ' ' '\n' | grep -x $i) ]; then
+ checkdep $i
+ fi
+ done
+ echo $DEPS | tr ' ' '\n'
+}
+
+pkg_depends() {
+ _path=$(pkg_path $1) >/dev/null || return 1
+ grep '# Depends' $_path/abuild | awk -F : '{print $2}' | tr ' ' '\n' | sed '/^$/d'
+}
+
+parsesubopt() {
+ # loop opts until found '-*'
+ shift; while [ "$1" ]; do
+ case $1 in
+ -*) break;;
+ *) echo $1;;
+ esac
+ shift
+ done
+}
+
+pkg_outdate() {
+ spm -a | while read -r n v; do
+ [ "$(pkg_path $n)" ] || continue
+ nv="$(grep ^version= $(pkg_path $n)/abuild | awk -F = '{print $2}')-$(grep ^release= $(pkg_path $n)/abuild | awk -F = '{print $2}')"
+ [ "$nv" ] || continue
+ [ "$v" = "$nv" ] || echo "$n $v -> $nv"
+ done
+}
+
+pkg_sysup() {
+ msg "Checking for outdated packages..."
+ od=$(pkg_outdate | awk '{print $1}')
+ if [ ! "$od" ]; then
+ msg "No outdated packages."
+ exit 0
+ else
+ totalpkg=$(echo $od | tr ' ' '\n' | wc -l)
+ echo
+ echo $od
+ echo
+ msg "Press ENTER to continue upgrade $totalpkg packages."
+ msg "Press Ctrl + C to abort."
+ read -r null
+ apkg -u $od || die
+ fi
+}
+
+parseopts() {
+ while [ "$1" ]; do
+ case $1 in
+ -I) pkg_depinstalll $(parsesubopt $@); exit 0;;
+ -D) pkg_deplist $(parsesubopt $@); exit 0;;
+ -f) forcerebuild=1;;
+ -i) install=1;;
+ -u) upgrade=1;;
+ -o) downloadonly=1;;
+ -U) pkg_sysup; exit 0;;
+ -d) pkg_depends $2; exit 0;;
+ -p) pkg_path $2; exit 0;;
+ -s) pkg_search $2; exit 0;;
+ -*) msg "invalid option '$1'"; exit 1;;
+ *) pkg="$pkg $1";;
+ esac
+ shift
+ done
+}
+
+updateopts() {
+ while [ "$1" ]; do
+ case $1 in
+ -*) newopt="$newopt $1";;
+ esac
+ shift
+ done
+ echo $newopt
+}
+
+pkg_search() {
+ if [ ! "$APKG_REPO" ]; then
+ msg "No repo configured."
+ exit 1
+ fi
+ [ "$1" ] && grep=grep || grep=cat
+ find $APKG_REPO -type f -name abuild -printf '%h\n' | rev | awk -F / '{print $1}' | rev | $grep $1
+}
+
+pkg_depinstalll() {
+ for p in $@; do
+ [ -s $SPM_PKGDB/$p ] && continue
+ pkg="$pkg $p"
+ done
+ set -- $pkg
+ msg "Solving dependencies..."
+ for p in $(pkg_deplist $@); do
+ [ -s $SPM_PKGDB/$p ] && continue
+ installthis="$installthis $p"
+ done
+ if [ ! "$installthis" ]; then
+ msg "Nothing to install. Exiting..."
+ exit 0
+ fi
+ totalpkg=$(echo $installthis | tr ' ' '\n' | wc -l)
+ echo
+ echo $installthis
+ echo
+ msg "Press ENTER to continue install $totalpkg packages."
+ msg "Press Ctrl + C to abort."
+ read -r null
+ apkg -i $installthis || die
+}
+
+runscript() {
+ if [ -x ./$1-install ]; then
+ msg "Running $1-install script..."
+ if [ "$ROOT" ]; then
+ cat ./$1-install > "$ROOT"/.runscript
+ chmod +x "$ROOT"/.runscript
+ chroot "$ROOT" /.runscript
+ rm -f "$ROOT"/.runscript
+ else
+ ./$1-install
+ fi
+ fi
+}
+
+main() {
+ parseopts $@
+ set -- $(updateopts $@)
+
+ for d in $APKG_PACKAGE_DIR $APKG_SOURCE_DIR $APKG_WORK_DIR; do
+ [ -d $d ] || { msg "Directory '$d' not exist"; exit 1; }
+ [ -w $d ] || { msg "Directory '$d' dont have write access"; exit 1; }
+ done
+
+ if [ "$pkg" ]; then
+ for p in $pkg; do
+ pkg_path $p >/dev/null || continue
+ #echo "[$p] package build starts..."
+ (cd $(pkg_path $p) && apkg $@)
+ [ "$?" = 0 ] || exit 1
+ done
+ exit 0
+ fi
+
+ if [ "$install" ] && [ -s $SPM_PKGDB/${PWD##*/} ]; then
+ msg "Package '${PWD##*/}' already installed."
+ exit 0
+ fi
+
+ if [ "$upgrade" ] && [ ! -s $SPM_PKGDB/${PWD##*/} ]; then
+ msg "Package '${PWD##*/}' not installed."
+ exit 0
+ fi
+
+ if [ ! -f ./abuild ]; then
+ msg "'abuild' not found."
+ exit 1
+ fi
+
+ . ./abuild
+ [ "$name" ] || die "name is empty"
+ [ "$version" ] || die "version is empty"
+ [ "$release" ] || die "release is empty"
+
+ packagefile=$APKG_PACKAGE_DIR/$name#$version-$release.spm
+
+ if [ "$downloadonly" ]; then
+ fetch_src
+ exit 0
+ fi
+
+ if [ -f "$packagefile" ] && [ ! "$forcerebuild" ]; then
+ if [ ! "$install" ] && [ ! "$upgrade" ]; then
+ msg "Package '$packagefile' found."
+ fi
+ else
+ fetch_src
+ extract_src
+ build_src
+ fi
+
+ if [ "$install" ]; then
+ runscript pre
+ SPM_ROOT=${ROOT%/} spm -i "$packagefile" || exit $?
+ runscript post
+ elif [ "$upgrade" ]; then
+ runscript pre
+ SPM_ROOT=${ROOT%/} spm -u "$packagefile" || exit $?
+ runscript post
+ fi
+}
+
+umask 022
+
+export HERE=$PWD
+
+APKG_REPO=""
+APKG_CONF="/etc/apkg.conf"
+APKG_PACKAGE_DIR="$PWD"
+APKG_SOURCE_DIR="$PWD"
+APKG_WORK_DIR="$PWD"
+SPM_PKGDB="${ROOT%/}/var/lib/spm/db"
+
+if [ -f $APKG_CONF ]; then
+ . $APKG_CONF
+fi
+
+export SRC=$APKG_WORK_DIR/apkg-src-${PWD##*/}
+export PKG=$APKG_WORK_DIR/apkg-pkg-${PWD##*/}
+
+main $@
+
+exit 0