summaryrefslogtreecommitdiff
path: root/src/chroot-tools/chcleanup
diff options
context:
space:
mode:
Diffstat (limited to 'src/chroot-tools/chcleanup')
-rwxr-xr-xsrc/chroot-tools/chcleanup102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/chroot-tools/chcleanup b/src/chroot-tools/chcleanup
new file mode 100755
index 0000000..a43065b
--- /dev/null
+++ b/src/chroot-tools/chcleanup
@@ -0,0 +1,102 @@
+#!/usr/bin/env bash
+set -eE
+# (c) Nicolás Reynolds <fauno@parabola.nu>
+# Released under GPLv3
+#
+# Performs chroot cleanup smartly, it only removes the unneeded packages or
+# leaves you with a cleansystem
+#
+# See: HOOKPREBUILD
+
+DRYRUN=${DRYRUN:-false}
+
+################################################################################
+# Define these here to avoid having dependencies on outside files
+
+if type gettext &>/dev/null; then
+ _() { gettext "$@"; }
+else
+ _() { echo "$@"; }
+fi
+
+plain() {
+ local mesg="$(_ "$1")"; shift
+ printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
+}
+
+msg() {
+ local mesg="$(_ "$1")"; shift
+ printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
+}
+
+msg2() {
+ local mesg="$(_ "$1")"; shift
+ printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
+}
+
+warning() {
+ local mesg="$(_ "$1")"; shift
+ printf "${YELLOW}==> $(gettext "WARNING:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
+}
+
+error() {
+ local mesg="$(_ "$1")"; shift
+ printf "${RED}==> $(gettext "ERROR:")${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
+}
+
+################################################################################
+
+if [[ ! -f /.arch-chroot ]] && ! ${DRYRUN}; then
+ error "(chcleanup): Must be run inside of a chroot"
+ exit 1
+fi
+
+source /etc/libretools.d/chroot.conf
+# If we're running makepkg
+if [ -f PKGBUILD ]; then
+ export CARCH="$(. /etc/makepkg.conf; printf '%s' "$CARCH")"
+ source PKGBUILD
+ CHROOTEXTRAPKG+=("${depends[@]}"
+ "${makedepends[@]}"
+ "${checkdepends[@]}")
+fi
+
+msg "Cleaning chroot..."
+msg2 "Fetching updated package lists..."
+pacman -Sy || {
+ warning "There was an error updating package lists, ignoring."
+}
+
+# Setup the temporary directory
+TEMPDIR="$(mktemp --tmpdir -d $(basename $0).XXXXX)"
+trap "rm -rf '$TEMPDIR'" EXIT
+
+cp -a /var/lib/pacman/sync "${TEMPDIR}/"
+pkglist="${TEMPDIR}"/pkglist.txt
+
+# Get the full list of packages needed by dependencies, including the base system
+msg2 "Creating a full list of packages..."
+pacman -b "${TEMPDIR}" \
+ -Sp --print-format "%n" base-devel "${CHROOTEXTRAPKG[@]}" >"$pkglist" || {
+ ret=$?
+ error "Could not create a full list of packages, exiting."
+ plain "This is likely caused by a dependency that could not be found."
+ exit $ret
+}
+
+# Diff installed packages against a clean chroot then remove leftovers
+packages=($(comm -23 <(pacman -Qq | sort -u) \
+ <(sort -u "${pkglist}")))
+
+if [[ ${#packages[@]} = 0 ]]; then
+ msg2 "No packages to remove"
+else
+ msg2 "Removing %d packages" ${#packages[@]}
+
+ if ${DRYRUN}; then
+ echo "${packages[*]}"
+ else
+ # Only remove leftovers, -Rcs removes too much
+ pacman --noconfirm -Rn "${packages[@]}"
+ fi
+fi