Rehash efficiently
[pacman-ng.git] / contrib / pacsearch.in
blobdd848a73f54c397f7a505cb82000ff01cb452bb5
1 #!/usr/bin/perl
2 # pacsearch - Adds color and install information to a 'pacman -Ss' search
4 # Copyright (C) 2008-2011 Dan McGee <dan@archlinux.org>
6 # Based off original shell script version:
7 # Copyright (C) 2006-2007 Dan McGee <dan@archlinux.org>
9 # This program is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU General Public License
11 # as published by the Free Software Foundation; either version 2
12 # of the License, or (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #TODO: colors flag on commandline
24 use strict;
25 use warnings;
27 my $progname = "pacsearch";
28 my $version = "2.0";
30 if ($#ARGV lt 0 || $ARGV[0] eq "--help" || $ARGV[0] eq "-h") {
31 print "$progname - Add color and install information to a pacman -Ss search\n";
32 print "Usage: $progname <pattern>\n";
33 print "Example: $progname ^gnome\n";
34 if ($#ARGV lt 0) {
35 exit 1;
37 exit 0;
40 if ($ARGV[0] eq "--version" || $ARGV[0] eq "-v") {
41 print "$progname version $version\n";
42 print "Copyright (C) 2006-2011 Dan McGee\n";
43 exit 0;
46 # define our colors to use when printing
47 my $CLR1 = "\e[0;34m";
48 my $CLR2 = "\e[0;32m";
49 my $CLR3 = "\e[0;35m";
50 my $CLR4 = "\e[0;36m";
51 my $CLR5 = "\e[0;31m";
52 my $CLR6 = "\e[0;33m";
53 my $CLR7 = "\e[1;36m";
54 my $INST = "\e[1;31m";
55 my $BASE = "\e[0m";
57 # color a "repo/pkgname pkgver" line based on the repository name
58 sub to_color {
59 my $line = shift;
60 # get the installed text colored first
61 $line =~ s/(\[.*\]$)/$INST$1$BASE/;
62 # and now the repo and dealings
63 $line =~ s/(^core\/.*)/$CLR1$1$BASE/;
64 $line =~ s/(^extra\/.*)/$CLR2$1$BASE/;
65 $line =~ s/(^community\/.*)/$CLR3$1$BASE/;
66 $line =~ s/(^testing\/.*)/$CLR4$1$BASE/;
67 $line =~ s/(^community-testing\/.*)/$CLR5$1$BASE/;
68 $line =~ s/(^multilib\/.*)/$CLR6$1$BASE/;
69 $line =~ s/(^local\/.*)/$CLR7$1$BASE/;
70 # any other unknown repository
71 $line =~ s/(^[\w-]*\/.*)/$CLR6$1$BASE/;
72 return $line;
75 my %allpkgs = ();
77 my $syncout = `pacman -Ss '@ARGV'`;
78 # split each sync search entry into its own array entry
79 my @syncpkgs = split(/\n^(?=\w)/m, $syncout);
80 # remove the extra \n from the last desc entry
81 if ($#syncpkgs >= 0) {
82 chomp($syncpkgs[$#syncpkgs]);
85 # counter var for packages, used here and in the query loop too
86 my $cnt = 0;
87 foreach $_ (@syncpkgs) {
88 # we grab 4 fields here: repo, name/ver, installed, and desc
89 my @pkgfields = /^(.*?)\/(.*?) ?(\[.*\])?\n(.*)$/s;
90 if(not @pkgfields) {
91 # skip any non-matching line and just print it for the user
92 print $_, "\n";
93 next;
95 # since installed is optional, we should fill it in if necessary
96 $pkgfields[2] = "" if not defined $pkgfields[2];
97 # add a fifth field that indicates original order
98 push (@pkgfields, $cnt++);
99 # add each sync pkg by name/ver to a hash table for quick lookup
100 $allpkgs{$pkgfields[1]} = [ @pkgfields ];
103 my $queryout = `pacman -Qs '@ARGV'`;
104 # split each querysearch entry into its own array entry
105 my @querypkgs = split(/\n^(?=\w)/m, $queryout);
106 # remove the extra \n from the last desc entry
107 if ($#querypkgs >= 0) {
108 chomp ($querypkgs[$#querypkgs]);
111 foreach $_ (@querypkgs) {
112 # we grab 4 fields here: repo, name/ver, installed, and desc
113 my @pkgfields = /^(.*?)\/(.*?) ?(\[.*\])?\n(.*)$/s;
114 # since installed is optional, we should fill it in if necessary
115 $pkgfields[2] = "" if not defined $pkgfields[2];
116 # check if the package was listed in the sync out
117 if (not exists $allpkgs{$pkgfields[1]}) {
118 $pkgfields[2] = "[installed]";
119 # add a fifth field that indicates original order (after sync)
120 push (@pkgfields, $cnt++);
121 # add our local-only package to the hash
122 $allpkgs{$pkgfields[1]} = [ @pkgfields ];
126 # sort by original order (the fifth field) and print
127 foreach $_ ( sort{ @{$allpkgs{$a}}[4] <=> @{$allpkgs{$b}}[4] } keys %allpkgs) {
128 my @v = @{$allpkgs{$_}};
129 my $line = "$v[0]/$v[1] $v[2]";
130 $line = to_color($line);
131 # print colorized "repo/pkgname pkgver" string with possible installed text
132 print "$line\n";
133 print "$v[3]\n";
136 #vim: set noet: