summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2009-09-28 11:09:32 +0300
committerPanu Matilainen <pmatilai@redhat.com>2009-11-25 08:56:24 +0200
commit4cca013b2d4b85a335d586559c16644dd8a17665 (patch)
tree4e9496cc7de628eee2ef115ecbf09cc3a4a1ee36
parent00628c8999ec713499a03c67c792756bc3c33832 (diff)
downloadrpm-4cca013b2d4b85a335d586559c16644dd8a17665.tar.gz
OSGi dependency generator fixes from Alphonse Van Assche (ticket #101)
- This patch fix some minor bug, remove unused code and increase drastically the perf by threading execution of tasks and using zip command instead of jar to get meta-data (cherry picked from commit a22fda5b5add3b96ac68a39ab8a6c88b72285098)
-rw-r--r--scripts/osgideps.pl315
1 files changed, 173 insertions, 142 deletions
diff --git a/scripts/osgideps.pl b/scripts/osgideps.pl
index 971dade94..9af050769 100644
--- a/scripts/osgideps.pl
+++ b/scripts/osgideps.pl
@@ -2,26 +2,18 @@
#
# osgideps.pl -- Analyze dependencies of OSGi bundles.
#
-# Kyu Lee
-# Alphonse Van Assche <alcapcom@fedoraproject.org>
+# Kyu Lee (initial idea)
+# Alphonse Van Assche <alcapcom@fedoraproject.org> (current maintainer)
#
# $Id: osgideps.pl,v 1.0 2009/06/08 12:12:12 mej Exp $
-#
-use Cwd;
use Getopt::Long;
use File::Temp qw/ tempdir /;
+use threads;
+use Thread::Queue;
-$cdir = getcwd();
-$TEMPDIR = tempdir( CLEANUP => 1 );
$MANIFEST_NAME = "META-INF/MANIFEST.MF";
-# prepare temporary directory
-if ( !( -d $TEMPDIR ) ) {
- if ( ( $_ = `mkdir $TEMPDIR` ) != 0 ) { exit 1; }
- elsif ( !( -w $TEMPDIR ) && ( -x $TEMPDIR ) ) { exit 1; }
-}
-
# parse options
my ( $show_provides, $show_requires, $show_system_bundles, $debug );
my $result = GetOptions(
@@ -47,168 +39,208 @@ exit(0);
# this function print provides of OSGi aware files
sub getProvides {
+
+ my $queue = Thread::Queue->new;
foreach $file (@_) {
- chomp($file);
- # we don't follow symlinks for provides
- next if -f $file && -r $file && -l $file;
- $file =~ s/[^[:print:]]//g;
- if ( $file =~ m/$MANIFEST_NAME$/ || $file =~ m/\.jar$/ ) {
- if ( $file =~ m/\.jar$/ ) {
- if ( `jar tf $file | grep -e \^$MANIFEST_NAME` eq "$MANIFEST_NAME\n" ) {
- # extract MANIFEST.MF file from jar to temporary directory
- chdir $TEMPDIR;
- `jar xf $file $MANIFEST_NAME`;
- open( MANIFEST, "$MANIFEST_NAME" );
- chdir $cdir;
+ $queue->enqueue($file);
+ }
+
+ my @workers;
+ push @workers, threads->create('getProvidesWorker');
+ push @workers, threads->create('getProvidesWorker');
+ push @workers, threads->create('getProvidesWorker');
+ push @workers, threads->create('getProvidesWorker');
+
+ map { $_->join } @workers;
+
+ sub getProvidesWorker {
+ while ( my $file = $queue->dequeue_nb ) {
+ chomp($file);
+ # we don't follow symlinks for provides
+ next if ( -f $file && -r $file && -l $file );
+ $file =~ s/[^[:print:]]//g;
+ if ( $file =~ m/$MANIFEST_NAME$/ || $file =~ m/\.jar$/ ) {
+ if ( $file =~ m/\.jar$/ ) {
+ if ( `zipinfo -1 $file 2> /dev/null | grep -e \^$MANIFEST_NAME` eq "$MANIFEST_NAME\n" ) {
+ # extract MANIFEST.MF file from jar to temporary directory
+ $tmpdir = tempdir( CLEANUP => 1 );
+ `unzip -d $tmpdir -qqo $file $MANIFEST_NAME`;
+ open( MANIFEST, "$tmpdir/$MANIFEST_NAME" );
+ }
+ } else {
+ open( MANIFEST, "$file" );
}
- } else {
- open( MANIFEST, "$file" );
- }
- my $bundleName = "";
- my $version = "";
- # parse Bundle-SymbolicName, Bundle-Version and Export-Package attributes
- while (<MANIFEST>) {
- # get rid of non-print chars (some manifest files contain weird chars)
- s/[^[:print]]//g;
- if ( m/(^(Bundle-SymbolicName): )(.*)$/ ) {
- $bundleName = "$3" . "\n";
- while (<MANIFEST>) {
- if ( m/^[[:upper:]][[:alpha:]]+-[[:upper:]][[:alpha:]]+: .*/ ) {
- $len = length $_;
- seek MANIFEST, $len * -1, 1;
- last;
+ my $bundleName = "";
+ my $version = "";
+ # parse Bundle-SymbolicName, Bundle-Version and Export-Package attributes
+ while (<MANIFEST>) {
+ # get rid of non-print chars (some manifest files contain weird chars)
+ s/[^[:print]]//g;
+ if ( m/(^(Bundle-SymbolicName): )(.*)$/ ) {
+ $bundleName = "$3" . "\n";
+ while (<MANIFEST>) {
+ if ( m/^[[:upper:]][[:alpha:]]+-[[:upper:]][[:alpha:]]+: .*/ ) {
+ $len = length $_;
+ seek MANIFEST, $len * -1, 1;
+ last;
+ }
+ $bundleName .= "$_";
}
- $bundleName .= "$_";
+ $bundleName =~ s/\s+//g;
+ $bundleName =~ s/;.*//g;
}
- $bundleName =~ s/\s+//g;
- $bundleName =~ s/;.*//g;
- }
- if ( m/(^Bundle-Version: )(.*)/ ) {
- $version = $2;
- }
- if ( m/(^(Export-Package): )(.*)$/ ) {
- my $bunlist = "$3" . "\n";
- while (<MANIFEST>) {
- if ( m/^[[:upper:]][[:alpha:]]+-[[:upper:]][[:alpha:]]+: .*/ ) {
- $len = length $_;
- seek MANIFEST, $len * -1, 1;
- last;
+ if ( m/(^Bundle-Version: )(.*)/ ) {
+ $version = $2;
+ }
+ if ( m/(^(Export-Package): )(.*)$/ ) {
+ my $bunlist = "$3" . "\n";
+ while (<MANIFEST>) {
+ if ( m/^[[:upper:]][[:alpha:]]+-[[:upper:]][[:alpha:]]+: .*/ ) {
+ $len = length $_;
+ seek MANIFEST, $len * -1, 1;
+ last;
+ }
+ $bunlist .= "$_";
}
- $bunlist .= "$_";
+ push @bundlelist, parsePkgString($bunlist, $file);
+ }
+ }
+
+ # skip this jar if no bundle name exists
+ if ( !$bundleName eq "" ) {
+ if ( !$version eq "" ) {
+ $version = parseVersion($version);
+ push @bundlelist, { FILE => "$file", NAME => "$bundleName", VERSION => "$version" };
+ } else {
+ push @bundlelist, { FILE => "$file", NAME => "$bundleName", VERSION => "" };
}
- push @bundlelist, parsePkgString($bunlist, $file);
- }
- }
-
- # skip this jar if no bundle name exists
- if ( !$bundleName eq "" ) {
- if ( !$version eq "" ) {
- $version = parseVersion($version);
- push @bundlelist, { FILE => "$file", NAME => "$bundleName", VERSION => "$version" };
- } else {
- push @bundlelist, { FILE => "$file", NAME => "$bundleName", VERSION => "" };
}
+ `rm -rf $tmpdir`;
}
}
- }
- if ( !$debug ) { @bundlelist = prepareOSGiBundlesList(@bundlelist); }
- $list = "";
- for $bundle (@bundlelist) {
- if ( !$debug ) {
- $list .= "osgi(" . $bundle->{NAME} . ")" . $bundle->{VERSION} . "\n";
- } else {
- $list .= $bundle->{FILE} . " osgi(" . $bundle->{NAME} . ")" . $bundle->{VERSION} . "\n";
+ if ( !$debug ) { @bundlelist = prepareOSGiBundlesList(@bundlelist); }
+ $list = "";
+ for $bundle (@bundlelist) {
+ if ( !$debug ) {
+ $list .= "osgi(" . $bundle->{NAME} . ")" . $bundle->{VERSION} . "\n";
+ } else {
+ $list .= $bundle->{FILE} . " osgi(" . $bundle->{NAME} . ")" . $bundle->{VERSION} . "\n";
+ }
}
+ print $list;
}
- print $list;
}
# this function print requires of OSGi aware files
sub getRequires {
+
+ my $queue = Thread::Queue->new;
foreach $file (@_) {
- next if (-f $file && -r $file);
- # we explicitly requires symlinked jars
- if (-l $file) {
- $file = readlink $file;
- if ( !$file eq "" ) {
- print "$file" . "\n";
- }
- next;
- }
- $file =~ s/[^[:print:]]//g;
- if ( $file =~ m/$MANIFEST_NAME$/ || $file =~ m/\.jar$/ ) {
- if ( $file =~ m/\.jar$/ ) {
- if ( `jar tf $file | grep -e \^$MANIFEST_NAME` eq "$MANIFEST_NAME\n" ) {
- # extract MANIFEST.MF file from jar to temporary directory
- chdir $TEMPDIR;
- `jar xf $file $MANIFEST_NAME`;
- open( MANIFEST, "$MANIFEST_NAME" );
- chdir $cdir;
- }
- } else {
- open( MANIFEST, "$file" );
- }
- while (<MANIFEST>) {
- if ( m/(^(Require-Bundle|Import-Package): )(.*)$/ ) {
- my $bunlist = "$3" . "\n";
- while (<MANIFEST>) {
- if (m/^[[:upper:]][[:alpha:]]+-[[:upper:]][[:alpha:]]+: .*/ ) {
- $len = length $_;
- seek MANIFEST, $len * -1, 1;
+ $queue->enqueue($file);
+ }
+
+ my @workers;
+ push @workers, threads->create('getRequiresWorker');
+ push @workers, threads->create('getRequiresWorker');
+ push @workers, threads->create('getRequiresWorker');
+ push @workers, threads->create('getRequiresWorker');
+
+ map { $_->join } @workers;
+
+ sub getRequiresWorker {
+ while ( my $file = $queue->dequeue_nb ) {
+ next if ( -f $file && -r $file );
+ $file =~ s/[^[:print:]]//g;
+ if ( $file =~ m/$MANIFEST_NAME$/ || $file =~ m/\.jar$/ ) {
+ # we explicitly requires symlinked jars
+ # _that_reside_outside_the_package_
+ if (-l $file) {
+ $exist = 0;
+ $lnksrc = `readlink -qen $file`;
+ foreach $exfile ( @allfiles ) {
+ $exfile =~ s/[^[:print:]]//g;
+ if ( $lnksrc =~ m/$exfile$/ ) {
+ $exist = 1;
last;
}
- $bunlist .= "$_";
}
- push @bundlelist, parsePkgString($bunlist, $file);
+ print "$lnksrc\n" if (!$exist);
+ next;
+ }
+
+ if ( $file =~ m/\.jar$/ ) {
+ if ( `zipinfo -1 $file 2> /dev/null | grep -e \^$MANIFEST_NAME` eq "$MANIFEST_NAME\n" ) {
+ # extract MANIFEST.MF file from jar to temporary directory
+ $tmpdir = tempdir( CLEANUP => 1 );
+ `unzip -d $tmpdir -qqo $file $MANIFEST_NAME`;
+ open( MANIFEST, "$tmpdir/$MANIFEST_NAME" );
+ }
+ } else {
+ open( MANIFEST, "$file" );
}
- # we also explicitly require symlinked jars define by
- # Bundle-ClassPath attribut
- if ( m/(^(Bundle-ClassPath): )(.*)$/ ) {
- $bunclp = "$3" . "\n";
- while (<MANIFEST>) {
- if ( m/^[[:upper:]][[:alpha:]]+-[[:upper:]][[:alpha:]]+: .*/ ) {
- $len = length $_;
- seek MANIFEST, $len * -1, 1;
- last;
+ while (<MANIFEST>) {
+ if ( m/(^(Require-Bundle|Import-Package): )(.*)$/ ) {
+ my $bunlist = "$3" . "\n";
+ while (<MANIFEST>) {
+ if (m/^[[:upper:]][[:alpha:]]+-[[:upper:]][[:alpha:]]+: .*/ ) {
+ $len = length $_;
+ seek MANIFEST, $len * -1, 1;
+ last;
+ }
+ $bunlist .= "$_";
}
- $bunclp .= "$_";
+ push @bundlelist, parsePkgString($bunlist, $file);
}
- $bunclp =~ s/\ //g;
- $bunclp =~ s/\n//g;
- $bunclp =~ s/[^[:print:]]//g;
- $dir = `dirname $file`;
- $dir =~ s/\n//g;
- @jars = split /,/, $bunclp;
- for $jarfile (@jars) {
- $jarfile = "$dir\/\.\.\/$jarfile";
- $jarfile = readlink $jarfile;
- if ( !$jarfile eq "" ) {
- print "$jarfile" . "\n";
+ # we also explicitly require symlinked jars define by
+ # Bundle-ClassPath attribut
+ if ( m/(^(Bundle-ClassPath): )(.*)$/ ) {
+ $bunclp = "$3" . "\n";
+ while (<MANIFEST>) {
+ if ( m/^[[:upper:]][[:alpha:]]+-[[:upper:]][[:alpha:]]+: .*/ ) {
+ $len = length $_;
+ seek MANIFEST, $len * -1, 1;
+ last;
+ }
+ $bunclp .= "$_";
+ }
+ $bunclp =~ s/\ //g;
+ $bunclp =~ s/\n//g;
+ $bunclp =~ s/[^[:print:]]//g;
+ $dir = `dirname $file`;
+ $dir =~ s/\n//g;
+ @jars = split /,/, $bunclp;
+ for $jarfile (@jars) {
+ $jarfile = "$dir\/\.\.\/$jarfile";
+ $jarfile = readlink $jarfile;
+ if ( !$jarfile eq "" ) {
+ print "$jarfile" . "\n";
+ }
}
}
}
+ `rm -rf $tmpdir`;
}
}
- }
- if ( !$debug ) { @bundlelist = prepareOSGiBundlesList(@bundlelist); }
- $list = "";
- for $bundle (@bundlelist) {
- # replace '=' by '>=' because qualifiers are set on provides
- # but not on requires.
- $bundle->{VERSION} =~ s/\ =/\ >=/g;
- if ( !$debug ) {
- $list .= "osgi(" . $bundle->{NAME} . ")" . $bundle->{VERSION} . "\n";
- } else {
- $list .= $bundle->{FILE} . " osgi(" . $bundle->{NAME} . ")" . $bundle->{VERSION} . "\n";
+ if ( !$debug ) { @bundlelist = prepareOSGiBundlesList(@bundlelist); }
+ $list = "";
+ for $bundle (@bundlelist) {
+ # replace '=' by '>=' because qualifiers are set on provides
+ # but not on requires.
+ $bundle->{VERSION} =~ s/\ =/\ >=/g;
+ if ( !$debug ) {
+ $list .= "osgi(" . $bundle->{NAME} . ")" . $bundle->{VERSION} . "\n";
+ } else {
+ $list .= $bundle->{FILE} . " osgi(" . $bundle->{NAME} . ")" . $bundle->{VERSION} . "\n";
+ }
}
+ print $list;
}
- print $list;
}
# this function print system bundles of OSGi profile files.
sub getSystemBundles {
foreach $file (@_) {
- if ( -r $file && -r $file ) {
+ if ( -f $file && -r $file ) {
print "'$file' file not found or cannot be read!";
next;
} else {
@@ -261,8 +293,7 @@ sub parsePkgString {
$version = "";
$name = $reqelementfrmnt[0];
$name =~ s/\"//g;
- # ignore 'system.bundle'.
- # see http://help.eclipse.org/stable/index.jsp?topic=/org.eclipse.platform.doc.isv/porting/3.3/incompatibilities.html
+ # ignoring OSGi 'system.bundle'
next if ( $name =~ m/^system\.bundle$/ );
for $i ( 1 .. $#reqelementfrmnt ) {
if ( $reqelementfrmnt[$i] =~ m/(^(bundle-|)version=")(.*)(")/ ) {