aboutsummaryrefslogtreecommitdiff
path: root/contrib/cpt-size
blob: 22a77b7dd6839354a20c2accb4eaead015e9d411 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#!/bin/sh -ef
# Show the size on disk for a package

## SYNOPSIS:
## .Nm
## .Op Fl st
## .Op Ar pkg...

## DESCRIPTION:
## .Nm
## 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. If no arguments have
## been given,
## .Nm
## 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"