Merge the FiledVersionTagger into the base VersionTagger.

This allows the behaviour to be used in just about any tagger sub-class.

Behaviour will be triggered on the presence of the 'version_template'
section in tito.props.

Renamed config:
  version -> version_template (section)
  file -> destination_file

Separated the replacement of version and release, as caller may just
want one or the other. (it works fine if only one of the variables is
present in your template file) Release is more of an rpm concept so may
not always be wanted in this context.

Removed the notion of default template files, if you want to use this
you need to specify the configuration for it.

Added a functional test to make sure I keep it working.
This commit is contained in:
Devan Goodwin 2013-11-12 12:16:12 -04:00
parent f695047a5c
commit a3363cb93f
5 changed files with 150 additions and 114 deletions

View file

@ -303,6 +303,8 @@ class VersionTagger(ConfigObject):
"""
If this project has a setup.py, attempt to update it's version.
"""
self._update_version_file(new_version)
setup_file = os.path.join(self.full_project_dir, "setup.py")
if not os.path.exists(setup_file):
return
@ -537,6 +539,62 @@ class VersionTagger(ConfigObject):
suffix = self.config.get("globalconfig", "tag_suffix")
return "%s-%s%s" % (self.project_name, new_version, suffix)
def _update_version_file (self, new_version):
"""
land this new_version in the designated file
and stages that file for a git commit
"""
version_file = self._version_file_path()
if not version_file:
debug("No destination version file found, skipping.")
return
debug("Found version file to write: %s" % version_file)
version_file_template = self._version_file_template()
if version_file_template is None:
error_out("Version file specified but without corresponding template.")
t = Template(version_file_template)
f = open(version_file, 'w')
(new_ver, new_rel) = new_version.split('-')
f.write(t.safe_substitute(
version = new_ver,
release = new_rel))
f.close()
run_command("git add %s" % version_file)
def _version_file_template (self):
"""
"$version_name = $version"
or provide a configuration in tito.props to a file that is a
python string.Template conforming blob, like
[version]
template_file = ./rel-eng/templates/my_java_properties
see also, http://docs.python.org/2/library/string.html#template-strings
"""
if self.config.has_option("version_template", "template_file"):
f = open(os.path.join(self.git_root,
self.config.get("version_template", "template_file")), 'r')
buf = f.read()
f.close()
return buf
return None
def _version_file_path (self):
"""
standard ${project_name}-version.conf
or provide a configuration in tito.props, like
[version]
file = ./foo.rb
"""
if self.config.has_option("version_template", "destination_file"):
return self.config.get("version_template", "destination_file")
return None
class ReleaseTagger(VersionTagger):
"""
@ -580,92 +638,4 @@ class ForceVersionTagger(VersionTagger):
self._update_setup_py(new_version)
self._update_package_metadata(new_version)
class FiledVersionTagger(VersionTagger):
"""
Default VersionTagger,
but land a file with the version of tagged
"""
# override
def _update_setup_py (self, new_version):
"""
I would rather have hooked into _tag_release(), but there
would not be easy access to the +new_version+
So we'll hook onto one of the things called that receives that argument
"""
self._update_version_file(new_version)
super(FiledVersionTagger, self)._update_setup_py(new_version)
# added
def _update_version_file (self, new_version):
"""
land this new_version in the designated file
and stages that file for a git commit
"""
version_file = self._version_file_path()
print "writing version file out to %s" % version_file
t = Template(self._version_file_template())
f = open(version_file, 'w')
f.write(t.safe_substitute(
version_name = self._version_file_variable_name(),
version = new_version
))
f.close()
run_command("git add %s" % version_file)
def _version_file_template (self):
"""
"$version_name = $version"
or provide a configuration in tito.props to a file that is a
python string.Template conforming blob, like
[version]
template_file = ./rel-eng/templates/my_java_properties
see also, http://docs.python.org/2/library/string.html#template-strings
"""
if self.config.has_option("version", "template_file"):
f = open(self.config.get("version", "template_file"), 'r')
buf = f.read()
f.close()
return buf
return "$version_name = $version"
# added
def _version_file_variable_name (self):
"""
"TAGGED_VERSION"
or provide a configuration in tito.props, like
[version]
variable_name = MY_TAGGED_VERSION
"""
if self.config.has_option("version", "variable_name"):
return self.config.get("version", "variable_name")
return "TAGGED_VERSION"
# added
def _version_file_path (self):
"""
standard ${project_name}-version.conf
or provide a configuration in tito.props, like
[version]
file = ./foo.rb
"""
if self.config.has_option("version", "file"):
return self.config.get("version", "file")
return "%s-version.conf" % (self.project_name)
# added: helper for relative path of this package
def _path(self):
if self.relative_project_dir != None: return self.relative_project_dir
return self.git_root

View file

@ -128,6 +128,12 @@ class TitoGitTestFixture(unittest.TestCase):
index.add(['rel-eng/tito.props'])
index.commit('Setting offline.')
def write_file(self, path, contents):
print path
out_f = open(path, 'w')
out_f.write(contents)
out_f.close()
def create_project(self, pkg_name, pkg_dir=''):
"""
Create a test project at the given location, assumed to be within

View file

@ -18,25 +18,20 @@ NOTE: These tests require a makeshift git repository created in /tmp.
"""
import os
from os.path import join
import unittest
from tito.common import check_tag_exists, commands, run_command, \
from tito.common import run_command, \
get_latest_tagged_version, tag_exists_locally
from fixture import *
# A location where we can safely create a test git repository.
# WARNING: This location will be destroyed if present.
TEST_PKG_1 = 'titotestpkg'
TEST_PKG_1_DIR = "%s/" % TEST_PKG_1
TEST_PKG_2 = 'titotestpkg2'
TEST_PKG_2_DIR = "%s/" % TEST_PKG_2
TEST_PKG_3 = 'titotestpkg3'
TEST_PKG_3_DIR = "blah/whatever/%s/" % TEST_PKG_3
TEST_PKGS = [TEST_PKG_1, TEST_PKG_2, TEST_PKG_3]
@ -46,6 +41,23 @@ def release_bumped(initial_version, new_version):
new_release = new_version.split('-')[-1]
return new_release == str(int(first_release) + 1)
TEMPLATE_TAGGER_TITO_PROPS = """
[buildconfig]
tagger = tito.tagger.VersionTagger
builder = tito.builder.Builder
[version_template]
destination_file = version.txt
template_file = rel-eng/templates/version.rb
"""
VERSION_TEMPLATE_FILE = """
module Iteng
module Util
VERSION = "$version-$release"
end
end
"""
class MultiProjectTests(TitoGitTestFixture):
@ -70,6 +82,37 @@ class MultiProjectTests(TitoGitTestFixture):
index.add(['pkg2/tito.props'])
index.commit("Adding tito.props for pkg2.")
def test_template_version_tagger(self):
"""
Make sure the template is applied and results in the correct file
being included in the tag.
"""
pkg_dir = join(self.repo_dir, 'pkg3')
filename = join(pkg_dir, "tito.props")
self.write_file(filename, TEMPLATE_TAGGER_TITO_PROPS)
run_command('mkdir -p %s' % join(self.repo_dir, 'rel-eng/templates'))
self.write_file(join(self.repo_dir,
'rel-eng/templates/version.rb'), VERSION_TEMPLATE_FILE)
index = self.repo.index
index.add(['pkg3/tito.props'])
index.commit("Adding tito.props for pkg3.")
# Create another pkg3 tag and make sure we got a generated
# template file.
os.chdir(os.path.join(self.repo_dir, 'pkg3'))
tito('tag --debug --accept-auto-changelog')
new_ver = get_latest_tagged_version(TEST_PKG_3)
self.assertEquals("0.0.2-1", new_ver)
dest_file = os.path.join(self.repo_dir, 'pkg3', "version.txt")
self.assertTrue(os.path.exists(dest_file))
f = open(dest_file, 'r')
contents = f.read()
f.close()
self.assertTrue("VERSION = \"0.0.2-1\"" in contents)
def test_initial_tag_keep_version(self):
# Tags were actually created in setup code:
for pkg_name in TEST_PKGS:

View file

@ -14,12 +14,9 @@
import os
import shutil
import unittest
import git
from tito.common import *
from fixture import TitoGitTestFixture, TEST_SPEC, tito
from fixture import TitoGitTestFixture, tito
#TITO_REPO = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
PKG_NAME = "titotestpkg"

View file

@ -106,6 +106,26 @@ for example:
This will run "make zstreams" in BASE directory and will then use EUS-VARIANT
branch.
VERSION_TEMPLATE
----------------
Allows the user to write out a template file containing version and/or release and add it to git during the tagging process.
template_file::
Path to a file conforming to a Python string template. Path is relative to root of the entire git checkout, as this is likely to be stored in the top level rel-eng directory.
destination_file::
Specifies a file to write, relative to the directory for the package being tagged.
Example:
----
[version_template]
destination_file = version.txt
template_file = rel-eng/templates/version.rb
----
REQUIREMENTS
------------
tito::