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