summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorKang Kai <kai.kang@windriver.com>2012-03-13 11:00:15 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2012-05-03 15:48:00 +0100
commita5e76f3a7baed646c6f21858726391d634720412 (patch)
treec0c4770d4d34f65b703d8fa1ff3e41f90d61cfee /scripts
parent845bcf0b1b2d76341910b22f80631c10bf316c38 (diff)
downloadpoky-a5e76f3a7baed646c6f21858726391d634720412.tar.gz
autospectacle.pl: pull it from meego as a base
This autospectacle.pl is from meego project http://meego.gitorious.org/meego-developer-tools/autospectacle And take its latest commit f462b759c6f569f35283d0885c97ae53b010bb03 as base of Yocto 1656: Recipe creation/import script. (From OE-Core rev: 74b1d119cf3712a64d627a2adc1adcf7b8cd4123) Signed-off-by: Kang Kai <kai.kang@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/autospectacle.pl1837
1 files changed, 1837 insertions, 0 deletions
diff --git a/scripts/autospectacle.pl b/scripts/autospectacle.pl
new file mode 100755
index 0000000000..bb9f8dc39b
--- /dev/null
+++ b/scripts/autospectacle.pl
@@ -0,0 +1,1837 @@
1#!/usr/bin/perl -w
2
3# Copyright (C) 2010 Intel Corporation
4#
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program. If not, see <http://www.gnu.org/licenses/>.
17#
18# As a special exception, you may create a larger work that contains
19# part or all of the autospectacle output and distribute that work
20# under terms of your choice.
21# Alternatively, if you modify or redistribute autospectacle itself,
22# you may (at your option) remove this special exception.
23#
24# This special exception was modeled after the bison exception
25# (as done by the Free Software Foundation in version 2.2 of Bison)
26#
27
28
29use File::Temp qw(tempdir);
30use File::Path qw(mkpath rmtree);
31use File::Spec ();
32
33
34my $name = "";
35my $version = "TO BE FILLED IN";
36my $description = "";
37my $summary = "";
38my $url = "";
39my $configure = "";
40my $localename = "";
41my @sources;
42my @mainfiles;
43my @patches;
44
45my $printed_subpackages = 0;
46my $fulldir = "";
47
48my $builder = "";
49
50
51my $oscmode = 0;
52
53my @banned_pkgconfig;
54my %failed_commands;
55my %failed_libs;
56my %failed_headers;
57
58
59
60######################################################################
61#
62# License management
63#
64# We store the sha1sum of common COPYING files in an associative array
65# %licenses.
66#
67# For all matching sha1's in the tarbal, we then push the result
68# in the @license array (which we'll dedupe at the time of printing).
69#
70
71my %licenses;
72my @license;
73
74sub setup_licenses
75{
76 $licenses{"06877624ea5c77efe3b7e39b0f909eda6e25a4ec"} = "GPLv2";
77 $licenses{"075d599585584bb0e4b526f5c40cb6b17e0da35a"} = "GPLv2";
78 $licenses{"10782dd732f42f49918c839e8a5e2894c508b079"} = "GPLv2";
79 $licenses{"2d29c273fda30310211bbf6a24127d589be09b6c"} = "GPLv2";
80 $licenses{"4df5d4b947cf4e63e675729dd3f168ba844483c7"} = "LGPLv2.1";
81 $licenses{"503df7650052cf38efde55e85f0fe363e59b9739"} = "GPLv2";
82 $licenses{"5405311284eab5ab51113f87c9bfac435c695bb9"} = "GPLv2";
83 $licenses{"5fb362ef1680e635fe5fb212b55eef4db9ead48f"} = "LGPLv2";
84 $licenses{"68c94ffc34f8ad2d7bfae3f5a6b996409211c1b1"} = "GPLv2";
85 $licenses{"66c77efd1cf9c70d4f982ea59487b2eeb6338e26"} = "LGPLv2.1";
86 $licenses{"74a8a6531a42e124df07ab5599aad63870fa0bd4"} = "GPLv2";
87 $licenses{"8088b44375ef05202c0fca4e9e82d47591563609"} = "LGPLv2.1";
88 $licenses{"8624bcdae55baeef00cd11d5dfcfa60f68710a02"} = "GPLv3";
89 $licenses{"8e57ffebd0ed4417edc22e3f404ea3664d7fed27"} = "MIT";
90 $licenses{"99b5245b4714b9b89e7584bfc88da64e2d315b81"} = "BSD";
91 $licenses{"aba8d76d0af67d57da3c3c321caa59f3d242386b"} = "MPLv1.1";
92 $licenses{"bf50bac24e7ec325dbb09c6b6c4dcc88a7d79e8f"} = "LGPLv2";
93 $licenses{"caeb68c46fa36651acf592771d09de7937926bb3"} = "LGPLv2.1";
94 $licenses{"dfac199a7539a404407098a2541b9482279f690d"} = "GPLv2";
95 $licenses{"e60c2e780886f95df9c9ee36992b8edabec00bcc"} = "LGPLv2.1";
96 $licenses{"c931aad3017d975b7f20666cde0953234a9efde3"} = "GPLv2";
97}
98
99sub guess_license_from_file {
100 my ($copying) = @_;
101
102 if (!-e $copying) {
103 return;
104 }
105
106 my $sha1output = `sha1sum $copying`;
107 $sha1output =~ /^([a-zA-Z0-9]*) /;
108 my $sha1 = $1;
109
110 chomp($sha1);
111
112 #
113 # if sha1 matches.. push there result
114 #
115 if (defined($licenses{$sha1})) {
116 my $lic = $licenses{$sha1};
117 push(@license, $lic);
118 }
119
120 #
121 # We also must make sure that the COPYING/etc files
122 # end up in the main package as %doc..
123 #
124 $copying =~ s/$fulldir//g;
125 $copying =~ s/^\///g;
126 $copying = "\"\%doc " . $copying ."\"";
127
128 push(@mainfiles, $copying);
129}
130
131sub print_license
132{
133 my $count = @license;
134 if ($count == 0) {
135 print OUTFILE "License: TO BE FILLED IN\n";
136 return;
137 }
138
139 # remove dupes
140 undef %saw;
141 @saw{@license} = ();
142 @out = sort keys %saw;
143
144 print OUTFILE "License : ";
145 foreach (@out) {
146 print OUTFILE "$_ ";
147 }
148 print OUTFILE "\n";
149}
150
151# end of license section
152#
153#######################################################################
154
155######################################################################
156#
157# Package group management
158#
159# We set up an associative array of regexp patterns, where the content
160# of the array is the name of the group.
161#
162# These are "strings of regexps", which means one needs to escape
163# everything, and if you want the actual regexp to have a \,
164# it needs to be a \\ in this string.
165
166my %group_patterns;
167my @groups;
168my $group = "TO_BE/FILLED_IN";
169
170sub setup_group_rules
171{
172 $group_patterns{"^\\/usr\\/lib\\/.*so"} = "System/Libraries";
173 $group_patterns{"^\\/lib\\/.*so"} = "System/Libraries";
174 $group_patterns{"^\\/bin\\/.*"} = "Applications/System";
175 $group_patterns{"^\\/sbin\\/.*"} = "Applications/System";
176 $group_patterns{"^\\/usr\\/sbin\\/.*"} = "Applications/System";
177}
178
179sub guess_group_from_file
180{
181 my ($filename) = @_;
182 while (($key,$value) = each %group_patterns) {
183 if ($filename =~ /$key/) {
184 push(@groups, $value);
185 }
186 }
187
188}
189
190# end of group section
191#
192######################################################################
193
194
195######################################################################
196#
197# Files and package section
198#
199# This section creates the %files section, but also decides which
200# subpackages (devel and/or doc) we need to have.
201#
202# We start out with the @allfiles array, which will contain all the
203# files installed by the %build phase of the package. The task is
204# to sort these into @mainfiles, @develfiles and @docfiles.
205# In addition, an attempt is made to compress the files list by
206# replacing full filenames with "*" patterns.
207#
208# For this we use a set of regexps from the @files_match array,
209# which are then used as index to three associative arrays:
210# %files_target : numerical index for which package the regexp
211# would place the file at hand.
212# 0 - main package
213# 1 - devel package
214# 2 - doc package
215# 99 - don't package this at all
216#
217# %files_from: regexp to match the file against for filename-wildcarding
218# %files_to : pattern to append to the ()'d part of %files_from to end up
219# with the filename-wildcard.
220
221my @allfiles;
222my @develfiles;
223my @docfiles;
224
225
226my @files_match;
227my %files_target;
228my %files_from;
229my %files_to;
230
231my $totaldocs = 0;
232
233
234sub add_files_rule
235{
236 my ($match, $target, $from, $to) =@_;
237 push(@files_match, $match);
238 $files_target{"$match"} = $target;
239
240 if (length($from) > 0) {
241 $files_from{"$match"} = $from;
242 }
243
244 if (length($to) > 0) {
245 $files_to{"$match"} = $to;
246 }
247}
248
249sub setup_files_rules
250{
251
252#
253# Files for the Main package
254#
255
256 add_files_rule("^\\/usr\\/lib\\/[a-z0-9A-Z\\_\\-\\.]+\\.so\\.", 0,
257 "(\\/usr\\/lib\\/.*\\.so\\.).*", "\*");
258
259
260 add_files_rule("^\\/usr\\/share\\/omf\\/", 0,
261 "(\\/usr\\/share\\/omf\\/.*?\\/).*", "\*");
262
263#
264# Files for the Devel subpackage
265#
266 add_files_rule("^\\/usr\\/share\\/gir-1\\.0\\/[a-z0-9A-Z\\_\\-\\.]+\\.gir\$", 1,
267 "(\\/usr\\/share\\/gir-1\\.0\/).*", "\*\.gir");
268 add_files_rule("^\\/usr\\/lib\\/girepository-1\\.0\\/[a-z0-9A-Z\\_\\-\\.]+\\.typelib\$", 1,
269 "(\\/usr\\/lib\\/girepository-1\\.0\/).*", "\*\.typelib");
270 add_files_rule("^\\/usr\\/include\\/[a-z0-9A-Z\\_\\-\\.]+\\.h\$", 1,
271 "(\\/usr\\/include\/).*", "\*\.h");
272 add_files_rule("^\\/usr\\/include\\/[a-z0-9A-Z\\_\\-\\.]+\\/.*?\\.h\$", 1,
273 "(\\/usr\\/include\\/[a-z0-9A-Z\\_\\-\\.]+\\/.*?)[a-z0-9A-Z\\_\\-\\.]+\\.h", "\*\.h");
274 add_files_rule("^\\/usr\\/lib\\/[a-z0-9A-Z\\_\\-\\.]+\\.so\$", 1,
275 "(\\/usr\\/lib\\/).*\\.so\$", "\*.so");
276 add_files_rule("^\\/usr\\/lib\\/pkgconfig\\/[a-z0-9A-Z\\_\\-\\.\+]+\\.pc\$", 1,
277 "(\\/usr\\/lib\\/pkgconfig\\/).*\\.pc\$", "\*.pc");
278 add_files_rule("^\\/usr\\/share\\/aclocal", 1, "", "");
279 add_files_rule("^\\/usr\\/lib\\/qt4\\/mkspecs/", 1, "", "");
280
281
282
283
284#
285# Files for the documentation subpackage
286#
287 add_files_rule("^\\/usr\\/share\\/gtk\-doc\\/html\\/[a-z0-9A-Z\\_\\-\\.]+\\/.\*", 2,
288 "(\\/usr\\/share\\/gtk\-doc\\/html\\/[a-z0-9A-Z\\_\\-\\.]+\\/).\*", "\*");
289 add_files_rule("^\\/usr\\/share\\/doc\\/[a-zA-Z0-9\-]*", 2,
290 "(\\/usr\\/share\\/doc\\/[a-zA-Z0-9\-]+\\/).*", "\*");
291 add_files_rule("^\\/usr\\/share\\/man\\/man[0-9]\\/[a-zA-Z0-9\-]*", 2,
292 "(\\/usr\\/share\\/man\\/man[0-9]\\/[a-zA-Z0-9\-]+\\/).*", "\*");
293 add_files_rule("^\\/usr\\/share\\/gnome\\/help\\/", 2,
294 "(\\/usr\\/share\\/gnome\\/help\\/.*?\\/.*?\\/).*", "\*");
295
296
297#
298# Files to just not package at all (picked up by other things)
299#
300 add_files_rule("^\\/usr\\/share\\/locale", 99, "", "");
301 # compiled python things will get auto cleaned by rpm
302# add_files_rule("\.pyo\$", 99, "", "");
303# add_files_rule("\.pyc\$", 99, "", "");
304
305}
306
307sub apply_files_rules
308{
309 my $filenumber = @allfiles;
310
311 if ($filenumber == 0) {
312 return;
313 }
314
315 while (@allfiles > 0) {
316 my $filename = $allfiles[0];
317 my $destname = $filename;
318 my $handled = 0;
319
320#
321# while we're here, try to guess what group our package is
322#
323 guess_group_from_file($filename);
324
325 foreach (@files_match) {
326 my $match = $_;
327
328 if ($filename =~ /$match/) {
329#
330# First try to see if we can turn the full filename into a
331# wildcard based filename
332#
333 if (defined($files_from{$match}) && defined($files_to{$match})) {
334 $from = $files_from{$match};
335 $to = $files_to{$match};
336 $destname =~ s/$from/$1$to/;
337# print "changing $filename to $destname\n";
338 }
339
340# devel package
341 if ($files_target{$match} == 1) {
342 $handled = 1;
343 push(@develfiles, $destname);
344 }
345# doc rules.. also prepend %doc
346 if ($files_target{$match} == 2) {
347 $handled = 1;
348 $destname = "\"%doc " . $destname . "\"";
349 push(@docfiles, $destname);
350 $totaldocs = $totaldocs + 1;
351 }
352# don't package
353 if ($files_target{$match} == 99) {
354 $handled = 1;
355 if ($filename =~ /\/usr\/share\/locale\/.*?\/LC_MESSAGES\/(.*)\.mo/) {
356 $localename = $1;
357 }
358 }
359 }
360 }
361
362
363#
364# if the destination name contains our package version,
365# use %version instead for future maintenance
366#
367 $destname =~ s/$version/\%\{version\}/g;
368 if ($handled == 0) {
369 push(@mainfiles, $destname);
370 }
371 shift(@allfiles);
372 }
373
374#
375# Now.. if we have less than 5 documentation files, just stick them in the main package
376#
377
378 $filenumber = @docfiles;
379
380 if ($filenumber <= 5) {
381 while (@docfiles > 0) {
382 my $filename = $docfiles[0];
383
384 push(@mainfiles, $filename);
385 shift(@docfiles);
386 }
387 }
388
389}
390
391sub print_files
392{
393 my $count = @mainfiles;
394 if ($count == 0) {
395 return;
396 }
397
398 # remove dupes
399 undef %saw;
400 @saw{@mainfiles} = ();
401 @out = sort keys %saw;
402
403 print OUTFILE "Files:\n";
404 foreach (@out) {
405 print OUTFILE " - $_\n";
406 }
407}
408
409sub print_devel
410{
411 my $count = @develfiles;
412 if ($count == 0) {
413 return;
414 }
415 print OUTFILE "SubPackages:\n";
416 $printed_subpackages = 1;
417 print OUTFILE " - Name: devel\n";
418 print OUTFILE " Summary: Development components for the $name package\n";
419 print OUTFILE " Group: Development/Libraries\n";
420 print OUTFILE " Description:\n";
421 print OUTFILE " - Development files for the $name package\n";
422
423 # remove dupes
424 undef %saw;
425 @saw{@develfiles} = ();
426 @out = sort keys %saw;
427
428 print OUTFILE " Files:\n";
429 foreach (@out) {
430 print OUTFILE " - $_\n";
431 }
432}
433
434sub print_doc
435{
436 my $count = @docfiles;
437 if ($count == 0) {
438 return;
439 }
440 if ($printed_subpackages == 0) {
441 print OUTFILE "SubPackages:\n";
442 $printed_subpackages = 1;
443 }
444 print OUTFILE " - Name: docs\n";
445 print OUTFILE " Summary: Documentation components for the $name package\n";
446 print OUTFILE " Group: Documentation\n";
447
448 # remove dupes
449 undef %saw;
450 @saw{@docfiles} = ();
451 @out = sort keys %saw;
452
453 print OUTFILE " Files:\n";
454 foreach (@out) {
455 print OUTFILE " - $_\n";
456 }
457}
458
459
460# end of %files section
461#
462######################################################################
463
464
465######################################################################
466#
467# What we can learn from configure.ac/configure
468#
469# - pkgconfig requirements
470# - regular build requirements
471# - package name / version
472
473
474sub setup_pkgconfig_ban
475{
476 push(@banned_pkgconfig, "^dnl\$");
477 push(@banned_pkgconfig, "^hal\$"); # we don't have nor want HAL
478 push(@banned_pkgconfig, "tslib-0.0"); # we don't want tslib-0.0 (legacy touchscreen interface)
479 push(@banned_pkgconfig, "intel-gen4asm");
480 push(@banned_pkgconfig, "^xp\$"); # xprint - deprecated and not in meego
481 push(@banned_pkgconfig, "^directfb\$"); # we use X, not directfb
482 push(@banned_pkgconfig, "^gtkmm-2.4\$"); # we use X, not directfb
483 push(@banned_pkgconfig, "^evil\$");
484 push(@banned_pkgconfig, "^directfb");
485 push(@banned_pkgconfig, "^sdl ");
486
487
488}
489
490sub setup_failed_commands
491{
492 $failed_commands{"doxygen"} = "doxygen";
493 $failed_commands{"scrollkeeper-config"} = "rarian-compat";
494 $failed_commands{"dot"} = "graphviz";
495 $failed_commands{"flex"} = "flex";
496 $failed_commands{"lex"} = "flex";
497 $failed_commands{"freetype-config"} = "freetype-devel";
498 $failed_commands{"makeinfo"} = "texinfo";
499 $failed_commands{"desktop-file-install"} = "desktop-file-utils";
500 $failed_commands{"deflateBound in -lz"} = "zlib-devel";
501 $failed_commands{"gconftool-2"} = "GConf-dbus";
502 $failed_commands{"jpeglib.h"} = "libjpeg-devel";
503 $failed_commands{"expat.h"} = "expat-devel";
504 $failed_commands{"bison"} = "bison";
505 $failed_commands{"msgfmt"} = "gettext";
506 $failed_commands{"curl-config"} = "libcurl-devel";
507 $failed_commands{"doxygen"} = "doxygen";
508 $failed_commands{"X"} = "pkgconfig(x11)";
509
510 $failed_commands{"gawk"} = "gawk";
511 $failed_commands{"xbkcomp"} = "xkbcomp";
512 $failed_commands{"Vorbis"} = "libvorbis-devel";
513 # checking Expat 1.95.x... no
514 $failed_commands{"Expat 1.95.x"} = "expat-devel";
515 $failed_commands{"xml2-config path"} = "libxml2-devel";
516
517 $failed_libs{"-lz"} = "zlib-devel";
518 $failed_libs{"-lncursesw"} = "ncurses-devel";
519 $failed_libs{"-ltiff"} = "libtiff-devel";
520 $failed_libs{"-lasound"} = "alsa-lib-devel";
521 $failed_libs{"Curses"} = "ncurses-devel";
522
523 $failed_headers{"X11/extensions/randr.h"} = "xrandr";
524 $failed_headers{"X11/Xlib.h"} = "x11";
525 $failed_headers{"X11/extensions/XShm.h"} = "xext";
526 $failed_headers{"X11/extensions/shape.h"} = "xext";
527 $failed_headers{"ncurses.h"} = "ncursesw";
528 $failed_headers{"curses.h"} = "ncursesw";
529 $failed_headers{"pci/pci.h"} = "libpci";
530 $failed_headers{"xf86.h"} = "xorg-server";
531 $failed_headers{"sqlite.h"} = "sqlite3";
532
533 $failed_headers{"X11/extensions/XIproto.h"} = "xi";
534 $failed_headers{"QElapsedTimer"} = "";
535}
536
537
538
539my @package_configs;
540my @buildreqs;
541my $uses_configure = 0;
542
543
544sub push_pkgconfig_buildreq
545{
546 my ($pr) = @_;
547
548 $pr =~ s/\s+//g;
549
550 # remove collateral ] ) etc damage in the string
551 $pr =~ s/\"//g;
552 $pr =~ s/\)//g;
553 $pr =~ s/\]//g;
554 $pr =~ s/\[//g;
555
556
557 # first, undo the space packing
558
559 $pr =~ s/\>\=/ \>\= /g;
560 $pr =~ s/\<\=/ \<\= /g;
561
562 $pr =~ s/\<1.1.1/ /g;
563
564 # don't show configure variables, we can't deal with them
565 if ($pr =~ /^\$/) {
566 return;
567 }
568 if ($pr =~ /AC_SUBST/) {
569 return;
570 }
571
572
573
574
575 # process banned pkgconfig options for things that we don't
576 # have or don't want.
577
578
579 # remore versions that are macros or strings, not numbers
580 $pr =~ s/\s\>\= \$.*//g;
581
582 $pr =~ s/\s\>\= [a-zA-Z]+.*//g;
583
584 # don't show configure variables, we can't deal with them
585 if ($pr =~ /\$/) {
586 return;
587 }
588
589 foreach (@banned_pkgconfig) {
590 my $ban = $_;
591 if ($pr =~ /$ban/) {
592 return;
593 }
594 }
595
596 push(@package_configs, $pr);
597}
598
599#
600# detect cases where we require both a generic pkgconfig, and a version specific
601# case
602#
603sub uniquify_pkgconfig
604{
605 # first remove real dupes
606 undef %saw;
607 @saw{@package_configs} = ();
608 @out = sort keys %saw;
609
610 my $count = 0;
611
612 while ($count < @out) {
613
614 my $entry = $out[$count];
615
616 foreach(@out) {
617 my $compare = $_;
618 if ($entry eq $compare) {
619 next;
620 }
621
622 $compare =~ s/ \>\=.*//g;
623 if ($entry eq $compare) {
624 $out[$count] = "";
625 }
626 }
627 $count = $count + 1;
628 }
629 @package_configs = @out;
630}
631
632
633sub process_configure_ac
634{
635 my ($filename) = @_;
636 my $line = "";
637 my $depth = 0;
638 my $keepgoing = 1;
639 my $buffer = "";
640
641 if (!-e $filename) {
642 return;
643 }
644
645 $uses_configure = 1;
646
647
648
649 open(CONFIGURE, "$filename") || die "Couldn't open $filename\n";
650 seek(CONFIGURE, 0,0) or die "seek : $!";
651 while ($keepgoing && !eof(CONFIGURE)) {
652 $buffer = getc(CONFIGURE);
653
654 if ($buffer eq "(") {
655 $depth = $depth + 1;
656 }
657 if ($buffer eq ")" && $depth > 0) {
658 $depth = $depth - 1;
659 }
660
661 if (!($buffer eq "\n")) {
662 $line = $line . $buffer;
663 }
664
665 if (!($buffer eq "\n") || $depth > 0) {
666 redo unless eof(CONFIGURE);
667 }
668
669 if ($line =~ /PKG_CHECK_MODULES\((.*)\)/) {
670 my $match = $1;
671 $match =~ s/\s+/ /g;
672 $match =~ s/, /,/g;
673 my @pkgs = split(/,/, $match);
674 my $pkg;
675 if (defined($pkgs[1])) {
676 $pkg = $pkgs[1];
677 } else {
678 next;
679 }
680 if ($pkg =~ /\[(.*)\]/) {
681 $pkg = $1;
682 }
683
684 $pkg =~ s/\s+/ /g;
685 # deal with versioned pkgconfig's by removing the spaces around >= 's
686 $pkg =~ s/\>\=\s/\>\=/g;
687 $pkg =~ s/\s\>\=/\>\=/g;
688 $pkg =~ s/\=\s/\=/g;
689 $pkg =~ s/\s\=/\=/g;
690 $pkg =~ s/\<\=\s/\<\=/g;
691 $pkg =~ s/\<\s/\</g;
692 $pkg =~ s/\s\<\=/\<\=/g;
693 $pkg =~ s/\s\</\</g;
694
695 @words = split(/ /, $pkg);
696 foreach(@words) {
697 push_pkgconfig_buildreq($_);
698 }
699 }
700
701 if ($line =~ /PKG_CHECK_EXISTS\((.*)\)/) {
702 my $match = $1;
703 $match =~ s/\s+/ /g;
704 $match =~ s/, /,/g;
705 my @pkgs = split(/,/, $match);
706 my $pkg = $pkgs[0];
707 if ($pkg =~ /\[(.*)\]/) {
708 $pkg = $1;
709 }
710
711 $pkg =~ s/\s+/ /g;
712 # deal with versioned pkgconfig's by removing the spaces around >= 's
713 $pkg =~ s/\>\=\s/\>\=/g;
714 $pkg =~ s/\s\>\=/\>\=/g;
715 $pkg =~ s/\<\=\s/\<\=/g;
716 $pkg =~ s/\<\s/\</g;
717 $pkg =~ s/\s\<\=/\<\=/g;
718 $pkg =~ s/\s\</\</g;
719 $pkg =~ s/\=\s/\=/g;
720 $pkg =~ s/\s\=/\=/g;
721
722 @words = split(/ /, $pkg);
723 foreach(@words) {
724 push_pkgconfig_buildreq($_);
725 }
726 }
727
728 if ($line =~ /XDT_CHECK_PACKAGE\(.*?,.*?\[(.*?)\].*\)/) {
729 my $pkg = $1;
730
731 $pkg =~ s/\s+/ /g;
732 # deal with versioned pkgconfig's by removing the spaces around >= 's
733 $pkg =~ s/\>\=\s/\>\=/g;
734 $pkg =~ s/\s\>\=/\>\=/g;
735 $pkg =~ s/\=\s/\=/g;
736 $pkg =~ s/\s\=/\=/g;
737
738 @words = split(/ /, $pkg);
739 foreach(@words) {
740 push_pkgconfig_buildreq($_);
741 }
742 }
743
744 if ($line =~ /XDT_CHECK_OPTIONAL_PACKAGE\(.*?,.*?\[(.*?)\].*\)/) {
745 my $pkg = $1;
746
747 $pkg =~ s/\s+/ /g;
748 # deal with versioned pkgconfig's by removing the spaces around >= 's
749 $pkg =~ s/\>\=\s/\>\=/g;
750 $pkg =~ s/\s\>\=/\>\=/g;
751 $pkg =~ s/\=\s/\=/g;
752 $pkg =~ s/\s\=/\=/g;
753
754 @words = split(/ /, $pkg);
755 foreach(@words) {
756 push_pkgconfig_buildreq($_);
757 }
758 }
759
760 if ($line =~ /AC_CHECK_LIB\(\[expat\]/) {
761 push(@buildreqs, "expat-devel");
762 }
763 if ($line =~ /AC_CHECK_FUNC\(\[tgetent\]/) {
764 push(@buildreqs, "ncurses-devel");
765 }
766 if ($line =~ /_PROG_INTLTOOL/) {
767 push(@buildreqs, "intltool");
768 }
769 if ($line =~ /GETTEXT_PACKAGE/) {
770 push(@buildreqs, "gettext");
771 }
772 if ($line =~ /GTK_DOC_CHECK/) {
773 push_pkgconfig_buildreq("gtk-doc");
774 }
775 if ($line =~ /GNOME_DOC_INIT/) {
776 push(@buildreqs, "gnome-doc-utils");
777 }
778 if ($line =~ /AM_GLIB_GNU_GETTEXT/) {
779 push(@buildreqs, "gettext");
780 }
781
782 if ($line =~ /AC_INIT\((.*)\)/) {
783 my $match = $1;
784 $match =~ s/\s+/ /g;
785 @acinit = split(/,/, $match);
786# $name = $acinit[0];
787
788 if ($name =~ /\[(.*)\]/) {
789# $name = $1;
790 }
791
792 if (defined($acinit[3])) {
793# $name = $acinit[3];
794 if ($name =~ /\[(.*)\]/) {
795# $name = $1;
796 }
797 }
798 if (defined($acinit[1])) {
799 my $ver = $acinit[1];
800 $ver =~ s/\[//g;
801 $ver =~ s/\]//g;
802 if ($ver =~ /\$/){} else {
803 $version = $ver;
804 $version =~ s/\s+//g;
805 }
806 }
807 }
808 if ($line =~ /AM_INIT_AUTOMAKE\((.*)\)/) {
809 my $match = $1;
810 $match =~ s/\s+/ /g;
811 @acinit = split(/,/, $match);
812# $name = $acinit[0];
813
814 if ($name =~ /\[(.*)\]/) {
815# $name = $1;
816 }
817
818 if (defined($acinit[3])) {
819# $name = $acinit[3];
820 if ($name =~ /\[(.*)\]/) {
821# $name = $1;
822 }
823 }
824 if (defined($acinit[1])) {
825 my $ver = $acinit[1];
826 $ver =~ s/\[//g;
827 $ver =~ s/\]//g;
828 if ($ver =~ /\$/){} else {
829 $version = $ver;
830 $version =~ s/\s+//g;
831 }
832 }
833 }
834
835 $line = "";
836 }
837 close(CONFIGURE);
838}
839
840sub process_qmake_pro
841{
842 my ($filename) = @_;
843 my $line = "";
844 my $depth = 0;
845 my $keepgoing = 1;
846 my $buffer = "";
847 my $prev_char = "";
848
849 if (!-e $filename) {
850 return;
851 }
852
853
854 open(CONFIGURE, "$filename") || die "Couldn't open $filename\n";
855 seek(CONFIGURE, 0,0) or die "seek : $!";
856 while ($keepgoing && !eof(CONFIGURE)) {
857 $buffer = getc(CONFIGURE);
858
859 if ($buffer eq "(") {
860 $depth = $depth + 1;
861 }
862 if ($buffer eq ")" && $depth > 0) {
863 $depth = $depth - 1;
864 }
865
866 if (!($buffer eq "\n")) {
867 $line = $line . $buffer;
868 }
869
870 if (!($buffer eq "\n") || ($prev_char eq "\\") ) {
871 $prev_char = $buffer;
872 redo unless eof(CONFIGURE);
873 }
874 $prev_char = " ";
875
876 if ($line =~ /PKGCONFIG.*?\=(.*)/) {
877 my $l = $1;
878 my @pkgs;
879
880 $l =~ s/\\//g;
881 $l =~ s/\s/ /g;
882 @pkgs = split(/ /, $l);
883 foreach (@pkgs) {
884 if (length($_)>1) {
885 push_pkgconfig_buildreq($_);
886 }
887 }
888 }
889
890 $line = "";
891 }
892 close(CONFIGURE);
893}
894
895#
896# We also check configure if it exists, it's nice for some things
897# because various configure.ac macros have been expanded for us already.
898#
899sub process_configure
900{
901 my ($filename) = @_;
902 my $line = "";
903 my $depth = 0;
904 my $keepgoing = 1;
905
906 if (!-e $filename) {
907 return;
908 }
909
910 $uses_configure = 1;
911
912 open(CONFIGURE, "$filename") || die "Couldn't open $filename\n";
913 seek(CONFIGURE, 0,0) or die "seek : $!";
914 while ($keepgoing && !eof(CONFIGURE)) {
915 $buffer = getc(CONFIGURE);
916
917 if ($buffer eq "(") {
918 $depth = $depth + 1;
919 }
920 if ($buffer eq ")" && $depth > 0) {
921 $depth = $depth - 1;
922 }
923
924 if (!($buffer eq "\n")) {
925 $line = $line . $buffer;
926 }
927
928 if (!($buffer eq "\n") || $depth > 0) {
929 redo unless eof(CONFIGURE);
930 }
931
932
933
934 if ($line =~ /^PACKAGE_NAME=\'(.*?)\'/) {
935 $name = $1;
936 }
937 if ($line =~ /^PACKAGE_TARNAME=\'(.*?)\'/) {
938 $name = $1;
939 }
940 if ($line =~ /^PACKAGE_VERSION=\'(.*?)\'/) {
941 $version = $1;
942 $version =~ s/\s+//g;
943 }
944 if ($line =~ /^PACKAGE_URL=\'(.*?)\'/) {
945 if (length($1) > 2) {
946 $url = $1;
947 }
948 }
949
950
951 $line = "";
952 }
953 close(CONFIGURE);
954}
955
956sub print_pkgconfig
957{
958 my $count = @package_configs;
959 if ($count == 0) {
960 return;
961 }
962
963 uniquify_pkgconfig();
964
965 print OUTFILE "PkgConfigBR:\n";
966 foreach (@out) {
967 $line = $_;
968 $line =~ s/^\s+//g;
969 if (length($line) > 1) {
970 print OUTFILE " - $line\n";
971 }
972 }
973}
974
975sub print_buildreq
976{
977 my $count = @buildreqs;
978 if ($count == 0) {
979 return;
980 }
981
982 # remove dupes
983 undef %saw;
984 @saw{@buildreqs} = ();
985 @out = sort keys %saw;
986
987 print OUTFILE "PkgBR:\n";
988 foreach (@out) {
989 print OUTFILE " - $_\n";
990 }
991}
992
993
994# end of configure section
995#
996######################################################################
997
998
999######################################################################
1000#
1001# Guessing the Description and Summary for a package
1002#
1003# We'll look at various sources of information for this:
1004# - spec files in the package
1005# - debain files in the package
1006# - DOAP files in the package
1007# - pkgconfig files in the package
1008# - the README file in the package
1009# - freshmeat.net online
1010#
1011
1012sub guess_description_from_spec {
1013 my ($specfile) = @_;
1014
1015 my $state = 0;
1016 my $cummul = "";
1017
1018 open(SPEC, $specfile);
1019 while (<SPEC>) {
1020 my $line = $_;
1021 if ($state == 1 && $line =~ /^\%/) {
1022 $state = 2;
1023 }
1024 if ($state == 1) {
1025 $cummul = $cummul . $line;
1026 }
1027 if ($state==0 && $line =~ /\%description/) {
1028 $state = 1;
1029 }
1030
1031 if ($line =~ /Summary:\s*(.*)/ && length($summary) < 2) {
1032 $summary = $1;
1033 }
1034 if ($line =~ /URL:\s*(.*)/ && length($url) < 2) {
1035 $url = $1;
1036 }
1037 }
1038 close(SPEC);
1039 if (length($cummul) > 4) {
1040 $description = $cummul;
1041 }
1042}
1043
1044#
1045# DOAP is a project to create an XML/RDF vocabulary to describe software projects, and in particular open source.
1046# so if someone ships a .doap file... we can learn from it.
1047#
1048sub guess_description_from_doap {
1049 my ($doapfile) = @_;
1050
1051 open(DOAP, $doapfile);
1052 while (<DOAP>) {
1053 my $line = $_;
1054 # <shortdesc xml:lang="en">Virtual filesystem implementation for gio</shortdesc>
1055 if ($line =~ /\<shortdesc .*?\>(.*)\<\/shortdesc\>/) {
1056 $summary = $1;
1057 }
1058 if ($line =~ /\<homepage .*?resource=\"(.*)\"\s*\/>/) {
1059 $url = $1;
1060 }
1061 }
1062 close(DOAP);
1063}
1064
1065#
1066# Debian control files have some interesting fields we can glean information
1067# from as well.
1068#
1069sub guess_description_from_debian_control {
1070 my ($file) = @_;
1071
1072 my $state = 0;
1073 my $cummul = "";
1074
1075 $file = $file . "/debian/control";
1076
1077 open(FILE, $file) || return;
1078 while (<FILE>) {
1079 my $line = $_;
1080 if ($state == 1 && length($line) < 2) {
1081 $state = 2;
1082 }
1083 if ($state == 1) {
1084 $cummul = $cummul . $line;
1085 }
1086 if ($state==0 && $line =~ /\Description: (.*)/) {
1087 $state = 1;
1088 $cummul = $1;
1089 }
1090
1091 }
1092 close(FILE);
1093 if (length($cummul) > 4) {
1094 $description = $cummul;
1095 }
1096}
1097
1098#
1099# the pkgconfig files have often a one line description
1100# of the software... good for Summary
1101#
1102sub guess_description_from_pkgconfig {
1103 my ($file) = @_;
1104
1105 open(FILE, $file);
1106 while (<FILE>) {
1107 my $line = $_;
1108
1109 if ($line =~ /Description:\s*(.*)/ && length($summary) < 2) {
1110 $summary = $1;
1111 }
1112 }
1113 close(FILE);
1114}
1115
1116#
1117# Freshmeat can provide us with a good one paragraph description
1118# of the software..
1119#
1120sub guess_description_from_freshmeat {
1121 my ($tarname) = @_;
1122 my $cummul = "";
1123 my $state = 0;
1124 open(HTML, "curl -s http://freshmeat.net/projects/$tarname |");
1125 while (<HTML>) {
1126 my $line = $_;
1127
1128 if ($state == 1) {
1129 $cummul = $cummul . $line;
1130 }
1131 if ($state == 0 && $line =~ /\<div class\=\"project-detail\"\>/) {
1132 $state = 1;
1133 }
1134 if ($state == 1 && $line =~/\<\/p\>/) {
1135 $state = 2;
1136 }
1137 }
1138 close(HTML);
1139 $cummul =~ s/\<p\>//g;
1140 $cummul =~ s/\r//g;
1141 $cummul =~ s/\<\/p\>//g;
1142 $cummul =~ s/^\s*//g;
1143 if (length($cummul)>10) {
1144 $description = $cummul;
1145 }
1146}
1147#
1148# If all else fails, just take the first paragraph of the
1149# readme file
1150#
1151sub guess_description_from_readme {
1152 my ($file) = @_;
1153
1154 my $state = 0;
1155 my $cummul = "";
1156
1157 open(FILE, $file);
1158 while (<FILE>) {
1159 my $line = $_;
1160 if ($state == 1 && $line =~ /^\n/ && length($cummul) > 80) {
1161 $state = 2;
1162 }
1163 if ($state == 0 && length($line)>1) {
1164 $state = 1;
1165 }
1166 if ($state == 1) {
1167 $cummul = $cummul . $line;
1168 }
1169 if ($line =~ /(http\:\/\/.*$name.*\.org)/) {
1170 my $u = $1;
1171 if ($u =~ /bug/ || length($url) > 1) {
1172 } else {
1173 $url = $u;
1174 }
1175 }
1176 }
1177 close(FILE);
1178 if (length($cummul) > 4 && length($description)<3) {
1179 $description = $cummul;
1180 }
1181}
1182
1183#
1184# Glue all the guesses together
1185#
1186sub guess_description {
1187 my ($directory) = @_;
1188
1189
1190 @files = <$directory/README*>;
1191 foreach (@files) {
1192 guess_description_from_readme($_);
1193 }
1194
1195 if (length($name)>2) {
1196 guess_description_from_freshmeat($name);
1197 }
1198
1199 @files = <$directory/*.spec*>;
1200 foreach (@files) {
1201 guess_description_from_spec($_);
1202 }
1203
1204 guess_description_from_debian_control($directory);
1205
1206 $name =~ s/ //g;
1207 @files = <$directory/$name.pc*>;
1208 foreach (@files) {
1209 guess_description_from_pkgconfig($_);
1210 }
1211 @files = <$directory/*.pc.*>;
1212 foreach (@files) {
1213 guess_description_from_pkgconfig($_);
1214 }
1215 @files = <$directory/*.pc>;
1216 foreach (@files) {
1217 guess_description_from_pkgconfig($_);
1218 }
1219 @files = <$directory/*.doap>;
1220 foreach (@files) {
1221 guess_description_from_doap($_);
1222 }
1223
1224 if (length($summary) < 2) {
1225 $summary = $description;
1226 $summary =~ s/\n/ /g;
1227 $summary =~ s/\s+/ /g;
1228 if ($summary =~ /(.*?)\./) {
1229 $summary = $1;
1230 }
1231 }
1232
1233}
1234
1235# end of Description / Summary section
1236#
1237######################################################################
1238
1239
1240
1241#
1242# Build the package, and wait for rpm to complain about unpackaged
1243# files.... which we then use as basis for our %files section
1244#
1245sub guess_files_from_rpmbuild {
1246 my $infiles = 0;
1247 open(OUTPUTF, "rpmbuild --nodeps --define \"\%_sourcedir $orgdir \" -ba $name.spec 2>&1 |");
1248 while (<OUTPUTF>) {
1249 my $line2 = $_;
1250
1251 if ($infiles == 1 && $line2 =~ /RPM build errors/) {
1252 $infiles = 2;
1253 }
1254 if ($infiles == 1 && $line2 =~ /^Building/) {
1255 $infiles = 2;
1256 }
1257
1258 if ($infiles == 1) {
1259 $line2 =~ s/\s*//g;
1260 push(@allfiles, $line2);
1261 }
1262 if ($line2 =~ / Installed \(but unpackaged\) file\(s\) found\:/) {
1263 $infiles = 1;
1264 }
1265 }
1266 close(OUTPUTF);
1267 if (@allfiles == 0) {
1268 print "Build failed ... stopping here.\n";
1269 exit(0);
1270 }
1271
1272}
1273
1274sub guess_files_from_oscbuild {
1275 my $infiles = 0;
1276 my $restart = 0;
1277 my $mustrestart = 0;
1278 my $rcount = 0;
1279 my $done_python = 0;
1280
1281 system("osc addremove &> /dev/null");
1282 system("osc ci -m \"Initial import by autospectacle\" &> /dev/null");
1283
1284retry:
1285 if ($restart > 0) {
1286 write_yaml();
1287 print "Restarting the build\n";
1288 }
1289 $restart = 0;
1290 $infiles = 0;
1291 $mustrestart = 0;
1292 open(OUTPUTF, "osc build --no-verify $name.spec 2>&1 |");
1293 while (<OUTPUTF>) {
1294 my $line2 = $_;
1295
1296# print "line is $line2\n";
1297 if ($infiles == 1 && $line2 =~ /RPM build errors/) {
1298 $infiles = 2;
1299 }
1300 if ($infiles == 1 && $line2 =~ /^Building/) {
1301 $infiles = 2;
1302 }
1303 if ($infiles == 1) {
1304 $line2 =~ s/\s*//g;
1305 push(@allfiles, $line2);
1306 }
1307 if ($line2 =~ /No package \'(.*)\' found/) {
1308 push_pkgconfig_buildreq("$1");
1309 $restart = $restart + 1;
1310 print " Adding pkgconfig($1) requirement\n";
1311 }
1312 if ($line2 =~ /Package requirements \((.*?)\) were not met/) {
1313 $pkg = $1;
1314 # deal with versioned pkgconfig's by removing the spaces around >= 's
1315 $pkg =~ s/\>\=\s/\>\=/g;
1316 $pkg =~ s/\s\>\=/\>\=/g;
1317 $pkg =~ s/\=\s/\=/g;
1318 $pkg =~ s/\s\=/\=/g;
1319 my @req = split(/ /,$pkg);
1320 foreach (@req) {
1321 push_pkgconfig_buildreq("$_");
1322
1323 $restart = $restart + 1;
1324 print " Adding pkgconfig($_) requirement\n";
1325 }
1326 }
1327 if ($line2 =~ /which: no qmake/) {
1328 $restart += 1;
1329 push_pkgconfig_buildreq("Qt");
1330 print " Adding Qt requirement\n";
1331 }
1332 if ($line2 =~ /Cannot find development files for any supported version of libnl/) {
1333 $restart += 1;
1334 push_pkgconfig_buildreq("libnl-1");
1335 print " Adding libnl requirement\n";
1336 }
1337 if ($line2 =~ /<http:\/\/www.cmake.org>/) {
1338 $restart += 1;
1339 push(@buildreqs, "cmake");
1340 print " Adding cmake requirement\n";
1341 }
1342 if ($line2 =~ /checking for (.*?)\.\.\. not_found/ || $line2 =~ /checking for (.*?)\.\.\. no/ || $line2 =~ /checking (.*?)\.\.\. no/) {
1343 $pkg = $1;
1344 while (($key,$value) = each %failed_commands) {
1345 if ($pkg eq $key) {
1346 push(@buildreqs, $value);
1347 print " Adding $value requirement\n";
1348 $restart += $restart + 1;
1349 $mustrestart = 1;
1350 }
1351 }
1352
1353 }
1354
1355 if ($line2 =~ /checking for [a-zA-Z0-9\_]+ in (.*?)\.\.\. no/) {
1356 $pkg = $1;
1357 while (($key,$value) = each %failed_libs) {
1358 if ($pkg eq $key) {
1359 push(@buildreqs, $value);
1360 print " Adding $value requirement\n";
1361 $restart += $restart + 1;
1362 $mustrestart = 1;
1363 }
1364 }
1365
1366 }
1367
1368 if ($line2 =~ /-- Could NOT find ([a-zA-Z0-9]+)/) {
1369 $pkg = $1;
1370 while (($key,$value) = each %failed_libs) {
1371 if ($pkg eq $key) {
1372 push(@buildreqs, $value);
1373 print " Adding $value requirement\n";
1374 $restart += $restart + 1;
1375 $mustrestart = 1;
1376 }
1377 }
1378
1379 }
1380
1381 if ($line2 =~ /fatal error\: (.*)\: No such file or directory/) {
1382 $pkg = $1;
1383 while (($key,$value) = each %failed_headers) {
1384 if ($pkg eq $key) {
1385 push_pkgconfig_buildreq($value);
1386 print " Adding $value requirement\n";
1387 $restart += $restart + 1;
1388 }
1389 }
1390
1391 }
1392 if ($line2 =~ /checking for UDEV\.\.\. no/) {
1393 print " Adding pkgconfig(udev) requirement\n";
1394 push_pkgconfig_buildreq("udev");
1395 }
1396 if ($line2 =~ /checking for Apache .* module support/) {
1397 print " Adding pkgconfig(httpd-devel) requirement\n";
1398 push(@buildreqs, "httpd-devel");
1399 if ($rcount < 3) {
1400 $restart = $restart + 1;
1401 }
1402 }
1403 if ($line2 =~ /([a-zA-Z0-9\-\_]*)\: command not found/i) {
1404 my $cmd = $1;
1405 my $found = 0;
1406
1407 while (($key,$value) = each %failed_commands) {
1408 if ($cmd eq $key) {
1409 push(@buildreqs, $value);
1410 print " Adding $value requirement\n";
1411 $restart += $restart + 1;
1412 $mustrestart = 1;
1413 $found = 1;
1414 }
1415 }
1416
1417 if ($found < 1) {
1418 print " Command $cmd not found!\n";
1419 }
1420 }
1421 if ($line2 =~ /checking for.*in -ljpeg... no/) {
1422 push(@buildreqs, "libjpeg-devel");
1423 print " Adding libjpeg-devel requirement\n";
1424 $restart = $restart + 1;
1425 }
1426 if ($line2 =~ /fatal error\: zlib\.h\: No such file or directory/) {
1427 push(@buildreqs, "zlib-devel");
1428 print " Adding zlib-devel requirement\n";
1429 $restart = $restart + 1;
1430 }
1431 if ($line2 =~ /error\: xml2-config not found/) {
1432 push_pkgconfig_buildreq("libxml-2.0");
1433 print " Adding libxml2-devel requirement\n";
1434 $restart = $restart + 1;
1435 }
1436 if ($line2 =~ /checking \"location of ncurses\.h file\"/) {
1437 push(@buildreqs, "ncurses-devel");
1438 print " Adding ncurses-devel requirement\n";
1439 $restart = $restart + 1;
1440 }
1441 if (($line2 =~ / \/usr\/include\/python2\.6$/ || $line2 =~ / to compile python extensions/) && $done_python == 0) {
1442 push(@buildreqs, "python-devel");
1443 print " Adding python-devel requirement\n";
1444 $restart = $restart + 1;
1445 $done_python = 1;
1446 }
1447 if ($line2 =~ /error: must install xorg-macros 1.6/) {
1448 push_pkgconfig_buildreq("xorg-macros");
1449 print " Adding xorg-macros requirement\n";
1450 $restart = $restart + 1;
1451 }
1452 if ($line2 =~ /installing .*?.gmo as [a-zA-Z0-9\-\.\/\_]+?\/([a-zA-Z0-9\-\_\.]+)\.mo$/) {
1453 my $loc = $1;
1454 if ($loc eq $localename) {} else {
1455 print " Changing localename from $localename to $loc\n";
1456 $localename = $loc;
1457 $restart = $restart + 1;
1458 }
1459 }
1460
1461 if ($infiles == 0 && $line2 =~ / Installed \(but unpackaged\) file\(s\) found\:/) {
1462 $infiles = 1;
1463 }
1464 }
1465 close(OUTPUTF);
1466 if (@allfiles == 0 || $mustrestart > 0) {
1467 if ($restart >= 1)
1468 {
1469 $rcount = $rcount + 1;
1470 if ($rcount < 10) {
1471 goto retry;
1472 }
1473 }
1474 print "Build failed ... stopping here.\n";
1475 exit(0);
1476 }
1477
1478}
1479
1480sub process_rpmlint {
1481 my $infiles = 0;
1482
1483
1484 if ($oscmode == 0) {
1485 return;
1486 }
1487
1488 print "Verifying package ....\n";
1489
1490 system("osc addremove &> /dev/null");
1491 system("osc ci -m \"Final import by autospectacle\" &> /dev/null");
1492
1493 open(OUTPUTF, "osc build --no-verify $name.spec 2>&1 |");
1494 while (<OUTPUTF>) {
1495 my $line2 = $_;
1496
1497# print "line is $line2\n";
1498 if ($infiles == 1 && $line2 =~ /RPM build errors/) {
1499 $infiles = 2;
1500 }
1501 if ($infiles == 1 && $line2 =~ /^Building/) {
1502 $infiles = 2;
1503 }
1504 if ($infiles == 1) {
1505 $line2 =~ s/\s*//g;
1506 push(@allfiles, $line2);
1507 }
1508 if ($infiles == 0 && $line2 =~ / Installed \(but unpackaged\) file\(s\) found\:/) {
1509 $infiles = 1;
1510 }
1511 }
1512 close(OUTPUTF);
1513
1514}
1515
1516sub guess_name_from_url {
1517 my ($bigurl) = @_;
1518
1519 @spliturl = split(/\//, $bigurl);
1520 while (@spliturl > 1) {
1521 shift(@spliturl);
1522 }
1523 my $tarfile = $spliturl[0];
1524
1525 if ($tarfile =~ /(.*?)\-([0-9\.\-\~]+)\.tar/) {
1526 $name = $1;
1527 $version = $2;
1528 $version =~ s/\-/\_/g;
1529 }
1530}
1531
1532############################################################################
1533#
1534# Output functions
1535#
1536
1537sub print_name_and_description
1538{
1539 my @lines;
1540
1541 print OUTFILE "Name : $name\n";
1542 print OUTFILE "Version : $version\n";
1543 print OUTFILE "Release : 1\n";
1544
1545 # remove dupes
1546 undef %saw;
1547 @saw{@groups} = ();
1548 @out = sort keys %saw;
1549
1550 if (@out == 1) {
1551 foreach (@out) {
1552 print OUTFILE "Group : $_\n";
1553 }
1554 } else {
1555 print OUTFILE "Group : $group\n";
1556 }
1557 #
1558 # Work around spectacle bug
1559 $summary =~ s/\:\s/ /g;
1560 $summary =~ s/^([a-z])/\u$1/ig;
1561 $summary =~ s/\@//g;
1562 $summary = substr($summary, 0, 79);
1563
1564 $summary =~ s/\.^//g;
1565 if (length($summary) < 1) {
1566 $summary = "TO BE FILLED IN";
1567 }
1568 #
1569 print OUTFILE "Summary : $summary\n";
1570 print OUTFILE "Description: |\n";
1571
1572 $description =~ s/&quot;/\"/g;
1573 $description =~ s/\@//g;
1574 @lines = split(/\n/, $description);
1575 foreach (@lines) {
1576 print OUTFILE " $_\n";
1577 }
1578 if (length($url)>1) {
1579 print OUTFILE "URL : $url\n";
1580 }
1581
1582 # remove dupes
1583 undef %saw;
1584 @saw{@sources} = ();
1585 @out = sort keys %saw;
1586
1587 print OUTFILE "Sources : \n";
1588 foreach (@out) {
1589 $source = $_;
1590 $source =~ s/$version/\%\{version\}/g;
1591
1592 print OUTFILE " - $source\n";
1593 }
1594
1595 if (@patches > 0) {
1596 print OUTFILE "Patches: \n";
1597 foreach (@patches) {
1598 my $patch = $_;
1599 print OUTFILE " - $patch\n";
1600 }
1601 }
1602
1603 print OUTFILE "\n";
1604 if (length($configure)>2) {
1605 print OUTFILE "Configure : $configure\n";
1606 }
1607 if (length($localename) > 2) {
1608 print OUTFILE "LocaleName : $localename\n";
1609 }
1610 if (length($builder) > 2) {
1611 print OUTFILE "Builder : $builder\n";
1612 }
1613}
1614
1615sub write_makefile
1616{
1617 open(MAKEFILE, ">Makefile");
1618
1619 print MAKEFILE "PKG_NAME := $name\n";
1620 print MAKEFILE "SPECFILE = \$(addsuffix .spec, \$(PKG_NAME))\n";
1621 print MAKEFILE "YAMLFILE = \$(addsuffix .yaml, \$(PKG_NAME))\n";
1622 print MAKEFILE "\n";
1623 print MAKEFILE "include /usr/share/packaging-tools/Makefile.common\n";
1624
1625 close(MAKEFILE);
1626}
1627
1628sub write_changelog
1629{
1630 open(CHANGELOG, ">$name.changes");
1631 $date = ` date +"%a %b %d %Y"`;
1632 chomp($date);
1633 print CHANGELOG "* $date - Autospectacle <autospectacle\@meego.com> - $version\n";
1634 print CHANGELOG "- Initial automated packaging\n";
1635 close(CHANGELOG);
1636}
1637
1638sub write_yaml
1639{
1640 open(OUTFILE, ">$name.yaml");
1641 print_name_and_description();
1642 print_license();
1643 print_pkgconfig();
1644 print_buildreq();
1645 print_files();
1646 print_devel();
1647 print_doc();
1648 close(OUTFILE);
1649
1650 write_makefile();
1651 write_changelog();
1652
1653 system("rm $name.spec");
1654 system("specify &> /dev/null");
1655 if ($oscmode > 0) {
1656 system("osc addremove");
1657 system("osc ci -m \"Import by autospectacle\" &> /dev/null");
1658 }
1659
1660}
1661
1662
1663############################################################################
1664#
1665# Main program
1666#
1667
1668if ( @ARGV < 1 ) {
1669 print "Usage: $0 <url-of-source-tarballs>\n";
1670 exit(1);
1671}
1672
1673if (@ARGV > 1) {
1674 my $i = 1;
1675 while ($i < @ARGV) {
1676 my $patch = $ARGV[$i];
1677 print "Adding patch $patch\n";
1678 push(@patches, $patch);
1679 $i++;
1680 }
1681}
1682
1683setup_licenses();
1684setup_files_rules();
1685setup_group_rules();
1686setup_pkgconfig_ban();
1687setup_failed_commands();
1688
1689if (-e ".osc/_packages") {
1690 $oscmode = 1;
1691}
1692
1693my $tmpdir = tempdir();
1694
1695$dir = $ARGV[0];
1696guess_name_from_url($dir);
1697push(@sources, $dir);
1698
1699
1700#system("cd $tmpdir; curl -s -O $dir");
1701$orgdir = `pwd`;
1702chomp($orgdir);
1703print "Downloading package: $dir\n";
1704system("wget --quiet $dir");
1705print "Unpacking to : $tmpdir\n";
1706
1707my @tgzfiles = <$orgdir/*.tgz>;
1708foreach (@tgzfiles) {
1709 my $tgz = $_;
1710 my $tar = $tgz;
1711 $tar =~ s/tgz/tar\.gz/g;
1712 $dir =~ s/tgz/tar\.gz/g;
1713 system("mv $tgz $tar");
1714 guess_name_from_url($dir);
1715}
1716
1717
1718#
1719# I really really hate the fact that meego deleted the -a option from tar.
1720# this is a step backwards in time that is just silly.
1721#
1722
1723
1724system("cd $tmpdir; tar -jxf $orgdir/*\.tar\.bz2");
1725system("cd $tmpdir; tar -zxf $orgdir/*\.tar\.gz");
1726print "Parsing content ....\n";
1727my @dirs = <$tmpdir/*>;
1728foreach (@dirs) {
1729 $dir = $_;
1730}
1731
1732$fulldir = $dir;
1733
1734if ( -e "$dir/autogen.sh" ) {
1735 $configure = "autogen";
1736 $uses_configure = 1;
1737}
1738if ( -e "$dir/BUILD-CMAKE" ) {
1739 $configure = "cmake";
1740 push(@buildreqs, "cmake");
1741 $uses_configure = 1;
1742}
1743
1744if ( -e "$dir/configure" ) {
1745 $configure = "";
1746}
1747
1748my @files = <$dir/configure.*>;
1749
1750my $findoutput = `find $dir -name "configure.ac"`;
1751my @findlist = split(/\n/, $findoutput);
1752foreach (@findlist) {
1753 push(@files, $_);
1754}
1755foreach (@files) {
1756 process_configure_ac("$_");
1757}
1758
1759$findoutput = `find $dir -name "*.pro"`;
1760@findlist = split(/\n/, $findoutput);
1761foreach (@findlist) {
1762 process_qmake_pro("$_");
1763}
1764
1765if (-e "$dir/$name.pro") {
1766 $builder = "qmake";
1767 push_pkgconfig_buildreq("Qt");
1768}
1769
1770
1771#
1772# This is a good place to generate configure.in
1773#
1774if (length($configure) > 2) {
1775 if ($configure eq "autogen") {
1776 system("cd $dir ; ./autogen.sh &> /dev/null");
1777 }
1778}
1779@files = <$dir/configure>;
1780foreach (@files) {
1781 process_configure("$_");
1782}
1783
1784if ($uses_configure == 0) {
1785 $configure = "none";
1786}
1787
1788@files = <$dir/COPY*>;
1789foreach (@files) {
1790 guess_license_from_file("$_");
1791}
1792
1793@files = <$dir/LICENSE*>;
1794foreach (@files) {
1795 guess_license_from_file("$_");
1796}
1797
1798
1799@files = <$dir/GPL*>;
1800foreach (@files) {
1801 guess_license_from_file("$_");
1802}
1803
1804
1805guess_description($dir);
1806
1807
1808#
1809# Output of the yaml file
1810#
1811
1812
1813if ($oscmode == 1) {
1814 print "Creating OBS project $name ...\n";
1815 system("osc mkpac $name &> /dev/null");
1816 system("mkdir $name &> /dev/null");
1817 chdir($name);
1818 system("mv ../$name*\.tar\.* .");
1819}
1820
1821write_yaml();
1822print "Building package ....\n";
1823
1824if ($oscmode == 0) {
1825 guess_files_from_rpmbuild();
1826} else {
1827 guess_files_from_oscbuild();
1828}
1829
1830apply_files_rules();
1831
1832$printed_subpackages = 0;
1833write_yaml();
1834
1835process_rpmlint();
1836
1837print "Spectacle creation complete.\n";