/) {
+ $state = 1;
+ }
+ if ($state == 1 && $line =~/\<\/p\>/) {
+ $state = 2;
+ }
+ }
+ close(HTML);
+ $cummul =~ s/\
//g;
+ $cummul =~ s/\r//g;
+ $cummul =~ s/\<\/p\>//g;
+ $cummul =~ s/^\s*//g;
+ if (length($cummul)>10) {
+ $description = $cummul;
+ }
+}
+#
+# If all else fails, just take the first paragraph of the
+# readme file
+#
+sub guess_description_from_readme {
+ my ($file) = @_;
+
+ my $state = 0;
+ my $cummul = "";
+
+ open(FILE, $file);
+ while () {
+ my $line = $_;
+ if ($state == 1 && $line =~ /^\n/ && length($cummul) > 80) {
+ $state = 2;
+ }
+ if ($state == 0 && length($line)>1) {
+ $state = 1;
+ }
+ if ($state == 1) {
+ $cummul = $cummul . $line;
+ }
+ if ($line =~ /(http\:\/\/.*$name.*\.org)/) {
+ my $u = $1;
+ if ($u =~ /bug/ || length($url) > 1) {
+ } else {
+ $url = $u;
+ }
+ }
+ }
+ close(FILE);
+ if (length($cummul) > 4 && length($description)<3) {
+ $description = $cummul;
+ }
+}
+
+#
+# Glue all the guesses together
+#
+sub guess_description {
+ my ($directory) = @_;
+
+
+ @files = <$directory/README*>;
+ foreach (@files) {
+ guess_description_from_readme($_);
+ }
+
+ if (length($name)>2) {
+ guess_description_from_freshmeat($name);
+ }
+
+ @files = <$directory/*.spec*>;
+ foreach (@files) {
+ guess_description_from_spec($_);
+ }
+
+ guess_description_from_debian_control($directory);
+
+ $name =~ s/ //g;
+ @files = <$directory/$name.pc*>;
+ foreach (@files) {
+ guess_description_from_pkgconfig($_);
+ }
+ @files = <$directory/*.pc.*>;
+ foreach (@files) {
+ guess_description_from_pkgconfig($_);
+ }
+ @files = <$directory/*.pc>;
+ foreach (@files) {
+ guess_description_from_pkgconfig($_);
+ }
+ @files = <$directory/*.doap>;
+ foreach (@files) {
+ guess_description_from_doap($_);
+ }
+
+ if (length($summary) < 2) {
+ $summary = $description;
+ $summary =~ s/\n/ /g;
+ $summary =~ s/\s+/ /g;
+ if ($summary =~ /(.*?)\./) {
+ $summary = $1;
+ }
+ }
+
+}
+
+# end of Description / Summary section
+#
+######################################################################
+
+
+
+#
+# Build the package, and wait for rpm to complain about unpackaged
+# files.... which we then use as basis for our %files section
+#
+sub guess_files_from_rpmbuild {
+ my $infiles = 0;
+ open(OUTPUTF, "rpmbuild --nodeps --define \"\%_sourcedir $orgdir \" -ba $name.spec 2>&1 |");
+ while () {
+ my $line2 = $_;
+
+ if ($infiles == 1 && $line2 =~ /RPM build errors/) {
+ $infiles = 2;
+ }
+ if ($infiles == 1 && $line2 =~ /^Building/) {
+ $infiles = 2;
+ }
+
+ if ($infiles == 1) {
+ $line2 =~ s/\s*//g;
+ push(@allfiles, $line2);
+ }
+ if ($line2 =~ / Installed \(but unpackaged\) file\(s\) found\:/) {
+ $infiles = 1;
+ }
+ }
+ close(OUTPUTF);
+ if (@allfiles == 0) {
+ print "Build failed ... stopping here.\n";
+ exit(0);
+ }
+
+}
+
+sub guess_files_from_oscbuild {
+ my $infiles = 0;
+ my $restart = 0;
+ my $mustrestart = 0;
+ my $rcount = 0;
+ my $done_python = 0;
+
+ system("osc addremove &> /dev/null");
+ system("osc ci -m \"Initial import by autospectacle\" &> /dev/null");
+
+retry:
+ if ($restart > 0) {
+ write_yaml();
+ print "Restarting the build\n";
+ }
+ $restart = 0;
+ $infiles = 0;
+ $mustrestart = 0;
+ open(OUTPUTF, "osc build --no-verify $name.spec 2>&1 |");
+ while () {
+ my $line2 = $_;
+
+# print "line is $line2\n";
+ if ($infiles == 1 && $line2 =~ /RPM build errors/) {
+ $infiles = 2;
+ }
+ if ($infiles == 1 && $line2 =~ /^Building/) {
+ $infiles = 2;
+ }
+ if ($infiles == 1) {
+ $line2 =~ s/\s*//g;
+ push(@allfiles, $line2);
+ }
+ if ($line2 =~ /No package \'(.*)\' found/) {
+ push_pkgconfig_buildreq("$1");
+ $restart = $restart + 1;
+ print " Adding pkgconfig($1) requirement\n";
+ }
+ if ($line2 =~ /Package requirements \((.*?)\) were not met/) {
+ $pkg = $1;
+ # deal with versioned pkgconfig's by removing the spaces around >= 's
+ $pkg =~ s/\>\=\s/\>\=/g;
+ $pkg =~ s/\s\>\=/\>\=/g;
+ $pkg =~ s/\=\s/\=/g;
+ $pkg =~ s/\s\=/\=/g;
+ my @req = split(/ /,$pkg);
+ foreach (@req) {
+ push_pkgconfig_buildreq("$_");
+
+ $restart = $restart + 1;
+ print " Adding pkgconfig($_) requirement\n";
+ }
+ }
+ if ($line2 =~ /which: no qmake/) {
+ $restart += 1;
+ push_pkgconfig_buildreq("Qt");
+ print " Adding Qt requirement\n";
+ }
+ if ($line2 =~ /Cannot find development files for any supported version of libnl/) {
+ $restart += 1;
+ push_pkgconfig_buildreq("libnl-1");
+ print " Adding libnl requirement\n";
+ }
+ if ($line2 =~ //) {
+ $restart += 1;
+ push(@buildreqs, "cmake");
+ print " Adding cmake requirement\n";
+ }
+ if ($line2 =~ /checking for (.*?)\.\.\. not_found/ || $line2 =~ /checking for (.*?)\.\.\. no/ || $line2 =~ /checking (.*?)\.\.\. no/) {
+ $pkg = $1;
+ while (($key,$value) = each %failed_commands) {
+ if ($pkg eq $key) {
+ push(@buildreqs, $value);
+ print " Adding $value requirement\n";
+ $restart += $restart + 1;
+ $mustrestart = 1;
+ }
+ }
+
+ }
+
+ if ($line2 =~ /checking for [a-zA-Z0-9\_]+ in (.*?)\.\.\. no/) {
+ $pkg = $1;
+ while (($key,$value) = each %failed_libs) {
+ if ($pkg eq $key) {
+ push(@buildreqs, $value);
+ print " Adding $value requirement\n";
+ $restart += $restart + 1;
+ $mustrestart = 1;
+ }
+ }
+
+ }
+
+ if ($line2 =~ /-- Could NOT find ([a-zA-Z0-9]+)/) {
+ $pkg = $1;
+ while (($key,$value) = each %failed_libs) {
+ if ($pkg eq $key) {
+ push(@buildreqs, $value);
+ print " Adding $value requirement\n";
+ $restart += $restart + 1;
+ $mustrestart = 1;
+ }
+ }
+
+ }
+
+ if ($line2 =~ /fatal error\: (.*)\: No such file or directory/) {
+ $pkg = $1;
+ while (($key,$value) = each %failed_headers) {
+ if ($pkg eq $key) {
+ push_pkgconfig_buildreq($value);
+ print " Adding $value requirement\n";
+ $restart += $restart + 1;
+ }
+ }
+
+ }
+ if ($line2 =~ /checking for UDEV\.\.\. no/) {
+ print " Adding pkgconfig(udev) requirement\n";
+ push_pkgconfig_buildreq("udev");
+ }
+ if ($line2 =~ /checking for Apache .* module support/) {
+ print " Adding pkgconfig(httpd-devel) requirement\n";
+ push(@buildreqs, "httpd-devel");
+ if ($rcount < 3) {
+ $restart = $restart + 1;
+ }
+ }
+ if ($line2 =~ /([a-zA-Z0-9\-\_]*)\: command not found/i) {
+ my $cmd = $1;
+ my $found = 0;
+
+ while (($key,$value) = each %failed_commands) {
+ if ($cmd eq $key) {
+ push(@buildreqs, $value);
+ print " Adding $value requirement\n";
+ $restart += $restart + 1;
+ $mustrestart = 1;
+ $found = 1;
+ }
+ }
+
+ if ($found < 1) {
+ print " Command $cmd not found!\n";
+ }
+ }
+ if ($line2 =~ /checking for.*in -ljpeg... no/) {
+ push(@buildreqs, "libjpeg-devel");
+ print " Adding libjpeg-devel requirement\n";
+ $restart = $restart + 1;
+ }
+ if ($line2 =~ /fatal error\: zlib\.h\: No such file or directory/) {
+ push(@buildreqs, "zlib-devel");
+ print " Adding zlib-devel requirement\n";
+ $restart = $restart + 1;
+ }
+ if ($line2 =~ /error\: xml2-config not found/) {
+ push_pkgconfig_buildreq("libxml-2.0");
+ print " Adding libxml2-devel requirement\n";
+ $restart = $restart + 1;
+ }
+ if ($line2 =~ /checking \"location of ncurses\.h file\"/) {
+ push(@buildreqs, "ncurses-devel");
+ print " Adding ncurses-devel requirement\n";
+ $restart = $restart + 1;
+ }
+ if (($line2 =~ / \/usr\/include\/python2\.6$/ || $line2 =~ / to compile python extensions/) && $done_python == 0) {
+ push(@buildreqs, "python-devel");
+ print " Adding python-devel requirement\n";
+ $restart = $restart + 1;
+ $done_python = 1;
+ }
+ if ($line2 =~ /error: must install xorg-macros 1.6/) {
+ push_pkgconfig_buildreq("xorg-macros");
+ print " Adding xorg-macros requirement\n";
+ $restart = $restart + 1;
+ }
+ if ($line2 =~ /installing .*?.gmo as [a-zA-Z0-9\-\.\/\_]+?\/([a-zA-Z0-9\-\_\.]+)\.mo$/) {
+ my $loc = $1;
+ if ($loc eq $localename) {} else {
+ print " Changing localename from $localename to $loc\n";
+ $localename = $loc;
+ $restart = $restart + 1;
+ }
+ }
+
+ if ($infiles == 0 && $line2 =~ / Installed \(but unpackaged\) file\(s\) found\:/) {
+ $infiles = 1;
+ }
+ }
+ close(OUTPUTF);
+ if (@allfiles == 0 || $mustrestart > 0) {
+ if ($restart >= 1)
+ {
+ $rcount = $rcount + 1;
+ if ($rcount < 10) {
+ goto retry;
+ }
+ }
+ print "Build failed ... stopping here.\n";
+ exit(0);
+ }
+
+}
+
+sub process_rpmlint {
+ my $infiles = 0;
+
+
+ if ($oscmode == 0) {
+ return;
+ }
+
+ print "Verifying package ....\n";
+
+ system("osc addremove &> /dev/null");
+ system("osc ci -m \"Final import by autospectacle\" &> /dev/null");
+
+ open(OUTPUTF, "osc build --no-verify $name.spec 2>&1 |");
+ while () {
+ my $line2 = $_;
+
+# print "line is $line2\n";
+ if ($infiles == 1 && $line2 =~ /RPM build errors/) {
+ $infiles = 2;
+ }
+ if ($infiles == 1 && $line2 =~ /^Building/) {
+ $infiles = 2;
+ }
+ if ($infiles == 1) {
+ $line2 =~ s/\s*//g;
+ push(@allfiles, $line2);
+ }
+ if ($infiles == 0 && $line2 =~ / Installed \(but unpackaged\) file\(s\) found\:/) {
+ $infiles = 1;
+ }
+ }
+ close(OUTPUTF);
+
+}
+
+sub guess_name_from_url {
+ my ($bigurl) = @_;
+
+ @spliturl = split(/\//, $bigurl);
+ while (@spliturl > 1) {
+ shift(@spliturl);
+ }
+ my $tarfile = $spliturl[0];
+
+ if ($tarfile =~ /(.*?)\-([0-9\.\-\~]+)\.tar/) {
+ $name = $1;
+ $version = $2;
+ $version =~ s/\-/\_/g;
+ }
+}
+
+############################################################################
+#
+# Output functions
+#
+
+sub print_name_and_description
+{
+ my @lines;
+
+ print OUTFILE "Name : $name\n";
+ print OUTFILE "Version : $version\n";
+ print OUTFILE "Release : 1\n";
+
+ # remove dupes
+ undef %saw;
+ @saw{@groups} = ();
+ @out = sort keys %saw;
+
+ if (@out == 1) {
+ foreach (@out) {
+ print OUTFILE "Group : $_\n";
+ }
+ } else {
+ print OUTFILE "Group : $group\n";
+ }
+ #
+ # Work around spectacle bug
+ $summary =~ s/\:\s/ /g;
+ $summary =~ s/^([a-z])/\u$1/ig;
+ $summary =~ s/\@//g;
+ $summary = substr($summary, 0, 79);
+
+ $summary =~ s/\.^//g;
+ if (length($summary) < 1) {
+ $summary = "TO BE FILLED IN";
+ }
+ #
+ print OUTFILE "Summary : $summary\n";
+ print OUTFILE "Description: |\n";
+
+ $description =~ s/"/\"/g;
+ $description =~ s/\@//g;
+ @lines = split(/\n/, $description);
+ foreach (@lines) {
+ print OUTFILE " $_\n";
+ }
+ if (length($url)>1) {
+ print OUTFILE "URL : $url\n";
+ }
+
+ # remove dupes
+ undef %saw;
+ @saw{@sources} = ();
+ @out = sort keys %saw;
+
+ print OUTFILE "Sources : \n";
+ foreach (@out) {
+ $source = $_;
+ $source =~ s/$version/\%\{version\}/g;
+
+ print OUTFILE " - $source\n";
+ }
+
+ if (@patches > 0) {
+ print OUTFILE "Patches: \n";
+ foreach (@patches) {
+ my $patch = $_;
+ print OUTFILE " - $patch\n";
+ }
+ }
+
+ print OUTFILE "\n";
+ if (length($configure)>2) {
+ print OUTFILE "Configure : $configure\n";
+ }
+ if (length($localename) > 2) {
+ print OUTFILE "LocaleName : $localename\n";
+ }
+ if (length($builder) > 2) {
+ print OUTFILE "Builder : $builder\n";
+ }
+}
+
+sub write_makefile
+{
+ open(MAKEFILE, ">Makefile");
+
+ print MAKEFILE "PKG_NAME := $name\n";
+ print MAKEFILE "SPECFILE = \$(addsuffix .spec, \$(PKG_NAME))\n";
+ print MAKEFILE "YAMLFILE = \$(addsuffix .yaml, \$(PKG_NAME))\n";
+ print MAKEFILE "\n";
+ print MAKEFILE "include /usr/share/packaging-tools/Makefile.common\n";
+
+ close(MAKEFILE);
+}
+
+sub write_changelog
+{
+ open(CHANGELOG, ">$name.changes");
+ $date = ` date +"%a %b %d %Y"`;
+ chomp($date);
+ print CHANGELOG "* $date - Autospectacle - $version\n";
+ print CHANGELOG "- Initial automated packaging\n";
+ close(CHANGELOG);
+}
+
+sub write_yaml
+{
+ open(OUTFILE, ">$name.yaml");
+ print_name_and_description();
+ print_license();
+ print_pkgconfig();
+ print_buildreq();
+ print_files();
+ print_devel();
+ print_doc();
+ close(OUTFILE);
+
+ write_makefile();
+ write_changelog();
+
+ system("rm $name.spec");
+ system("specify &> /dev/null");
+ if ($oscmode > 0) {
+ system("osc addremove");
+ system("osc ci -m \"Import by autospectacle\" &> /dev/null");
+ }
+
+}
+
+
+############################################################################
+#
+# Main program
+#
+
+if ( @ARGV < 1 ) {
+ print "Usage: $0 \n";
+ exit(1);
+}
+
+if (@ARGV > 1) {
+ my $i = 1;
+ while ($i < @ARGV) {
+ my $patch = $ARGV[$i];
+ print "Adding patch $patch\n";
+ push(@patches, $patch);
+ $i++;
+ }
+}
+
+setup_licenses();
+setup_files_rules();
+setup_group_rules();
+setup_pkgconfig_ban();
+setup_failed_commands();
+
+if (-e ".osc/_packages") {
+ $oscmode = 1;
+}
+
+my $tmpdir = tempdir();
+
+$dir = $ARGV[0];
+guess_name_from_url($dir);
+push(@sources, $dir);
+
+
+#system("cd $tmpdir; curl -s -O $dir");
+$orgdir = `pwd`;
+chomp($orgdir);
+print "Downloading package: $dir\n";
+system("wget --quiet $dir");
+print "Unpacking to : $tmpdir\n";
+
+my @tgzfiles = <$orgdir/*.tgz>;
+foreach (@tgzfiles) {
+ my $tgz = $_;
+ my $tar = $tgz;
+ $tar =~ s/tgz/tar\.gz/g;
+ $dir =~ s/tgz/tar\.gz/g;
+ system("mv $tgz $tar");
+ guess_name_from_url($dir);
+}
+
+
+#
+# I really really hate the fact that meego deleted the -a option from tar.
+# this is a step backwards in time that is just silly.
+#
+
+
+system("cd $tmpdir; tar -jxf $orgdir/*\.tar\.bz2");
+system("cd $tmpdir; tar -zxf $orgdir/*\.tar\.gz");
+print "Parsing content ....\n";
+my @dirs = <$tmpdir/*>;
+foreach (@dirs) {
+ $dir = $_;
+}
+
+$fulldir = $dir;
+
+if ( -e "$dir/autogen.sh" ) {
+ $configure = "autogen";
+ $uses_configure = 1;
+}
+if ( -e "$dir/BUILD-CMAKE" ) {
+ $configure = "cmake";
+ push(@buildreqs, "cmake");
+ $uses_configure = 1;
+}
+
+if ( -e "$dir/configure" ) {
+ $configure = "";
+}
+
+my @files = <$dir/configure.*>;
+
+my $findoutput = `find $dir -name "configure.ac"`;
+my @findlist = split(/\n/, $findoutput);
+foreach (@findlist) {
+ push(@files, $_);
+}
+foreach (@files) {
+ process_configure_ac("$_");
+}
+
+$findoutput = `find $dir -name "*.pro"`;
+@findlist = split(/\n/, $findoutput);
+foreach (@findlist) {
+ process_qmake_pro("$_");
+}
+
+if (-e "$dir/$name.pro") {
+ $builder = "qmake";
+ push_pkgconfig_buildreq("Qt");
+}
+
+
+#
+# This is a good place to generate configure.in
+#
+if (length($configure) > 2) {
+ if ($configure eq "autogen") {
+ system("cd $dir ; ./autogen.sh &> /dev/null");
+ }
+}
+@files = <$dir/configure>;
+foreach (@files) {
+ process_configure("$_");
+}
+
+if ($uses_configure == 0) {
+ $configure = "none";
+}
+
+@files = <$dir/COPY*>;
+foreach (@files) {
+ guess_license_from_file("$_");
+}
+
+@files = <$dir/LICENSE*>;
+foreach (@files) {
+ guess_license_from_file("$_");
+}
+
+
+@files = <$dir/GPL*>;
+foreach (@files) {
+ guess_license_from_file("$_");
+}
+
+
+guess_description($dir);
+
+
+#
+# Output of the yaml file
+#
+
+
+if ($oscmode == 1) {
+ print "Creating OBS project $name ...\n";
+ system("osc mkpac $name &> /dev/null");
+ system("mkdir $name &> /dev/null");
+ chdir($name);
+ system("mv ../$name*\.tar\.* .");
+}
+
+write_yaml();
+print "Building package ....\n";
+
+if ($oscmode == 0) {
+ guess_files_from_rpmbuild();
+} else {
+ guess_files_from_oscbuild();
+}
+
+apply_files_rules();
+
+$printed_subpackages = 0;
+write_yaml();
+
+process_rpmlint();
+
+print "Spectacle creation complete.\n";