Merge pull request #1030 from AladW/build-conf-fallback
[aurutils.git] / lib / aur-query
blobd7846b9d9d4eaf984ceb37fbca8eb9f51b6116ba
1 #!/usr/bin/env perl
2 use strict;
3 use warnings;
4 use v5.20;
6 my $argv0 = 'query';
7 my @curl_args = ('-A', 'aurutils', '-fgLsSq');
9 # environment variables
10 my $aur_location = $ENV{AUR_LOCATION} // 'https://aur.archlinux.org';
11 my $aur_rpc = $ENV{AUR_QUERY_RPC} // $aur_location . "/rpc";
12 my $aur_rpc_ver = $ENV{AUR_QUERY_RPC_VERSION} // 5;
13 my $aur_splitno = $ENV{AUR_QUERY_RPC_SPLITNO} // 5000;
15 # https://code.activestate.com/recipes/577450-perl-url-encode-and-decode/#c6
16 sub urlencode {
17 my $s = shift;
18 $s =~ s/([^A-Za-z0-9])/sprintf("%%%2.2X", ord($1))/ge;
19 return $s;
22 # option handling
23 use Getopt::Long;
24 my $opt_by;
25 my $opt_dry_run;
26 my $opt_type = "";
28 GetOptions('t|type=s' => \$opt_type,
29 'b|by=s' => \$opt_by,
30 'n|dry-run' => \$opt_dry_run)
31 or exit(1);
33 if ($opt_type eq "search" or $opt_type eq "suggest") {
34 $aur_splitno = 1;
37 # process package names from stdin or the command-line
38 if (not scalar(@ARGV)) {
39 say STDERR "$argv0: at least one argument required";
40 exit(1);
42 if ($ARGV[0] eq "-" or $ARGV[0] eq "/dev/stdin") {
43 while (my $arg = <STDIN>) {
44 chomp($arg);
45 push(@ARGV, $arg);
47 shift(@ARGV);
50 # generate POST data
51 my @forms;
52 my $NR = 0;
54 # URI/URI::QueryParam is extremely slow for large inputs. Build the form data
55 # by hand and use sprintf to encode the package names.
56 for my $target (@ARGV) {
57 if ($NR % $aur_splitno == 0) {
58 # Create new form element
59 push @forms, "";
61 # Set fields and values
62 $forms[$#forms] .= '&v=' . $aur_rpc_ver;
63 $forms[$#forms] .= '&type=' . $opt_type;
64 $forms[$#forms] .= '&by=' . $opt_by if defined($opt_by);
66 $forms[$#forms] .= '&arg[]=' . urlencode($target);
67 $NR++;
70 # Output as JSON lines
71 for my $form (@forms) {
72 my @cmd = ('curl', @curl_args, $aur_rpc, '--data-raw', $form);
74 if ($opt_dry_run) {
75 say join(" ", map(qq/'$_'/, @cmd));
76 } else {
77 my $child_pid = open(my $fh, "-|", @cmd) or die $!;
79 if ($child_pid) { # parent process
80 say <$fh>;
81 die "$argv0: response error (multi-line output)" if defined(<$fh>);
83 waitpid($child_pid, 0);
85 # Return a generic error code on `curl` failure, to avoid overlap with
86 # codes from other tools which use pipelines (`aur-repo`, `aur-vercmp`).
87 # 2 is the same code returned if `curl` is not found in `open` above.
88 exit(2) if $?;