From 0b56edb01710763778d6fa6c213c7c9f1c140a238541ba55d55feafe16dd765c Mon Sep 17 00:00:00 2001 From: Stephan Kulow Date: Tue, 6 Dec 2011 08:55:21 +0000 Subject: [PATCH] - update from https://github.com/openSUSE/obs-service-format_spec_file OBS-URL: https://build.opensuse.org/package/show/openSUSE:Tools/obs-service-format_spec_file?expand=0&rev=26 --- ...pec_file:obs-service-format_spec_file.spec | 59 +++ obs-service-format_spec_file.changes | 5 + obs-service-format_spec_file.spec | 9 +- prepare_spec | 380 +++++++++++++----- 4 files changed, 338 insertions(+), 115 deletions(-) create mode 100644 _service:format_spec_file:obs-service-format_spec_file.spec diff --git a/_service:format_spec_file:obs-service-format_spec_file.spec b/_service:format_spec_file:obs-service-format_spec_file.spec new file mode 100644 index 0000000..7613a14 --- /dev/null +++ b/_service:format_spec_file:obs-service-format_spec_file.spec @@ -0,0 +1,59 @@ +# +# spec file for package obs-service-format_spec_file +# +# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany. +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# + + + +Name: obs-service-format_spec_file +Summary: An OBS source service: reformats a spec file to SUSE standard. +License: GPL-2.0+ +Group: Development/Tools/Building +Version: 0.3 +Release: 0 +Source: format_spec_file +Source1: format_spec_file.service +Source2: prepare_spec +Requires: osc-source_validator +BuildRoot: %{_tmppath}/%{name}-%{version}-build +BuildArch: noarch + +%description +This is a source service for openSUSE Build Service. + +This source service is formating the spec file to SUSE standard. The rational +behind is to make it easier to review spec files from unknown packagers. + +This should be used in "trylocal" mode, so that osc is adapting the existing +spec file instead of creating a new one. + +%prep + +%setup -q -D -T 0 -n . + +%build + +%install +mkdir -p $RPM_BUILD_ROOT/usr/lib/obs/service/format_spec_file.files +install -m 0755 %{SOURCE0} $RPM_BUILD_ROOT/usr/lib/obs/service +install -m 0644 %{SOURCE1} $RPM_BUILD_ROOT/usr/lib/obs/service +install -m 0755 %{SOURCE2} $RPM_BUILD_ROOT/usr/lib/obs/service/format_spec_file.files + +%files +%defattr(-,root,root) +%dir /usr/lib/obs +/usr/lib/obs/service + +%changelog diff --git a/obs-service-format_spec_file.changes b/obs-service-format_spec_file.changes index 9b95e02..1aa0934 100644 --- a/obs-service-format_spec_file.changes +++ b/obs-service-format_spec_file.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Tue Dec 6 08:50:41 UTC 2011 - coolo@suse.com + +- update from https://github.com/openSUSE/obs-service-format_spec_file + ------------------------------------------------------------------- Thu Dec 1 14:10:52 UTC 2011 - adrian@suse.de diff --git a/obs-service-format_spec_file.spec b/obs-service-format_spec_file.spec index 8616a34..4463c72 100644 --- a/obs-service-format_spec_file.spec +++ b/obs-service-format_spec_file.spec @@ -16,13 +16,12 @@ # - Name: obs-service-format_spec_file -License: GPL v2 or later -Group: Development/Tools/Building Summary: An OBS source service: reformats a spec file to SUSE standard. -Version: 0.2 -Release: 11 +License: GPL-2.0+ +Group: Development/Tools/Building +Version: 0.3 +Release: 0 Source: format_spec_file Source1: format_spec_file.service Source2: prepare_spec diff --git a/prepare_spec b/prepare_spec index 5c6517b..43615d0 100644 --- a/prepare_spec +++ b/prepare_spec @@ -15,21 +15,20 @@ use strict; my @oldspec = (); my @newspec = (); my $base_package = ""; -my $neededforbuild = ""; my $icecreamforbuild = ""; -my $norootforbuild = 0; my @copyrights = (); my $needsrootforbuild = 0; my $needsbinariesforbuild = 0; my $nodebuginfo = 0; -my %multiline_macros = (); +my $vim_modeline; my $nosrc_result = 0; my $current_section = "header"; my $had_debug_package = 0; my %pkg_version = (); -my %pkg_release = (); -my %please_replace = (); -my %replace_hash = (); +my $main_license; +my %seen_licenses = (); +my $main_group; +my %seen_groups = (); my $build_root = $ENV{'BUILD_ROOT'}; my $disabled_packs; my $ifhandler; @@ -51,6 +50,8 @@ my @global_tags_list = 'ExcludeArch', 'ExclusiveArch', 'Freshens', + 'Group', + 'Name', 'NoPatch', 'NoSource', 'Obsoletes', @@ -62,6 +63,7 @@ my @global_tags_list = 'Requires', 'Source\d*', 'Suggests', + 'Summary', 'Supplements', 'Url', ); @@ -93,10 +95,19 @@ sub capitalize_case($) return $tag; } +sub compare_arrays { + my ($first, $second) = @_; + return 0 unless @$first == @$second; + for (my $i = 0; $i < @$first; $i++) { + return 0 if $first->[$i] ne $second->[$i]; + } + return 1; +} + sub maybe_add_empty_line() { push @oldspec, "XXXBLANKLINE" - if ($current_section ne "description" && $oldspec[-1] !~ /^\s*$/); + if ($current_section ne "description" && $oldspec[-1] !~ /^\s*$/ && $oldspec[-1] !~ /^[#%]/); } sub change_section($) @@ -109,6 +120,149 @@ sub change_section($) warn "section changed to $current_section\n" if $debug; } +sub replace_single_spdx($) +{ + my ($l) = @_; + + my %replace = ( + "lgplv2.1only" =>"LGPL-2.1", + "lgplv2.1orlater" => "LGPL-2.1+", + "lgplv2.1+" => "LGPL-2.1+", + "lgplv2.1" => "LGPL-2.1", + "lgplv2.0+" => "LGPL-2.0+", + "lgplv2.0" => "LGPL-2.0", + "lgplv2+" => "LGPL-2.1+", + + 'lgplv3' => "LGPL-3.0", + 'lgplv3+' => "LGPL-3.0+", + 'gnulgplv2.1orlater' => "LGPL-2.1+", + 'gnulgplv2.1' => "LGPL-2.1", + 'lgplv2.0orlater' => 'LGPL-2.0+', + 'lgplv2orlater' => 'LGPL-2.0+', + + "lgplv3only" => "LGPL-3.0", + "lgplv3orlater" => "LGPL-3.0+", + + "gpl" => "GPL-1.0", + "gpl+" => "GPL-1.0+", + "gplv2only" => "GPL-2.0", + "gplv2" => "GPL-2.0", + "gpl2" => "GPL-2.0", + "gplv2orlater" => "GPL-2.0+", + "gplv2.0orlater" => "GPL-2.0+", + "gplv2+" => "GPL-2.0+", + "gpl-2+" => "GPL-2.0+", + "gplv3only" => "GPL-3.0", + "gplv3orlater" => "GPL-3.0+", + "gplv3+" => "GPL-3.0+", + "gplv3" => "GPL-3.0", + "gpl-3+" => "GPL-3.0+", + "gnugplversion3" => "GPL-3.0", + + "fdl1.1" => "GFDL-1.1", + "gfdlv1.1" => "GFDL-1.1", + 'gnufreedocumentationlicense,version1.1(fdl1.1)' => "GFDL-1.1", + 'gnufreedocumentationlicense,version1.1(gfdl1.1)' => "GFDL-1.1", + "fdl1.2" => "GFDL-1.2", + "gfdl1.2" => "GFDL-1.2", + "gfdlv1.2" => "GFDL-1.2", + 'gnufreedocumentationlicense,version1.2(fdl1.2)' => "GFDL-1.2", + 'gnufreedocumentationlicense,version1.2(gfdl1.2)' => "GFDL-1.2", + "fdl1.3" => "GFDL-1.3", + + "bsd-2c" => "BSD-2-Clause", + "bsd3-clause" => "BSD-3-Clause", + "bsd3c" => "BSD-3-Clause", + "bsd3c(orsimilar)" => "BSD-3-Clause", + "bsd3-clause(orsimilar)" => "BSD-3-Clause", + + "bsd4c" => "BSD-4-Clause", + "bsd4c(orsimilar)" => "BSD-4-Clause", + + "x11/mit" => "MIT", + "X11mit" => "MIT", + "mitlicense(orsimilar)" => "MIT", + + "asl2.0" => "Apache-2.0", + 'apachelicense2.0' => "Apache-2.0", + 'apachelicense' => "Apache-2.0", + 'theapachesoftwarelicense' => "Apache-2.0", + "apachesoftwarelicense.." => "Apache-2.0", + 'apachesoftware license..' => "Apache-2.0", + 'aslv..' => "Apache-2.0", + 'aslv2' => "Apache-2.0", + + "artistic" => "Artistic-1.0", + "artistic2.0" => "Artistic-2.0", + + "thephplicense,version3.01" => "PHP-3.01", + "phplicense" => "PHP-3.01", + "mplv1.0" => "MPL-1.0", + "mplv1.1" => "MPL-1.1", + + "ibmpubliclicense.." => "IPL-1.0", + "ibmpl" => "IPL-1.0", + + "eclipsepubliclicense" => "EPL-1.0", + + "openldap2.8" => "OLDAP-2.8", + + "zliblicense" => "Zlib" + + ); + + my $tl = lc $l; + $tl =~ s, ,,g; + if (defined $replace{$tl}) { + $l = $replace{$tl}; + } else { + my @m = grep(lc($_) eq lc($l), values(%replace)); + if (@m) { + $l = $m[0]; + } else { + print STDERR "unknown license '$l'\n"; + } + } + return $l; +} + +sub replace_spdx_or($) +{ + my ($license) = @_; + + # special case as or later is common in our spec files + $license =~ s, or later, orlater,g; + + my @licenses = (); + for (split(/\s+or\s+/, $license)) { + push @licenses, replace_single_spdx($_); + } + + return join(' or ', sort(@licenses)); +} + +sub replace_spdx_and($) +{ + my ($license) = @_; + + my @licenses = (); + for (split(/\s*and\s*/, $license)) { + push @licenses, replace_spdx_or($_); + } + return join(' and ', sort(@licenses)); +} + +sub replace_spdx($) +{ + my ($license) = @_; + + my @licenses = (); + for (split(/\s*;\s*/, $license)) { + push @licenses, replace_spdx_and($_); + } + return join(' ; ', sort(@licenses)); +} + sub set_current_pkg { my ( $arg ) = @_; print "DEBUG: set_current_pkg receiving $arg\n" if $debug; @@ -148,15 +302,23 @@ sub read_and_parse_old_spec { while (@readspec) { $_ = shift @readspec; + if ( /^\s*$/ && $current_section ne "description") { + # stop preamble parsing on two blank lines + if ($print_comments eq "false" && $oldspec[0] && $oldspec[-1] eq "XXXBLANKLINE") { + $print_comments = "true"; + push @oldspec, "XXXDOUBLELINE"; + next; + } push @oldspec, "XXXBLANKLINE"; next; } - - if ( /^#\s*norootforbuild\s*$/ ) { - $norootforbuild = 1; - next; + + if ( /^# vim:/ ) { + $vim_modeline = $_; + next; } + if ( /^#\s*needsrootforbuild\s*$/ ) { $needsrootforbuild = 1; next; @@ -165,6 +327,10 @@ sub read_and_parse_old_spec { $needsbinariesforbuild = 1; next; } + if ( /^#\s*norootforbuild/ ) { + next; + } + if ( /^#\s*nodebuginfo\s*$/ ) { $nodebuginfo = 1; next; @@ -175,6 +341,7 @@ sub read_and_parse_old_spec { next; } if ( /^#\s*Copyright\s*/ ) { + my $lastlineblank = 0; for (;;) { # check if line is ONLY a standard copyright line, if so, ignore. @@ -182,22 +349,11 @@ sub read_and_parse_old_spec { $c =~ s{\s*(\d+|copyrights?|\(c\)|suse|linux|products|gmbh|nuremberg|n..?rnberg|germany|\W+)\s*}{}gi; push(@copyrights, $_) if length $c > 5; last if length $readspec[0] < 10 || $readspec[0] =~ m{modifications and additions}i || $readspec[0] !~ /^[\#\s]/ - || grep { $readspec[0] =~ /^#\s*$_/ } ("norootforbuild","needsrootforbuild","needsbinariesforbuild","nodebuginfo","icecream","neededforbuild","usedforbuild","Commandline","MD5SUM","!BuildIgnore"); + || grep { $readspec[0] =~ /^#\s*$_/ } ("needsrootforbuild","needsbinariesforbuild","nodebuginfo","icecream","usedforbuild","Commandline","MD5SUM","!BuildIgnore"); $_ = shift @readspec; } next; } - if ( /^#\s*neededforbuild/ ) { - $neededforbuild = $_; - $neededforbuild =~ s/^#\s*neededforbuild\s*//; - my (%aa) = (); - foreach my $x (split(' ',$neededforbuild)){ - $aa{$x}=1; - } - $neededforbuild = join(' ',sort keys (%aa)); - - next; - } # evil epoch removal next if ( /^Epoch:/ ); $_ =~ s/%{?epoch}?[:-]//g; @@ -213,7 +369,9 @@ sub read_and_parse_old_spec { # ignore line if it looks like a "usedforbuild" line, i.e. # if it contains too many base packages next if (grep {$aa{$_}} qw{gcc rpm glibc bash}) > 2; - push @oldspec, "BuildRequires: ".join(' ',sort keys(%aa)); + for my $br (sort keys(%aa)) { + push @oldspec, "BuildRequires: $br"; + } next; } next if ( /^#\s*usedforbuild/ ); @@ -229,6 +387,7 @@ sub read_and_parse_old_spec { push @oldspec, $_; next; } + if ( /^#/ && $current_section ne "description") { warn "$_ $current_section\n" if $debug; if ( $print_comments eq "true" || $readspec[0] =~ /^%define/ || $readspec[0] =~ /^%if/) { @@ -236,6 +395,7 @@ sub read_and_parse_old_spec { } next; } + if ( /^%debug_package/ ) { # remove, we add this ourselves next; @@ -245,9 +405,7 @@ sub read_and_parse_old_spec { if ( /^%define\s*vendor\s/ || /^%define\s*distribution\s/ ) { next; } - if ( /^%define\s+(\w[\w\d]+).*\\$/ ) { - $multiline_macros{$1} = 1; - } + if ( /^\s*%if/ || /^\s*%\{/ || /^\s*%define/ || /^\s*%el/ || /^\s*%endif/ ) { change_section("header") if ($current_section eq "description"); push @oldspec, $_; @@ -330,13 +488,7 @@ sub read_and_parse_old_spec { } if ( /^%description\b/i ) { change_section("description"); - $_ =~ s/^(%\w+)/lc($1)/e; push @oldspec, $_; - ($current_package, $current_lang) = set_current_pkg ( $_ ); - my $target = $current_package; - $target .= "_$current_lang" if $current_lang; - $target .= "_disabled" if $ifhandler->{"disabled"}; - push @oldspec, "XXXDESCRIPTION $target"; next; } if ( /^%install\b/i ) { @@ -363,64 +515,56 @@ sub read_and_parse_old_spec { } push @oldspec, "$_"; - # multiline macros need an extra newline with old RPMs - if (/^%(\w[\w\d]+).*[^\\]$/) { - push @oldspec, "" if (defined($multiline_macros{$1})); - } next; } + if ($current_section eq "header") { my $c_pack = $current_package; $c_pack .= "_disabled" if $ifhandler->{"disabled"}; - if ( /^Summary\b\s*:\s*(.*)/i ) { - $replace_hash{"XXXSUMMARY $c_pack"} = sprintf("%-16s%s","Summary:", $1); - push @oldspec, "XXXSUMMARY $c_pack"; - next; - } - if ( /^Group\b\s*:\s*(.*)/i ) { - $replace_hash{"XXXGROUP $c_pack"} = sprintf("%-16s%s", "Group:", $1); - push @oldspec, "XXXGROUP $c_pack"; - next; - } + if ( /^Vendor:/ || /^Distribution:/ || /^Packager:/ ) { next; } - if ( /^Name\s*:\s*(.*)/i ) { - my $orig_name = $1; - my $changed_name = $orig_name; - $changed_name =~ s/\Q$_\E/$definelist->{$_}/ for (sort { length($b) <=> length($a) } keys (%{$definelist})); - if ($changed_name eq $base_package) { - push @oldspec, sprintf("\n%-16s%s","Name:", $orig_name); - } else { - push @oldspec, sprintf("\n%-16s%s","Name:", $base_package); - } - $definelist->{"%name"} = $base_package if $ifhandler->{"disabled"} == 0; - $definelist->{"%{name}"} = $base_package if $ifhandler->{"disabled"} == 0; - warn ("line is $_, orig_name is $orig_name, base_package is $base_package\n") if $ifhandler->{"disabled"} == 0 && $debug; - next; + # remove default value of Autoreqprov + if ( /^Autoreqprov\s*:\s*(.*)/i ) { + next if ( lc($1) eq "on" || lc($1) eq "yes"); } + # reset Release + if ( /^Release\s*:\s*(.*)/i ) { + # will be after Version + next; + } + if ( /^Summary\s*:\s*(.*)\s*$/i ) { + push @oldspec, sprintf("%-16s%s", "Summary:", $1); + push @oldspec, "XXXPOSTSUMMARY $current_package"; + next; + } + + # remove license and print out after license later + if ( /^License\s*:\s*(.*)\s*$/i || /^Copyright\s*:\s*(.*)\s*$/i ) { + my $license = replace_spdx($1); + $main_license = $license if (!$main_license); + $seen_licenses{$current_package} = $license; + next; + } + + # remove groups and print out after summary later + if ( /^Group\s*:\s*(.*)\s*$/i ) { + my $group = $1; + $main_group = $group if (!$main_group); + $seen_groups{$current_package} = $group; + next; + } + if ( /^BuildArchitectures\s*:/i ) { $_ =~ s/^[^:]+:/BuildArch:/; } - if ( /^Release\s*:\s*(.*)/i ) { - $pkg_release{$c_pack} = $_; - $replace_hash{"XXXRELEASE $c_pack"} = sprintf("%-16s%s","Release:", $1); - next; - } + if ( /^BuildRoot\s*:/i ) { push @oldspec, "BuildRoot: %{_tmppath}/%{name}-%{version}-build"; next; } - if ( /^Copyright\s*:\s*(.*)/i || /^License\s*:\s*(.*)/i ) { - $replace_hash{"XXXLICENSE $c_pack"} = sprintf("%-16s%s","License:", $1); - push @oldspec, "XXXLICENSE $c_pack"; - next; - } - if ( /^Url\s*:\s*(.*)/i ) { - $replace_hash{"XXXURL $c_pack"} = sprintf("%-16s%s","Url:", $1); - push @oldspec, "XXXURL $c_pack"; - next; - } + if ( m/$global_tags_re\s*(.*)/oi ) { my ($tag, $value) = ($1, $2); $nosrc_result = 1 if ($tag =~ /(?:nosource|nopatch)/i); @@ -431,24 +575,17 @@ sub read_and_parse_old_spec { warn "found Version, section = $current_section\n" if $debug; $version{$c_pack} = $_; $version{$c_pack} =~ s/^Version:\s*(.*)\s*/$1/; - $replace_hash{"XXXVERSION $c_pack"} = sprintf("%-16s%s","Version:",$version{$c_pack}); - push @oldspec, $replace_hash{"XXXVERSION $c_pack"}; - push @oldspec, "XXXRELEASE $c_pack"; + push @oldspec, sprintf("%-16s%s","Version:",$version{$c_pack}); + push @oldspec, sprintf("%-16s%s","Release:", "0"); next; } } - if ( $current_section eq "description" ) { - my $target = $current_package; - $target .= "_$current_lang" if $current_lang; - $target .= "_disabled" if $ifhandler->{"disabled"}; - $replace_hash{"XXXDESCRIPTION $target"} .= "\n" if ( $replace_hash{"XXXDESCRIPTION $target"} ); - $replace_hash{"XXXDESCRIPTION $target"} .= $_; + if ( $current_section ne "changelog" ) { + push @oldspec, $_; next; } - if ( $current_section ne "description" && $current_section ne "changelog" ) { - push @oldspec, $_; - } } + } if ($ARGV[0] eq '--debug') { @@ -518,16 +655,40 @@ if ( ! stat ((glob("$specdir/$base_package*.spec"))[0] || "") ) { read_and_parse_old_spec ( $specfile, $base_package ); -for (@oldspec) { - next unless /^XXX/; - $please_replace{$_} = 1; +my $linesmoved = 1; +while ($linesmoved) { + $linesmoved = 0; + my @firstlines = (); + my @buildrequires = (); + while ($oldspec[0]) { + my $l = shift @oldspec; + if ($l =~ m/^BuildRequires:/ ) { + push(@buildrequires, $l); + } else { + # if there are already buildrequires, we need to sort and exit + if (@buildrequires > 0) { + my @sortedbrs = sort(@buildrequires); + $linesmoved = !compare_arrays(\@buildrequires, \@sortedbrs); + @oldspec = (@firstlines, sort(@buildrequires), $l, @oldspec); + @firstlines = (); + @buildrequires = (); + last; + } else { + push(@firstlines, $l); + } + } + } + @oldspec = (@firstlines, @oldspec); } + my $thisyear = localtime->year() + 1900; unshift @copyrights, "# Copyright (c) $thisyear SUSE LINUX Products GmbH, Nuernberg, Germany."; my $copy_list = join("\n", @copyrights); + +print $vim_modeline . "\n" if (defined $vim_modeline); print <