Merge pull request #1008 from AladW/fetch-rework-iv
[aurutils.git] / lib / aur-repo-filter
blob3be57ac28d12da50c772b283adbdd61b3a4891f8
1 #!/bin/bash
2 # aur-repo-filter - filter packages in the Arch Linux repositories
3 [[ -v AUR_DEBUG ]] && set -o xtrace
4 argv0='repo-filter'
5 PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
6 arch_repo=(core extra testing community{,-testing} multilib{,-testing})
8 # default options
9 sync_repo=0
11 # The command line will hit ARG_MAX on approximately 70k packages;
12 # spread arguments with xargs (and printf, as a shell built-in).
13 satisfies() {
14 #global sift_args
15 xargs -a <(printf -- "--satisfies=%s\n" "$@") pacsift "${sift_args[@]}" <&-
18 provides() {
19 #global info_args
20 pacinfo "${info_args[@]}" | awk -F'[:<=>]' '
21 /Name:/ { pkgname=$2; }
22 /Repository:/ { repo=$2
23 print repo, pkgname, pkgname; }
24 /Provides:/ { print repo, pkgname, $2; }
25 /Replaces:/ { print repo, pkgname, $2; }
29 usage() {
30 plain >&2 'usage: %s [-d repo] [-S]' "$argv0"
31 exit 1
34 source /usr/share/makepkg/util/parseopts.sh
36 opt_short='d:a'
37 opt_long=('all' 'sync' 'config:' 'database:' 'sysroot:')
38 opt_hidden=('dump-options' 'repo:')
40 if ! parseopts "$opt_short" "${opt_long[@]}" "${opt_hidden[@]}" -- "$@"; then
41 usage
43 set -- "${OPTRET[@]}"
45 unset argv_repo sift_args info_args
46 while true; do
47 case "$1" in
48 -a|--all|--sync)
49 sync_repo=1 ;;
50 -d|--database|--repo)
51 shift; argv_repo+=("$1") ;;
52 --config)
53 shift; sift_args+=(--config="$1")
54 info_args+=(--config="$1") ;;
55 --sysroot)
56 shift; sift_args+=(--sysroot="$1")
57 info_args+=(--sysroot="$1") ;;
58 --dump-options)
59 printf -- '--%s\n' "${opt_long[@]}" ${AUR_DEBUG+"${opt_hidden[@]}"}
60 printf -- '%s' "${opt_short}" | sed 's/.:\?/-&\n/g'
61 exit ;;
62 --) shift; break;;
63 esac
64 shift
65 done
67 if (( sync_repo )); then
68 sift_args+=(--sync)
69 elif [[ -v argv_repo ]]; then
70 sift_args+=(--exact "${argv_repo[@]/#/--repo=}")
71 else
72 sift_args+=(--exact "${arch_repo[@]/#/--repo=}")
75 # check for interactive terminal
76 if [[ -t 0 ]]; then
77 cat >&2 <<EOF
78 Warning: Input is read from the terminal. You either know what you
79 Warning: are doing, or you forgot to pipe data into $argv0.
80 Warning: Press CTRL-D to exit.
81 EOF
84 # associative array for input package names
85 declare -A pkgset
86 strset=()
88 while IFS= read -r str; do
89 # store unversioned string as key
90 name=${str%%[<>=]*}
92 # store version + operator as value (1 if unavailable)
93 if (( ${#str} - ${#name} )); then
94 pkgset[$name]=${str:${#name}}
95 else
96 pkgset[$name]=1
99 # store original versioned string
100 strset+=("$str")
101 done
103 # exit on empty stdin
104 if ! (( ${#pkgset[@]} )); then
105 exit 0
108 # Standard input is taken as "provides[<cmp><version>]", where pacsift
109 # checks for a package satisfying this condition. Results are printed
110 # as "repository/package", and piped to pacinfo to relate the names of
111 # the original provides to its corresponding package(s).
112 satisfies "${strset[@]}" | provides | while read -r repo package virtual; do
113 if [[ ${pkgset[$package]} ]]; then
114 printf '%s\n' "$package"
117 if [[ $virtual != "$package" ]]; then
118 version=${pkgset[$virtual]:-1}
119 else
120 continue
123 case $version in
124 1) printf >&2 'dependency %s satisfied by %s/%s\n' "$virtual" "$repo" "$package"
125 printf '%s\n' "$virtual" ;;
126 *) printf >&2 'dependency %s%s satisfied by %s/%s\n' "$virtual" "$version" "$repo" "$package"
127 printf '%s\n' "$virtual" ;;
128 esac
129 done | sort | uniq
131 # vim: set et sw=4 sts=4 ft=sh: