Merge pull request #1008 from AladW/fetch-rework-iv
[aurutils.git] / lib / aur-search
blob4e610de634cf270ca03be38f87be59ef636aea6f
1 #!/bin/bash
2 # aur-search - search for AUR packages
3 [[ -v AUR_DEBUG ]] && set -o xtrace
4 argv0=search
5 AUR_LOCATION=${AUR_LOCATION:-'https://aur.archlinux.org'}
6 PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
8 # default options
9 multiple=section search_by=name-desc sort_key=Name type=search mode=query
11 # default arguments
12 query_args=()
14 hyperlink() {
15 local uri=$1 mesg=$2
17 # Interpret escapes with %b for "dumb" terminals (#1001)
18 printf "\e]8;;%s\e\\%b\e]8;;\e\\" "$uri" "$mesg"
21 tabulate() {
22 # It is important to have a default value for every field, or
23 # parsing of the @tsv result might break.
24 # See: https://lists.gnu.org/archive/html/help-bash/2016-05/msg00041.html
25 # For arrays, individual elements have to be checked as well.
26 # See: https://gitlab.archlinux.org/archlinux/aurweb/-/issues/332
27 jq -r --arg key "$1" '
28 def sel_join:
29 if length > 0 then
30 map(if . == "" then "-" else . end) | join(" ")
31 else
32 "-"
33 end;
35 [.results[]] | sort_by(.[$key])[] | [
36 .Name // "-",
37 .PackageBase // "-",
38 .Version // "-",
39 .Description // "-",
40 .URL // "-",
42 (.Keywords | sel_join),
43 (.License | sel_join),
45 .Maintainer // "-",
46 .NumVotes // "-",
47 .Popularity // "-",
48 .OutOfDate // "-",
50 (.FirstSubmitted | todate),
51 (.LastModified | todate),
52 (.Depends | sel_join),
53 (.MakeDepends | sel_join),
54 (.CheckDepends | sel_join),
55 (.OptDepends | sel_join)
56 ] | @tsv'
59 info_long() {
60 local -a desc=(
61 'Name'
62 'Base'
63 'Version'
64 'Description'
65 'URL'
66 'Keywords'
67 'License'
68 'Maintainer'
69 'Votes'
70 'Popularity'
71 'Out Of Date'
72 'Submitted'
73 'Last Modified'
74 'Depends On'
75 'Makedepends'
76 'Checkdepends'
77 'Optdepends'
79 local -a info
81 while IFS=$'\t' read -r -a info; do
82 printf "$BOLD%s:$ALL_OFF\\t%s\\n" "AUR URL" "$AUR_LOCATION/packages/${info[0]}"
84 for i in "${!info[@]}"; do
85 printf "$BOLD%s:$ALL_OFF\\t%s\\n" "${desc[i]}" "${info[i]}"
86 done
88 # column(1) ignores empty lines (package delimitation)
89 printf '%s\n' '-'
90 done
93 info_short() {
94 local Name Version NumVotes Popularity Maintainer OutOfDate Description Url Link
96 while IFS=$'\t' read -r Name _ Version Description _ _ _ Maintainer NumVotes Popularity OutOfDate _; do
97 case $OutOfDate in
98 -) unset OutOfDate ;;
99 *) printf -v OutOfDate '(Out-of-date: %(%d %B %Y)T)' "$OutOfDate"
100 esac
102 case $Maintainer in
103 -) Maintainer='(Orphaned) ' ;;
104 *) unset Maintainer ;;
105 esac
107 # Unset LC_ALL to ensure it doesn't override LC_NUMERIC.
108 LC_ALL='' LC_NUMERIC=C printf -v Popularity '%.2f' "$Popularity"
110 Url="${AUR_LOCATION}/packages/${Name}"
111 Link="$(hyperlink "$Url" "${BLUE}aur/${ALL_OFF}${BOLD}${Name}")"
113 printf "%s ${GREEN}%s ${ALL_OFF}(+%s %s%%) ${RED}%s%s${ALL_OFF}\\n %s\\n" \
114 "$Link" "$Version" "$NumVotes" "$Popularity" "$Maintainer" "$OutOfDate" "$Description"
115 done
118 usage() {
119 plain >&2 'usage: %s [-adimnqrsv] [-k key] pkgname...' "$argv0"
120 exit 1
123 source /usr/share/makepkg/util/message.sh
124 source /usr/share/makepkg/util/parseopts.sh
126 if [[ ! -v NO_COLOR ]] && [[ ! -v AUR_DEBUG ]]; then
127 # We use colored messages on both stdout and stderr, and these may
128 # be desired even if stdout is not connected to a terminal. (in
129 # particular, aur search foo | less -R, #585)
130 colorize
133 opt_short='k:adimnqrsv'
134 opt_long=('any' 'info' 'search' 'desc' 'maintainer' 'name' 'depends' 'verbose'
135 'makedepends' 'optdepends' 'checkdepends' 'key:' 'short' 'table' 'json')
136 opt_hidden=('dump-options' 'raw' 'json-stdin')
138 if ! parseopts "$opt_short" "${opt_long[@]}" "${opt_hidden[@]}" -- "$@"; then
139 usage
141 set -- "${OPTRET[@]}"
143 unset format
144 while true; do
145 case "$1" in
146 -a|--any)
147 multiple=union ;;
148 -i|--info)
149 type=info ;;
150 -s|--search)
151 type=search ;;
152 -d|--desc)
153 search_by=name-desc ;;
154 -m|--maintainer)
155 search_by=maintainer ;;
156 -n|--name)
157 search_by=name ;;
158 --depends)
159 search_by=depends ;;
160 --makedepends)
161 search_by=makedepends ;;
162 --optdepends)
163 search_by=optdepends ;;
164 --checkdepends)
165 search_by=checkdepends ;;
166 -q|--short)
167 format=short ;;
168 -v|--verbose)
169 format=long ;;
170 --table)
171 format=table ;;
172 -r|--raw|--json)
173 mode=json ;;
174 --json-stdin)
175 mode=json_stdin ;;
176 -k|--key)
177 shift; sort_key=$1 ;;
178 --dump-options)
179 printf -- '--%s\n' "${opt_long[@]}" ${AUR_DEBUG+"${opt_hidden[@]}"}
180 printf -- '%s' "${opt_short}" | sed 's/.:\?/-&\n/g'
181 exit ;;
182 --) shift; break ;;
183 esac
184 shift
185 done
187 if ! (( $# )) && ! [[ $mode == "stdin_json" || $mode == "stdin_table" ]]; then
188 usage
191 # set format depending on query type (#319)
192 case $type in
193 info) format=${format-long} ;;
194 search) format=${format-short} ;;
195 esac
197 # set filters (1)
198 case $format in
199 long) info() { info_long | column -ts $'\t' | sed -E 's/^-//; $d'; } ;;
200 short) info() { info_short; } ;;
201 table) info() { tee; } ;;
202 esac
204 # set filters (2)
205 case $multiple in
206 section) ;; # aur-query default
207 union) query_args+=('--any') ;;
208 esac
210 case $mode in
211 query)
212 aur query -t "$type" -b "$search_by" -e "${query_args[@]}" "$@" | tabulate "$sort_key" | info
213 exit "${PIPESTATUS[0]}" ;;
214 json)
215 aur query -t "$type" -b "$search_by" -e "${query_args[@]}" "$@"
217 json_stdin)
218 tabulate "$sort_key" | info
220 esac
222 # vim: set et sw=4 sts=4 ft=sh: