[pacman-dev] [PATCH v2] paccache: adding the possibility for multiple cachedirs

Dave Reisner d at falconindy.com
Mon Aug 25 15:36:31 EDT 2014


On Aug 25, 2014 3:09 PM, "Maxim Andersson" <thesilentboatman at gmail.com>
wrote:
>
> Either by specifing several -c parameters or only
> one -c parameter with a comma separated value.
> One could for example be for the official arch packages
> and one for the aur.
>
> Signed-off-by: Maxim Andersson <thesilentboatman at gmail.com>
> ---
>  contrib/paccache.sh.in| 82
++++++++++++++++++++++++++++++--------------------
>  1 file changed, 49 insertions(+), 33 deletions(-)
>
> diff --git a/contrib/paccache.sh.inb/contrib/paccache.sh.in
> index 039ac8a..e96bf81 100644
> --- a/contrib/paccache.sh.in
> +++ b/contrib/paccache.sh.in
> @@ -23,9 +23,9 @@ shopt -s extglob
>  declare -r myname='paccache'
>  declare -r myver='@PACKAGE_VERSION@'
>
> -declare -a candidates=() cmdopts=() whitelist=() blacklist=()
> +declare -a cachedirs=() candidates=() cmdopts=() whitelist=()
blacklist=()
>  declare -i delete=0 dryrun=0 filecount=0 move=0 needsroot=0 totalsaved=0
verbose=0
> -declare    cachedir=@localstatedir@/cache/pacman/pkg delim=$'\n' keep=3
movedir= scanarch=
> +declare    delim=$'\n' keep=3 movedir= scanarch=
>
>  USE_COLOR='y'
>
> @@ -159,25 +159,25 @@ A flexible pacman cache cleaning utility.
>  Usage: ${myname} <operation> [options] [targets...]
>
>    Operations:
> -    -d, --dryrun          perform a dry run, only finding candidate
packages.
> -    -m, --move <dir>      move candidate packages to "dir".
> -    -r, --remove          remove candidate packages.
> +    -d, --dryrun           perform a dry run, only finding candidate
packages.
> +    -m, --move <dir>       move candidate packages to "dir".
> +    -r, --remove           remove candidate packages.
>
>    Options:
> -    -a, --arch <arch>     scan for "arch" (default: all architectures).
> -    -c, --cachedir <dir>  scan "dir" for packages.
> -                          (default: @localstatedir@/cache/pacman/pkg).
> -    -f, --force           apply force to mv(1) and rm(1) operations.
> -    -h, --help            display this help message and exit.
> -    -i, --ignore <pkgs>   ignore "pkgs", comma-separated. Alternatively,
specify
> -                          "-" to read package names from stdin, newline-
> -                          delimited.
> -    -k, --keep <num>      keep "num" of each package in the cache
(default: 3).
> -    --nocolor             remove color from output.
> -    -u, --uninstalled     target uninstalled packages.
> -    -v, --verbose         increase verbosity. specify up to 3 times.
> -    -z, --null            use null delimiters for candidate names (only
with -v
> -                          and -vv).
> +    -a, --arch <arch>      scan for "arch" (default: all architectures).
> +    -c, --cachedir <dirs>  scan "dirs" for packages, comma-separated.
> +                           (default: @localstatedir@/cache/pacman/pkg).
> +    -f, --force            apply force to mv(1) and rm(1) operations.
> +    -h, --help             display this help message and exit.
> +    -i, --ignore <pkgs>    ignore "pkgs", comma-separated. Alternatively,
> +                           pecify "-" to read package names from stdin,
newline-
> +                           delimited.
> +    -k, --keep <num>       keep "num" of each package in the cache
(default: 3).
> +    --nocolor              remove color from output.
> +    -u, --uninstalled      target uninstalled packages.
> +    -v, --verbose          increase verbosity. specify up to 3 times.
> +    -z, --null             use null delimiters for candidate names (only
with -v
> +                           and -vv).
>
>  EOF
>  }
> @@ -203,7 +203,9 @@ while :; do
>                         scanarch=$2
>                         shift ;;
>                 -c|--cachedir)
> -                       cachedir=$2
> +                       IFS=',' read -r -a dirs <<< "$2"
> +                       cachedirs+=("${dirs[@]}")
> +                       unset dirs
>                         shift ;;
>                 -d|--dryrun)
>                         dryrun=1 ;;
> @@ -256,6 +258,11 @@ done
>
>  m4_include(../scripts/library/term_colors.sh)
>
> +# setting default cachedir
> +if [ "${#cachedirs[@]}" -eq 0 ]; then
> +       cachedirs[0]='@localstatedir@/cache/pacman/pkg'
> +else

