ambevar-dotfiles/.scripts/pacsize

149 lines
3.7 KiB
Bash
Executable File

#!/bin/sh
# pacsize -- display package sizes
#
# Copyright (C) 2014 Pierre Neidhardt <ambrevar@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 2
# 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 <http://www.gnu.org/licenses/>.
################################################################################
## Helper functions.
calc_total () {
awk '{
total += $1
print
}
END {
printf ("%7s KIB TOTAL\n", total)
}'
}
remove_duplicates () {
awk '! table[$0]++'
}
usage() {
cat <<EOF
Usage: ${1##*/} [OPTIONS] PACKAGES
${1##*/} -a [OPTIONS]
Display package sizes. Duplicates are removed if any. Output can be sorted by
name or size. A grand total can be printed at the end. Both the sync and the
local databes can be used for lookup.
Options:
-a: All installed packages. Implies -Q.
-h: Show this help.
-n: Output is sorted by name.
-Q: Use local database. It speeds up queries and allows displaying
size of local packages not available in repos.
-S: Use sync database. It is slower but allows to display size of
non-installed packages.
-s: Output is sorted by size.
-t: Print total.
Examples:
${1##*/} -ast
Convenient way to keep track of big packages.
${1##*/} -Q \$(pactree -ld1 linux)
Print the size of linux and all its direct dependencies.
${1##*/} -Qst \$(pacman -Qdtq)
Print a grand total of orphan packages, and sort by size.
EOF
}
db="Q"
opt_sort=false
opt_all=false
opt_total=false
while getopts ":ahnQSst" opt; do
case $opt in
a)
opt_all=true
db="Q" ;;
h)
usage "$0"
exit ;;
n)
opt_sort="sort -uk3" ;;
Q)
db="Q" ;;
S)
db="S" ;;
s)
opt_sort="sort -un" ;;
t)
opt_total="calc_total" ;;
?)
usage "$0"
exit 1 ;;
esac
done
shift $(($OPTIND - 1))
################################################################################
## All-packages mode. We use a dedicated algorithm which is much faster than
## per-package mode.
if $opt_all; then
DBPath="$(awk -F = '/^ *DBPath/{print $2}' /etc/pacman.conf)"
[ ! -d "$DBPath" ] && DBPath="/var/lib/pacman/"
[ ! -d "$DBPath/local/" ] && exit
awk '/^%NAME%/ {
getline
pkg=$0
}
/^%SIZE%/ {
getline
size = $0 / 1024
printf ("%6s KiB %s\n", size, pkg)
}' "$DBPath"/local/*/desc | ($opt_sort || cat) | ($opt_total || cat)
exit
fi
################################################################################
## Per-package mode.
if [ $# -eq 0 ]; then
echo "Missing argument." >&2
usage "$0"
exit 1
fi
if ! command -v pacman >/dev/null 2>&1; then
echo "'pacman' not found." >&2
exit 1
fi
## Locale.
LC_NAME="$(gettext pacman "Name")"
LC_SIZE="$(gettext pacman "Installed Size :" | sed 's/ *: *$//')"
## We use external variable for awk to fit current locales. In the following
## command, we strip the decimals. This makes output lighter.
pacman -${db}i "$@" 2>/dev/null | awk -F ": " \
-v pkgsize="$LC_SIZE" -v pkgname="$LC_NAME" \
'$0 ~ pkgname {
pkg = $2
}
$0 ~ pkgsize {
gsub (/[\.,].*/, "")
printf ("%7s KiB %s\n", $2, pkg)
}' | ($opt_sort || remove_duplicates) | ($opt_total || cat)