2 # aur-query - interface with AurJson
3 [[ -v AUR_DEBUG
]] && set -o xtrace
5 AUR_LOCATION
=${AUR_LOCATION:-https://aur.archlinux.org}
6 AUR_QUERY_PARALLEL
=${AUR_QUERY_PARALLEL:-0}
7 AUR_QUERY_PARALLEL_MAX
=${AUR_QUERY_PARALLEL_MAX:-15}
8 AUR_QUERY_RPC
=${AUR_QUERY_RPC:-$AUR_LOCATION/rpc}
9 AUR_QUERY_RPC_POST
=${AUR_QUERY_RPC_POST:-1}
10 AUR_QUERY_RPC_SPLITNO
=${AUR_QUERY_RPC_SPLITNO:-150}
11 AUR_QUERY_RPC_SPLITNO_POST
=${AUR_QUERY_RPC_SPLITNO_POST:-500}
12 AUR_QUERY_RPC_VERSION
=${AUR_QUERY_RPC_VERSION:-5}
13 PS4
='+(${BASH_SOURCE}:${LINENO}):${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
16 curl_args
=(-A aurutils
-fgLsSq)
18 # Filters for generating curl configuration
20 local rpc_url
="$AUR_QUERY_RPC?v=$AUR_QUERY_RPC_VERSION&type=info"
21 local splitno
="$AUR_QUERY_RPC_SPLITNO"
23 # Write opening and closing quotes with \x22 (hexadecimal)
24 awk -v rpc
="$rpc_url" -v splitno
="$splitno" '{
25 if ((NR-1) % splitno == 0) {
28 printf "output \x22args-%s-%s\x22\n", NR-1, (NR-1)+splitno
29 printf "url \x22%s&arg[]=%s", rpc, $0
31 printf "&arg[]=%s", $0
39 # POST requests are useful for info-type requests to circumvent limits on the
40 # URL length with GET requests. The difference is that all data is now included
41 # in the message body, instead of in the URI.
43 local rpc_url
="$AUR_QUERY_RPC"
44 local rpc_ver
="$AUR_QUERY_RPC_VERSION"
45 local splitno
="$AUR_QUERY_RPC_SPLITNO_POST"
47 # Write opening and closing quotes with \x22 (hexadecimal)
48 awk -v rpc
="$rpc_url" -v version
="$rpc_ver" -v splitno
="$splitno" '{
49 if ((NR-1) % splitno == 0) {
51 printf "output \x22args-%s-%s\x22\n", NR-1, (NR-1)+splitno
52 printf "url \x22%s\x22\n", rpc
53 printf "data \x22v=%s\x22\n", version
54 printf "data \x22type=info\x22\n"
56 printf "data-urlencode \x22arg[]=%s\x22\n", $0
60 # Search-type requests can only contain one package argument, and GET requests
61 # are sufficient for this.
63 local rpc_url
="$AUR_QUERY_RPC?v=$AUR_QUERY_RPC_VERSION&type=search&by=$1&arg"
65 while IFS
= read -r term
; do
66 printf 'url "%s=%s"\n' "$rpc_url" "$term"
67 printf 'output "arg-%s"\n' "$term"
72 if [[ ! -v AUR_DEBUG
]]; then
75 printf >&2 'AUR_DEBUG: %s: temporary files at %s\n' "$argv0" "$tmp"
80 printf 'usage: %s [-t [info|search] ] [-b by] <package...>\n' "$argv0" >&2
84 source /usr
/share
/makepkg
/util
/parseopts.sh
87 opt_long
=('by:' 'type:' 'any' 'raw')
88 opt_hidden
=('dump-options' 'dump-curl-config')
90 if ! parseopts
"$opt_short" "${opt_long[@]}" "${opt_hidden[@]}" -- "$@"; then
95 unset arg_by arg_type multiple dump_curl_config
105 shift; arg_type
=$1 ;;
107 dump_curl_config
=1 ;;
109 printf -- '--%s\n' "${opt_long[@]}" ${AUR_DEBUG+"${opt_hidden[@]}"}
110 printf -- '%s' "${opt_short}" | sed 's/.:\?/-&\n/g'
117 # shellcheck disable=SC2174
118 mkdir -pm 0700 "${TMPDIR:-/tmp}/aurutils-
$UID"
119 tmp=$(mktemp -d --tmpdir "aurutils-
$UID/$argv0.XXXXXXXX
") || exit
120 trap 'trap_exit' EXIT
127 if [[ $arg_type == "search
" ]]; then
128 curl_config() { jq -R -r '@uri' | rpc_search "${arg_by:-name-desc}"; }
130 elif [[ $arg_type == "info
" ]] && (( AUR_QUERY_RPC_POST )); then
131 curl_config() { rpc_info_post; } # URI encoding is handled by curl --data-urlencode
133 elif [[ $arg_type == "info
" ]]; then
134 curl_config() { jq -R -r '@uri' | rpc_info; }
137 # generate curl configuration
138 if (( $# == 1 )) && [[ $1 == "-" || $1 == "/dev
/stdin
" ]]; then
142 fi | curl_config >"$tmp"/config
144 # easy access to curl config for debugging
145 if (( ${dump_curl_config-0} )); then
150 # exit cleanly on empty input (#706)
151 if [[ ! -s $tmp/config ]]; then
155 # Set intersection only applies to search queries, where one search term leads
156 # to multiple results. This is the default, unless --any is specified. Info
157 # queries are already implicitly a union of terms (packages), unless duplicate
158 # packages were specified, and are so not processed further.
159 multiple=${multiple:-section}
161 if [[ $arg_type == "info
" ]]; then
165 # set operations on search output
168 combine() { jq -Mrcs '(length - 1) as $n
169 | [map(.results | unique[]) | group_by(.)[][$n] | objects] as $r
171 "resultcount
": ($r | length),
176 combine() { jq -Mrcs '([.[].results] | add | unique) as $r
178 "resultcount
": ($r | length),
183 combine() { tee; } ;;
186 # support parallel transfers (curl >7.66.0)
187 if (( AUR_QUERY_PARALLEL )); then
188 # curl 7.77.0: tool_operate: don't discard failed parallel transfer result
189 curl_args+=(--parallel --parallel-max "$AUR_QUERY_PARALLEL_MAX" --fail-early)
192 # requests are stored in a subdirectory to avoid problems from the random
193 # ordering of curl --parallel output (#925)
195 env -C "$tmp"/output curl "${curl_args[@]}" -K "$tmp"/config || exit
197 files=("$tmp"/output/*)
198 if [[ ! -f ${files[0]} ]]; then
202 # check responses for errors (#257)
203 for f in "${files[@]}"; do
204 f_count=$(jq -sr 'map(.resultcount) | add' "$f")
205 f_error=$(jq -r '.error' "$f")
207 if (( ! f_count )) && [[ $f_error != 'null' ]]; then
208 cat "$f" # type=error
213 # concatenate results
214 cat "${files[@]}" | combine
216 # vim: set et sw=4 sts=4 ft=sh: