aurutils / aurutils

Helper tools for the AUR.
ISC License
950 stars 89 forks source link

`repo`: default for `--sync` without `--database` #1088

Closed AladW closed 1 year ago

AladW commented 1 year ago

When --database is not specified, --sync could imply all pacman sync databases. This is possible since repo-parse can take multiple database paths as argument.

To disambiguate targets, the repository name should be prefixed (repo/pkgname).

AladW commented 1 year ago

Problematic is that this changes the semantics of aur repo -S with a single configured local repository. Current behavior:

> aur repo -S  # master branch
repo:alad
root:/var/lib/aurutils/alad
path:/var/lib/pacman//sync/alad.db
> aur repo
repo:alad
root:/var/lib/aurutils/alad
path:/var/lib/aurutils/alad/alad.db.tar.gz

If -S implies all sync repositories, it's unclear what aur repo -S [--status] or aur repo -S --path should return (multiple lists or an ambiguity error).

A wrapper script sidesteps the issue:

#!/bin/bash
[[ -v AUR_DEBUG ]] && set -o xtrace
argv0='repo-search'
search_by='name'
mode='format'
format_str='%R/%n\t%v\n'  # append repository name
repo_args=()

while getopts b:lJtf: OPT; do
    case $OPT in
        b) search_by=$OPTARG ;;
        l) mode=list ;;
        t) mode=table ;;
        J) mode=json ;;
        f) mode=format; format_str=$1 ;;
        *) echo "usage: ${0##*/} [+-s ARG] [+-b ARG} [--] ARGS..."
           exit 2 ;;
    esac
done
shift $(( OPTIND - 1 ))
OPTIND=1

# Get list of all sync repositories
mapfile -t sync_repos < <(pacconf --repo-list)
wait "$!"

# Transform into local file paths
db_path=$(pacconf DBPath)/sync

for r in "${sync_repos[@]}"; do
    if [[ $mode == 'format' ]]; then
        aur repo-parse --path "$db_path/$r".db --jsonl --search "$1" --search-by "$search_by" | aur format -f "$format_str"
    else
        aur repo-parse --path "$db_path/$r".db --search "$1" --search-by "$search_by"
    fi
done

The performance is disappointing:

> hyperfine 'aur repo-search python --list' 'pacman -Ss python'
Benchmark 1: aur repo-search python --list
  Time (mean ± σ):     805.1 ms ±  10.3 ms    [User: 1067.6 ms, System: 105.3 ms]
  Range (min … max):   792.6 ms … 821.1 ms    10 runs

Benchmark 2: pacman -Ss python
  Time (mean ± σ):     232.2 ms ±   3.5 ms    [User: 210.4 ms, System: 21.3 ms]
  Range (min … max):   228.6 ms … 239.0 ms    12 runs

Summary
  'pacman -Ss python' ran
    3.47 ± 0.07 times faster than 'aur repo-search python --list

The following allows repo-search above to print the local repository name:

diff --git a/lib/aur-format b/lib/aur-format
index 8ed204dc..e713447b 100755
--- a/lib/aur-format
+++ b/lib/aur-format
@@ -29,6 +29,7 @@ my %aur_formats = (
     'm' => ['string',   'Maintainer'    ],
     'n' => ['string',   'Name'          ],
     'r' => ['string',   'DBPath'        ],  # aur-repo-parse
+    'R' => ['string',   'Repository'    ],  # aur-repo-parse
     'U' => ['string',   'URL'           ],
     'v' => ['string',   'Version'       ],
     's' => ['string',   'Submitter'     ],  # aur-pkglist
diff --git a/lib/aur-repo-parse b/lib/aur-repo-parse
index 93fee5dd..d539a6a9 100755
--- a/lib/aur-repo-parse
+++ b/lib/aur-repo-parse
@@ -53,6 +53,7 @@ sub handler_search {

 sub parse_db {
     my ($fh, $db_path, $first, $handler, $search_expr, $search_label, @varargs) = @_;
+    (my $repo = basename($db_path)) =~ s/\.db?+$//;
     my $count = 0;
     my ($entry, $filename, $attr, $attr_label);

@@ -74,6 +75,7 @@ sub parse_db {
             # New entry in the database (hashref)
             %{$entry} = ();
             $entry->{'DBPath'} = $db_path;
+            $entry->{'Repository'} = $repo;
             $entry->{$repo_add_attributes{$first}} = $filename;
         }
         elsif ($row =~ /^%.+%$/) {
AladW commented 1 year ago

a5a78e1e7292760afc0ec171eb09cf76b9ade88f