diff options
Diffstat (limited to 'contrib/cpt-size')
-rwxr-xr-x | contrib/cpt-size | 102 |
1 files changed, 65 insertions, 37 deletions
diff --git a/contrib/cpt-size b/contrib/cpt-size index 2812d56..22a77b7 100755 --- a/contrib/cpt-size +++ b/contrib/cpt-size @@ -3,6 +3,7 @@ ## SYNOPSIS: ## .Nm +## .Op Fl st ## .Op Ar pkg... ## DESCRIPTION: @@ -10,41 +11,68 @@ ## calculates the sizes of given ## .Ar packages ## using the files from the package manifest and outputs a total size of the -## packages along with all the files associated with them. - -## CAVEATS: +## packages along with all the files associated with them. If no arguments have +## been given, ## .Nm -## uses the non-POSIX -## .Fl h -## and -## .Fl c -## flags for -## .Xr du 1 , -## which will not work with -## .Em sbase , -## but it is a major performance improvement compared to calculating -## total and human-readable sizes by hand. - -case "$1" in - --help|-h) - printf '%s\n' "usage: ${0##*/} [pkg...]" - exit 0 - ;; - '') set -- "${PWD##*/}" -esac - -for pkg; do cpt-list "$pkg" >/dev/null; done - -files= -for pkg; do - while read -r file; do - # Filter directories from manifest and leave only files. - # Directories in the manifest end in a trailing '/'. - case $file in */) continue; esac - files="$files '$file'" - done < "$CPT_ROOT/var/db/cpt/installed/$pkg/manifest" -done -eval "set -- $files" - -# Send the file list to 'du'. -du -shc -- "$@" 2>/dev/null +## will use the name of the current directory as an argument. +## .Pp +## The options are as follows: +## .Bl -tag -width 13n +## .It Fl s +## Sort the output by size. +## .It Fl t +## Output only the size of given packages and not individual files. +parser_definition() { + setup REST help:usage -- "usage: ${0##*/} [-st] [pkg...]" + flag sort -s hidden:1 + flag total -t hidden:1 + disp :usage -h --help hidden:1 +} + +# shellcheck source=../src/cpt-lib +# shellcheck disable=1091 +. cpt-lib + +# Use the current directory if no arguments have been given. +[ "$1" ] || set -- "${PWD##*/}" + +# Ensure that all the packages given as arguments are installed. +pkg_list "$@" >/dev/null + +mkdir -p "$tmp_dir" + +# We don't immediately pipe into awk as we want to exit in an error. +if [ "$total" ]; then + for pkg; do + sed '/\/$/d;s/./\\&/g' "$sys_db/$pkg/manifest" | + xargs du -k | + awk -v name="$pkg" '{size+=$1}END{printf("%s %s\n", size, name)}' >> "$tmp_dir/size" + done +else + for pkg; do sed '/\/$/d;s/./\\&/g' "$sys_db/$pkg/manifest"; done | + xargs du -k > "$tmp_dir/size" +fi + +# Do a numerical sort on the file if requested. +[ "$sort" ] && sort -no "$tmp_dir/size" "$tmp_dir/size" + +# This awk function formats the `du` output similar to the '-hc' flags. We +# could have used a shell `while read` loop to do the exact same thing, but that +# would be much much slower. +awk 'function fmtsize(s) { + if (s==0) f="" + else if (s<1024) f="K" + else if (s<(1048576)){f="M";s=s/1024;} + else if (s<(1073741824)){f="G";s=s/1048576;} + else f="" + return int(s) f + } + { + sc = $1 + size += $1 + sub(sprintf("^%s\s*", $1), "") + printf("%-6s %s\n", fmtsize(sc), $0) + } + END { + printf("%-6s total\n", fmtsize(size)) + }' "$tmp_dir/size" |