This "else" is a syntax error that make check would catch... I was fine
with the PE, I just wanted the decl to be an array, i.e.

d=("${d[@]:-'default'}")

> +
>  # remaining args are a whitelist
>  whitelist=("$@")
>
> @@ -265,28 +272,37 @@ case $(( dryrun+delete+move )) in
>         [^1]) die "only one operation may be used at a time" ;;
>  esac
>
> -[[ -d $cachedir ]] ||
> -       die "cachedir '%s' does not exist or is not a directory"
"$cachedir"
> -
>  [[ $movedir && ! -d $movedir ]] &&
>         die "destination directory '%s' does not exist or is not a
directory" "$movedir"
>
>  if (( move || delete )); then
>         # make it an absolute path since we're about to chdir
>         [[ ${movedir:0:1} != '/' ]] && movedir=$PWD/$movedir
> -       [[ ! -w $cachedir || ( $movedir && ! -w $movedir ) ]] &&
needsroot=1
> +       [[ $movedir && ! -w $movedir ]] && needsroot=1
>  fi
>
> -# unlikely that this will fail, but better make sure
> -cd "$cachedir" >/dev/null || die "failed to chdir to '%s'" "$cachedir"
> +for cachedir in "${cachedirs[@]}"; do
> +       [[ -d $cachedir ]] ||
> +               die "cachedir '%s' does not exist or is not a directory"
"$cachedir"
> +
> +       if (( move || delete )); then
> +               [[ ! -w $cachedir  ]] && needsroot=1
> +       fi
>
> -# note that these results are returned in an arbitrary order from awk,
but
> -# they'll be resorted (in summarize) iff we have a verbosity level set.
> -IFS=$'\n' read -r -d '' -a candidates < \
> -       <(printf '%s\n' *.pkg.tar?(.+([^.])) | pacsort --files |
> -               pkgfilter "$keep" "$scanarch" \
> -                       "${#whitelist[*]}" "${whitelist[@]}" \
> -                       "${#blacklist[*]}" "${blacklist[@]}")
> +       # unlikely that this will fail, but better make sure
> +       cd "$cachedir" >/dev/null || die "failed to chdir to '%s'"
"$cachedir"

This might fail on an iteration after the first since we don't enforce
absolute dirs for cachedirs. You probably want to return to the original
dir after each iteration using pushd/popd. Add error catching and redirect
output to /dev/null as we do in makepkg.

> +
> +       # note that these results are returned in an arbitrary order from
awk, but
> +       # they'll be resorted (in summarize) iff we have a verbosity
level set.
> +       IFS=$'\n' read -r -d '' -a cand < \
> +               <(printf '%s\n' *.pkg.tar?(.+([^.])) | pacsort --files |
> +                       pkgfilter "$keep" "$scanarch" \
> +                               "${#whitelist[*]}" "${whitelist[@]}" \
> +                               "${#blacklist[*]}" "${blacklist[@]}")
> +
> +       candidates+=("${cand[@]}")
> +       unset cand
> +done

>
>  if (( ! ${#candidates[*]} )); then
>         msg 'no candidate packages found for pruning'
> --
> 2.0.3
>

I have my doubts about how this works across multiple dirs because we rely
on PWD being the cachedir. I'm not in a position to test this (on a phone
hours away from home).


More information about the pacman-dev mailing list