summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2008-05-10 01:56:15 +0200
committerDan McGee <dan@archlinux.org>2008-05-10 18:04:17 +0200
commit1ba0d84da29d436f2b82c8961886ea2d021194d0 (patch)
tree8b144ed34d3907faf77ab54a95d49b4aaebfcf33
parentb49fc504acffa470cce31fb889723ecd86b314de (diff)
downloadpacman-1ba0d84da29d436f2b82c8961886ea2d021194d0.tar.gz
pacman-1ba0d84da29d436f2b82c8961886ea2d021194d0.tar.xz
pacsearch: rewrite in perl
This rewrite in perl blows the socks off the old shell script version for large searches: $ time ./pacsearch.perl ^.*$ >/dev/null real    0m0.836s user    0m0.593s sys     0m0.217s $ time pacsearch.sh ^.*$ >/dev/null real    1m53.818s user    1m16.818s sys     0m33.694s Functionality and output is identical to the old version with the exception of the old version's missing EOL after all the output. It should be a lot easier to add new things like the --color flag that has been a TODO at the top of the script for a long time. Signed-off-by: Dan McGee <dan@archlinux.org>
-rwxr-xr-xcontrib/pacsearch163
1 files changed, 103 insertions, 60 deletions
diff --git a/contrib/pacsearch b/contrib/pacsearch
index c07c28a8..3cf8b925 100755
--- a/contrib/pacsearch
+++ b/contrib/pacsearch
@@ -1,6 +1,9 @@
-#!/bin/bash
+#!/usr/bin/perl
# pacsearch - Adds color and install information to a 'pacman -Ss' search
#
+# Copyright (C) 2008 Dan McGee <dpmcgee@gmail.com>
+#
+# Based off original shell script version:
# Copyright (C) 2006-2007 Dan McGee <dpmcgee@gmail.com>
#
# This program is free software; you can redistribute it and/or
@@ -18,72 +21,112 @@
#TODO: colors flag on commandline
-readonly progname="pacsearch"
-readonly version="1.0"
+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;
+}
-readonly CLR1='\\\e[0;34m'
-readonly CLR2='\\\e[0;32m'
-readonly CLR3='\\\e[0;35m'
-readonly CLR4='\\\e[0;36m'
-readonly CLR5='\\\e[0;31m'
-readonly CLR6='\\\e[0;33m'
-readonly CLR7='\\\e[1;36m'
-readonly INST='\\\e[1;31m'
-readonly BASE='\\\e[0m'
+if ($ARGV[0] eq "--version" || $ARGV[0] eq "-v") {
+ print "$progname version $version\n";
+ print "Copyright (C) 2006-2008 Dan McGee\n";
+ exit 0;
+}
-if [ "$1" = "--help" -o "$1" = "-h" ]; then
- echo "Usage: $progname <pattern>"
- echo "Ex: $progname ^gnome"
- exit 0
-fi
+# 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";
+my $INSTMARK = $INST."***";
-if [ "$1" = "--version" -o "$1" = "-v" ]; then
- echo "$progname version $version"
- echo "Copyright (C) 2006-2007 Dan McGee"
- exit 0
-fi
+# color a "repo/pkgname pkgver" line based on the respository name
+sub to_color {
+ my $line = shift;
+ $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/(^unstable\/.*)/$CLR5$1$BASE/;
+ $line =~ s/(^custom\/.*)/$CLR6$1$BASE/;
+ $line =~ s/(^local\/.*)/$CLR7$1$BASE/;
+ # any other unknown repository
+ $line =~ s/(^[\w-]*\/.*)/$CLR6$1$BASE/;
+ return $line;
+}
-if [ -z "$1" -o "${1:0:1}" = "-" ]; then
- echo "Usage: $progname <pattern>"
- echo "Ex: $progname ^gnome"
- exit 1
-fi
+my %allpkgs = ();
-# Make two temp files and send output of commands to these files
-querydump=$(mktemp)
-pacman -Qs $1 > $querydump
-syncdump=$(mktemp)
-pacman -Ss $1 > $syncdump
+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]);
+}
-# Strip descriptions and 'local/' from -Qs query
-instpkg=$(mktemp)
-egrep '^[^ ]' $querydump | sed -e 's@^local/@@' > $instpkg
+# counter var for packages, used here and in the query loop too
+my $cnt = 0;
+foreach $_ (@syncpkgs) {
+ # we grab 3 fields here: repo, name/ver, and desc
+ my @pkgfields = /^(.*?)\/(.*?)\n(.*)$/s;
+ # add a fourth field that will indicate install status
+ push (@pkgfields, "");
+ # 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 ];
+}
-# Add pkgs not in sync db, mark pkgs that are installed
-cat $instpkg | while read -r pkg; do
- if [ -z "$(grep "$pkg" $syncdump)" ]; then
- # grep package name; pipe to another grep that prints at most one
- # line starting with 'local/', allows for comments >1 line
- grep -A10 "$pkg" $querydump | grep -A10 -m1 "local/" >> $syncdump
- fi
- sed -i "s@^\(.\+/$pkg\)@\***\1@" $syncdump
-done
+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]);
+}
-# Print colorized package list and descriptions to screen
-echo -e "$(sed -r \
- -e "s@core/.*@$CLR1&$BASE@" \
- -e "s@extra/.*@$CLR2&$BASE@" \
- -e "s@community/.*@$CLR3&$BASE@" \
- -e "s@testing/.*@$CLR4&$BASE@" \
- -e "s@unstable/.*@$CLR5&$BASE@" \
- -e "s@custom/.*@$CLR6&$BASE@" \
- -e "s@local/.*@$CLR7&$BASE@" \
- -e "s@(^|\*\*\*)([[:alnum:]]*/.* .*)@\1$CLR6\2$BASE@" \
- -e "s@\*\*\*@$INST&@" \
- < $syncdump )"
-echo -en "\e[0m"
+foreach $_ (@querypkgs) {
+ # we grab 3 fields here: repo, name/ver, and desc
+ my @pkgfields = /^(.*?)\/(.*?)\n(.*)$/s;
+ # check if the package was listed in the sync out
+ # if it is we want to mark it with a *** marker
+ if (exists $allpkgs{$pkgfields[1]}) {
+ # mark it in our fourth field as installed
+ @{ $allpkgs{$pkgfields[1]} }[3] = $INSTMARK;
+ } else {
+ # add a fourth field that will indicate install status
+ push (@pkgfields, $INSTMARK);
+ # 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 ];
+ }
+}
-rm $querydump
-rm $syncdump
-rm $instpkg
+# 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]";
+ $line = to_color($line);
+ # print install marker + colorized "repo/pkgname pkgver" string
+ print "$v[3]$line\n";
+ print "$v[2]\n";
+}
+#vim: set noet: