Merge pull request #1106 from AladW/depends-reqby-dict
[aurutils.git] / lib / aur-repo
blob01f185790ed00d436e853a894be20861e8386583
1 #!/bin/bash
2 # aur-repo - operate on local repositories
3 [[ -v AUR_DEBUG ]] && set -o xtrace
4 argv0=repo
5 PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
7 # default options
8 db_query=file mode=none conf_args=() vercmp_args=() parse_args=()
10 args_csv() {
11 # shellcheck disable=SC2155
12 local str=$(printf '%s,' "$@")
13 printf '%s' "${str%,}"
16 usage() {
17 printf >&2 'usage: %s [-d repo] [-r path] [-alqtuS]\n' "$argv0"
18 exit 1
21 # option parsing
22 opt_short='c:f:d:r:s:F:alqtuJS'
23 opt_long=('config:' 'database:' 'root:' 'all' 'list' 'path' 'list-path' 'list-repo'
24 'search:' 'search-by:' 'list-attr' 'sync' 'upgrades' 'table' 'quiet'
25 'attr:' 'json' 'jsonl' 'format:' 'delim:')
26 opt_hidden=('dump-options' 'repo:' 'repo-list' 'path-list' 'attr-list' 'status' 'field:')
28 if opts=$(getopt -o "$opt_short" -l "$(args_csv "${opt_long[@]}" "${opt_hidden[@]}")" -n "$argv0" -- "$@"); then
29 eval set -- "$opts"
30 else
31 usage
34 unset mode list db_name db_root format status_file pacman_conf format_args vercmp_args attr
35 while true; do
36 case $1 in
37 -d|--database|--repo)
38 shift; db_name=$1 ;;
39 -f|--format)
40 shift; format=$1; mode=format ;;
41 --delim)
42 shift; format_args+=(--delim "$1") ;;
43 -r|--root)
44 shift; db_root=$1 ;;
45 -c|--config)
46 shift; conf_args+=(--config "$1") ;;
47 -l|--list)
48 mode=list ;;
49 -t|--table)
50 mode=table ;;
51 -J|--json)
52 mode=json ;;
53 --jsonl)
54 mode=jsonl ;;
55 -a|--all)
56 mode=upgrades; vercmp_args+=(-a) ;;
57 -u|--upgrades)
58 mode=upgrades ;;
59 -q|--quiet)
60 parse_args+=(-q); vercmp_args+=(-q) ;;
61 -S|--sync)
62 db_query=sync ;;
63 -F|--attr|--field)
64 shift; mode=attr; attr=$1 ;;
65 -s|--search)
66 shift; parse_args+=(--search "$1") ;;
67 --search-by)
68 shift; parse_args+=(--search-by "$1") ;;
69 --path)
70 mode=path ;;
71 --status)
72 mode=status ;;
73 --path-list|--list-path)
74 list=path ;;
75 --repo-list|--list-repo)
76 list=repo ;;
77 --attr-list|--list-attr)
78 list=attr ;;
79 --dump-options)
80 printf -- '--%s\n' "${opt_long[@]}" ${AUR_DEBUG+"${opt_hidden[@]}"}
81 printf -- '%s' "${opt_short}" | sed 's/.:\?/-&\n/g'
82 exit ;;
83 --) shift; break ;;
84 esac
85 shift
86 done
88 # assign environment variables
89 : "${db_ext=$AUR_DBEXT}" "${db_name=$AUR_REPO}" "${db_root=$AUR_DBROOT}"
91 # parse pacman configuration
92 unset conf_file_repo conf_file_serv conf_file_path server
94 while read -r key _ value; do
95 case $key=$value in
96 \[*\]*)
97 section=${key:1:-1}
99 DBPath=*)
100 pacman_dbpath=$value
102 Server=file://*)
103 server=${value#file://}
104 conf_file_repo+=("$section")
105 conf_file_serv+=("$server")
106 conf_file_path+=("$server/$section.${db_ext:-db}")
108 if [[ $section == "$db_name" ]] && [[ ! $db_root ]]; then
109 db_root=$server
110 fi ;;
111 Server=*://*)
112 if [[ $section == "$db_name" ]] && [[ ! $db_root ]]; then
113 db_root=$value
114 fi ;;
115 esac
116 done < <(pacman-conf "${conf_args[@]}")
117 wait $! || exit
119 # list information on available local repositories
120 case $list in
121 path|repo)
122 if ! (( ${#conf_file_repo[@]} )); then
123 printf >&2 '%s: no file:// repository configured\n' "$argv0"
124 exit 2
125 fi ;;&
126 path)
127 realpath -- "${conf_file_path[@]}" # resolve repo-add symlinks
128 exit 0 ;;
129 repo)
130 printf '%s\n' "${conf_file_repo[@]}"
131 exit 0 ;;
132 attr)
133 aur repo-parse --list-attr
134 exit ;;
135 esac
137 # select local repository from pacman configuration, if no repository
138 # was specified on the command-line
139 if ! [[ $db_name ]]; then
140 case ${#conf_file_repo[@]} in
141 1) db_name=${conf_file_repo[0]}
142 db_root=${conf_file_serv[0]}
144 0) printf >&2 '%s: no file:// repository configured\n' "$argv0"
145 exit 2
147 *) printf >&2 '%s: repository choice is ambiguous (use -d to specify)\n' "$argv0"
149 for i in "${!conf_file_repo[@]}"; do
150 printf '%q\t%q\n' "${conf_file_repo[$i]}" "${conf_file_path[$i]}"
151 done | column -o $'\t' -t >&2
152 exit 1
154 esac
157 # basic file checks
158 case $db_query in
159 file)
160 if [[ ! $db_root ]]; then
161 printf >&2 '%s: %s: repository root not found\n' "$argv0" "$db_name"
162 exit 2
163 elif [[ $db_root == *://* ]]; then
164 printf >&2 '%s: %s: object is remote (use -S to query)\n' "$argv0" "$db_root"
165 exit 66
167 db_path=$db_root/$db_name.${db_ext:-db}
168 db_path=$(realpath -- "$db_path") # resolve repo-add symlink
170 sync)
171 db_path=$pacman_dbpath/sync/$db_name.${db_ext:-db}
173 esac
175 if [[ ! -f $db_path ]]; then
176 printf >&2 '%s: %s: not a file\n' "$argv0" "$db_path"
177 exit 2
180 # database operations
181 case $mode in
182 list|table|json|jsonl)
183 aur repo-parse "${parse_args[@]}" -p "$db_path" --"$mode"
185 format)
186 aur repo-parse "${parse_args[@]}" -p "$db_path" --jsonl | aur format "${format_args[@]}" -f "$format"
188 upgrades)
189 aur repo-parse "${parse_args[@]}" -p "$db_path" --list | aur vercmp "${vercmp_args[@]}"
191 attr)
192 aur repo-parse "${parse_args[@]}" -p "$db_path" --attr "$attr"
194 path)
195 printf '%s\n' "$db_path"
198 printf 'repo:%s\nroot:%s\npath:%s\n' "$db_name" "$db_root" "$db_path"
200 esac
202 # vim: set et sw=4 sts=4 ft=sh: