Keeping Your autopkg Cache So Fresh and So Clean, Clean

It’s been a minute since I felt I had something worthwhile to write about. In the past, the autopkg systems I had configured either had plenty of internal storage or external storage available to more or less “set it and forget it”. The consequence of this approach is over time if you have many software titles your autopkg cache folder will become quite large. Depending on the recipes you use, say you have many that involve naming downloaded or packaged software with the version, this can also greatly increase the size because new software version downloads and packages don’t overwrite the previous ones. So if you find yourself like I do where free space is precious on your autopkg system, you need an automated way to clean it.

While I haven’t yet taken the leap to implement autopkg in a CI workflow that makes this whole issue moot, I wrote a script to periodically clean out old downloads, packages, as well as the tmp files that can result from incomplete downloads.

As written, running this on the command line will remove any .dmg, .pkg, .tar.gz, and .zip files older than 7 days. It also removes those pesky tmp files that can get leftover from incomplete software downloads. This can also be triggered to be run as part of a LaunchDaemon.

If you wish, you can tweak the threshold for removing old files by entering your own day value for DAYS_TO_DELETE. Additionally, if you wish to exclude any items that would normally be deleted, uncomment the EXCLUSIONS variable and enter any desired search terms.

Happy cleaning!

#!/bin/bash
# Script to find and delete .dmg, .pkg, .tar.gz, and .zip files from
# your autopkg cache
# Failed / incomplete downloads (prefixed with tmp) are also removed
# Number of days after which to delete matching files
readonly DAYS_TO_DELETE=7
# Path to autopkg Cache folder for current user
readonly SEARCH_PATH="/Users/${USER}/Library/AutoPkg/Cache"
# List of search terms to exclude from cleanup, separated by spaces
#
# readonly EXCLUSIONS="Slack Firefox"
# Path to autopkg cleanup log. For CLI use, otherwise comment out
readonly LOG="/Library/Logs/autopkg_cleanup.log"
#######################################
# Output errors with timestamp to STDERR
# Globals:
# CLEANUP_LIST
# DAYS_TO_DELETE
# SEARCH_PATH
# EXCLUSIONS
# Arguments:
# None
# Outputs:
# None
#######################################
get_files_to_clean() {
CLEANUP_LIST="$(/usr/bin/find ${SEARCH_PATH} \( -iname "*.pkg" -o -iname "*.dmg" -o -iname "*.zip" -o -iname "tmp*" -o -iname "*.tar.gz" \) -mtime +${DAYS_TO_DELETE} -maxdepth 5 -print | sort)"
# Remove any excluded items from the list
for i in $EXCLUSIONS; do
CLEANUP_LIST=$(echo "$CLEANUP_LIST" | grep -v ${i})
done
}
#######################################
# Output results
# Globals:
# CLEANUP_LIST
# DAYS_TO_DELETE
# Arguments:
# None
# Outputs:
# Prints & writes to log if no files found older
# than specified DAYS_TO_DELETE, or prints & writes
# all found files to clean and indicates if it failed
#######################################
clean_files() {
# Output results
if [ -z "$CLEANUP_LIST" ]; then
# Indicate no files found to delete
writelog "No files found to clean older than ${DAYS_TO_DELETE} days."
else
# Indicate found files to delete
writelog "Files found to clean older than ${DAYS_TO_DELETE} days:"
for i in ${CLEANUP_LIST}; do
writelog "${i}"
done
# Remove found files and output any failures
for f in $CLEANUP_LIST; do
writelog "Removing $(basename ${f})"
/bin/rm -f "$f" || writelog "Failed to remove ${f}."
done
fi
}
start_run() {
writelog "####### START $(/bin/date +'%Y-%m-%d') #######"
}
end_run() {
writelog "####### END $(/bin/date +'%Y-%m-%d') #######"
}
writelog() {
# For LaunchDaemon use
#echo "$(/bin/date +'%Y-%m-%dT%H:%M:%S') – $*" #>&1
# For CLI use
echo "$(/bin/date +'%Y-%m-%dT%H:%M:%S')$*" >> "$LOG"
}
main() {
start_run
get_files_to_clean
clean_files
end_run
}
main "@"

3 comments

  1. Graham · March 2

    I’d love a version of this script which would keep the latest download and converted package, but remove any older downloads and packages. AutoPkg needs the most recent download and package to correctly determine whether something is new or not, and my workflows require the package to still be there when the time comes to stage to production.

    Like

    • apizz · March 2

      I appreciate the feedback. This was meant to simply clean old downloads & pkgs, as we don’t care about redownloading old software or rebuilding packages that we may already have since ultimately these won’t be reimported into our distribution if it’s the same version that we already have. I’m not likely to spend time on adding your requested functionality in the near future, but feel free to use mine as base for whatever you come up with to meet your needs.

      Like

  2. Julian Müller · March 5

    We had about the same idea 🙂 I would make the file types variable. Also include an exclusion for the paths with the suffix .app in order not to delete required files inside apps.

    References here: https://github.com/Bretterteig/autopkg-tools/blob/master/autopkg-cache-cleaner.sh

    Like

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s