1
0
mirror of https://github.com/moparisthebest/pacman synced 2024-11-10 03:25:01 -05:00
pacman/contrib/pacsearch.in
Dan McGee 0f24390fe8 pkgsearch: handle non-matching lines gracefully
Before any non-matching line would trigger some perl warnings about
undefined variables. If a line doesn't match, just show it to the user
unprocessed; this is seen with warning and error messages pacman not so
helpfully emits on stdout rather than stderr.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-01-24 15:20:10 -06:00

137 lines
4.2 KiB
Perl
Executable File

#!/usr/bin/perl
# pacsearch - Adds color and install information to a 'pacman -Ss' search
#
# Copyright (C) 2008-2011 Dan McGee <dan@archlinux.org>
#
# Based off original shell script version:
# Copyright (C) 2006-2007 Dan McGee <dan@archlinux.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#TODO: colors flag on commandline
use strict;
use warnings;
my $progname = "pacsearch";
my $version = "2.0";
if ($#ARGV lt 0 || $ARGV[0] eq "--help" || $ARGV[0] eq "-h") {
print "$progname - Add color and install information to a pacman -Ss search\n";
print "Usage: $progname <pattern>\n";
print "Example: $progname ^gnome\n";
if ($#ARGV lt 0) {
exit 1;
}
exit 0;
}
if ($ARGV[0] eq "--version" || $ARGV[0] eq "-v") {
print "$progname version $version\n";
print "Copyright (C) 2006-2011 Dan McGee\n";
exit 0;
}
# define our colors to use when printing
my $CLR1 = "\e[0;34m";
my $CLR2 = "\e[0;32m";
my $CLR3 = "\e[0;35m";
my $CLR4 = "\e[0;36m";
my $CLR5 = "\e[0;31m";
my $CLR6 = "\e[0;33m";
my $CLR7 = "\e[1;36m";
my $INST = "\e[1;31m";
my $BASE = "\e[0m";
# color a "repo/pkgname pkgver" line based on the repository name
sub to_color {
my $line = shift;
# get the installed text colored first
$line =~ s/(\[.*\]$)/$INST$1$BASE/;
# and now the repo and dealings
$line =~ s/(^core\/.*)/$CLR1$1$BASE/;
$line =~ s/(^extra\/.*)/$CLR2$1$BASE/;
$line =~ s/(^community\/.*)/$CLR3$1$BASE/;
$line =~ s/(^testing\/.*)/$CLR4$1$BASE/;
$line =~ s/(^community-testing\/.*)/$CLR5$1$BASE/;
$line =~ s/(^multilib\/.*)/$CLR6$1$BASE/;
$line =~ s/(^local\/.*)/$CLR7$1$BASE/;
# any other unknown repository
$line =~ s/(^[\w-]*\/.*)/$CLR6$1$BASE/;
return $line;
}
my %allpkgs = ();
my $syncout = `pacman -Ss '@ARGV'`;
# split each sync search entry into its own array entry
my @syncpkgs = split(/\n^(?=\w)/m, $syncout);
# remove the extra \n from the last desc entry
if ($#syncpkgs >= 0) {
chomp($syncpkgs[$#syncpkgs]);
}
# counter var for packages, used here and in the query loop too
my $cnt = 0;
foreach $_ (@syncpkgs) {
# we grab 4 fields here: repo, name/ver, installed, and desc
my @pkgfields = /^(.*?)\/(.*?) ?(\[.*\])?\n(.*)$/s;
if(not @pkgfields) {
# skip any non-matching line and just print it for the user
print $_, "\n";
next;
}
# since installed is optional, we should fill it in if necessary
$pkgfields[2] = "" if not defined $pkgfields[2];
# add a fifth field that indicates original order
push (@pkgfields, $cnt++);
# add each sync pkg by name/ver to a hash table for quick lookup
$allpkgs{$pkgfields[1]} = [ @pkgfields ];
}
my $queryout = `pacman -Qs '@ARGV'`;
# split each querysearch entry into its own array entry
my @querypkgs = split(/\n^(?=\w)/m, $queryout);
# remove the extra \n from the last desc entry
if ($#querypkgs >= 0) {
chomp ($querypkgs[$#querypkgs]);
}
foreach $_ (@querypkgs) {
# we grab 4 fields here: repo, name/ver, installed, and desc
my @pkgfields = /^(.*?)\/(.*?) ?(\[.*\])?\n(.*)$/s;
# since installed is optional, we should fill it in if necessary
$pkgfields[2] = "" if not defined $pkgfields[2];
# check if the package was listed in the sync out
if (not exists $allpkgs{$pkgfields[1]}) {
$pkgfields[2] = "[installed]";
# add a fifth field that indicates original order (after sync)
push (@pkgfields, $cnt++);
# add our local-only package to the hash
$allpkgs{$pkgfields[1]} = [ @pkgfields ];
}
}
# sort by original order (the fifth field) and print
foreach $_ ( sort{ @{$allpkgs{$a}}[4] <=> @{$allpkgs{$b}}[4] } keys %allpkgs) {
my @v = @{$allpkgs{$_}};
my $line = "$v[0]/$v[1] $v[2]";
$line = to_color($line);
# print colorized "repo/pkgname pkgver" string with possible installed text
print "$line\n";
print "$v[3]\n";
}
#vim: set noet: