apkg (24184B)
1 #!/bin/sh 2 # ______ ______ __ __ ______ 3 # /\ __ \ /\ == \/\ \/ / /\ ___\ 4 # \ \ __ \\ \ _-/\ \ _"-.\ \ \__ \ 5 # \ \_\ \_\\ \_\ \ \_\ \_\\ \_____\ 6 # \/_/\/_/ \/_/ \/_/\/_/ \/_____/ 7 # 8 # APKG - Alice Package Manager (C) 2023-2025 Emmett1 9 # 10 11 fetch_src() { 12 [ "$source" ] || return 0 13 for i in $source; do 14 i=${i%::noextract} 15 case $i in 16 *::*) sn=${i%::*};; 17 *) sn=${i##*/};; 18 esac 19 case ${i#*::} in 20 http://*|https://*|ftp://*) 21 if [ ! -f $APKG_SOURCE_DIR/$sn ]; then 22 [ -f $APKG_SOURCE_DIR/$sn.tmp ] && resume="-C -" 23 msg "fetching ${i#*::}" 24 curl $resume --fail --retry 3 --retry-delay 3 -L -o $APKG_SOURCE_DIR/$sn.tmp ${i#*::} || { 25 msg "Failed downloading source '$sn'." 26 exit 1 27 } 28 mv $APKG_SOURCE_DIR/$sn.tmp $APKG_SOURCE_DIR/$sn 29 fi;; 30 esac 31 done 32 } 33 34 extract_src() { 35 prepare_workdir 36 [ "$source" ] || return 0 37 checksource 38 for i in $source; do 39 case $i in 40 */*) S=$APKG_SOURCE_DIR;; 41 *) S=$HERE;; 42 esac 43 case ${i%::noextract} in 44 *::*) sn=${i%%::*};; 45 *) sn=${i##*/}; sn=${sn%::noextract};; 46 esac 47 case $i in 48 *::noextract) 49 i=${i%::noextract} 50 cp $S/$sn $SRC || { 51 msg "Failed copy '$S/$sn' to '$SRC'." 52 ret 1 53 };; 54 *.tar.bz2|*.tar.gz|*.tar.lz|*.tar.lzma|*.tar.lzo|*.tar.xz|*.tar.Z|*.tb2|*.tbz|*.tbz2|*.tz2|*.taz|*.tgz|*.tlz|*.txz|*.tZ|*.taZ) 55 msg "Unpacking '$S/$sn'..." 56 tar -p -o -C $SRC -xf $S/$sn || { 57 msg "Failed unpacking source '${i##*/}'." 58 ret 1 59 };; 60 *) 61 i=${i%::noextract} 62 cp $S/$sn $SRC || { 63 msg "Failed copy '$S/$sn' to '$SRC'." 64 ret 1 65 };; 66 esac 67 done 68 } 69 70 prepare_workdir() { 71 export SRC=$APKG_WORK_DIR/apkg-src-${PWD##*/} 72 export PKG=$APKG_WORK_DIR/apkg-pkg-${PWD##*/} 73 74 remove_workdir 75 mkdir -p "$PKG" "$SRC" 76 } 77 78 remove_workdir() { 79 rm -rf "$PKG" "$SRC" 80 } 81 82 ret() { 83 [ "$APKG_KEEP_WORKDIR" ] || remove_workdir 84 exit $1 85 } 86 87 detect_buildtype() { 88 if [ -f meson.build ]; then 89 build_type=meson_build 90 elif [ -f configure ]; then 91 build_type=configure_build 92 elif [ -f CMakeLists.txt ]; then 93 build_type=cmake_build 94 elif [ -f setup.py ]; then 95 build_type=python_build 96 elif [ -f Makefile.PL ]; then 97 build_type=perlmodule_build 98 elif [ -f Makefile ] || [ -f makefile ] || [ -f GNUmakefile ]; then 99 build_type=makefile_build 100 else 101 msg "failed to detect buildtype" 102 ret 1 103 fi 104 } 105 106 _makefile_build() { 107 make \ 108 PREFIX=/usr \ 109 prefix=/usr \ 110 SYSCONFDIR=/etc \ 111 sysconfdir=/etc \ 112 MANDIR=/usr/share/man \ 113 mandir=/usr/share/man \ 114 LIBDIR=/usr/lib \ 115 PKGCONFIGDIR=/usr/lib/pkgconfig 116 make \ 117 PREFIX=/usr \ 118 prefix=/usr \ 119 SYSCONFDIR=/etc \ 120 sysconfdir=/etc \ 121 MANDIR=/usr/share/man \ 122 mandir=/usr/share/man \ 123 LIBDIR=/usr/lib \ 124 PKGCONFIGDIR=/usr/lib/pkgconfig \ 125 DESTDIR=$PKG install 126 } 127 128 _perlmodule_build() { 129 perl Makefile.PL 130 make 131 make DESTDIR=$PKG install 132 } 133 134 _cmake_build() { 135 mkdir -p cmakebuild 136 cd cmakebuild 137 cmake \ 138 -DCMAKE_INSTALL_PREFIX=/usr \ 139 -DCMAKE_INSTALL_SYSCONFDIR=/etc \ 140 -DCMAKE_INSTALL_LIBDIR=lib \ 141 -DCMAKE_BUILD_TYPE=Release \ 142 -DFETCHCONTENT_FULLY_DISCONNECTED=ON \ 143 -DCMAKE_C_FLAGS_RELEASE="$CFLAGS" \ 144 -DCMAKE_CXX_FLAGS_RELEASE="$CXXFLAGS" \ 145 $build_opt \ 146 -B build .. 147 if [ -f build.ninja ]; then 148 ninja 149 DESTDIR=$PKG ninja install 150 else 151 cmake --build build 152 DESTDIR=$PKG cmake --install build 153 fi 154 } 155 156 _python_build() { 157 python3 setup.py build 158 python3 setup.py install --prefix=/usr --root=$PKG --optimize=1 $build_opt 159 } 160 161 _configure_build() { 162 ./configure \ 163 --prefix=/usr \ 164 --sysconfdir=/etc \ 165 --localstatedir=/var \ 166 --libdir=/usr/lib \ 167 --infodir=/usr/share/info \ 168 --mandir=/usr/share/man \ 169 $build_opt 170 make 171 make DESTDIR=$PKG install 172 } 173 174 _meson_build() { 175 meson setup \ 176 -Dprefix=/usr \ 177 -Dlibdir=/usr/lib \ 178 -Dincludedir=/usr/include \ 179 -Ddatadir=/usr/share \ 180 -Dmandir=/usr/share/man \ 181 -Dinfodir=/usr/share/info \ 182 -Dlocaledir=/usr/share/locale \ 183 -Dsysconfdir=/etc \ 184 -Dlocalstatedir=/var \ 185 -Dsharedstatedir=/var/lib \ 186 -Dbuildtype=plain \ 187 -Dauto_features=auto \ 188 -Dwrap_mode=nodownload \ 189 -Db_lto=true \ 190 -Db_pie=true \ 191 $build_opt \ 192 build 193 ninja -C build 194 DESTDIR=$PKG meson install -C build 195 } 196 197 apply_patch() { 198 [ "$skip_patch" ] && { 199 unset skip_patch # allowing manual patch in build() using apply_patch 200 return 0 201 } 202 if [ "$source" ]; then 203 for p in $source; do 204 case ${p%::noextract} in 205 *::*) pn=${p%::*};; 206 *) pn=${p##*/};; 207 esac 208 case $pn in 209 *.patch|*.diff) 210 msg "applying patch '$SRC/$pn'." 211 patch ${patch_opt:--p1} -t -i $SRC/$pn || ret 1;; 212 esac 213 done 214 fi 215 } 216 217 msg() { 218 # Don't bother if we're not in a terminal 219 if [ -t 1 ]; then 220 ttysize=$(stty size 2>/dev/null | awk '{print $2}' || echo "80") 221 fi 222 printf "%s\n" "[${name:-...}] $@" | fold -sw ${ttysize:-80} 223 } 224 225 buildstatus() { 226 [ "$?" = 0 ] || { 227 msg "build package '$name-$version-$release' failed on '$1'." 228 ret 1 229 } 230 } 231 232 build_src() { 233 cd $SRC 234 235 if [ "$build_dir" ]; then 236 if [ ! -d "$build_dir" ]; then 237 msg "Source directory '$build_dir' not found." 238 ret 1 239 fi 240 elif [ -d $name-$version ]; then 241 build_dir=$name-$version 242 elif [ -d "$(ls -1 --group-directories-first | head -n1)" ]; then 243 build_dir=$(ls -1 --group-directories-first | head -n1) 244 fi 245 246 # cd into extracted source directory 247 if [ "$build_dir" ]; then 248 cd $build_dir 249 fi 250 251 apply_patch 252 253 export CARGO_HOME=${CARGO_HOME:-$SRC/.cargo} 254 export GOCACHE=${GOCACHE:-$SRC/.go} 255 export DESTDIR=$PKG 256 export DEST_DIR=$PKG # p7zip 257 export INSTALLROOT=$PKG # syslinux 258 export install_root=$PKG # glibc 259 export INSTALL_ROOT=$PKG # qt5 260 261 if [ ! "$source" ]; then 262 # dummy pkg 263 mkdir -p $PKG/usr 264 elif [ "$(command -v build)" ]; then 265 (set -e -x; build) 266 buildstatus build 267 else 268 if [ "$(command -v prebuild)" ]; then 269 (set -e -x; prebuild) 270 buildstatus prebuild 271 fi 272 if [ ! "${build_type}" ]; then 273 detect_buildtype 274 fi 275 (set -e -x; _${build_type}) 276 buildstatus ${build_type} 277 if [ "$(command -v postbuild)" ]; then 278 (set -e -x; postbuild) 279 buildstatus postbuild 280 fi 281 fi 282 283 msg "build $name-$version-$release success" 284 285 # compress man pages 286 if [ -d $PKG/usr/share/man ]; then 287 # only keep man[1-8] man pages 288 for m in $PKG/usr/share/man/*; do 289 case ${m##*/} in 290 man[1-8]) continue;; 291 esac 292 rm -rf $m 293 done 294 for i in $(find $PKG/usr/share/man -type f); do 295 [ $i = ${i%%.gz} ] || continue 296 gzip -9 $i 297 done 298 for i in $(find $PKG/usr/share/man -type l) ; do 299 ln -s $(readlink $i).gz ${i%.gz}.gz 300 rm $i 301 done 302 fi 303 304 # compress info pages 305 if [ -d $PKG/usr/share/info ]; then 306 rm -f $PKG/usr/share/info/dir 307 find $PKG/usr/share/info -type f -exec gzip -9 {} \; 308 fi 309 310 # possible conflicts 311 find $PKG -name "fonts.dir" -exec rm {} \; 312 find $PKG -name "fonts.scale" -exec rm {} \; 313 find $PKG -name "perllocal.pod" -exec rm {} \; 314 find $PKG -name "charset.alias" -exec rm {} \; 315 316 if [ ! "$keep_static" ]; then 317 find $PKG -name "*.a" -exec rm {} \; 318 fi 319 320 if [ ! "$keep_libtool" ]; then 321 find $PKG -name "*.la" -exec rm {} \; 322 fi 323 324 if [ ! "$keep_locale" ]; then 325 rm -rf $PKG/usr/share/locale 326 rm -rf $PKG/usr/lib/locale 327 fi 328 329 if [ ! "$keep_doc" ]; then 330 rm -rf $PKG/usr/share/doc 331 rm -rf $PKG/usr/doc 332 fi 333 334 # strip binaries and libraries 335 if [ ! "$no_strip" ]; then 336 find $PKG | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs ${CROSS_COMPILE}strip --strip-all 2>/dev/null 337 find $PKG | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs ${CROSS_COMPILE}strip --strip-unneeded 2>/dev/null 338 find $PKG | xargs file | grep "current ar archive" | cut -f 1 -d : | xargs ${CROSS_COMPILE}strip --strip-debug 2>/dev/null 339 fi 340 341 # usrmerge 342 if [ "$APKG_BINMERGE" ]; then 343 for b in bin sbin usr/sbin; do 344 if [ -d $PKG/$b ]; then 345 mkdir -p $PKG/usr/bin 346 mv $PKG/$b/* $PKG/usr/bin 347 rm -rf $PKG/$b 348 fi 349 done 350 fi 351 352 # runit service 353 for s in $sv; do 354 [ -f $SRC/$s ] || ret 1 355 case $s in 356 run) install -Dm755 $SRC/$s $PKG/etc/sv/$name/run 357 ln -s ../../../run/runit/supervise.$name $PKG/etc/sv/$name/supervise;; 358 finish) install -Dm755 $SRC/$s $PKG/etc/sv/$name/finish;; 359 *.run) install -Dm755 $SRC/$s $PKG/etc/sv/${s%.*}/run 360 ln -s ../../../run/runit/supervise.${s%.*} $PKG/etc/sv/${s%.*}/supervise;; 361 *.finish) install -Dm755 $SRC/$s $PKG/etc/sv/${s%.*}/finish;; 362 *.*) install -Dm644 $SRC/$s $PKG/etc/sv/${s%%.*}/${s#*.};; 363 *) install -Dm644 $SRC/$s $PKG/etc/sv/$name/$s;; 364 esac 365 done 366 367 if [ ! "$(ls -1 $PKG)" ]; then 368 msg "\$PKG is empty" 369 ret 1 370 fi 371 372 # temporary: for backward compatibility 373 if [ "$(grep '#MARKER' /usr/bin/spm)" ]; then 374 cd $PKG 375 spm -b $packagefile || { 376 msg "Failed packaging $packagefile" 377 ret 1 378 } 379 else 380 cd $APKG_PACKAGE_DIR 381 spm -b $PKG && { 382 mv package.spm $packagefile 383 } || { 384 msg "Failed packaging $packagefile" 385 ret 1 386 } 387 fi 388 389 if [ ! -f "$HERE"/.files ] || [ "$HERE"/abuild -nt "$HERE"/.files ]; then 390 pkg_updatefiles 391 fi 392 393 cd $HERE 394 remove_workdir 395 } 396 397 pkg_updatefiles() { 398 if [ ! -f "$packagefile" ]; then 399 msg "Package '$packagefile' not found." 400 ret 1 401 fi 402 msg "filelist updated." 403 tar -tvf $packagefile | awk '{$3=$4=$5=""; print $0}' | sort -k 3 > "$HERE"/.files 404 } 405 406 pkg_path() { 407 for p in $@; do 408 for r in $APKG_REPO; do 409 [ -f $r/$p/abuild ] && { 410 printf "%s\n" $r/$p 411 break 412 } 413 done 414 done 415 } 416 417 die() { 418 [ "$1" ] && printf "%s\n" "error: $1" 419 ret 1 420 } 421 422 checkdep() { 423 [ "$(pkg_path $1)" ] || return 424 # track processed pkg to avoid cycle deps 425 process="$process $1" 426 for ii in $(pkg_depends $1); do 427 # if already installed, skip 428 if [ "$skip_installed" ]; then 429 [ -s $SPM_PKGDB/$ii ] && continue 430 fi 431 # if deps already in process list, skip, cycle deps detected 432 printf "%s\n" $process | tr ' ' '\n' | grep -qx $ii && continue 433 # skip if itself in depends list 434 [ "$ii" = "$1" ] && continue 435 # skip if pkg already in deps list 436 printf "%s\n" $DEPS | tr ' ' '\n' | grep -x $ii && continue 437 # check deps 438 checkdep $ii 439 done 440 # will go here if no deps anymore to check, add it to list deps 441 DEPS="$DEPS $1" 442 } 443 444 pkg_deplist() { 445 for i in $@; do 446 # if already have in list deps, dont check again 447 if [ ! $(printf "%s\n" $DEPS | tr ' ' '\n' | grep -x $i) ]; then 448 checkdep $i 449 fi 450 done 451 printf "%s\n" $DEPS | tr ' ' '\n' 452 } 453 454 pkg_fsearch() { 455 for r in $APKG_REPO; do 456 rr="$rr $r/*/.files" 457 done 458 grep $1 $rr 2>/dev/null | tr ':' ' ' | awk '{print $1,$4}' | sed 's,/.files,,g' 459 } 460 461 pkg_dependents() { 462 for r in $APKG_REPO; do 463 rr="$rr $r/*/depends" 464 done 465 grep -x $1 $rr 2>/dev/null | rev | cut -d / -f 2 | rev 466 } 467 468 pkg_depends() { 469 _path=$(pkg_path $1) || return 1 470 [ -s $_path/depends ] || return 471 solve_alias $(grep -Ev ^'(#|$)' $_path/depends | awk '{print $1}') 472 } 473 474 solve_alias() { 475 [ "$APKG_ALIAS" ] || { 476 printf "%s\n" $@ 477 return 478 } 479 while [ "$1" ]; do 480 d=$(printf "%s\n" $APKG_ALIAS | tr ' ' '\n' | grep ^$1:* | head -n1 | awk -F : '{print $2}') 481 printf "%s\n" ${d:-$1} 482 shift 483 done 484 } 485 486 pkg_outdate() { 487 verbose=1 pkg_allinstalled | while read -r n v; do 488 if [ "$mask" ]; then 489 [ "$APKG_MASK" ] && { 490 printf "%s\n" "$APKG_MASK" | tr ' ' '\n' | grep -xq $n && continue 491 } 492 fi 493 [ "$(pkg_path $n)" ] || continue 494 nv="$(grep ^version= $(pkg_path $n)/abuild | tail -n1 | awk -F = '{print $2}')-$(grep ^release= $(pkg_path $n)/abuild | awk -F = '{print $2}')" 495 [ "$nv" ] || continue 496 [ "$v" = "$nv" ] || printf "%s\n" "$n $v -> $nv" 497 done 498 } 499 500 pkg_remove() { 501 needroot 502 for i in $@; do 503 SPM_ROOT=$APKG_ROOT spm -r $i 504 done 505 } 506 507 pkg_sysup() { 508 needroot 509 msg "Checking for outdated packages..." 510 od=$(mask=1 pkg_outdate | awk '{print $1}') 511 if [ ! "$od" ]; then 512 msg "No outdated packages." 513 exit 0 514 else 515 msg "Solving dependencies..." 516 for p in $(pkg_deplist $od); do 517 [ -s $SPM_PKGDB/$p ] || ni="$ni $p" 518 printf "%s\n" $od | tr ' ' '\n' | grep -qx $p && pu="$pu $p" 519 done 520 if [ "$ni" ]; then 521 newpkg=$(printf "%s\n" $ni | tr ' ' '\n' | wc -l) 522 msg "Installing $newpkg new package(s): $ni" 523 fi 524 totalpkg=$(printf "%s\n" $pu | tr ' ' '\n' | wc -l) 525 msg "Upgrading $totalpkg package(s): $pu" 526 prompt_user 527 if [ "$ni" ]; then 528 $APKG -i $ni #|| die 529 fi 530 $APKG -u $pu #|| die 531 fi 532 } 533 534 pkg_search() { 535 if [ ! "$APKG_REPO" ]; then 536 msg "No repo configured." 537 exit 1 538 fi 539 if [ "$pkg" ]; then 540 for p in $pkg; do 541 grep="$grep -e $p" 542 done 543 grep="grep $grep" 544 else 545 grep=cat 546 fi 547 [ "$verbose" ] && { 548 find $APKG_REPO -type f -name abuild 2>/dev/null | sed 's|/abuild||' | rev | awk -F / '{print $1}' | rev | $grep | while read line; do printf "$line "; awk -F'=' '/^version/ {print $2}' $($APKG -p $line)/abuild ; done 549 } || { 550 find $APKG_REPO -type f -name abuild 2>/dev/null | sed 's|/abuild||' | rev | awk -F / '{print $1}' | rev | $grep 551 } 552 } 553 554 pkg_depinstalll() { 555 needroot 556 for p in $@; do 557 if [ -s $SPM_PKGDB/$p ]; then 558 msg "Package '$p' is installed" 559 continue 560 fi 561 if [ ! "$(pkg_path $p)" ]; then 562 msg "Package '$p' not found" 563 continue 564 fi 565 pkg="$pkg $p" 566 done 567 [ "$pkg" ] || exit 0 568 set -- $pkg 569 msg "Solving dependencies..." 570 for p in $(skip_installed=1 pkg_deplist $@); do 571 [ -s $SPM_PKGDB/$p ] && continue 572 installthis="$installthis $p" 573 done 574 if [ ! "$installthis" ]; then 575 msg "Nothing to install. Exiting..." 576 exit 0 577 fi 578 totalpkg=$(printf "%s\n" $installthis | tr ' ' '\n' | wc -l) 579 msg "Installing $totalpkg package(s): $installthis" 580 prompt_user 581 $APKG -i $installthis || die 582 } 583 584 _trigger_fccache() { 585 command -v fc-cache >/dev/null || return 0 586 spm -l $1 | grep -q ^usr/share/fonts/$ && { 587 msg "Updating fontconfig cache..." 588 fc-cache -sf 589 } 590 } 591 592 _trigger_gdkpixbufcache() { 593 command -v gdk-pixbuf-query-loaders >/dev/null || return 0 594 spm -l $1 | grep -q ^usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/$ && { 595 msg "Probing GDK-Pixbuf loader modules..." 596 gdk-pixbuf-query-loaders --update-cache 597 } 598 } 599 600 _trigger_giomodules() { 601 command -v gio-querymodules >/dev/null || return 0 602 spm -l $1 | grep -q ^usr/lib/gio/modules/$ && { 603 msg "Updating GIO module cache..." 604 gio-querymodules /usr/lib/gio/modules 605 } 606 } 607 608 _trigger_glibschema() { 609 command -v glib-compile-schemas >/dev/null || return 0 610 spm -l $1 | grep -q ^usr/share/glib-2.0/schemas/$ && { 611 msg "Compiling GSettings XML schema files..." 612 glib-compile-schemas /usr/share/glib-2.0/schemas 613 } 614 } 615 616 _trigger_gtk2immodules() { 617 command -v gtk-query-immodules-2.0 >/dev/null || return 0 618 spm -l $1 | grep -q ^usr/lib/gtk-2.0/2.10.0/immodules/$ && { 619 msg "Probing GTK2 input method modules..." 620 gtk-query-immodules-2.0 --update-cache 621 } 622 } 623 624 _trigger_gtk3immodules() { 625 command -v gtk-query-immodules-3.0 >/dev/null || return 0 626 spm -l $1 | grep -q ^usr/lib/gtk-3.0/3.0.0/immodules/$ && { 627 msg "Probing GTK3 input method modules..." 628 gtk-query-immodules-3.0 --update-cache 629 } 630 } 631 632 _trigger_iconcache() { 633 command -v gtk-update-icon-cache >/dev/null || return 0 634 spm -l $1 | grep -q ^usr/share/icons/$ && { 635 msg "Updating icon theme caches..." 636 for dir in /usr/share/icons/* ; do 637 if [ -e $dir/index.theme ]; then 638 gtk-update-icon-cache -q $dir 2>/dev/null 639 else 640 rm -f $dir/icon-theme.cache 641 rmdir --ignore-fail-on-non-empty $dir 642 fi 643 done 644 } 645 } 646 647 _trigger_udevdb() { 648 command -v udevadm >/dev/null || return 0 649 spm -l $1 | grep -q ^etc/udev/hwdb.d/$ && { 650 msg "Updating hardware database..." 651 udevadm hwdb --update 652 } 653 } 654 655 _trigger_fontcache() { 656 command -v mkfontdir >/dev/null || return 0 657 command -v mkfontscale >/dev/null || return 0 658 spm -l $1 | grep -q ^usr/share/fonts/$ && { 659 msg "Updating X fontdir indices..." 660 for dir in $(find /usr/share/fonts -maxdepth 1 -type d \( ! -path /usr/share/fonts \)); do 661 rm -f $dir/fonts.scale $dir/fonts.dir $dir/.uuid 662 rmdir --ignore-fail-on-non-empty $dir 663 [ -d "$dir" ] || continue 664 mkfontdir $dir 665 mkfontscale $dir 666 done 667 } 668 } 669 670 _trigger_desktopdb() { 671 command -v update-desktop-database >/dev/null || return 0 672 spm -l $1 | grep -q ^usr/share/applications/$ && { 673 msg "Updating desktop file MIME type cache..." 674 update-desktop-database --quiet 675 } 676 } 677 678 _trigger_mimedb() { 679 command -v update-mime-database >/dev/null || return 0 680 spm -l $1 | grep -q ^usr/share/mime/$ && { 681 msg "Updating the MIME type database..." 682 update-mime-database /usr/share/mime 683 } 684 } 685 686 pkg_trigger() { 687 needroot 688 [ "$@" ] || set -- $($APKG -a) 689 for t in mimedb desktopdb fontcache fccache udevdb iconcache gtk3immodules gtk2immodules glibschema giomodules gdkpixbufcache; do 690 for p in $@; do 691 _trigger_$t $p && break 692 done 693 done 694 } 695 696 pkg_allinstalled() { 697 if [ "$pkg" ]; then 698 for p in $pkg; do 699 grep="$grep -e $p" 700 done 701 grep="grep $grep" 702 else 703 grep=cat 704 fi 705 [ "$verbose" ] && { 706 ls -1 $SPM_PKGDB | $grep | while read line; do printf "$line "; head -n1 $SPM_PKGDB/$line ; done 707 } || { 708 ls -1 $SPM_PKGDB | $grep 709 } 710 } 711 712 checksum_src() { 713 if [ ! -s "$checksum_file" ]; then 714 gencsum 715 else 716 b3sumcheck || return 0 717 printcsum > ${checksum_file}.tmp 718 diff -U 0 ${checksum_file} ${checksum_file}.tmp | \ 719 sed '/---/d;/+++/d;/@@/d' | \ 720 sed 's/^+/ new : /' | \ 721 sed 's/^-/ missing: /' > ${checksum_file}.diff 722 [ -s "${checksum_file}.diff" ] && { 723 cat ${checksum_file}.diff 724 msg "Checksum failed." 725 failed=1 726 } 727 rm -f ${checksum_file}.tmp ${checksum_file}.diff 728 [ "$failed" ] && ret 1 729 fi 730 } 731 732 printsource() { 733 # print out source full path 734 for printsource in $source; do 735 printsource=${printsource%::noextract} 736 case $printsource in 737 *::*) sourcename=${printsource%::*};; 738 *) sourcename=${printsource##*/};; 739 esac 740 case ${printsource#*::} in 741 */*) sourcenamefullpath=${APKG_SOURCE_DIR}/$sourcename;; 742 *) sourcenamefullpath=${HERE}/$sourcename;; 743 esac 744 printf "%s\n" $sourcenamefullpath 745 done 746 } 747 748 checksource() { 749 # check for source existence, exit non-zero if missing 750 for checksource in $(printsource); do 751 [ -f "$checksource" ] || { 752 msg "Source file '$checksource' not found." 753 failed=1 754 } 755 done 756 [ "$failed" ] && ret 1 757 } 758 759 b3sumcheck() { 760 command -v b3sum >/dev/null || { msg "'b3sum' not installed."; return 1; } 761 } 762 763 gencsum() { 764 checksource 765 b3sumcheck || return 0 766 rm -f .checksum 767 printcsum > .checksum 768 msg "Checksum file updated." 769 } 770 771 printcsum() { 772 for printcsum in $(printsource); do 773 [ -f "$printcsum" ] || continue 774 b3sum $printcsum | sed "s,$APKG_SOURCE_DIR/,,;s,$HERE/,," 775 done | sort -k 2 776 } 777 778 prompt_user() { 779 if [ ! "$APKG_NOPROMPT" ]; then 780 msg "Press ENTER to continue operation." 781 msg "Press Ctrl + C to abort." 782 read -r null 783 fi 784 } 785 786 runscript() { 787 if [ -x ./${1}install ]; then 788 msg "Running ${1}install script..." 789 if [ "$APKG_ROOT" ]; then 790 cat ./${1}install > "$APKG_ROOT"/.runscript 791 chmod +x "$APKG_ROOT"/.runscript 792 chroot "$APKG_ROOT" /.runscript 793 rm -f "$APKG_ROOT"/.runscript 794 else 795 ./${1}install 796 fi 797 fi 798 } 799 800 needroot() { 801 [ $(id -u) = 0 ] || { 802 msg 'This operation need root access' 803 exit 1 804 } 805 } 806 807 parsesubopt() { 808 # loop opts until found '-*' 809 shift; while [ "$1" ]; do 810 case $1 in 811 -*) break;; 812 *) printf "%s\n" "$1";; 813 esac 814 shift 815 done 816 } 817 818 updateopts() { 819 while [ "$1" ]; do 820 case $1 in 821 -*) newopt="$newopt $1";; 822 esac 823 shift 824 done 825 printf "%s\n" "$newopt" 826 } 827 828 parseopts() { 829 while [ "$1" ]; do 830 case $1 in 831 -I) pkg_depinstalll "$(parsesubopt "$@")"; exit 0;; 832 -D) pkg_deplist "$(parsesubopt "$@")"; exit 0;; 833 -r) pkg_remove "$(parsesubopt "$@")"; exit 0;; 834 -p) pkg_path "$(parsesubopt "$@")"; exit 0;; 835 -t) pkg_trigger "$(parsesubopt "$@")"; exit 0;; 836 -U) pkg_sysup; exit 0;; 837 -d) pkg_depends "$2"; exit 0;; 838 -s) search=1;; 839 -S) pkg_fsearch "$2"; exit 0;; 840 -j) pkg_dependents "$2"; exit 0;; 841 -a) allinstalled=1;; 842 -h) apkg_help; exit 0;; 843 -l) pkg_outdate; exit 0;; 844 -g) updatecsum=1;; 845 -k) updatefiles=1;; 846 -f) forcerebuild=1;; 847 -i) install=1;; 848 -u) upgrade=1;; 849 -o) downloadonly=1;; 850 -v) verbose=1;; 851 -*) msg "invalid option '$1'"; exit 1;; 852 *) pkg="$pkg $1";; 853 esac 854 shift 855 done 856 } 857 858 apkg_help() { 859 cat << EOF 860 usage: ${0##*/} <option> <arg(s)> 861 862 options: 863 -i <pkg(s)> install package(s) 864 -I <pkg(s)> install packages(s) with dependencies 865 -d <pkg> list <pkg> dependencies 866 -D <pkg(s)> list all dependencies 867 -j <pkg> list all dependents 868 -u <pkg(s)> upgrade package(s) 869 -r <pkg(s)> remove package(s) 870 -t [pkg(s)] trigger system cache/db updates 871 -U update system 872 -f force rebuild 873 -o <pkg(s)> download source 874 -p <pkg> print package path 875 -g <pkg> update package checksum 876 -k <pkg> update package files 877 -l list outdated packages 878 -s <pattern> search packages 879 -S <pattern> search files 880 -v be verbose 881 -h print this help message 882 883 environment variables: 884 APKG_ROOT override default root (${APKG_ROOT:-/}) location 885 APKG_CONF override default $APKG_CONF location 886 APKG_NOPROMPT set the variable for non-interactive use 887 APKG_LOG set the variable for logging the output to a file 888 889 EOF 890 exit 0 891 } 892 893 main() { 894 parseopts "$@" 895 set -- $(updateopts "$@") 896 897 if [ "$search" ]; then 898 pkg_search $@ 899 exit 0 900 fi 901 902 if [ "$allinstalled" ]; then 903 pkg_allinstalled $@ 904 exit 0 905 fi 906 907 for d in $APKG_PACKAGE_DIR $APKG_SOURCE_DIR $APKG_WORK_DIR $APKG_LOG_DIR; do 908 [ -d "$d" ] || { msg "Directory '$d' not exist"; exit 1; } 909 [ -w "$d" ] || { msg "Directory '$d' dont have write access"; exit 1; } 910 done 911 912 if [ "$pkg" ]; then 913 for p in $pkg; do 914 [ "$(pkg_path "$p")" ] || { 915 msg "Package '$p' not found" 916 continue 917 } 918 (cd "$(pkg_path "$p")" && $APKG "$@") || exit 1 919 done 920 exit 0 921 fi 922 923 if [ ! -f ./abuild ]; then 924 msg "'abuild' not found." 925 exit 1 926 fi 927 928 . ./abuild 929 [ "$name" ] || die "name is empty" 930 [ "$version" ] || die "version is empty" 931 [ "$release" ] || die "release is empty" 932 [ "$name" = "${PWD##*/}" ] || { 933 msg "'name' should be same as package directory name (${PWD##*/})." 934 exit 1 935 } 936 937 logfile="$APKG_LOG_DIR"/$name.log 938 packagefile="$APKG_PACKAGE_DIR"/$name#$version-$release.spm 939 940 if [ "$install" ] && [ -s "$SPM_PKGDB/${PWD##*/}" ]; then 941 msg "Package '${PWD##*/}' already installed." 942 exit 0 943 fi 944 945 if [ "$upgrade" ] && [ ! -s "$SPM_PKGDB/${PWD##*/}" ]; then 946 msg "Package '${PWD##*/}' not installed." 947 exit 0 948 fi 949 950 if [ "$updatecsum" ]; then 951 gencsum 952 exit 0 953 fi 954 955 if [ "$downloadonly" ]; then 956 fetch_src 957 exit 0 958 fi 959 960 if [ "$updatefiles" ]; then 961 pkg_updatefiles 962 exit 0 963 fi 964 965 if [ "$(id -u)" != 0 ]; then 966 msg "Packages need to build as root. Aborted." 967 exit 1 968 fi 969 970 if [ -f "$packagefile" ] && [ ! "$forcerebuild" ]; then 971 if [ ! "$install" ] && [ ! "$upgrade" ]; then 972 msg "Package '$packagefile' found." 973 fi 974 else 975 if [ "$install" ] || [ "$upgrade" ]; then 976 # run preinstall script before build 977 runscript pre 978 fi 979 fetch_src 980 checksum_src 981 extract_src 982 [ "$APKG_LOG" ] && { 983 build_src 2>&1 | tee -- "$logfile" 984 } || { 985 build_src 986 } 987 fi 988 989 if [ "$install" ]; then 990 SPM_ROOT=${APKG_ROOT%/} spm -i "$packagefile" || exit $? 991 elif [ "$upgrade" ]; then 992 SPM_ROOT=${APKG_ROOT%/} spm -u "$packagefile" || exit $? 993 fi 994 995 if [ "$install" ] || [ "$upgrade" ]; then 996 # run postinstall script after installed/upgraded 997 runscript post 998 [ "$APKG_ROOT" ] || pkg_trigger "$name" 999 fi 1000 } 1001 1002 umask 022 1003 1004 export HERE="$PWD" 1005 1006 APKG=$0 1007 SPM_PKGDB="${APKG_ROOT%/}/var/lib/spm/db" 1008 1009 # for apkg config, either override or default 1010 APKG_CONF="${APKG_CONF:-/etc/apkg.conf}" 1011 1012 ## NEED BETTER WAY TO DO THIS? 1013 # environment override 1014 O_APKG_REPO=$APKG_REPO 1015 O_APKG_PACKAGE_DIR=$APKG_PACKAGE_DIR 1016 O_APKG_SOURCE_DIR=$APKG_SOURCE_DIR 1017 O_APKG_WORK_DIR=$APKG_WORK_DIR 1018 O_APKG_LOG_DIR=$APKG_LOG_DIR 1019 O_APKG_MASK=$APKG_MASK 1020 1021 # default value 1022 APKG_REPO="$PWD" 1023 APKG_PACKAGE_DIR="$PWD" 1024 APKG_SOURCE_DIR="$PWD" 1025 APKG_WORK_DIR="$PWD" 1026 APKG_LOG_DIR="$PWD" 1027 1028 checksum_file="$HERE/.checksum" 1029 1030 # source config 1031 if [ -f "$APKG_CONF" ]; then 1032 . "$APKG_CONF" 1033 fi 1034 1035 # reset value, use override first, else either from config or use default 1036 APKG_REPO=${O_APKG_REPO:-$APKG_REPO} 1037 APKG_PACKAGE_DIR=${O_APKG_PACKAGE_DIR:-$APKG_PACKAGE_DIR} 1038 APKG_SOURCE_DIR=${O_APKG_SOURCE_DIR:-$APKG_SOURCE_DIR} 1039 APKG_WORK_DIR=${O_APKG_WORK_DIR:-$APKG_WORK_DIR} 1040 APKG_LOG_DIR=${O_APKG_LOG_DIR:-$APKG_LOG_DIR} 1041 APKG_MASK=${O_APKG_MASK:-$APKG_MASK} 1042 1043 main "$@" 1044 1045 exit 0