Parsing spec files and bumping their versions or releases is now in Python.

This commit is contained in:
Alex Wood 2011-10-13 11:28:44 -04:00
parent df594445e3
commit fd4af9ef85
6 changed files with 129 additions and 128 deletions

View file

@ -1,115 +0,0 @@
#!/usr/bin/perl
#
# Copyright (c) 2008-2009 Red Hat, Inc.
#
# This software is licensed to you under the GNU General Public License,
# version 2 (GPLv2). There is NO WARRANTY for this software, express or
# implied, including the implied warranties of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
# along with this software; if not, see
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
#
# Red Hat trademarks are not licensed under GPLv2. No permission is
# granted to use or replicate Red Hat trademarks that are incorporated
# in this software or its documentation.
use strict;
use warnings FATAL => 'all';
my $command = shift @ARGV;
if (not defined $command
or ($command ne 'bump-version' and $command ne 'bump-release' and $command ne 'zstream-release')) {
usage();
}
my $specfile = 0;
if (@ARGV and $ARGV[0] eq '--specfile') {
$specfile = 1;
shift @ARGV;
}
if (not @ARGV) {
usage();
}
sub usage {
die "usage: $0 { bump-version | bump-release | zstream-release } [--specfile] file [ files ... ]\n";
}
my $newfile;
my @content;
while (<ARGV>) {
if ($specfile) {
if ($command eq 'bump-version') {
s/^(version:\s*)(.+)/ $1 . bump_version($2) /ei;
s/^(release:\s*)(.+)/ $1 . reset_release($2) /ei;
} elsif ($command eq 'bump-release') {
s/^(release:\s*)(.+)/ $1 . bump_version($2) /ei;
} else { # zstream-release Release: 7%{?dist}
s/^(release:\s*)(.+)/ $1 . bump_zstream($2) /ei;
}
push @content, $_;
} else {
chomp;
my ($version, $release, $rest) = split /\s/, $_, 3;
if ($command eq 'bump-version') {
$version = bump_version($version);
$release = reset_release($release);
} else {
$release = bump_version($release);
}
if (defined $rest) {
$release .= ' ' . $rest;
}
push @content, "$version $release\n";
# slurp the rest of the file
while (not eof(ARGV)) {
push @content, scalar <ARGV>;
}
}
} continue {
if (eof(ARGV)) {
local *OUT;
undef $newfile;
if ($ARGV eq '-') {
*OUT = \*STDOUT;
} else {
$newfile = $ARGV . ".$$";
open OUT, "> $newfile" or die "Error writing [$newfile]: $!\n";
}
print OUT @content;
if (defined $newfile) {
close OUT;
rename $newfile, $ARGV;
}
}
}
sub bump_version {
local $_ = shift;
no warnings 'uninitialized';
s/^(.+\.)?([0-9]+)(\.|%|$)/$1 . ($2 + 1) . $3/e;
$_;
}
sub bump_zstream {
my $version = shift;
# if we do not have zstream, create .0 and then bump the version
$version =~ s/^(.*)(%{\?dist})$/$1$2.0/i;
return bump_version($version);
}
sub reset_release {
local $_ = shift;
s/(^|\.)([.0-9]+)(\.|%|$)/${1}1$3/;
$_;
}
__END__ {
if (defined $newfile and -f $newfile) {
unlink $newfile;
}
}
1;

View file

@ -37,7 +37,6 @@ setup(
# non-python scripts go here
scripts = [
'bin/tito',
'bin/bump-version.pl',
'bin/tar-fixup-stamp-comment.pl',
'bin/test-setup-specfile.pl',
'bin/generate-patches.pl'

View file

@ -478,4 +478,26 @@ def get_class_by_name(name):
mod = __import__(module, globals(), locals(), [class_name])
return getattr(mod, class_name)
def increase_version(version_string):
regex = re.compile(r"^(%.*)|(.+\.)?([0-9]+)(\..*|%.*|$)")
match = re.match(regex, version_string)
if match:
matches = list(match.groups())
# Increment the number in the third match group, if there is one
if matches[2]:
matches[2] = str(int(matches[2]) + 1)
# Join everything back up, skipping match groups with None
return "".join([x for x in matches if x])
# If no match, return an empty string
return ""
def reset_release(release_string):
regex = re.compile(r"(^|\.)([.0-9]+)(\.|%|$)")
return regex.sub(r"\g<1>1\g<3>", release_string)
def increase_zstream(release_string):
# If we do not have zstream, create .0 and then bump the version
regex = re.compile(r"^(.*%{\?dist})$")
bumped_string = regex.sub(r"\g<1>.0", release_string)
return increase_version(bumped_string)

View file

@ -29,7 +29,8 @@ from time import strftime
from tito.common import (debug, error_out, run_command, find_git_root,
find_spec_file, get_project_name, get_latest_tagged_version,
get_script_path, get_spec_version_and_release, replace_version,
tag_exists_locally, tag_exists_remotely, head_points_to_tag, undo_tag)
tag_exists_locally, tag_exists_remotely, head_points_to_tag, undo_tag,
increase_version, reset_release, increase_zstream)
from tito.exception import TitoException
@ -314,18 +315,48 @@ class VersionTagger(object):
old_version = get_latest_tagged_version(self.project_name)
if old_version == None:
old_version = "untagged"
# TODO: Do this here instead of calling out to an external Perl script:
if not self.keep_version:
bump_type = "bump-version"
if release:
bump_type = "bump-release"
elif zstream:
bump_type = "bump-zstream"
version_regex = re.compile("^(version:\s*)(.+)$", re.IGNORECASE)
release_regex = re.compile("^(release:\s*)(.+)$", re.IGNORECASE)
script_path = get_script_path("bump-version.pl")
cmd = "%s %s --specfile %s" % \
(script_path, bump_type, self.spec_file)
run_command(cmd)
in_f = open(self.spec_file, 'r')
out_f = open(self.spec_file + ".new", 'w')
for line in in_f.readlines():
if release:
match = re.match(release_regex, line)
if match:
line = "".join((match.group(1)
, increase_version(match.group(2))
, "\n"
))
elif zstream:
match = re.match(release_regex, line)
if match:
line = "".join((match.group(1)
, increase_zstream(match.group(2))
, "\n"
))
else:
match = re.match(version_regex, line)
if match:
line = "".join((match.group(1)
, increase_version(match.group(2))
, "\n"
))
match = re.match(release_regex, line)
if match:
line = "".join((match.group(1)
, reset_release(match.group(2))
, "\n"
))
out_f.write(line)
in_f.close()
out_f.close()
shutil.move(self.spec_file + ".new", self.spec_file)
new_version = self._get_spec_version_and_release()
if new_version.strip() == "":

View file

@ -74,6 +74,71 @@ class CommonTests(unittest.TestCase):
line = "this isn't a version fool.\n"
self.assertEquals(line, replace_version(line, "2.5.3"))
class VersionMathTest(unittest.TestCase):
def test_increase_version_minor(self):
line = "1.0.0"
expected="1.0.1"
self.assertEquals(expected, increase_version(line))
def test_increase_version_major(self):
line = "1.0"
expected="1.1"
self.assertEquals(expected, increase_version(line))
def test_increase_release(self):
line = "1"
expected="2"
self.assertEquals(expected, increase_version(line))
def test_increase_versionless(self):
line = "%{app_version}"
expected="%{app_version}"
self.assertEquals(expected, increase_version(line))
def test_increase_release_with_rpm_cruft(self):
line = "1%{?dist}"
expected="2%{?dist}"
self.assertEquals(expected, increase_version(line))
def test_increase_release_with_zstream(self):
line = "1%{?dist}.1"
expected="1%{?dist}.2"
self.assertEquals(expected, increase_version(line))
def test_unknown_version(self):
line = "somethingstrange"
expected=""
self.assertEquals(expected, increase_version(line))
def test_empty_string(self):
line = ""
expected=""
self.assertEquals(expected, increase_version(line))
def test_increase_zstream(self):
line = "1%{?dist}"
expected="1%{?dist}.1"
self.assertEquals(expected, increase_zstream(line))
def test_increase_zstream_already_appended(self):
line = "1%{?dist}.1"
expected="1%{?dist}.2"
self.assertEquals(expected, increase_zstream(line))
def test_reset_release_with_rpm_cruft(self):
line = "2%{?dist}"
expected="1%{?dist}"
self.assertEquals(expected, reset_release(line))
def test_reset_release_with_more_rpm_cruft(self):
line = "2.beta"
expected="1.beta"
self.assertEquals(expected, reset_release(line))
def test_reset_release(self):
line = "2"
expected="1"
self.assertEquals(expected, reset_release(line))
class ExtractBugzillasTest(unittest.TestCase):

View file

@ -64,7 +64,6 @@ rm -rf $RPM_BUILD_ROOT
%doc %{_mandir}/man5/build.py.props.5.gz
%doc %{_mandir}/man8/tito.8.gz
%{_bindir}/tito
%{_bindir}/bump-version.pl
%{_bindir}/tar-fixup-stamp-comment.pl
%{_bindir}/test-setup-specfile.pl
%{_bindir}/generate-patches.pl