Mon Oct 22 10:26:46 2012: Request 80333 was acted upon.
Transaction: Ticket created by thoke
       Queue: PAR-Dist
     Subject: PAR::Dist::parse_dist_name mis-parses par file name when arch
 contains digits
   Broken in: 0.49
    Severity: Important
       Owner: Nobody
  Requestors: th...@northpeak.org
      Status: new
 Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=80333 >


I've taken KENO's example from RT78194 and applied it to Solaris platforms 
(Sparc and x86-64).

The idea is that I am unable to load a module with an arch containing digits 
(e.g. sun4-solaris-thread-multi-64 or i86pc-solaris-thread-multi-64) from a 
PAR::Repository.  When parsing the par file 
name, PAR::Dist::parse_dist_name() counts 64 as a Perl version.  The test is to 
create a repository containing some module that is not otherwise available on 
the system.  I 
used Acme::Drunk.

$ cat ~/tmp/testpar.pl 
#!/bin/env perl
use strict;
use warnings;

use Test::More tests => 1;

BEGIN {
  SKIP: {
        eval { require Acme::Drunk; 1 }
          and skip 'Acme::Drunk must not be available.';
        eval { require PAR;
               PAR->import( {
                             repository => 'file:///path/to/tmp/repo/',
                             fallback   => 0,
                            });
               1; }
          or skip 'Could not load PAR.';
        use_ok('Acme::Drunk');
    }
}

$ find ./Acme-Drunk-0.03 -name \*.par
./Acme-Drunk-0.03/Acme-Drunk-0.03-i86pc-solaris-thread-multi-64-5.14.2.par

The problem first arises when I use parrepo inject:


$ parrepo inject -r repo -f 
Acme-Drunk-0.03/Acme-Drunk-0.03-i86pc-solaris-thread-multi-64-5.14.2.par 
Injecting file 
'Acme-Drunk-0.03/Acme-Drunk-0.03-i86pc-solaris-thread-multi-64-5.14.2.par' into 
repository.

$ find ./repo -type f -name \*.par
./repo/i86pc-solaris-thread-multi/64/Acme-Drunk-0.03-i86pc-solaris-thread-multi-64.par

I can work around that issue by injecting with all parameters specified:

$ parrepo inject -r repo -f 
Acme-Drunk-0.03/Acme-Drunk-0.03-i86pc-solaris-thread-multi-64-5.14.2.par -n 
Acme::Drunk -v 0.03 -a i86pc-solaris-thread-multi-64 -p 5.14.2
Injecting file 
'Acme-Drunk-0.03/Acme-Drunk-0.03-i86pc-solaris-thread-multi-64-5.14.2.par' into 
repository.

$ find ./repo -type f -name 
\*.par./repo/i86pc-solaris-thread-multi/64/Acme-Drunk-0.03-i86pc-solaris-thread-multi-64.par
./repo/i86pc-solaris-thread-multi-64/5.14.2/Acme::Drunk-0.03-i86pc-solaris-thread-multi-64-5.14.2.par

However, when i execute the script, we can see the error:

$ perl testpar.pl 
1..1
not ok 1 - use Acme::Drunk;
#   Failed test 'use Acme::Drunk;'
#   at testpar.pl line 18.
#     Tried to use 'Acme::Drunk'.
#     Error:  Can't locate Acme/Drunk.pm in @INC (@INC contains: CODE(0x7ed788) 
/path/to/perl5lib/perl-5.14.2/solaris_x86_10_64/lib/perl5/i86pc-solaris-thread-multi-64
 /path/to/perl5lib/perl-
5.14.2/solaris_x86_10_64/lib/perl5 
/path/to/perl/5.14.2/app/SunOS_5.10_i386_SunS_5.8/lib/site_perl/5.14.2/i86pc-solaris-thread-multi-64
 
/path/to/perl/5.14.2/app/SunOS_5.10_i386_SunS_5.8/lib/site_perl/5.14.2 
/path/to/perl/5.14.2/app/SunOS_5.10_i386_SunS_5.8/lib/5.14.2/i86pc-solaris-thread-multi-64
 
/path/to/perl/5.14.2/app/SunOS_5.10_i386_SunS_5.8/lib/5.14.2 . CODE(0x8a0108)) 
at (eval 32) line 2.
# BEGIN failed--compilation aborted at (eval 32) line 2.
# Looks like you failed 1 test of 1.

I've modified parse_dist_name to eliminate stepping through the arch section of 
the filename, instead, popping the perl version off the end and then setting 
the remainder to be the arch:

$ diff -u Dist-orig.pm Dist-new.pm 
--- Dist-orig.pm        2012-10-22 08:37:10.757544000 -0500
+++ Dist-new.pm 2012-10-22 08:40:10.968501000 -0500
@@ -1166,17 +1166,10 @@
         return( $dn, $dv, undef, undef);
     }
 
-    while (@elem) {
-        my $e = shift @elem;
-        if ($e =~ /^(?:$version|any_version)$/) {
-            $pv = $e;
-            last;
-        }
-        push @arch, $e;
-    }
+    $pv = pop @elem;
 
     my $arch;
-    $arch = join('-', @arch) if @arch;
+    $arch = join('-', @elem) if @elem;
 
     return($dn, $dv, $arch, $pv);
 }


With that patch applied, both parrepo inject and PAR->import work:

$ parrepo inject -r repo -f 
Acme-Drunk-0.03/Acme-Drunk-0.03-i86pc-solaris-thread-multi-64-5.14.2.par
Injecting file 
'Acme-Drunk-0.03/Acme-Drunk-0.03-i86pc-solaris-thread-multi-64-5.14.2.par' into 
repository.

$ find ./repo -type f -name \*.par
./repo/i86pc-solaris-thread-multi-64/5.14.2/Acme-Drunk-0.03-i86pc-solaris-thread-multi-64-5.14.2.par

$ perl testpar.pl 
1..1
ok 1 - use Acme::Drunk;

Attachment: pop_perl_ver.diff
Description: Binary data

Reply via email to