mirror of
https://github.com/rpm-software-management/tito.git
synced 2025-02-23 12:12:47 +00:00
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:
parent
f695047a5c
commit
a3363cb93f
5 changed files with 150 additions and 114 deletions
|
@ -47,7 +47,7 @@ class VersionTagger(ConfigObject):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, global_config=None, keep_version=False, offline=False, user_config=None, pkg_config=None):
|
def __init__(self, global_config=None, keep_version=False, offline=False, user_config=None, pkg_config=None):
|
||||||
"""
|
"""
|
||||||
pkg_config - Package specific configuration.
|
pkg_config - Package specific configuration.
|
||||||
|
|
||||||
global_config - Global configuration from rel-eng/tito.props.
|
global_config - Global configuration from rel-eng/tito.props.
|
||||||
|
@ -303,6 +303,8 @@ class VersionTagger(ConfigObject):
|
||||||
"""
|
"""
|
||||||
If this project has a setup.py, attempt to update it's version.
|
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")
|
setup_file = os.path.join(self.full_project_dir, "setup.py")
|
||||||
if not os.path.exists(setup_file):
|
if not os.path.exists(setup_file):
|
||||||
return
|
return
|
||||||
|
@ -537,6 +539,62 @@ class VersionTagger(ConfigObject):
|
||||||
suffix = self.config.get("globalconfig", "tag_suffix")
|
suffix = self.config.get("globalconfig", "tag_suffix")
|
||||||
return "%s-%s%s" % (self.project_name, new_version, 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):
|
class ReleaseTagger(VersionTagger):
|
||||||
"""
|
"""
|
||||||
|
@ -580,92 +638,4 @@ class ForceVersionTagger(VersionTagger):
|
||||||
self._update_setup_py(new_version)
|
self._update_setup_py(new_version)
|
||||||
self._update_package_metadata(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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,12 @@ class TitoGitTestFixture(unittest.TestCase):
|
||||||
index.add(['rel-eng/tito.props'])
|
index.add(['rel-eng/tito.props'])
|
||||||
index.commit('Setting offline.')
|
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=''):
|
def create_project(self, pkg_name, pkg_dir=''):
|
||||||
"""
|
"""
|
||||||
Create a test project at the given location, assumed to be within
|
Create a test project at the given location, assumed to be within
|
||||||
|
|
|
@ -18,25 +18,20 @@ NOTE: These tests require a makeshift git repository created in /tmp.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
from os.path import join
|
||||||
|
|
||||||
import unittest
|
from tito.common import run_command, \
|
||||||
|
|
||||||
from tito.common import check_tag_exists, commands, run_command, \
|
|
||||||
get_latest_tagged_version, tag_exists_locally
|
get_latest_tagged_version, tag_exists_locally
|
||||||
from fixture import *
|
from fixture import *
|
||||||
|
|
||||||
|
|
||||||
# A location where we can safely create a test git repository.
|
# A location where we can safely create a test git repository.
|
||||||
# WARNING: This location will be destroyed if present.
|
# WARNING: This location will be destroyed if present.
|
||||||
|
|
||||||
TEST_PKG_1 = 'titotestpkg'
|
TEST_PKG_1 = 'titotestpkg'
|
||||||
TEST_PKG_1_DIR = "%s/" % TEST_PKG_1
|
|
||||||
|
|
||||||
TEST_PKG_2 = 'titotestpkg2'
|
TEST_PKG_2 = 'titotestpkg2'
|
||||||
TEST_PKG_2_DIR = "%s/" % TEST_PKG_2
|
|
||||||
|
|
||||||
TEST_PKG_3 = 'titotestpkg3'
|
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]
|
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]
|
new_release = new_version.split('-')[-1]
|
||||||
return new_release == str(int(first_release) + 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):
|
class MultiProjectTests(TitoGitTestFixture):
|
||||||
|
|
||||||
|
@ -70,6 +82,37 @@ class MultiProjectTests(TitoGitTestFixture):
|
||||||
index.add(['pkg2/tito.props'])
|
index.add(['pkg2/tito.props'])
|
||||||
index.commit("Adding tito.props for pkg2.")
|
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):
|
def test_initial_tag_keep_version(self):
|
||||||
# Tags were actually created in setup code:
|
# Tags were actually created in setup code:
|
||||||
for pkg_name in TEST_PKGS:
|
for pkg_name in TEST_PKGS:
|
||||||
|
|
|
@ -14,12 +14,9 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import unittest
|
|
||||||
|
|
||||||
import git
|
|
||||||
|
|
||||||
from tito.common import *
|
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__)))
|
#TITO_REPO = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
||||||
PKG_NAME = "titotestpkg"
|
PKG_NAME = "titotestpkg"
|
||||||
|
|
|
@ -21,9 +21,9 @@ Project settings can be stored in files:
|
||||||
|
|
||||||
`GITROOT/SOME/PACKAGE/tito.props`
|
`GITROOT/SOME/PACKAGE/tito.props`
|
||||||
|
|
||||||
The global rel-eng/tito.props is generally where settings are defined. For
|
The global rel-eng/tito.props is generally where settings are defined. For
|
||||||
some multi-project git repositories, individual packages can override these
|
some multi-project git repositories, individual packages can override these
|
||||||
settings by placing a tito.props in the project directory. (i.e. same location
|
settings by placing a tito.props in the project directory. (i.e. same location
|
||||||
as it's .spec file)
|
as it's .spec file)
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,19 +39,19 @@ default builder and tagger for you project. You can use following variables:
|
||||||
|
|
||||||
default_builder::
|
default_builder::
|
||||||
The fully qualified Builder class implementation to use.
|
The fully qualified Builder class implementation to use.
|
||||||
You can either specify builders shipped with tito(5) (see BUILDERS section
|
You can either specify builders shipped with tito(5) (see BUILDERS section
|
||||||
below), or a custom builder located within the directory your `lib_dir` option
|
below), or a custom builder located within the directory your `lib_dir` option
|
||||||
points to.
|
points to.
|
||||||
|
|
||||||
default_tagger::
|
default_tagger::
|
||||||
The fully qualified Tagger class implementation to use.
|
The fully qualified Tagger class implementation to use.
|
||||||
You can either specify builders shipped with tito(5) (see TAGGERS section
|
You can either specify builders shipped with tito(5) (see TAGGERS section
|
||||||
below), or a custom builder located within the directory your `lib_dir` option
|
below), or a custom builder located within the directory your `lib_dir` option
|
||||||
points to.
|
points to.
|
||||||
|
|
||||||
lib_dir::
|
lib_dir::
|
||||||
Optional property defining a directory to be added to the Python path when
|
Optional property defining a directory to be added to the Python path when
|
||||||
executing tito. Allows you to store custom implementations of Builder, Tagger,
|
executing tito. Allows you to store custom implementations of Builder, Tagger,
|
||||||
and Releaser.
|
and Releaser.
|
||||||
|
|
||||||
changelog_format::
|
changelog_format::
|
||||||
|
@ -70,9 +70,9 @@ If set to 0, it will not remove from cherry picked commits the part "(cherry
|
||||||
picked from commit ...)"
|
picked from commit ...)"
|
||||||
|
|
||||||
tag_suffix::
|
tag_suffix::
|
||||||
An optional specification of a suffix to append to all tags created by tito
|
An optional specification of a suffix to append to all tags created by tito
|
||||||
for this repo. Can be useful for situations where one git repository is
|
for this repo. Can be useful for situations where one git repository is
|
||||||
inheriting from another, but tags are created in both. The suffix will be an
|
inheriting from another, but tags are created in both. The suffix will be an
|
||||||
indicator as to which repo the tag originated in. (i.e. tag_suffix = -mysuffix)
|
indicator as to which repo the tag originated in. (i.e. tag_suffix = -mysuffix)
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,6 +106,26 @@ for example:
|
||||||
This will run "make zstreams" in BASE directory and will then use EUS-VARIANT
|
This will run "make zstreams" in BASE directory and will then use EUS-VARIANT
|
||||||
branch.
|
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
|
REQUIREMENTS
|
||||||
------------
|
------------
|
||||||
tito::
|
tito::
|
||||||
|
@ -114,11 +134,11 @@ If tito is older then specified version, it will refuse to continue.
|
||||||
BUILDCONFIG
|
BUILDCONFIG
|
||||||
-----------
|
-----------
|
||||||
builder::
|
builder::
|
||||||
This option is used in package specific tito.props only, and allows that
|
This option is used in package specific tito.props only, and allows that
|
||||||
project to override the default_builder defined in rel-eng/tito.props.
|
project to override the default_builder defined in rel-eng/tito.props.
|
||||||
|
|
||||||
tagger::
|
tagger::
|
||||||
This option is used in package specific tito.props only, and allows that
|
This option is used in package specific tito.props only, and allows that
|
||||||
project to override the default_tagger defined in rel-eng/tito.props.
|
project to override the default_tagger defined in rel-eng/tito.props.
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue