Skip to content

Instantly share code, notes, and snippets.

@FriendlyNeighborhoodShane
Last active October 6, 2021 10:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FriendlyNeighborhoodShane/ffcac3df6d796023d2283a6afdacedbc to your computer and use it in GitHub Desktop.
Save FriendlyNeighborhoodShane/ffcac3df6d796023d2283a6afdacedbc to your computer and use it in GitHub Desktop.
Package manager cache cleaner tool for kisslinux
#!/bin/sh -e
# Manage your kiss source/tarball cache
# See if terminal is interactive
[ -t 1 ] || KISS_COLOR=0;
# Conditionally use sexy kiss-accurate colors for prompts
if [ "$KISS_COLOR" != "0" ]; then
col0="$(printf "\033[m")";
col1="$(printf "\033[1;33m")";
col2="$(printf "\033[1;34m")";
else
col0="";
col1="";
col2="";
fi;
prompt="${col1}->${col0}";
indir="$KISS_ROOT/var/db/kiss/installed";
chdir="$HOME/.cache/kiss";
# Exit with failure
abort() {
echo "${col1}!>${col0} FATAL: $1";
exit 1;
}
# substitute pairs of string args from first sring
# taken from kiss
fnr() {
_fnr="$1"; shift 1;
while :; do
case "$_fnr-$#" in
*"$1"*) _fnr="${_fnr%"$1"*}${2}${_fnr##*"$1"}" ;;
*-2) break ;;
*) shift 2 ;;
esac;
done;
printf '%s\n' "$_fnr";
}
# use fnr() subst on a source file line
fnr_src() {
str="$1"; shift 1;
for subst in VERSION RELEASE MAJOR MINOR PATCH IDENT PACKAGE; do
str="$(fnr "$str" "\\$subst" ' ' "$subst" "$1" ' ' "$subst")";
shift 1;
done;
printf '%s\n' "$str";
}
# use fnr_src() on a pkg dir's sources file
fnr_cat() {
repo="$1";
read -r version release _ < "$repo/version" || :;
IFS=.+-_ read -r major minor patch ident <<EOF;
$version
EOF
package="$(basename "$repo")";
while read -r src path; do
src="$(fnr_src "$src" "$version" "$release" "$major" "$minor" "$patch" "$ident" "$package")";
printf '%s %s\n' "$src" "$path";
done < "$repo/sources" || :;
}
# Record size of object, output name and perhaps delete
clean() {
[ -e "$1" ] || return;
cachesize="$(( cachesize + $(du -s "$1" | awk '{ print $1 }') ))";
echo "${prompt} Found: ${col2}$1${col0}";
[ "$reallydelete" = "yes" ] && {
# Make sure we don't ruin stuff out of $chdir by mistake
[ "$1" = "$chdir/${1##$chdir/}" ] && rm -rf "$1";
} || :;
}
# Help screen
usage() {
echo "
usage: $0 [-dbls]
options:
-d actually delete the files listed
(otherwise only list and calculate size)
-b list all binaries, including those of latest/installed versions
(otherwise only list old versions)
-l list all logs, including error logs
(otherwise only list post-install logs)
-s list all sources, including those of latest/installed versions
(otherwise only list old sources)
Run the command first without the -d flag to see what will be deleted and how
much space will be freed, then run again with the flag to actually delete files.
";
}
reallydelete="no"; # Whether to actually delete stuff
cleanallbin="no"; # Whether to include currently installed/latest bins
cleanalllog="no"; # Whether to include build error logs
cleanallsource="no"; # Whether to include currently installed/latest sources
for arg in "$@"; do
case "$arg" in
--)
shift 1;
break;
;;
--help)
usage;
exit 0;
;;
-*)
shift 1;
# Split the shortarg into letters
for option in $(echo "${arg##-}" | sed "s|.|& |g"); do
case "$option" in
d)
reallydelete="yes";
;;
b)
cleanallbin="yes";
;;
l)
cleanalllog="yes";
;;
s)
cleanallsource="yes";
;;
h)
usage;
exit 0;
;;
*)
abort "Unrecognised option [$option]";
;;
esac;
done;
;;
*)
abort "Unrecognised argument [$arg]";
;;
esac;
done;
cachesize="0";
for bin in "$chdir"/bin/*; do
[ -e "$bin" ] || continue;
pkgbin="$(basename "$bin")";
pkg="${pkgbin%%[@#]*}";
ver="${pkgbin##*[@#]}";
ver="${ver%%.tar.gz}";
# Do more checks if it's installed and we are not deleting all
[ "$cleanallbin" != "yes" ] && [ -d "$indir/$pkg" ] && {
# Version is installed, keep
[ "$ver" = "$(cat "$indir/$pkg/version" | awk '{ print $1 "-" $2 }' || :)" ] && continue;
# Version is latest in top repo, keep
[ "$ver" = "$(cat "$(kiss search "$pkg" | head -n1)/version" | awk '{ print $2 "-" $3 }' || :)" ] && continue;
} || :
clean "$bin";
done;
for log in "$chdir"/logs/*; do
[ -e "$log" ] || continue;
case "$(basename "$log")" in
post-install-*)
# Is a post-install log
;;
*)
# Is not a post-install log, check if we are deleting all logs
[ "$cleanalllog" != "yes" ] && continue || :;
;;
esac;
clean "$log";
done;
for source in "$chdir"/sources/*; do
[ -e "$source" ] || continue;
pkg="$(basename "$source")";
# Do more checks if it's installed and we are not deleting all
if [ "$cleanallsource" != "yes" ] && [ -d "$indir/$pkg" ]; then
find "$source/" -type f | while read -r file; do
[ -e "$file" ] || continue;
name="${file#$source/}";
str="$(basename "$name")";
[ "$(dirname "$name")" = "." ] || str="$str\([[:space:]]\{1,\}$(dirname "$name")[/]*\)$";
# Source of installed version, keep
fnr_cat "$indir/$pkg" | grep -q "$str" && continue || :;
# Source of latest version from top repo, keep
fnr_cat "$(kiss search "$pkg" | head -n1)" | grep -q "$str" && continue || :;
clean "$file";
done;
else
clean "$source";
fi;
done;
[ "$cachesize" = "0" ] && cachesizem="0" || cachesizem="$(( cachesize / 1024 + 1 ))";
echo;
echo "${prompt} Total size: ${col2}${cachesizem}mb${col0}";
echo;
exit 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment