openSUSE-release-tools/check_source.pl

302 lines
8.7 KiB
Perl
Raw Normal View History

2011-11-22 13:00:03 +01:00
#! /usr/bin/perl
use File::Basename;
2013-01-11 07:17:41 +01:00
use File::Temp qw/ tempdir /;
2011-11-22 15:04:01 +01:00
use XML::Simple;
use Data::Dumper;
use Cwd;
use Text::Diff;
BEGIN {
unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
}
use Build;
2011-11-22 13:00:03 +01:00
my $ret = 0;
2011-11-22 13:55:12 +01:00
my $old = $ARGV[0];
my $dir = $ARGV[1];
2011-11-22 13:00:03 +01:00
my $bname = basename($dir);
if (-f "$dir/_service") {
my $service = XMLin("$dir/_service", ForceArray => ['service']);
while( my ($name, $s) = each %{$service->{service}} ) {
my $mode = $s->{mode} || '';
next if ($mode eq "localonly" || $mode eq "disabled" || $mode eq "buildtime");
print "Services are only allowed if they are mode='localonly', 'disabled' or 'buildtime'. Please change the mode of $name and use `osc service localrun/disabledrun`.\n";
$ret = 1;
}
# move it away to have full service from source validator
rename("$dir/_service", "$dir/_service.bak") || die "rename failed";
2013-01-11 07:17:41 +01:00
}
for my $file (glob("$dir/_service:*")) {
$file=basename($file);
print "Found _service generated file $file in checkout. Please clean this up first.";
$ret = 1;
2011-11-22 13:00:03 +01:00
}
my @specs = map basename($_), glob("$dir/*.spec");
2011-11-22 13:00:03 +01:00
if (@specs) {
if (!-f "$dir/$bname.changes") {
print "$bname.changes is missing. A package submitted as FooBar needs to have a FooBar.changes file with a format created by `osc vc`.\n";
$ret = 1;
}
if (!-f "$dir/$bname.spec") {
print "$bname.spec is missing. A package submitted as FooBar needs to have a FooBar.spec file.\n";
$ret = 1;
}
exit($ret) if ($ret);
} else {
# package without spec files, eg kiwi only
exit($ret);
}
2011-11-22 13:55:12 +01:00
open(SPEC, "$dir/$bname.spec");
my $spec = join("", <SPEC>);
2011-11-22 13:00:03 +01:00
close(SPEC);
2011-12-22 12:47:45 +01:00
if ($spec !~ m/#[*\s]+Copyright\s/) {
2011-12-22 12:47:45 +01:00
print "$bname.spec does not appear to contain a Copyright comment. Please stick to the format\n\n";
print "# Copyright (c) 2011 Stephan Kulow\n\n";
print "or use osc service runall format_spec_file\n";
$ret = 1;
2011-12-22 12:47:45 +01:00
}
2011-11-22 13:55:12 +01:00
if ($spec =~ m/\nVendor:/) {
print "$bname.spec contains a Vendor line, this is forbidden.\n";
$ret = 1;
2011-11-22 13:55:12 +01:00
}
2012-01-26 15:11:10 +01:00
# Check that we have for each spec file a changes file - and that at least one
# contains changes
my $changes_updated = 0;
for my $spec (@specs) {
$changes = $spec;
2012-01-26 15:11:10 +01:00
$changes =~ s/\.spec$/.changes/;
if (!-f "$dir/$changes") {
print "$changes is missing. A package containing FooBar.spec needs to have a FooBar.changes file with a format created by `osc vc`.\n";
$ret = 1;
2011-11-22 13:55:12 +01:00
}
2012-01-26 15:11:10 +01:00
if (-f "$old/$changes") {
if (system(("cmp", "-s", "$old/$changes", "$dir/$changes"))) {
$changes_updated = 1;
}
}
else { # a new file is an update too
$changes_updated = 1;
2012-01-26 15:11:10 +01:00
}
}
2012-01-26 15:11:10 +01:00
if (!$changes_updated) {
print "No changelog. Please use 'osc vc' to update the changes file(s).\n";
$ret = 1;
2011-11-22 13:55:12 +01:00
}
2012-08-09 11:47:27 +02:00
if ($spec !~ m/\n%changelog\s/ && $spec != m/\n%changelog$/) {
2011-11-22 13:55:12 +01:00
print "$bname.spec does not contain a %changelog line. We don't want a changelog in the spec file, but the %changelog section needs to be present\n";
$ret = 1;
2011-11-22 13:55:12 +01:00
}
2011-11-22 14:36:27 +01:00
if ($spec !~ m/(#[^\n]*license)/i) {
print "$bname.spec does not appear to have a license. The file needs to contain a free software license\n";
print "Suggestion: use \"osc service runall format_spec_file\" to get our default license or\n";
2011-11-22 14:36:27 +01:00
print "the minimal license:\n\n";
print "# This file is under MIT license\n";
$ret = 1;
2011-11-22 14:36:27 +01:00
}
my %patches = ();
for my $test (glob("/usr/lib/obs/service/source_validators/*")) {
next if (!-f "$test");
my $checkivsd = `/bin/bash $test --batchmode $dir $old < /dev/null 2>&1`;
if ($?) {
print "Source validator failed. Try \"osc service runall source_validator\"\n";
print $checkivsd;
print "\n";
$ret = 1;
}
else {
for my $line (split(/\n/, $checkivsd)) {
# pimp up some warnings
if ($line =~ m/Attention.*not mentioned/) {
$line =~ s,\(W\) ,,;
print "$line\n";
$ret = 1;
}
}
}
}
my $odir = getcwd();
chdir($dir) || "chdir $dir failed";
for my $patch (glob("*.diff *.patch *.dif")) {
$patches{$patch} = 'current';
2011-12-22 12:47:45 +01:00
}
chdir($odir) || die "chdir $odir failed";
2011-12-22 12:47:45 +01:00
if (-d "$old") {
chdir($old) || die "chdir $old failed";
my $cf = Build::read_config("x86_64", "/usr/lib/build/configs/default.conf");
2011-12-22 12:47:45 +01:00
my %thash = ();
my %rhash = ();
for my $spec (glob("*.spec")) {
my $ps = Build::Rpm::parse($cf, $spec);
while (my ($k, $v) = each %$ps) {
if ($k =~ m/^source/) {
$thash{$v} = 1;
}
}
}
for my $patch (glob("*.diff *.patch *.dif")) {
if ($patches{$patch}) {
delete $patches{$patch};
}
else {
$patches{$patch} = 'old';
}
2011-12-22 12:47:45 +01:00
}
chdir($odir) || die "chdir $odir failed";
chdir($dir) || die "chdir $dir failed";
2011-12-22 12:47:45 +01:00
for my $spec (glob("*.spec")) {
my $ps = Build::Rpm::parse($cf, $spec);
open(OSPEC, "$spec");
open(NSPEC, ">$spec.new");
while (<OSPEC>) {
chomp;
if (m/^Source/) {
my $line = $_;
$line =~ s/^(Source[0-9]*)\s*:\s*//;
if ($patches{$line}) {
delete $patches{$line};
}
my $prefix = $1;
my $parsedline = $ps->{lc $prefix};
if (defined $thash{$parsedline}) {
my $file = $line;
my $bname = basename($file);
print NSPEC "$prefix: $bname\n";
}
else {
print NSPEC "$_\n";
}
}
else {
print NSPEC "$_\n";
}
}
close(OSPEC);
close(NSPEC);
system(("cp", "$spec", "$spec.beforeurlstrip"));
rename("$spec.new", "$spec") || die "rename failed";
2011-12-22 12:47:45 +01:00
}
2014-06-05 11:27:51 +02:00
chdir($dir);
my @changes = glob("*.changes");
chdir($odir);
if (%patches) {
# parse changes
2014-06-05 11:27:51 +02:00
for my $changes (@changes) {
my $diff = "";
if (! -e "$old/$changes") {
$diff = diff "/dev/null", "$dir/$changes";
}
else {
$diff = diff "$old/$changes", "$dir/$changes";
}
2014-06-05 11:27:51 +02:00
for my $line (split(/\n/, $diff)) {
next unless $line =~ m/^+/;
$line =~ s/^\+//;
for my $patch (keys %patches) {
2014-06-25 16:10:08 +02:00
if (index($line, $patch) != -1) {
2014-06-05 11:27:51 +02:00
delete $patches{$patch};
}
}
}
}
}
# still some left?
if (%patches) {
$ret = 1;
for my $patch (keys %patches) {
# wording stolen from Raymond's declines :)
if ($patches{$patch} eq 'current') {
print "A patch ($patch) is being added without this addition being mentioned in the changelog.\n";
}
else {
print "A patch ($patch) is being deleted without this removal being mentioned in the changelog.\n";
}
}
}
2011-12-22 12:47:45 +01:00
}
2011-11-22 14:36:27 +01:00
my $odir = getcwd;
my $tmpdir = tempdir("obs-XXXXXXX", TMPDIR => 1, CLEANUP => 1);
2013-01-11 07:17:41 +01:00
chdir($dir) || die 'tempdir failed';
2011-12-22 12:47:45 +01:00
if (system("/usr/lib/obs/service/download_files","--enforceupstream", "yes", "--enforcelocal", "yes", "--outdir", $tmpdir)) {
print "Source URLs are not valid. Try \"osc service runall download_files\".\n";
$ret = 2;
2011-12-22 12:47:45 +01:00
}
2011-11-22 14:36:27 +01:00
chdir($odir);
for my $rpmlint (glob("$dir/*rpmlintrc")) {
2011-12-22 12:47:45 +01:00
open(RPMLINTRC, $rpmlint);
while (<RPMLINTRC>) {
if (m/^\s*setBadness/) {
print "For Factory submissions, you cannot use setBadness. Use filters in $rpmlint.\n";
$ret = 1;
}
2011-12-22 12:47:45 +01:00
}
}
exit($ret) if $ret;
# now check if the change is small enough to warrent a review-by-mail
exit(0) unless -d $old;
sub prepare_package($) {
my $files = shift;
unlink glob "*.changes"; # ignore changes
unlink glob "*.tar.*"; # we can't diff them anyway
2014-06-28 09:36:09 +02:00
unlink glob "*.zip";
# restore original spec file
for my $spec (glob("*.beforeurlstrip")) {
my $oldname = $spec;
$oldname =~ s/.beforeurlstrip//;
rename($spec, $oldname);
}
for my $spec (glob("*.spec")) {
open(SPEC, "/usr/lib/obs/service/format_spec_file.files/prepare_spec $spec | grep -v '^#' |");
my @lines = <SPEC>;
close(SPEC);
open(SPEC, ">", $spec);
print SPEC join('', @lines);
close(SPEC);
}
}
# move it back so we also diff the service file
if (-f "$dir/_service.bak") {
rename("$dir/_service.bak", "$dir/_service") || die "rename failed";
}
my %files;
chdir($old);
prepare_package(\%files);
chdir($odir);
chdir($dir);
prepare_package(\%files);
exit(0);