File zypper_urlnames of Package jw-env

#! /usr/bin/perl -w
#
# zypper_urlnames - make urls appear as names, next to the alias.
#
# zypper has 4 ways to address a repository,
# by number, by name, by alias, by url.
# 
# For a listing, a descriptive name is needed, to distinguish
# between beta versions, architectures, etc. Alias and Name often
# do not provide this level of detail, as they are short and often identical.
# Only the URL has a full level of detail.
# So users of 'zypper lr' usually add the -u or -d switch to 
# include the url.
# This has the unfortunate sideeffect of producing long lines (as all of 
# number, alias, name, url are shown, together with other info).
#
# When adding a repository an Alias is mandatory.
# Both Name and Alias are set to the given alias.
# That is not needed, as Alias and Name are always printed side by side.
#
# This script sets the Name equal to URL, so that a maximum of 
# information is presented using the least screen space.
#
# If possible, please improve zypper command line interface
# instead of adding to this script.
#
# Suggested fixes:
# - 'zypper ar' requires two parameters, the URL and an alias.
#   As users tend to be lazy, they specify an overly short alias. Please make the alias optional, 
#   defaulting it to the URL.
# - 'zypper lr' prints a column labeled 'alias'. This column is unchangeable, and likley to contain
#   useless autogenerared names like 'tmp1' or 'http-download.opensuse.org-34c579b2'
#   No commandline option exists to supress printing of this 'alias'. Please add one.
# - in 'zypper lr' both alias and name are user defined, and thus inherently incomplete or misleading.
#   In order to creae a short human readable name or alias, user normally chooses to omit some 
#   detail information, which may turn out to be critical later. The only reliable (although lengthy)
#   specification of a repo is its URL. Currently only -d or -u include the url in the output.
#   They produce typical lines with > 200 chars, having the url near the end. This is not usedful.
#   Please provide an option to print the URL in a format that has a chance to fit into 80 characters. 
#
#
# 2008-12-15, jw - initial draft.
# 2009-04-05, jw - using abbreviated d.o.o/r/ for download.opensuse.org/repositores/
# 2010-02-08, jw - optional abbreviation, optional write, useful as zypper lr replacement.
#                  Warn (or fix) where enable=no and refresh=yes.

use Data::Dumper;

# UPDATE by mls 2010-02-25:
# we can also change the alias. But not through zypper.
# for this we need to go to /etc/zypp/repos.d
# and edit the [...] line of the files.
# apparently zypper mr does nothing else than editing these files anyway.

my $zypper = '/usr/bin/zypper';
my $printonly = 1;
my $unabbreviated = 0;

$printonly = 0 if $0 =~ m{zypper.urlnames$}i;

while (defined(my $arg = shift))
  {
    $printonly	= 0    if $arg eq '-w';	
    $unabbreviated = 1 if $arg eq '-u';
    die qq{Usage: $0 [option]

valid options are:
  -w      Change name to become identical to (abbreviated) URL.
          This is default, whenn called as 'zypper_urlname'.
  -u      Print/Write unabbreviated URLs.
}                  unless $arg =~ m{^-[wu]};
  }

my %url_of;
my %disref;
open my $fd, "$zypper lr -d|" or die "failed to run '$zypper lr -u'\n";

print " id  ena  ref  pri  url\n----+----+----+---+-------------------------------------------\n" if $printonly;
while (defined(my $line = <$fd>))
  {
    chomp $line;
    # | Alias | Name | Enabled | Refresh | Priority | Type | URI | Service
    # 1 | Packman Repository | Packman Repository | Yes | No | 99 | rpm-md | http://packman.mirrors.skynet.be/pub/packman/suse/11.2 | 
    # 4  | SUSE-Linux-Enterprise-Desktop 11-0    | SUSE-Linux-Enterprise-Desktop 11-0                                             | Yes     | Yes     | ftp://dist.suse.de/install/SLP/SLED-11-RC1/i386/DVD1
    next unless $line =~ m{^\s*(\d+)\s*\|.*(Yes|No)\s*\|\s*(Yes|No)\s*\|\s*(\d+)\s*\|.*(\b\w+://\S+)\s*}i;
    my ($id,$ena,$ref,$pri,$url) = ($1,$2,$3,$4,$5);

    unless ($unabbreviated)
      {
        $url =~ s{\?.*$}{};	# remove '?credentials=NCCcredentials'
        $url =~ s{/+$}{};	# remove trailing slashes
	$url =~ s{%([0-9a-f][0-9a-f])}{pack "H2", $1}gei;	# url-decode
        $url =~ s{://download.opensuse.org/}{://d.o.o/};	# shorten the extra long urls.
        $url =~ s{/openSUSE_(\d)}{/oS_$1};		# shorten the extra long urls.
        $url =~ s{/repositories/}{/r/};			# shorten the extra long urls.
      }
    if (lc $ena eq 'no' and lc $ref eq 'yes')
      {
        $ref = "*YES*";
	$disref{$id}++;
      }
    else
      {
        $ref = " $ref";
      }
    printf "%3d  %-3s %-5s%3d  %s\n", $id,$ena,$ref,$pri,$url if $printonly;
    $url_of{$id} = $url unless $line =~ m{\Q$url\E.*\Q$url\E}s;
  }
close $fd;
exit 0 if $printonly;
print "nothing to do.\n" unless %url_of or %disref;

while (my ($id,$url) = each %url_of)
  {
    my $cmd = "$zypper mr -n '$url' '$id'";
    system $cmd and die "$cmd failed. $@ $!\n";
  }

for my $id (keys %disref)
  {
    my $cmd = "$zypper mr -R '$id'";
    system $cmd and die "$cmd failed. $@ $!\n";
  }
openSUSE Build Service is sponsored by