Files
scratchpkg/scratch
2020-02-07 23:22:30 +08:00

1232 lines
28 KiB
Bash
Executable File

#!/bin/sh
#
# scratchpkg
#
# Copyright (c) 2018 by Emmett1 (emmett1.2miligrams@gmail.com)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
RED='\e[0;31m'
GREEN='\e[0;32m'
YELLOW='\e[0;33m'
CYAN='\e[0;36m'
PURPLE='\e[0;35m'
CRESET='\e[0m'
nocolor() {
RED=
GREEN=
YELLOW=
CYAN=
PURPLE=
CRESET=
}
msg() {
printf "${GREEN}==>${CRESET} $1\n"
}
msgerr() {
printf "${RED}==> ERROR:${CRESET} $1\n"
}
msginst() {
printf "[${GREEN}i${CRESET}] $1\n"
}
msgmiss() {
printf "[${YELLOW}m${CRESET}] $1\n"
}
msgnoinst() {
printf "[-] $1\n"
}
msgwarn() {
printf "${YELLOW}==> WARNING:${CRESET} $1\n"
}
needroot() {
if [ "$(id -u)" != 0 ]; then
if [ "$#" -eq 0 ]; then
needroot "This operation"
else
msgerr "$* need root access!"
fi
exit 1
fi
}
getportpath() {
for repo in $PORT_REPO; do
if [ -f "$repo/$1/$BUILD_SCRIPT" ]; then
dirname "$repo/$1/$BUILD_SCRIPT"
return 0
fi
done
return 1
}
vercomp() {
if [ "$1" = "$2" ]; then
return 0 # same version
elif [ "$1" = "$(echo "$1\n$2" | sort -V | head -n1)" ]; then
return 1 # $1 lower than $2
else
return 2 # $1 higher than $2
fi
}
installed_pkg_info() {
if isinstalled $2; then
grep ^$1 $INDEX_DIR/$2/.pkginfo | cut -d " " -f3-
fi
}
allinstalled() {
grep ^name "$INDEX_DIR"/*/.pkginfo | awk '{print $3}'
}
deps_alias() {
[ -f $ALIAS_FILE ] || {
echo $@
return
}
while [ "$1" ]; do
getalias=$(grep -w ^$1 $ALIAS_FILE | awk '{print $2}')
echo ${getalias:-$1}
shift
done
unset getalias
}
get_depends() {
ppath=$(getportpath $1) || return 0
deps=$(grep "^# depends[[:blank:]]*:" $ppath/$BUILD_SCRIPT \
| sed 's/^# depends[[:blank:]]*:[[:blank:]]*//' \
| tr ' ' '\n' \
| awk '!a[$0]++' \
| sed 's/,//')
deps_alias $deps
}
confirm() {
printf "$1 (Y/n) "
read -r response
case "$response" in
[Nn][Oo]|[Nn]) echo "$2"; return 2 ;;
*) : ;;
esac
return 0
}
checktool() {
if ! type -p $1 >/dev/null; then
msgerr "'$1' not exist in your system!"
exit 1
fi
}
needarg() {
[ "$*" ] || {
msgerr "This operation required an arguments!"
exit 1
}
}
isinstalled() {
if [ -s "$INDEX_DIR/$1/.pkginfo" ] && [ "$(grep $1 $INDEX_DIR/$1/.pkginfo)" ]; then
return 0
else
return 1
fi
}
settermtitle() {
printf "\033]0;$*\a"
}
scratch_integrity() {
if [ "$1" ]; then
cd /
if [ -f $INDEX_DIR/$1/.files ]; then
cat $INDEX_DIR/$1/.files | while read -r line; do
if [ ! -e "$line" ]; then
if [ -L "$line" ]; then
printf "${YELLOW}broken symlink${CRESET} $1: /$line"
else
printf "${RED}file missing${CRESET} $1: /$line"
fi
fi
done
else
echo "Package '$1' not installed."
exit 1
fi
cd - >/dev/null
else
cd /
for pkg in $(allinstalled); do
cat $INDEX_DIR/$pkg/.files | while read -r line; do
if [ ! -e "$line" ]; then
if [ -L "$line" ]; then
echo "broken symlink $pkg: /$line"
else
echo "missing file $pkg: /$line"
fi
fi
done
done
cd - >/dev/null
fi
}
scratch_lock() {
needroot "Locking package"
for pkg in "$@"; do
if ! isinstalled $pkg; then
msgerr "Package '$pkg' is not installed."
elif [ -f $INDEX_DIR/$pkg/.lock ]; then
msgerr "Package '$pkg' already locked."
else
touch $INDEX_DIR/$pkg/.lock && msg "Successfully locked package '$pkg'."
fi
done
}
scratch_unlock() {
needroot "Unlocking package"
for pkg in "$@"; do
if ! isinstalled $pkg; then
msgerr "Package '$pkg' is not installed."
elif [ ! -f $INDEX_DIR/$pkg/.lock ]; then
msgerr "Package '$pkg' is not locked."
else
rm -f $INDEX_DIR/$pkg/.lock && msg "Successfully unlocked package '$pkg'."
fi
done
}
scratch_isorphan() {
needarg $@
for pkg in $(allinstalled); do
if depend=$(get_depends $pkg); then
for dep in $depend; do
if [ $dep = $1 ]; then
return 1
fi
done
fi
unset depend dep
done
return 0
}
scratch_sync() {
checktool httpup
needroot "Updating ports"
if [ ! -e "$REPO_FILE" ]; then
msgerr "Repo file not found! ($REPO_FILE)"
exit 1
fi
grep -Ev '^(#|$)' "$REPO_FILE" | awk '{print $1,$2}' | while read -r repodir repourl; do
if [ "$repodir" ] && [ "$repourl" ]; then
httpup sync $repourl $repodir || {
msgerr "Failed sync from $repourl"
exit 1
}
fi
done
}
scratch_trigger() {
needroot "Run trigger"
if [ -z "$*" ]; then
for i in $(seq 12); do
eval trig_$i=1
done
else
pre_triggers $@
fi
post_triggers
}
post_triggers() {
if [ "$trig_12" = 1 ]; then
echo "trigger: Running mkdirs..."
for mkd in $INDEX_DIR/*/.pkgmkdirs; do
[ -s $mkd ] || continue
grep -Ev '^(#|$)' $mkd | while read -r dir mode uid gid junk; do
if [ -e "$dir" ]; then
if [ "$uid" != '-' ]; then
getent passwd $uid >/dev/null && chown "$uid" "$dir"
fi
if [ "$gid" != '-' ]; then
getent group $gid >/dev/null && chgrp "$gid" "$dir"
fi
if [ "$mode" != '-' ]; then
chmod "$mode" "$dir"
fi
fi
done
done
fi
if [ "$trig_11" = 1 ] && [ $(type -p fc-cache) ]; then
echo "trigger: Updating fontconfig cache..."
fc-cache -s
fi
if [ "$trig_10" = 1 ] && [ $(type -p gdk-pixbuf-query-loaders) ]; then
echo "trigger: Probing GDK-Pixbuf loader modules..."
gdk-pixbuf-query-loaders --update-cache
fi
if [ "$trig_9" = 1 ] && [ $(type -p gio-querymodules) ]; then
echo "trigger: Updating GIO module cache..."
gio-querymodules /usr/lib/gio/modules
fi
if [ "$trig_8" = 1 ] && [ $(type -p glib-compile-schemas) ]; then
echo "trigger: Compiling GSettings XML schema files..."
glib-compile-schemas /usr/share/glib-2.0/schemas
fi
if [ "$trig_7" = 1 ] && [ $(type -p gtk-query-immodules-2.0) ]; then
echo "trigger: Probing GTK2 input method modules..."
gtk-query-immodules-2.0 --update-cache
fi
if [ "$trig_6" = 1 ] && [ $(type -p gtk-query-immodules-3.0) ]; then
echo "trigger: Probing GTK3 input method modules..."
gtk-query-immodules-3.0 --update-cache
fi
if [ "$trig_5" = 1 ] && [ $(type -p gtk-update-icon-cache) ]; then
echo "trigger: Updating icon theme caches..."
for dir in /usr/share/icons/* ; do
if [ -e $dir/index.theme ]; then
gtk-update-icon-cache -q $dir 2>/dev/null
else
rm -f $dir/icon-theme.cache
rmdir --ignore-fail-on-non-empty $dir
fi
done
fi
if [ "$trig_4" = 1 ] && [ $(type -p udevadm) ]; then
echo "trigger: Updating hardware database..."
udevadm hwdb --update
fi
if [ "$trig_3" = 1 ] && [ $(type -p mkfontdir) ] && [ $(type -p mkfontscale) ]; then
echo "trigger: Updating X fontdir indices..."
for dir in $(find /usr/share/fonts -maxdepth 1 -type d \( ! -path /usr/share/fonts -a ! -name X11 \)) /usr/share/fonts/X11/*; do
rm -f $dir/fonts.scale $dir/fonts.dir $dir/.uuid
rmdir --ignore-fail-on-non-empty $dir
[ -d "$dir" ] || continue
mkfontdir $dir
mkfontscale $dir
done
fi
if [ "$trig_2" = 1 ] && [ $(type -p update-desktop-database) ]; then
echo "trigger: Updating desktop file MIME type cache..."
update-desktop-database --quiet
fi
if [ "$trig_1" = 1 ] && [ $(type -p update-mime-database) ]; then
echo "trigger: Updating the MIME type database..."
update-mime-database /usr/share/mime
fi
}
pre_triggers() {
# mime db
if [ "$trig_1" != "1" ]; then
for pkg in $@; do
if [ -s "$INDEX_DIR/$pkg/.files" ] && [ "$(grep ^usr/share/mime/$ $INDEX_DIR/$pkg/.files)" ]; then
trig_1=1
break
fi
done
fi
# desktop db
if [ "$trig_2" != "1" ]; then
for pkg in $@; do
if [ -s "$INDEX_DIR/$pkg/.files" ] && [ "$(grep ^usr/share/applications/$ $INDEX_DIR/$pkg/.files)" ]; then
trig_2=1
break
fi
done
fi
# mkfontdir
if [ "$trig_3" != "1" ]; then
for pkg in $@; do
if [ -s "$INDEX_DIR/$pkg/.files" ] && [ "$(grep ^usr/share/fonts/$ $INDEX_DIR/$pkg/.files)" ]; then
trig_3=1
break
fi
done
fi
# hwdb
if [ "$trig_4" != "1" ]; then
for pkg in $@; do
if [ -s "$INDEX_DIR/$pkg/.files" ] && [ "$(grep ^etc/udev/hwdb.d/$ $INDEX_DIR/$pkg/.files)" ]; then
trig_4=1
break
fi
done
fi
# icon caches
if [ "$trig_5" != "1" ]; then
for pkg in $@; do
if [ -s "$INDEX_DIR/$pkg/.files" ] && [ "$(grep ^usr/share/icons/$ $INDEX_DIR/$pkg/.files)" ]; then
trig_5=1
break
fi
done
fi
# gtk3 immodules
if [ "$trig_6" != "1" ]; then
for pkg in $@; do
if [ -s "$INDEX_DIR/$pkg/.files" ] && [ "$(grep ^usr/lib/gtk-3.0/3.0.0/immodules/.*.so $INDEX_DIR/$pkg/.files)" ]; then
trig_6=1
break
fi
done
fi
# gtk2 immodules
if [ "$trig_7" != "1" ]; then
for pkg in $@; do
if [ -s "$INDEX_DIR/$pkg/.files" ] && [ "$(grep ^usr/lib/gtk-2.0/2.10.0/immodules/.*.so $INDEX_DIR/$pkg/.files)" ]; then
trig_7=1
break
fi
done
fi
# gsettings schema
if [ "$trig_8" != "1" ]; then
for pkg in $@; do
if [ -s "$INDEX_DIR/$pkg/.files" ] && [ "$(grep ^usr/share/glib-2.0/schemas/$ $INDEX_DIR/$pkg/.files)" ]; then
trig_8=1
break
fi
done
fi
# gio modules
if [ "$trig_9" != "1" ]; then
for pkg in $@; do
if [ -s "$INDEX_DIR/$pkg/.files" ] && [ "$(grep ^usr/lib/gio/modules/.*.so $INDEX_DIR/$pkg/.files)" ]; then
trig_9=1
break
fi
done
fi
# gdk-pixbuf
if [ "$trig_10" != "1" ]; then
for pkg in $@; do
if [ -s "$INDEX_DIR/$pkg/.files" ] && [ "$(grep ^usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/.*.so $INDEX_DIR/$pkg/.files)" ]; then
trig_10=1
break
fi
done
fi
# font caches
if [ "$trig_11" != "1" ]; then
for pkg in $@; do
if [ -s "$INDEX_DIR/$pkg/.files" ] && [ "$(grep ^usr/share/fonts/$ $INDEX_DIR/$pkg/.files)" ]; then
trig_11=1
break
fi
done
fi
# makedirs
if [ "$trig_12" != "1" ]; then
for pkg in $@; do
if [ -s "$INDEX_DIR/$pkg/.pkgmkdirs" ]; then
trig_12=1
break
fi
done
fi
}
scratch_build() {
while [ "$1" ]; do
case $1 in
-i|-u|-r|-g|-p) ;;
-*) OPTS="$OPTS $1";;
*) PKGNAME="$PKGNAME $1";;
esac
shift
done
[ "$PKGNAME" ] || {
echo "Please specify package(s) to build."
return 1
}
for pkg in $PKGNAME; do
ppath=$(getportpath $pkg) || {
echo "Package '$pkg' not found."
return 1
}
cd $ppath
settermtitle "Building $pkg..."
pkgbuild $OPTS || {
settermtitle "Building $pkg failed."
return 1
}
settermtitle "Building $pkg done."
cd - >/dev/null
done
}
scratch_install() {
needroot "Installing package"
while [ "$1" ]; do
case $1 in
-i|-u) ;;
-r|--reinstall) REINSTALL=1;;
-y|--yes) NOCONFIRM=1;;
-n|--no-dep) NO_DEP=1;;
--exclude=*) EXOPT=$1;;
-*) OPTS="$OPTS $1";;
*) PKGNAME="$PKGNAME $1";;
esac
shift
done
[ "$PKGNAME" ] || {
echo "Please specify package(s) to install."
return 1
}
# if reinstall, dont calculate dep, just reinstall it then exit
if [ "$REINSTALL" = 1 ]; then
error=0
for ii in $PKGNAME; do
if [ ! $(getportpath $ii) ]; then
echo "Package '$ii' not found."
elif ! isinstalled $ii; then
echo "Package '$ii' not installed."
else
cd $(getportpath $ii)
settermtitle "Reinstalling $ii..."
pkgbuild $OPTS -r || {
error=1
break
}
done_pkg="$done_pkg $ii"
cd - >/dev/null
fi
done
settermtitle "Triggering install hook..."
[ "$done_pkg" ] && scratch_trigger $done_pkg
settermtitle "Reinstalling done."
return "$error"
fi
if [ "$NO_DEP" = 1 ]; then
error=0
for ii in $PKGNAME; do
if [ ! $(getportpath $ii) ]; then
echo "Package '$ii' not found."
elif isinstalled $ii; then
echo "Package '$ii' already installed."
continue
else
cd $(getportpath $ii)
settermtitle "Installing $ii..."
pkgbuild -i $OPTS || {
error=1
break
}
done_pkg="$done_pkg $ii"
cd - >/dev/null
fi
done
settermtitle "Triggering install hook..."
[ "$done_pkg" ] && scratch_trigger $done_pkg
settermtitle "Installing done."
return "$error"
fi
for i in $PKGNAME; do
if [ ! $(getportpath $i) ]; then
echo "Package '$i' not found."
elif isinstalled $i; then
echo "Package '$i' already installed."
else
IPKG="$IPKG $i"
fi
done
[ "$IPKG" ] || return 0
echo "Resolving dependencies..."
INST="$(scratch_deplist -q $IPKG $EXOPT)"
if [ "$INST" ]; then
echo
pkgcount=0
for pkg in $INST; do
pkgcount=$(( pkgcount + 1 ))
printf "[${GREEN}i${CRESET}] $pkg "
done
echo; echo
echo "( $pkgcount install )"
echo
if [ ! "$NOCONFIRM" ]; then
confirm "Continue install package(s)?" "Package installation cancelled." || exit $?
echo
fi
error=0
count=0
total=$(echo $INST | wc -w)
for int in $INST; do
count=$(( count + 1 ))
if portpathh=$(getportpath $int); then
cd $portpathh
settermtitle "[ $count/$total ] installing $int..."
pkgbuild -i $OPTS || {
error=1
count=$(( count - 1 ))
break
}
done_pkg="$done_pkg $int"
cd - >/dev/null
else
msgwarn "Skipping missing package: $int"
fi
unset portpathh
done
settermtitle "Triggering install hook..."
[ "$done_pkg" ] && scratch_trigger $done_pkg
settermtitle "$count/$total package(s) installed."
return "$error"
fi
}
scratch_remove() {
needroot "Removing package"
while [ "$1" ]; do
case $1 in
-y|--yes) NOCONFIRM=1;;
-*) OPTS="$OPTS $1";;
*) PKGNAME="$PKGNAME $1";;
esac
shift
done
[ "$PKGNAME" ] || {
echo "Please specify package(s) to remove."
return 1
}
for i in $PKGNAME; do
if ! isinstalled $i; then
echo "Package '$i' not installed."
else
IPKG="$IPKG $i"
fi
done
[ "$IPKG" ] || return 0
echo "Removing packages..."
echo
pkgcount=0
count=0
for pkg in $IPKG; do
pkgcount=$(( pkgcount + 1 ))
printf "[${RED}x${CRESET}] $pkg "
done
echo; echo
echo "( $pkgcount remove )"
echo
[ "$NOCONFIRM" ] || {
confirm "Continue remove package(s)?" "Package removing cancelled." || exit $?
echo
}
for pkg in $IPKG; do
count=$(( count + 1 ))
pre_triggers $pkg
settermtitle "[ $count/$pkgcount ] Removing $pkg..."
pkgdel $pkg $OPTS || {
error=1
break
}
done
settermtitle "Triggering remove hook..."
post_triggers
settermtitle "$pkgcount package(s) removed."
}
outdatepkg() {
for pkg in $(allinstalled); do
if [ ! -e "$INDEX_DIR/$pkg/.lock" ] && getportpath $pkg >/dev/null; then
. $(getportpath $pkg)/$BUILD_SCRIPT
if [ -z "$name" ] || [ -z "$version" ]; then
continue
fi
iversion=$(installed_pkg_info version $pkg)
irelease=$(installed_pkg_info release $pkg)
if [ "$release" != "$irelease" ] || [ "$version" != "$iversion" ]; then
echo $name
fi
unset iversion irelease version release
fi
done
}
scratch_sysup() {
needroot "Upgrading package"
while [ "$1" ]; do
case $1 in
-i|-u|-r) ;;
-y|--yes) NOCONFIRM=1;;
-n|--no-dep) NODEP=1;;
--exclude=*) EXOPT=$1;;
-*) OPTS="$OPTS $1";;
esac
shift
done
echo "Checking for outdated packages..."
PKGOUTDATE=$(outdatepkg)
[ "$PKGOUTDATE" ] || {
echo "All packages are up to date."
return 0
}
[ "$(echo $PKGOUTDATE | tr ' ' '\n' | grep -x scratchpkg)" ] && {
echo
msgwarn "Please upgrade 'scratchpkg' first.'"
return 1
}
UPGPKG=0
NEWPKG=0
if [ "$NODEP" != 1 ]; then
echo "Resolving dependencies..."
DEP=$(scratch_deplist $PKGOUTDATE $EXOPT | awk '{print $2}')
echo
for d in $DEP; do
if [ "$(echo $PKGOUTDATE | tr ' ' '\n' | grep -x $d)" = "$d" ]; then
printf "[${GREEN}u${CRESET}] $d "
WILLINSTALL="$WILLINSTALL $d"
UPGPKG=$(( UPGPKG + 1 ))
elif ! isinstalled $d && [ "$(getportpath "$d")" ]; then
printf "[${CYAN}n${CRESET}] $d "
WILLINSTALL="$WILLINSTALL $d"
NEWPKG=$(( NEWPKG + 1 ))
fi
done
else
echo
for dd in $PKGOUTDATE; do
printf "[${GREEN}u${CRESET}] $dd "
WILLINSTALL="$WILLINSTALL $dd"
UPGPKG=$(( UPGPKG + 1 ))
done
fi
echo; echo
echo "( $UPGPKG upgrade, $NEWPKG new install )"
echo
[ "$NOCONFIRM" ] || {
confirm "Continue upgrade/install these package(s)?" "Package upgrade cancelled." || exit $?
echo
}
error=0
count=0
total=$(echo $WILLINSTALL | wc -w)
for inst in $WILLINSTALL; do # install all required dependencies and target packages itself
count=$(( count + 1 ))
cd $(getportpath $inst)
if ! isinstalled $inst; then
settermtitle "[ $count/$total ] Installing $inst..."
pkgbuild -i $OPTS || {
error=1
count=$(( count - 1 ))
break
}
else
settermtitle "[ $count/$total ] Upgrading $inst..."
pkgbuild -u $OPTS || {
error=1
count=$(( count - 1 ))
break
}
fi
cd - >/dev/null
done_pkg="$done_pkg $inst"
done
settermtitle "Triggering install hook."
[ "$done_pkg" ] && scratch_trigger $done_pkg
settermtitle "$count/$total package(s) upgraded."
return "$error"
}
scratch_upgrade() {
needroot "Upgrading package"
while [ "$1" ]; do
case $1 in
-i|-r) ;;
-y|--yes) NOCONFIRM=1;;
-d|--no-dep) NO_DEP=1;;
--exclude=*) EXOPT=$1;;
-*) OPTS="$OPTS $1";;
*) PKGNAME="$PKGNAME $1";;
esac
shift
done
[ "$PKGNAME" ] || {
echo "Please specify package(s) to upgrade."
return 1
}
for pkg in $PKGNAME; do
if ! isinstalled $pkg; then
msgerr "Package '$pkg' not installed."
continue
elif [ ! $(getportpath $pkg) ]; then
msgerr "Package '$pkg' not exist."
continue
else
. $(getportpath $pkg)/$BUILD_SCRIPT
if [ "$(installed_pkg_info version $pkg)-$(installed_pkg_info release $pkg)" = "$version-$release" ]; then
msg "Package '$pkg' is up to date."
continue
fi
fi
upkg="$upkg $pkg"
done
[ "$upkg" ] || return 0
[ "$NO_DEP" ] || {
echo "Resolving dependencies..."
DEP=$(scratch_deplist $upkg $EXOPT | awk '{print $2}')
for dep in $DEP; do
if ! isinstalled $dep; then
[ "$(getportpath $dep)" ] && newpkg="$newpkg $dep"
fi
done
}
echo
tnew=0
tup=0
for i in $newpkg; do
tnew=$(( tnew + 1 ))
printf "[${CYAN}n${CRESET}] $i "
done
for i in $upkg; do
tup=$(( tup + 1 ))
printf "[${GREEN}u${CRESET}] $i "
done
echo; echo
echo "( $tup upgrade, $tnew new install )"
echo
[ "$NOCONFIRM" ] || {
confirm "Continue upgrade/install these package(s)?" "Package upgrade cancelled." || exit $?
echo
}
total=$(( tup + tnew ))
count=0
error=0
if [ "$newpkg" ]; then
for pkg in $newpkg; do
count=$(( count + 1 ))
cd $(getportpath $pkg)
settermtitle "[ $count/$total ] Installing $pkg..."
pkgbuild -i $OPTS || {
error=1
count=$(( count - 1 ))
break
}
done_pkg="$done_pkg $pkg"
cd - >/dev/null
done
fi
for pkg in $upkg; do # upgrade all target packages
count=$(( count + 1 ))
cd $(getportpath $pkg)
settermtitle "[ $count/$total ] Upgrading $pkg..."
pkgbuild -u $OPTS || {
error=1
count=$(( count - 1 ))
break
}
done_pkg="$done_pkg $pkg"
cd - >/dev/null
done
settermtitle "triggering upgrade hook..."
[ "$done_pkg" ] && scratch_trigger $done_pkg
settermtitle "$count/$total package(s) upgraded."
return "$error"
}
scratch_outdate() {
for pkg in $(allinstalled); do
if [ "$(getportpath $pkg)" ]; then
. $(getportpath $pkg)/$BUILD_SCRIPT
if [ -z "$name" ] || [ -z "$version" ]; then
continue
fi
iversion=$(installed_pkg_info version $pkg)
irelease=$(installed_pkg_info release $pkg)
[ -f "$INDEX_DIR/$pkg/.lock" ] && ITSLOCK="[locked]"
outdatemsg="$name $iversion-$irelease => $version-$release $ITSLOCK"
newerinstmsg="$name $iversion-$irelease => $version-$release [newer installed] $ITSLOCK"
if [ "$version" != "$iversion" ]; then
vercomp $version $iversion
if [ $? = 2 ]; then
echo "$outdatemsg"
OUTDATE=yes
elif [ $? = 1 ]; then
echo "$newerinstmsg"
OUTDATE=yes
fi
elif [ "$release" != "$irelease" ]; then
vercomp $release $irelease
if [ $? = 2 ]; then
echo "$outdatemsg"
OUTDATE=yes
elif [ $? = 1 ]; then
echo "$newerinstmsg"
OUTDATE=yes
fi
fi
unset ITSLOCK name version
fi
done
[ ! "$OUTDATE" ] && msg "All packages are up to date."
}
scratch_search() {
needarg $@
arg=$*
for repo in $PORT_REPO; do
out=$(grep -R "# description" $repo | grep $BUILD_SCRIPT | grep "$arg" | awk -F : '{print $1}' | sort)
[ "$out" ] || continue
found=1
for line in $out; do
repo=$(echo $line | rev | awk -F / '{print $3}' | rev)
desc=$(grep "^# description[[:blank:]]*:" $line | sed 's/^# description[[:blank:]]*:[[:blank:]]*//')
. $line
if isinstalled $name; then
ins="[${GREEN}*${CRESET}]"
else
ins="[ ]"
fi
printf "$ins ${PURPLE}($repo)${CRESET} $name ${CYAN}$version-$release${CRESET}: $desc\n"
unset repo desc name version release build
done
unset out
done
if [ ! "$found" ]; then
msg "No matching package found."
fi
}
scratch_cache() {
needroot "Clear old caches"
allcachepkg=/tmp/.allcachepkg.$$
allcachesrc=/tmp/.allcachesrc.$$
keepcachepkg=/tmp/.keepcachepkg.$$
keepcachesrc=/tmp/.keepcachesrc.$$
diffcachepkg=/tmp/.diffcachepkg.$$
diffcachesrc=/tmp/.diffcachesrc.$$
[ -f /etc/scratchpkg.conf ] && . /etc/scratchpkg.conf
touch \
$allcachepkg \
$allcachesrc \
$keepcachepkg \
$keepcachesrc \
$diffcachepkg \
$diffcachesrc
if [ "$(find $PACKAGE_DIR -mindepth 1 -print -quit 2>/dev/null)" ]; then
for list in "$PACKAGE_DIR"/*; do
basename $list >> "$allcachepkg"
done
fi
if [ "$(find $SOURCE_DIR -mindepth 1 -print -quit 2>/dev/null)" ]; then
for list in "$SOURCE_DIR"/*; do
basename $list >> "$allcachesrc"
done
fi
for repo in $PORT_REPO; do
if [ "$(find $repo/*/ -mindepth 1 -print -quit 2>/dev/null)" ]; then # check directory if its not empty
for port in $repo/*/$BUILD_SCRIPT; do
. $port
echo "$name-$version-$release.spkg.tar.$COMPRESSION_MODE" >> "$keepcachepkg"
if [ "$source" ]; then
for src in $source; do
if echo $src | grep -Eq "(ftp|http|https)://"; then
if echo $src | grep -Eq "::(ftp|http|https)://"; then
sourcename="$(echo $src | awk -F '::' '{print $1}')"
else
sourcename="$(echo $src | rev | cut -d / -f 1 | rev)"
fi
echo $sourcename >> "$keepcachesrc"
fi
done
fi
done
fi
done
grep -Fxv -f "$keepcachepkg" "$allcachepkg" > "$diffcachepkg"
grep -Fxv -f "$keepcachesrc" "$allcachesrc" > "$diffcachesrc"
cat $diffcachepkg
cat $diffcachesrc
if [ -s "$diffcachepkg" ]; then
cd "$PACKAGE_DIR"
sizepkg=$(du -ch $(cat $diffcachepkg) | grep total | awk '{print $1}')
cd - >/dev/null
else
sizepkg=0M
fi
if [ -s "$diffcachesrc" ]; then
cd "$SOURCE_DIR"
sizesrc=$(du -ch $(cat $diffcachesrc) | grep total | awk '{print $1}')
cd - >/dev/null
else
sizesrc=0M
fi
echo "Total package cache size: $sizepkg"
echo "Total source cache size : $sizesrc"
if [ -s "$diffcachepkg" ] || [ -s "$diffcachesrc" ]; then
echo
confirm "Clear old caches?" "Old caches is kept." && {
for i in $(cat $diffcachepkg); do
[ -e "$PACKAGE_DIR/$i" ] && rm -v "$PACKAGE_DIR/$i"
done
for i in $(cat $diffcachesrc); do
[ -e "$SOURCE_DIR/$i" ] && rm -v "$SOURCE_DIR/$i"
done
}
fi
rm -f \
"$allcachepkg" \
"$allcachesrc" \
"$keepcachepkg" \
"$keepcachesrc" \
"$diffcachepkg" \
"$diffcachesrc"
}
scratch_deplist() {
OLDIFS=$IFS
IFS=,
while [ "$1" ]; do
case $1 in
-q|--quick) quick=1;;
--exclude=*) for i in ${1#*=}; do exclude="$exclude $i"; done;;
-*) ;;
*) PKG="$PKG $1";;
esac
shift
done
IFS=$OLDIFS
[ "$PKG" ] || {
echo "Please specify package(s) to list dependencies."
return 1
}
for p in $PKG; do
if [ "$(getportpath $p)" ]; then
PPKG="$PPKG $p"
else
[ "$quick" = 1 ] || msgerr "Package '$p' not exist."
fi
done
for p in $PPKG; do
deplist $p
done
[ "$DEP" ] || return 0
if [ "$quick" = 1 ]; then
echo $DEP | tr ' ' '\n'
else
for p in $DEP; do
if isinstalled $p; then
echo "[*] $p"
else
echo "[-] $p"
fi
done
if [ "$MISSINGDEP" ]; then
for m in $MISSINGDEP; do
echo "Missing deps: $m" | sed 's/(/ (/'
done
fi
fi
}
deplist() {
# skip excluded dependencies
if echo $exclude | tr " " "\n" | grep -qx $1; then
return 0
fi
# check currently process for circular dependencies
# for circular dependencies, found first will take precedence
[ "$CHECK" ] && {
if echo $CHECK | tr " " "\n" | grep -qx $1; then
return 0
fi
}
# add package to currently process
CHECK="$CHECK $1"
# check dependencies
for i in $(get_depends $1); do
if [ "$quick" = 1 ] && isinstalled $i; then
continue
else
if ! echo $DEP | tr " " "\n" | grep -qx $i; then
if ! getportpath $i >/dev/null; then
MISSINGDEP="$MISSINGDEP $i($1)"
else
deplist $i
fi
fi
fi
done
# add dependency to list checked dep
if ! echo $DEP | tr " " "\n" | grep -qx $1; then
if [ "$quick" = 1 ]; then
isinstalled $1 || DEP="$DEP $1"
else
DEP="$DEP $1"
fi
fi
# delete item from loop process
CHECK=$(echo $CHECK | sed "s/$1//")
}
scratch_help() {
cat << EOF
Usage:
$(basename $0) <options> [<arg>]
Options:
install <ports> <arg> install ports (use pkgbuild arg, except '-i' & '-u')
-r|--reinstall reinstall
-n|--no-dep skip dependencies
-y|--yes skip ask user permission
--exclude=* exclude dependencies, comma separated
upgrade <ports> <arg> upgrade ports (use pkgbuild arg, except '-i' & '-r')
-n|--no-dep skip dependencies
-y|--yes skip ask user permission
--exclude=* exclude dependencies, comma separated
remove <ports> <arg> remove installed ports (use pkgdel arg)
-y|--yes skip ask user permission
sysup <arg> full system upgrade (use pkgbuild arg, except '-i', '-r' & '-u')
-n|--no-dep skip dependencies
-y|--yes skip ask user permission
--exclude=* exclude dependencies, comma separated
deplist <ports> print all dependencies for ports
-q|--quick skip installed ports
--exclude=* exclude dependencies, comma separated
build <ports> <arg> build ports (use pkgbuild arg, except '-i', '-u', '-r', '-g', & '-p')
lock <ports> locking ports prevent upgrade
unlock <ports> unlock locked ports
trigger [ports] run system trigger
sync update ports database
search <pattern> find ports in repo
outdate print outdated ports
cache print and clear old pkg and src caches
integrity check installed port integrity
help print this help msg
Global options:
--repo=<repo path> add custom repo path
--nocolor disable colour for output
EOF
}
print_runhelp_msg() {
echo "Run '$(basename $0) help' to see available options."
exit 2
}
BUILD_SCRIPT="spkgbuild"
INDEX_DIR="/var/lib/scratchpkg/index"
REPO_FILE="/etc/scratchpkg.repo"
ALIAS_FILE="/etc/scratchpkg.alias"
# default value from pkgbuild
SOURCE_DIR="/var/cache/scratchpkg/sources"
PACKAGE_DIR="/var/cache/scratchpkg/packages"
COMPRESSION_MODE="xz"
mode=$1
if [ -z "$mode" ]; then
print_runhelp_msg
fi
shift
for opt in $@; do
case $opt in
--nocolor) nocolor;;
--repo=*) PORT_REPO="$PORT_REPO ${opt#*=}";;
--*) MAINOPTS="$MAINOPTS $opt";;
-*) char=${#opt}; count=1
while [ "$count" != "$char" ]; do
count=$((count+1))
MAINOPTS="$MAINOPTS -$(echo $opt | cut -c $count)"
done;;
*) MAINOPTS="$MAINOPTS $opt";;
esac
shift
done
if [ -f "$REPO_FILE" ]; then
for repodir in $(grep -Ev '^(#|$)' "$REPO_FILE" | awk '{print $1}'); do
PORT_REPO="$PORT_REPO $repodir"
done
fi
if [ "$(type -t scratch_$mode)" = "function" ]; then
scratch_$mode $MAINOPTS
else
print_runhelp_msg
fi
exit $?