aboutsummaryrefslogtreecommitdiff
path: root/contrib/cpt-size
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cpt-size')
-rwxr-xr-xcontrib/cpt-size102
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"