Merge pull request #1008 from AladW/fetch-rework-iv
[aurutils.git] / lib / aur-pkglist
blob84bba21a6d14e5cde47fbc31d6fa24222553e2ef
1 #!/bin/bash
2 # aur-pkglist - print the AUR package list
3 [[ -v AUR_DEBUG ]] && set -o xtrace
4 argv0=pkglist
5 XDG_CACHE_HOME=${XDG_CACHE_HOME:-$HOME/.cache}
6 AUR_LOCATION=${AUR_LOCATION:-'https://aur.archlinux.org'}
7 AUR_METADEST=${AUR_METADEST:-$XDG_CACHE_HOME/aurutils/$argv0} # variable name prone to change
8 PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
10 # default options
11 ttl=300 pkglist=packages update=0 verify=0 use_system_time=0
13 http_last_modified() {
14 awk -F', ' '/^[Ll]ast-[Mm]odified:/ {print $2}' "$1"
17 list_fetch() {
18 curl -A aurutils -f "$1" "${@:2}" --remote-name
21 list_headers() {
22 curl -A aurutils -f "$1" --head -Ss
25 usage() {
26 printf >&2 'usage: %s [-bqsiv] [-t ttl] [-FP pattern]\n' "$argv0"
27 exit 1
30 source /usr/share/makepkg/util/parseopts.sh
32 opt_short='t:bqsivFPJISu'
33 opt_long=('pkgbase' 'search' 'info' 'fixed-strings' 'perl-regexp' 'plain'
34 'ttl:' 'users' 'verify' 'quiet' 'systime')
35 opt_hidden=('dump-options' 'time:' 'json')
37 if ! parseopts "$opt_short" "${opt_long[@]}" "${opt_hidden[@]}" -- "$@"; then
38 usage
40 set -- "${OPTRET[@]}"
42 unset mode
43 while true; do
44 case "$1" in
45 -b|--pkgbase)
46 pkglist=pkgbase ;;
47 -s|--search)
48 pkglist=packages-meta-v1.json ;;
49 -i|--info)
50 pkglist=packages-meta-ext-v1.json ;;
51 --users)
52 pkglist=users ;;
53 -F|--fixed-strings)
54 mode=fixed ;;
55 -P|--perl-regexp)
56 mode=regex ;;
57 --plain)
58 mode=plain ;;
59 -q|--quiet)
60 mode=none ;;
61 -t|--time|--ttl)
62 shift; ttl=$1 ;;
63 -v|--verify)
64 verify=1 ;;
65 --systime)
66 use_system_time=1 ;;
67 # Deprecated options
68 -u) printf >&2 'deprecation notice: %s -u is an alias for --quiet\n' "$argv0"
69 mode=none ;;
70 -I) printf >&2 'deprecation notice: %s -I is an alias for --info\n' "$argv0"
71 pkglist=packages-meta-ext-v1.json ;;
72 -S) printf >&2 'deprecation notice: %s -S is an alias for --search\n' "$argv0"
73 pkglist=packages-meta-v1.json ;;
74 -J|--json)
75 printf >&2 'deprecation notice: %s --json is an alias for --info | jq\n' "$argv0"
76 mode=json ;;
77 --dump-options)
78 printf -- '--%s\n' "${opt_long[@]}" ${AUR_DEBUG+"${opt_hidden[@]}"}
79 printf -- '%s' "${opt_short}" | sed 's/.:\?/-&\n/g'
80 exit ;;
81 --) shift; break ;;
82 esac
83 shift
84 done
86 if [[ ! -v mode ]]; then
87 # default to json for info/search lists
88 if [[ $pkglist == *.json ]]; then
89 mode=json
91 # default to regex if >0 arguments specified
92 elif (( $# > 0 )); then
93 mode=regex
94 else
95 mode=plain
99 if ! [[ $ttl =~ [0-9]+ ]]; then
100 printf >&2 "error: --ttl requires an integer ('%s' provided)\n" "$ttl"
101 exit 1
104 # packages.gz cache
105 install -dm700 "$AUR_METADEST"
106 cd "$AUR_METADEST" || exit
108 if [[ ! -s headers_$pkglist || ! -s $pkglist ]]; then
109 update=1
111 elif [[ -s $pkglist ]]; then
112 sec_l=$(http_last_modified "headers_$pkglist" | date -f - '+%s')
114 if (( use_system_time )); then
115 sec_d=$(date '+%s')
116 else
117 sec_d=$(http_last_modified <(list_headers "$AUR_LOCATION/$pkglist.gz") | date -f - '+%s')
120 if (( sec_d - sec_l > ttl )); then
121 update=1
125 if (( update )); then
126 list_fetch "$AUR_LOCATION/$pkglist.gz" --dump-header "headers_$pkglist"
128 if (( verify )); then
129 list_fetch "$AUR_LOCATION/$pkglist.gz.sha256"
130 sha256sum --check --strict --quiet "$pkglist.gz.sha256" || exit
133 if [[ $pkglist == *.json ]]; then
134 # Remove newlines separating partial objects, i.e.
135 # [\n{...},\n{...},...\n] => [{...}{...},...]\n
136 { gunzip -c "$pkglist.gz" | tr -d '\n'
137 printf '\n'
138 } > "$pkglist"
139 else
140 gunzip -f "$pkglist.gz"
142 fi >&2
144 # pattern match
145 case $mode in
146 plain)
147 cat "$pkglist" ;;
148 fixed)
149 grep -F "$1" "$pkglist" ;;
150 regex)
151 grep -P "$1" "$pkglist" ;;
152 json)
153 jq -r "$1" "$pkglist" ;;
154 none)
155 printf '%s\n' "$PWD/$pkglist" ;;
156 esac
158 # vim: set et sw=4 sts=4 ft=sh: