Ticket #39: osgideps.pl.patch.20090617

File osgideps.pl.patch.20090617, 15.1 kB (added by alcapcom, 3 years ago)

osgideps.pl.patch

Line 
1 --- osgideps.pl.ori     2009-04-16 11:30:39.000000000 +0200
2 +++ osgideps.pl 2009-06-17 10:58:22.849272922 +0200
3 @@ -1,203 +1,357 @@
4  #!/usr/bin/perl
5 -
6 +#
7 +# osgideps.pl -- Analyze dependencies of OSGi bundles.
8 +#
9 +# Kyu Lee
10 +# Alphonse Van Assche <alcapcom@fedoraproject.org>
11 +#
12 +# $Id: osgideps.pl,v 1.0 2009/06/08 12:12:12 mej Exp $
13 +#
14  
15  use Cwd;
16  use Getopt::Long;
17 -
18 +use File::Temp qw/ tempdir /;
19  
20  $cdir = getcwd();
21 -$TEMPDIR="/tmp";
22 -$MANIFEST_NAME="META-INF/MANIFEST.MF";
23 -
24 +$TEMPDIR = tempdir( CLEANUP => 1 );
25 +$MANIFEST_NAME = "META-INF/MANIFEST.MF";
26  
27  # prepare temporary directory
28 -if (! (-d $TEMPDIR)) {
29 -        if (($_ = `mkdir $TEMPDIR`) != 0) {exit 1;}
30 -        elsif (! (-w $TEMPDIR) && (-x $TEMPDIR)) {exit 1;}
31 +if ( !( -d $TEMPDIR ) ) {
32 +       if ( ( $_ = `mkdir $TEMPDIR` ) != 0 ) { exit 1; }
33 +       elsif ( !( -w $TEMPDIR ) && ( -x $TEMPDIR ) ) { exit 1; }
34  }
35  
36  # parse options
37 -my ($show_provides, $show_requires);
38 -
39 -my $result = GetOptions("provides" => \$show_provides,
40 -                       "requires" => \$show_requires);
41 -
42 -exit(1) if (not $result);
43 -
44 -
45 +my ( $show_provides, $show_requires, $show_system_bundles, $debug );
46 +my $result = GetOptions(
47 +       "provides" => \$show_provides,
48 +       "requires" => \$show_requires,
49 +       "system" => \$show_system_bundles,
50 +       "debug" => \$debug
51 +);
52 +exit(1) if ( not $result );
53  
54 +# run selected function
55  @allfiles = <STDIN>;
56 -
57  if ($show_provides) {
58 -       do_provides(@allfiles);
59 +       getProvides(@allfiles);
60  }
61 -
62  if ($show_requires) {
63 -       do_requires(@allfiles);
64 +       getRequires(@allfiles);
65 +}
66 +if ($show_system_bundles) {
67 +       getSystemBundles(@allfiles);
68  }
69 -
70 -
71  exit(0);
72  
73 +# this function print provides of OSGi aware files
74 +sub getProvides {
75 +       foreach $file (@_) {
76 +               chomp($file);
77 +               # we don't follow symlinks for provides
78 +               next if -f $file && -r $file && -l $file;
79 +               $file =~ s/[^[:print:]]//g;
80 +               if ( $file =~ m/$MANIFEST_NAME$/ || $file =~ m/\.jar$/ ) {
81 +                       if ( $file =~ m/\.jar$/ ) {
82 +                               if ( `jar tf $file | grep -e \^$MANIFEST_NAME` eq "$MANIFEST_NAME\n" ) {
83 +                                       # extract MANIFEST.MF file from jar to temporary directory
84 +                                       chdir $TEMPDIR;
85 +                                       `jar xf $file $MANIFEST_NAME`;
86 +                                       open( MANIFEST, "$MANIFEST_NAME" );
87 +                                       chdir $cdir;
88 +                               }
89 +                       } else {
90 +                               open( MANIFEST, "$file" );
91 +                       }
92 +                       my $bundleName = "";
93 +                       my $version = "";
94 +                       # parse Bundle-SymbolicName, Bundle-Version and Export-Package attributes
95 +                       while (<MANIFEST>) {
96 +                               # get rid of non-print chars (some manifest files contain weird chars)
97 +                               s/[^[:print]]//g;
98 +                               if ( m/(^(Bundle-SymbolicName): )(.*)$/ ) {
99 +                                       $bundleName = "$3" . "\n";
100 +                                       while (<MANIFEST>) {
101 +                                               if ( m/^[[:upper:]][[:alpha:]]+-[[:upper:]][[:alpha:]]+: .*/ ) {
102 +                                                       $len = length $_;
103 +                                                       seek MANIFEST, $len * -1, 1;
104 +                                                       last;
105 +                                               }
106 +                                               $bundleName .= "$_";
107 +                                       }
108 +                                       $bundleName =~ s/\s+//g;
109 +                                       $bundleName =~ s/;.*//g;
110 +                               }
111 +                               if ( m/(^Bundle-Version: )(.*)/ ) {
112 +                                       $version = $2;
113 +                               }
114 +                               if ( m/(^(Export-Package): )(.*)$/ ) {
115 +                                       my $bunlist = "$3" . "\n";
116 +                                       while (<MANIFEST>) {
117 +                                               if ( m/^[[:upper:]][[:alpha:]]+-[[:upper:]][[:alpha:]]+: .*/ ) {
118 +                                                       $len = length $_;
119 +                                                       seek MANIFEST, $len * -1, 1;
120 +                                                       last;
121 +                                               }
122 +                                               $bunlist .= "$_";
123 +                                       }
124 +                                       push @bundlelist, parsePkgString($bunlist, $file);
125 +                               }
126 +                       }
127  
128 -
129 -sub do_provides {
130 -
131 -foreach $file (@_) {
132 -
133 -       next if -f $file && -r $file && !-l $file;
134 -       $file =~ s/[^[:print:]]//g;
135 -       if ($file =~ m/$MANIFEST_NAME$/ || $file =~ m/\.jar$/ ) {
136 -               if ($file =~ m/\.jar$/) {
137 -                       # if this jar contains MANIFEST.MF file
138 -                       if (`jar tf $file | grep -e \^$MANIFEST_NAME` eq "$MANIFEST_NAME\n") {
139 -                               # extract MANIFEST.MF file from jar to temporary directory
140 -                               chdir $TEMPDIR;
141 -                               `jar xf $file $MANIFEST_NAME`; 
142 -                               open(MANIFEST, "$MANIFEST_NAME");
143 -                               chdir $cdir;
144 -                       }
145 -               } else  {
146 -                       open(MANIFEST, "$file");
147 -               }
148 -               my $bundleName = "";
149 -               my $version = "";
150 -               # parse bundle name and version
151 -               while(<MANIFEST>) {
152 -                       # get rid of non-print chars (some manifest files contain weird chars)
153 -                       s/[^[:print]]//g;
154 -                       if (m/(^Bundle-SymbolicName: )((\w|\.)+)(\;*)(.*\n)/) {
155 -                               $bundleName = $2;
156 -                       }
157 -                       if (m/(^Bundle-Version: )(.*)/) {
158 -                               $version = $2;
159 -                               $version = fixVersion($version);
160 -                       }
161 -                       if (m/(^(Export-Package): )(.*)$/) {
162 -                               my $bunlist = "$3"."\n";
163 -                               while(<MANIFEST>) {
164 -                                       if (m/^[[:upper:]][[:alpha:]]+-[[:upper:]][[:alpha:]]+: .*/) {
165 -                                               $len = length $_;
166 -                                               seek MANIFEST, $len*-1 , 1;
167 -                                               last;
168 -                                       }
169 -                                       $bunlist.="$_";
170 -                               }
171 -                               push @bundlelist,  parsePkgString($bunlist);
172 -                       }
173 -                }
174 -                # skip this jar if no bundle name exists
175 -                if (! $bundleName eq "") {
176 -                       if (! $version eq "") {
177 -                               print "osgi(".$bundleName.") = ".$version."\n";
178 -                       } else {
179 -                                print "osgi(".$bundleName.")\n";
180 -                        }
181 -                }
182 -       }
183 -}
184 -$list = "";
185 -for $bundle (@bundlelist) {
186 -       $list .= "osgi(".$bundle->{NAME}.")".$bundle->{VERSION}."\n";
187 -}
188 -# For now we dont take Require-Bundle AND Import-Package in account
189 -#print $list;
190 +                       # skip this jar if no bundle name exists
191 +                       if ( !$bundleName eq "" ) {
192 +                               if ( !$version eq "" ) {
193 +                                       $version = parseVersion($version);
194 +                                       push @bundlelist, { FILE => "$file", NAME => "$bundleName", VERSION => "$version" };
195 +                               } else {
196 +                                       push @bundlelist, { FILE => "$file", NAME => "$bundleName", VERSION => "" };
197 +                               }
198 +                       }
199 +               }
200 +       }
201 +       if ( !$debug ) { @bundlelist = prepareOSGiBundlesList(@bundlelist); }
202 +       $list = "";
203 +       for $bundle (@bundlelist) {
204 +               if ( !$debug ) {
205 +                       $list .= "osgi(" . $bundle->{NAME} . ")" . $bundle->{VERSION} . "\n";
206 +               } else {
207 +                       $list .= $bundle->{FILE} . " osgi(" . $bundle->{NAME} . ")" . $bundle->{VERSION} . "\n";
208 +               }
209 +       }
210 +       print $list;
211  }
212  
213 -
214 -sub do_requires {
215 -
216 +# this function print requires of OSGi aware files
217 +sub getRequires {
218         foreach $file (@_) {
219 -
220 -               next if -f $file && -r $file;
221 +               next if (-f $file && -r $file);
222 +               # we explicitly requires symlinked jars
223 +               if (-l $file) {
224 +                       $file = readlink $file;
225 +                       if ( !$file eq "" ) {                                                   
226 +                               print "$file" . "\n";
227 +                       }
228 +                       next;
229 +               }
230                 $file =~ s/[^[:print:]]//g;
231 -               if ($file =~ m/$MANIFEST_NAME$/ || $file =~ m/\.jar$/ ) {
232 -                       if ($file =~ m/\.jar$/) {
233 -                               # if this jar contains MANIFEST.MF file
234 -                               if (`jar tf $file | grep -e \^$MANIFEST_NAME` eq "$MANIFEST_NAME\n") {
235 +               if ( $file =~ m/$MANIFEST_NAME$/ || $file =~ m/\.jar$/ ) {
236 +                       if ( $file =~ m/\.jar$/ ) {
237 +                               if ( `jar tf $file | grep -e \^$MANIFEST_NAME` eq "$MANIFEST_NAME\n" ) {
238                                         # extract MANIFEST.MF file from jar to temporary directory
239 -                                       chdir $TEMPDIR;
240 -                                       `jar xf $file $MANIFEST_NAME`; 
241 -                                       open(MANIFEST, "$MANIFEST_NAME");
242 +                                       chdir $TEMPDIR;
243 +                                       `jar xf $file $MANIFEST_NAME`;
244 +                                       open( MANIFEST, "$MANIFEST_NAME" );
245                                         chdir $cdir;
246                                 }
247 -                       } else  {
248 -                               open(MANIFEST, "$file");
249 +                       } else {
250 +                               open( MANIFEST, "$file" );
251 +                       }
252 +                       while (<MANIFEST>) {
253 +                               if ( m/(^(Require-Bundle|Import-Package): )(.*)$/ ) {
254 +                                       my $bunlist = "$3" . "\n";
255 +                                       while (<MANIFEST>) {
256 +                                               if (m/^[[:upper:]][[:alpha:]]+-[[:upper:]][[:alpha:]]+: .*/ ) {
257 +                                                       $len = length $_;
258 +                                                       seek MANIFEST, $len * -1, 1;
259 +                                                       last;
260 +                                               }
261 +                                               $bunlist .= "$_";
262 +                                       }
263 +                                       push @bundlelist, parsePkgString($bunlist, $file);
264 +                               }
265 +                               # we also explicitly require symlinked jars define by
266 +                               # Bundle-ClassPath attribut
267 +                               if ( m/(^(Bundle-ClassPath): )(.*)$/ ) {
268 +                                       $bunclp = "$3" . "\n";
269 +                                       while (<MANIFEST>) {
270 +                                               if ( m/^[[:upper:]][[:alpha:]]+-[[:upper:]][[:alpha:]]+: .*/ ) {
271 +                                                       $len = length $_;
272 +                                                       seek MANIFEST, $len * -1, 1;
273 +                                                       last;
274 +                                               }
275 +                                               $bunclp .= "$_";
276 +                                       }
277 +                                       $bunclp =~ s/\ //g;
278 +                                       $bunclp =~ s/\n//g;
279 +                                       $bunclp =~ s/[^[:print:]]//g;
280 +                                       $dir = `dirname $file`;
281 +                                       $dir =~ s/\n//g;
282 +                                       @jars = split /,/, $bunclp;
283 +                                       for $jarfile (@jars) {
284 +                                               $jarfile = "$dir\/\.\.\/$jarfile";
285 +                                               $jarfile = readlink $jarfile;
286 +                                               if ( !$jarfile eq "" ) {                                                       
287 +                                                       print "$jarfile" . "\n";
288 +                                               }
289 +                                       }
290 +                               }
291                         }
292 -                               my %reqcomp = ();
293 -                       while(<MANIFEST>) {
294 -                               if (m/(^(Require-Bundle|Import-Package): )(.*)$/) {
295 -                               my $bunlist = "$3"."\n";
296 -                                while(<MANIFEST>) {
297 -                                        if (m/^[[:upper:]][[:alpha:]]+-[[:upper:]][[:alpha:]]+: .*/) {
298 -                                                $len = length $_;
299 -                                                seek MANIFEST, $len*-1 , 1;
300 -                                                last;
301 -                                        }
302 -                                       $bunlist.="$_";
303 -                                }
304 -                               push @bundlelist,  parsePkgString($bunlist);
305 -                        }
306 -                }
307 +               }
308         }
309 +       if ( !$debug ) { @bundlelist = prepareOSGiBundlesList(@bundlelist); }
310 +       $list = "";
311 +       for $bundle (@bundlelist) {
312 +               # replace '=' by '>=' because qualifiers are set on provides
313 +               # but not on requires.
314 +               $bundle->{VERSION} =~ s/\ =/\ >=/g;
315 +               if ( !$debug ) {
316 +                       $list .= "osgi(" . $bundle->{NAME} . ")" . $bundle->{VERSION} . "\n";
317 +               } else {
318 +                       $list .= $bundle->{FILE} . " osgi(" . $bundle->{NAME} . ")" . $bundle->{VERSION} . "\n";
319 +               }
320 +       }
321 +       print $list;
322  }
323  
324 -$list = "";
325 -for $bundle (@bundlelist) {
326 -       $list .= "osgi(".$bundle->{NAME}.")".$bundle->{VERSION}."\n";
327 -}
328 -# For now we dont take Require-Bundle AND Import-Package in account
329 -#print $list;
330 +# this function print system bundles of OSGi profile files.
331 +sub getSystemBundles {
332 +       foreach $file (@_) {
333 +               if ( -r $file && -r $file ) {
334 +                       print "'$file' file not found or cannot be read!";
335 +                       next;
336 +               } else {
337 +                       open( PROFILE, "$file" );
338 +                       while (<PROFILE>) {
339 +                               if ( $file =~ m/\.profile$/ ) {
340 +                                       if (m/(^(org\.osgi\.framework\.system\.packages)[=|\ ]+)(.*)$/) {
341 +                                               $syspkgs = "$3" . "\n";
342 +                                               while (<PROFILE>) {
343 +                                                       if (m/^[a-z]/) {
344 +                                                               $len = length $_;
345 +                                                               seek MANIFEST, $len * -1, 1;
346 +                                                               last;
347 +                                                       }
348 +                                                       $syspkgs .= "$_";
349 +                                               }
350 +                                               $syspkgs =~ s/\s+//g;
351 +                                               $syspkgs =~ s/\\//g;
352 +                                               @bundles = split /,/, $syspkgs;
353 +                                               foreach $bundle (@bundles) {
354 +                                                       print "osgi(" . $bundle . ")\n";
355 +                                               }
356 +                                       }
357 +                               }
358 +                       }
359 +               }
360 +       }
361  }
362  
363  sub parsePkgString {
364 -        my $bunstr = $_[0];
365 -        my @return;
366 +       my $bunstr = $_[0];
367 +       my $file = $_[1];
368 +       my @return;
369         $bunstr =~ s/ //g;
370 -        $bunstr =~ s/\n//g;
371 -        $bunstr =~ s/[^[:print:]]//g;
372 -        $bunstr =~ s/("[[:alnum:]|\-|\_|\.|\(|\)|\[|\]]+)(,)([[:alnum:]|\-|\_|\.|\(|\)|\[|\]]+")/$1 $3/g;
373 -        @reqcomp = split /,/g, $bunstr;
374 -        foreach $reqelement (@reqcomp) {
375 -                @reqelementfrmnt = split /;/g, $reqelement;
376 -                $name="";
377 -                $version="";
378 -                $name = $reqelementfrmnt[0];
379 -                for $i (1 .. $#reqelementfrmnt) {
380 -                        if ($reqelementfrmnt[$i] =~ m/(^(bundle-|)version=")(.*)(")/){
381 -                                $version = $3;
382 -                                last;
383 -                        }
384 -                }
385 -                $version = parseVersion($version);
386 -               $version = fixVersion($version);
387 -               # dirty fix for provides that contain " char
388 +       $bunstr =~ s/\n//g;
389 +       $bunstr =~ s/[^[:print:]]//g;
390 +       $bunstr =~ s/("[[:alnum:]|\-|\_|\.|\(|\)|\[|\]]+)(,)([[:alnum:]|\-|\_|\.|\(|\)|\[|\]]+")/$1 $3/g;
391 +       # remove uses bundle from Export-Package attribute
392 +       $bunstr =~ s/uses:="[[:alnum:]|\-|\_|\.|\(|\)|\[|\]|,]+"//g;
393 +       # remove optional dependencies
394 +       $bunstr =~ s/,.*;resolution:=optional//g;
395 +       # remove x-friends
396 +       $bunstr =~ s/;x-friends:="[[:alnum:]|\-|\_|\.|\(|\)|\[|\]|,]+"//g;
397 +       # remove signatures
398 +       $bunstr =~ s/Name:.*SHA1-Digest:.*//g;
399 +       @reqcomp = split /,/, $bunstr;
400 +       foreach $reqelement (@reqcomp) {
401 +               @reqelementfrmnt = split /;/, $reqelement;
402 +               $name = "";
403 +               $version = "";
404 +               $name = $reqelementfrmnt[0];
405                 $name =~ s/\"//g;
406 -                push @return, { NAME=>"$name", VERSION=>"$version"};
407 -        }
408 -
409 -        return @return;
410 +               # ignore 'system.bundle'.
411 +               # see http://help.eclipse.org/stable/index.jsp?topic=/org.eclipse.platform.doc.isv/porting/3.3/incompatibilities.html
412 +               next if ( $name =~ m/^system\.bundle$/ );
413 +               for $i ( 1 .. $#reqelementfrmnt ) {
414 +                       if ( $reqelementfrmnt[$i] =~ m/(^(bundle-|)version=")(.*)(")/ ) {
415 +                               $version = $3;
416 +                               last;
417 +                       }
418 +               }
419 +               $version = parseVersion($version);
420 +               push @return, { FILE => "$file", NAME => "$name", VERSION => "$version" };
421 +       }
422 +       return @return;
423  }
424  
425  sub parseVersion {
426 -        my $ver = $_[0];
427 -        if ($ver eq "") { return "";}
428 -        if ($ver =~ m/(^[\[|\(])(.+)\ (.+)([\]|\)]$)/) {
429 -               # FIXME: The right rpm match of osgi version [1,2) seems to be <= 2
430 -               # but when you look at the requires >= look more permssive/correct?
431 -               ($1 eq "\[") ? return " >= $2" : return " > $2";
432 -        } else {
433 -                return " = $ver";
434 -        }
435 -        return $ver;
436 -}
437 -
438 -sub fixVersion {
439 -        my $version = $_[0];
440 -       # remove version qualifier.
441 -       $version =~ s/\.v.[0-9]*.*//g;
442 -       # We try to match RPM version, so remove last .0
443 -       $version =~ s/\.0$//g;
444 -       return $version;
445 +       my $ver = $_[0];
446 +       if ( $ver eq "" ) { return ""; }
447 +       if ( $ver =~ m/(^[\[|\(])(.+)\ (.+)([\]|\)]$)/ ) {
448 +               if ( $1 eq "\[" ) {
449 +                       $ver = " >= $2";
450 +               } else {
451 +                       $ver = " > $2";
452 +               }
453 +       } else {
454 +               $ver = " = $ver";
455 +       }
456 +       # we always return a full OSGi version to be able to match 1.0
457 +       # and 1.0.0 as equal in RPM.
458 +       ( $major, $minor, $micro, $qualifier ) = split( '\.', $ver );
459 +       if ( !defined($minor) || !$minor ) {
460 +               $minor = 0;
461 +       }
462 +       if ( !defined($micro) || !$micro ) {
463 +               $micro = 0;
464 +       }
465 +       if ( !defined($qualifier) || !$qualifier ) {
466 +               $qualifier = "";
467 +       } else {
468 +               $qualifier = "." . $qualifier;
469 +       }
470 +       $ver = $major . "." . $minor . "." . $micro . $qualifier;
471 +       return $ver;
472  }
473  
474 +# this function put the max version on each bundles to be able to remove
475 +# duplicate deps with 'sort -u' command.
476 +sub prepareOSGiBundlesList {
477 +       foreach $bundle (@_) {
478 +               foreach $cmp (@_) {
479 +                       if ( $bundle->{NAME} eq $cmp->{NAME} ) {
480 +                               $result = compareVersion( $bundle->{VERSION}, $cmp->{VERSION} );
481 +                               if ( $result < 0 ) {
482 +                                       $bundle->{VERSION} = $cmp->{VERSION};
483 +                               }
484 +                       }
485 +               }
486 +       }
487 +       return @_;
488 +}
489 +
490 +# this function returns a negative integer, zero, or a positive integer if
491 +# $ver1 is less than, equal to, or greater than $ver2.
492 +#
493 +# REMEMBER: we mimic org.osgi.framework.Version#compareTo method but
494 +# *at this time* we don't take care of the qualifier part of the version.
495 +sub compareVersion {
496 +       my $ver1 = $_[0];
497 +       my $ver2 = $_[1];
498 +       
499 +       $ver1 = "0.0.0" if ( $ver1 eq "" );
500 +       $ver2 = "0.0.0" if ( $ver2 eq "" );
501 +
502 +       $ver1 =~ m/([0-9]+)(\.)([0-9]+)(\.)([0-9]+)/;
503 +       $major1 = $1;
504 +       $minor1 = $3;
505 +       $micro1 = $5;
506 +
507 +       $ver2 =~ m/([0-9]+)(\.)([0-9]+)(\.)([0-9]+)/;
508 +       $major2 = $1;
509 +       $minor2 = $3;
510 +       $micro2 = $5;
511 +
512 +       $result = $major1 - $major2;
513 +       return $result if ( $result != 0 );
514 +       
515 +       $result = $minor1 - $minor2;
516 +       return $result if ( $result != 0 );
517 +       
518 +       $result = $micro1 - $micro2;
519 +       return $result if ( $result != 0 );
520 +       
521 +       return $result;
522 +}