Revision 866bb9c1
b/devflow/autopkg.py | ||
---|---|---|
37 | 37 |
from sh import mktemp, cd, rm, git_dch, python |
38 | 38 |
from optparse import OptionParser |
39 | 39 |
|
40 |
from devflow.versioning import (get_python_version, |
|
41 |
debian_version_from_python_version) |
|
42 |
|
|
40 | 43 |
try: |
41 | 44 |
from colors import red, green |
42 | 45 |
except ImportError: |
... | ... | |
55 | 58 |
|
56 | 59 |
def main(): |
57 | 60 |
from devflow.version import __version__ |
58 |
|
|
59 | 61 |
parser = OptionParser(usage="usage: %prog [options] mode", |
60 |
version="%prog - devflow %s" % __version__)
|
|
62 |
version="devflow %s" % __version__) |
|
61 | 63 |
parser.add_option("-k", "--keep-repo", |
62 | 64 |
action="store_true", |
63 | 65 |
dest="keep_repo", |
... | ... | |
79 | 81 |
|
80 | 82 |
(options, args) = parser.parse_args() |
81 | 83 |
|
82 |
mode = args[0] |
|
84 |
try: |
|
85 |
mode = args[0] |
|
86 |
except IndexError: |
|
87 |
raise ValueError("Mode argument is mandatory. Usage: %s" |
|
88 |
% parser.usage) |
|
83 | 89 |
if mode not in AVAILABLE_MODES: |
84 | 90 |
raise ValueError(red("Invalid argument! Mode must be one: %s" |
85 | 91 |
% ", ".join(AVAILABLE_MODES))) |
... | ... | |
118 | 124 |
repo.references[debian_branch] |
119 | 125 |
except IndexError: |
120 | 126 |
# Branch does not exist |
121 |
# FIXME: remove hard-coded strings.. |
|
122 |
if branch == "debian": |
|
123 |
repo.git.branch("--track", debian_branch, "origin/debian") |
|
124 |
else: |
|
125 |
repo.git.branch("--track", debian_branch, "origin/debian-develop") |
|
127 |
repo.git.branch("--track", debian_branch, "origin/" + debian_branch) |
|
126 | 128 |
|
127 | 129 |
repo.git.checkout(debian_branch) |
128 | 130 |
print_green("Changed to branch '%s'" % debian_branch) |
... | ... | |
131 | 133 |
print_green("Merged branch '%s' into '%s'" % (branch, debian_branch)) |
132 | 134 |
|
133 | 135 |
cd(repo_dir) |
134 |
version = python(repo_dir + "/devflow/version.py", "debian").strip() |
|
135 |
print_green("The new debian version will be: '%s'" % version) |
|
136 |
python_version = get_python_version() |
|
137 |
debian_version = debian_version_from_python_version(python_version) |
|
138 |
print_green("The new debian version will be: '%s'" % debian_version) |
|
136 | 139 |
|
137 | 140 |
dch = git_dch("--debian-branch=%s" % debian_branch, |
138 | 141 |
"--git-author", |
139 | 142 |
"--ignore-regex=\".*\"", |
140 | 143 |
"--multimaint-merge", |
141 | 144 |
"--since=HEAD", |
142 |
"--new-version=%s" % version) |
|
145 |
"--new-version=%s" % debian_version)
|
|
143 | 146 |
print_green("Successfully ran '%s'" % " ".join(dch.cmd)) |
144 | 147 |
|
145 |
os.system("vim debian/changelog") |
|
146 | 148 |
repo.git.add("debian/changelog") |
147 | 149 |
|
148 | 150 |
if mode == "release": |
151 |
os.system("vim debian/changelog") |
|
152 |
repo.git.add("debian/changelog") |
|
149 | 153 |
repo.git.commit("-s", "-a", "-m", "Bump new upstream version") |
150 |
if branch == "master": |
|
151 |
repo.git.tag("debian/" + version) |
|
154 |
python_tag = python_version |
|
155 |
debian_tag = "debian/" + python_tag |
|
156 |
repo.git.tag(debian_tag) |
|
157 |
repo.git.tag(python_tag, branch) |
|
152 | 158 |
|
153 | 159 |
for package in PACKAGES: |
154 | 160 |
# python setup.py should run in its directory |
155 | 161 |
cd(package) |
156 | 162 |
package_dir = repo_dir + "/" + package |
157 | 163 |
res = python(package_dir + "/setup.py", "sdist", _out=sys.stdout) |
158 |
cd("../") |
|
159 | 164 |
print res.stdout |
165 |
if package != ".": |
|
166 |
cd("../") |
|
160 | 167 |
|
161 | 168 |
# Add version.py files to repo |
162 | 169 |
os.system("grep \"__version_vcs\" -r . -l -I | xargs git add -f") |
... | ... | |
167 | 174 |
print_green("Created directory '%s' to store the .deb files." % |
168 | 175 |
build_dir) |
169 | 176 |
|
177 |
cd(repo_dir) |
|
170 | 178 |
os.system("git-buildpackage --git-export-dir=%s --git-upstream-branch=%s" |
171 | 179 |
" --git-debian-branch=%s --git-export=INDEX --git-ignore-new -sa" |
172 | 180 |
% (build_dir, branch, debian_branch)) |
... | ... | |
178 | 186 |
print_green("Repository dir '%s'" % repo_dir) |
179 | 187 |
|
180 | 188 |
print_green("Completed. Version '%s', build area: '%s'" |
181 |
% (version, build_dir)) |
|
189 |
% (debian_version, build_dir)) |
|
190 |
|
|
191 |
if mode == "release": |
|
192 |
TAG_MSG = "Tagged branch %s with tag %s\n" |
|
193 |
print_green(TAG_MSG % (branch, python_tag)) |
|
194 |
print_green(TAG_MSG % (debian_branch, debian_tag)) |
|
195 |
|
|
196 |
UPDATE_MSG = "To update repository %s, go to %s, and run the"\ |
|
197 |
" following commands:\n" + "git_push origin %s\n" * 3 |
|
198 |
|
|
199 |
origin_url = repo.remotes['origin'].url |
|
200 |
remote_url = original_repo.remotes['origin'].url |
|
201 |
|
|
202 |
print_green(UPDATE_MSG % (origin_url, repo_dir, debian_branch, |
|
203 |
debian_tag, python_tag)) |
|
204 |
print_green(UPDATE_MSG % (remote_url, original_repo.working_dir, |
|
205 |
debian_branch, debian_tag, python_tag)) |
|
182 | 206 |
|
183 | 207 |
|
184 | 208 |
if __name__ == "__main__": |
/dev/null | ||
---|---|---|
1 |
#!/usr/bin/env python |
|
2 |
# |
|
3 |
# Copyright 2012 GRNET S.A. All rights reserved. |
|
4 |
# |
|
5 |
# Redistribution and use in source and binary forms, with or |
|
6 |
# without modification, are permitted provided that the following |
|
7 |
# conditions are met: |
|
8 |
# |
|
9 |
# 1. Redistributions of source code must retain the above |
|
10 |
# copyright notice, this list of conditions and the following |
|
11 |
# disclaimer. |
|
12 |
# |
|
13 |
# 2. Redistributions in binary form must reproduce the above |
|
14 |
# copyright notice, this list of conditions and the following |
|
15 |
# disclaimer in the documentation and/or other materials |
|
16 |
# provided with the distribution. |
|
17 |
# |
|
18 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
19 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
20 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
21 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
22 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
23 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
24 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
25 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
26 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
27 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
28 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
29 |
# POSSIBILITY OF SUCH DAMAGE. |
|
30 |
# |
|
31 |
# The views and conclusions contained in the software and |
|
32 |
# documentation are those of the authors and should not be |
|
33 |
# interpreted as representing official policies, either expressed |
|
34 |
# or implied, of GRNET S.A. |
|
35 |
# |
|
36 |
# |
|
37 |
|
|
38 |
"""Unit Tests for devflow.versioning |
|
39 |
|
|
40 |
Provides unit tests for module devflow.versioning, |
|
41 |
for automatic generation of version strings. |
|
42 |
|
|
43 |
""" |
|
44 |
|
|
45 |
import os |
|
46 |
import unittest |
|
47 |
from pkg_resources import parse_version |
|
48 |
from versioning import debian_version_from_python_version |
|
49 |
|
|
50 |
|
|
51 |
class DebianVersionObject(object): |
|
52 |
"""Object representing a Debian Version.""" |
|
53 |
def __init__(self, pyver): |
|
54 |
self.version = debian_version_from_python_version(pyver) |
|
55 |
|
|
56 |
def __str__(self): |
|
57 |
return self.version |
|
58 |
|
|
59 |
|
|
60 |
def debian_compare_versions(a, op, b): |
|
61 |
i = os.system("dpkg --compare-versions %s %s %s" % (a, op, b)) |
|
62 |
return i == 0 |
|
63 |
|
|
64 |
# Set ordering between DebianVersionObject objects, by adding |
|
65 |
# debian_compare_versions |
|
66 |
for op in ["lt", "le", "eq", "ne", "gt", "ge"]: |
|
67 |
def gen(op): |
|
68 |
def operator_func(self, other): |
|
69 |
return debian_compare_versions(self.version, op, other.version) |
|
70 |
return operator_func |
|
71 |
setattr(DebianVersionObject, "__%s__" % op, gen(op)) |
|
72 |
|
|
73 |
|
|
74 |
def _random_commit(): |
|
75 |
import random |
|
76 |
import string |
|
77 |
return "".join(random.choice(string.hexdigits) for n in xrange(8)).lower() |
|
78 |
|
|
79 |
|
|
80 |
# Add a random commit number at the end of snapshot versions |
|
81 |
def version_with_commit(parse_func, v): |
|
82 |
if "_" in v: |
|
83 |
return parse_func(v + "_" + _random_commit()) |
|
84 |
else: |
|
85 |
return parse_func(v) |
|
86 |
|
|
87 |
V = lambda v: version_with_commit(parse_version, v) |
|
88 |
D = lambda v: version_with_commit(DebianVersionObject, v) |
|
89 |
|
|
90 |
|
|
91 |
class TestVersionFunctions(unittest.TestCase): |
|
92 |
def setUp(self): |
|
93 |
self.version_orderings = ( |
|
94 |
("0.14next", ">", "0.14"), |
|
95 |
("0.14next", ">", "0.14rc7"), |
|
96 |
("0.14next", "<", "0.14.1"), |
|
97 |
("0.14rc6", "<", "0.14"), |
|
98 |
("0.14.2rc6", ">", "0.14.1"), |
|
99 |
("0.14next_150", "<", "0.14next"), |
|
100 |
("0.14.1next_150", "<", "0.14.1next"), |
|
101 |
("0.14.1_149", "<", "0.14.1"), |
|
102 |
("0.14.1_149", "<", "0.14.1_150"), |
|
103 |
("0.13next_102", "<", "0.13next"), |
|
104 |
("0.13next", "<", "0.14rc5_120"), |
|
105 |
("0.14rc3_120", "<", "0.14rc3"), |
|
106 |
# The following test fails, but versioning.python_version |
|
107 |
# will never try to produce such a version: |
|
108 |
# ("0.14rc3", "<", "0.14_1"), |
|
109 |
("0.14_120", "<", "0.14"), |
|
110 |
("0.14", "<", "0.14next_20"), |
|
111 |
("0.14next_20", "<", "0.14next"), |
|
112 |
) |
|
113 |
|
|
114 |
def test_python_versions(self): |
|
115 |
for a, op, b in self.version_orderings: |
|
116 |
res = compare(V, a, op, b) |
|
117 |
self.assertTrue(res, "Python version: %s %s %s" |
|
118 |
" is not True" % (a, op, b)) |
|
119 |
|
|
120 |
def test_debian_versions(self): |
|
121 |
for a, op, b in self.version_orderings: |
|
122 |
res = compare(D, a, op, b) |
|
123 |
self.assertTrue(res, "Debian version %s %s %s" |
|
124 |
" is not True" % (a, op, b)) |
|
125 |
|
|
126 |
|
|
127 |
def compare(function, a, op, b): |
|
128 |
import operator |
|
129 |
str_to_op = {"<": operator.lt, |
|
130 |
"<=": operator.le, |
|
131 |
"==": operator.eq, |
|
132 |
">": operator.gt, |
|
133 |
">=": operator.ge} |
|
134 |
try: |
|
135 |
return str_to_op[op](function(a), function(b)) |
|
136 |
except KeyError: |
|
137 |
raise ValueError("Unknown operator '%s'" % op) |
|
138 |
|
|
139 |
if __name__ == '__main__': |
|
140 |
unittest.main() |
b/devflow/versioning.py | ||
---|---|---|
83 | 83 |
elif len(parents) == 2: |
84 | 84 |
if cur_br_name.startswith("debian-") or cur_br_name == "debian": |
85 | 85 |
pr1, pr2 = parents |
86 |
return short_id(pr1) + "~" + short_id(pr2)
|
|
86 |
return short_id(pr1) + "-" + short_id(pr2)
|
|
87 | 87 |
else: |
88 | 88 |
return short_id(commit) |
89 | 89 |
else: |
... | ... | |
107 | 107 |
branch = repo.head.reference |
108 | 108 |
revid = get_commit_id(branch.commit, branch) |
109 | 109 |
revno = len(list(repo.iter_commits())) |
110 |
desc = repo.git.describe("--tags") |
|
111 | 110 |
toplevel = repo.working_dir |
112 | 111 |
except git.InvalidGitRepositoryError: |
113 | 112 |
log.error("Could not retrieve git information. " + |
... | ... | |
115 | 114 |
return None |
116 | 115 |
|
117 | 116 |
info = namedtuple("vcs_info", ["branch", "revid", "revno", |
118 |
"desc", "toplevel"])
|
|
117 |
"toplevel"]) |
|
119 | 118 |
|
120 |
return info(branch=branch.name, revid=revid, revno=revno, desc=desc,
|
|
119 |
return info(branch=branch.name, revid=revid, revno=revno, |
|
121 | 120 |
toplevel=toplevel) |
122 | 121 |
|
123 | 122 |
|
... | ... | |
137 | 136 |
try: |
138 | 137 |
mode = os.environ["GITFLOW_BUILD_MODE"] |
139 | 138 |
assert mode == "release" or mode == "snapshot" |
140 |
except (KeyError, AssertionError): |
|
141 |
raise ValueError("GITFLOW_BUILD_MODE environment variable must be " |
|
142 |
"'release' or 'snapshot'") |
|
139 |
except KeyError: |
|
140 |
raise ValueError("GITFLOW_BUILD_MODE environment variable is not set." |
|
141 |
" Set this variable to 'release' or 'snapshot'") |
|
142 |
except AssertionError: |
|
143 |
raise ValueError("GITFLOW_BUILD_MODE environment variable must be" |
|
144 |
" 'release' or 'snapshot'") |
|
143 | 145 |
return mode |
144 | 146 |
|
145 | 147 |
|
... | ... | |
390 | 392 |
return pyver.replace("_", "~").replace("rc", "~rc") + "-1" |
391 | 393 |
|
392 | 394 |
|
395 |
def get_python_version(): |
|
396 |
v = vcs_info() |
|
397 |
b = base_version(v) |
|
398 |
mode = build_mode() |
|
399 |
return python_version(b, v, mode) |
|
400 |
|
|
401 |
|
|
393 | 402 |
def debian_version(base_version, vcs_info, mode): |
394 | 403 |
p = python_version(base_version, vcs_info, mode) |
395 | 404 |
return debian_version_from_python_version(p) |
396 | 405 |
|
397 | 406 |
|
407 |
def get_debian_version(): |
|
408 |
v = vcs_info() |
|
409 |
b = base_version(v) |
|
410 |
mode = build_mode() |
|
411 |
return debian_version(b, v, mode) |
|
412 |
|
|
413 |
|
|
398 | 414 |
def user_info(): |
399 | 415 |
import getpass |
400 | 416 |
import socket |
... | ... | |
410 | 426 |
|
411 | 427 |
""" |
412 | 428 |
|
429 |
paths = [root] + module.split(".") + ["%s.py" % name] |
|
430 |
module_filename = os.path.join(*paths) |
|
431 |
|
|
413 | 432 |
v = vcs_info() |
414 | 433 |
if not v: |
415 | 434 |
# Return early if not in development environment |
435 |
log.error("Can not compute version outside of a git repository." |
|
436 |
" Will not update %s version file" % module_filename) |
|
416 | 437 |
return |
417 | 438 |
b = base_version(v) |
418 | 439 |
mode = build_mode() |
419 |
paths = [root] + module.split(".") + ["%s.py" % name] |
|
420 |
module_filename = os.path.join(*paths) |
|
421 | 440 |
version = python_version(b, v, mode) |
422 | 441 |
content = """ |
423 | 442 |
__version__ = "%(version)s" |
424 | 443 |
__version_info__ = %(version_info)s |
425 | 444 |
__version_vcs_info__ = %(vcs_info)s |
426 | 445 |
__version_user_info__ = "%(user_info)s" |
427 |
""" % dict(version=version, version_info=version.split("."),
|
|
446 |
""" % dict(version=version, version_info=version.split("."), |
|
428 | 447 |
vcs_info=pprint.PrettyPrinter().pformat(dict(v._asdict())), |
429 | 448 |
user_info=user_info()) |
430 | 449 |
|
431 | 450 |
module_file = file(module_filename, "w+") |
432 | 451 |
module_file.write(content) |
433 | 452 |
module_file.close() |
453 |
return module_filename |
|
434 | 454 |
|
435 | 455 |
|
436 |
if __name__ == "__main__":
|
|
456 |
def main():
|
|
437 | 457 |
v = vcs_info() |
438 | 458 |
b = base_version(v) |
439 | 459 |
mode = build_mode() |
... | ... | |
448 | 468 |
print python_version(b, v, mode) |
449 | 469 |
elif arg == "debian": |
450 | 470 |
print debian_version(b, v, mode) |
471 |
|
|
472 |
if __name__ == "__main__": |
|
473 |
sys.exit(main()) |
b/setup.py | ||
---|---|---|
1 |
# Copyright 2011 GRNET S.A. All rights reserved.
|
|
1 |
# Copyright 2012 GRNET S.A. All rights reserved.
|
|
2 | 2 |
# |
3 | 3 |
# Redistribution and use in source and binary forms, with or |
4 | 4 |
# without modification, are permitted provided that the following |
... | ... | |
31 | 31 |
# interpreted as representing official policies, either expressed |
32 | 32 |
# or implied, of GRNET S.A. |
33 | 33 |
# |
34 |
|
|
35 | 34 |
import distribute_setup |
36 | 35 |
distribute_setup.use_setuptools() |
37 | 36 |
|
... | ... | |
43 | 42 |
from setuptools import setup, find_packages |
44 | 43 |
|
45 | 44 |
HERE = os.path.abspath(os.path.normpath(os.path.dirname(__file__))) |
46 |
|
|
47 | 45 |
try: |
46 |
from devflow import versioning |
|
48 | 47 |
# use devflow to update the version file |
49 |
from devflow.versioning import update_version |
|
50 |
update_version('devflow', 'version', HERE) |
|
48 |
versioning.update_version('devflow', 'version', HERE) |
|
51 | 49 |
except ImportError: |
52 |
raise RuntimeError("devflow is a build dependency") |
|
50 |
version_fpath = os.path.join(HERE, 'devflow', 'version.py') |
|
51 |
sys.stdout.write("WARNING: Can not update version because `devflow` is" |
|
52 |
" not installed. Please make sure to manually" |
|
53 |
" update version file %s" % version_fpath) |
|
53 | 54 |
|
54 | 55 |
from devflow.version import __version__ |
55 | 56 |
|
... | ... | |
67 | 68 |
|
68 | 69 |
# Package requirements |
69 | 70 |
INSTALL_REQUIRES = [ |
70 |
'git' |
|
71 |
'gitpython'
|
|
71 | 72 |
] |
72 | 73 |
|
73 | 74 |
# Provided as an attribute, so you can append to these instead |
... | ... | |
141 | 142 |
new_package = package + "." + name |
142 | 143 |
stack.append((fn, "", new_package, False)) |
143 | 144 |
else: |
144 |
stack.append((fn, prefix + name + "/", package, only_in_packages)) |
|
145 |
stack.append((fn, prefix + name + "/", package, |
|
146 |
only_in_packages)) |
|
145 | 147 |
elif package or not only_in_packages: |
146 | 148 |
# is a file |
147 | 149 |
bad_name = False |
... | ... | |
156 | 158 |
break |
157 | 159 |
if bad_name: |
158 | 160 |
continue |
159 |
out.setdefault(package, []).append(prefix+name)
|
|
161 |
out.setdefault(package, []).append(prefix + name)
|
|
160 | 162 |
return out |
161 | 163 |
|
162 | 164 |
setup( |
163 |
name = 'devflow',
|
|
164 |
version = VERSION,
|
|
165 |
license = 'BSD',
|
|
166 |
url = 'http://www.synnefo.ogr/',
|
|
167 |
description = SHORT_DESCRIPTION,
|
|
168 |
long_description=README + '\n\n' + CHANGES,
|
|
169 |
classifiers = CLASSIFIERS,
|
|
170 |
|
|
171 |
author = 'GRNET dev team',
|
|
172 |
author_email = 'okeanos-dev@lists.grnet.gr',
|
|
173 |
maintainer = 'GRNET dev team',
|
|
174 |
maintainer_email = 'okeanos-dev@lists.grnet.gr',
|
|
175 |
|
|
176 |
packages = PACKAGES,
|
|
177 |
package_dir= {'': PACKAGES_ROOT},
|
|
178 |
include_package_data = True,
|
|
179 |
package_data = find_package_data('.'),
|
|
180 |
zip_safe = False,
|
|
181 |
|
|
182 |
install_requires = INSTALL_REQUIRES,
|
|
183 |
|
|
184 |
entry_points = {
|
|
165 |
name='devflow',
|
|
166 |
version=VERSION,
|
|
167 |
license='BSD',
|
|
168 |
url='http://www.synnefo.ogr/',
|
|
169 |
description=SHORT_DESCRIPTION,
|
|
170 |
long_description=README + '\n\n' + CHANGES, |
|
171 |
classifiers=CLASSIFIERS,
|
|
172 |
|
|
173 |
author='GRNET dev team',
|
|
174 |
author_email='okeanos-dev@lists.grnet.gr',
|
|
175 |
maintainer='GRNET dev team',
|
|
176 |
maintainer_email='okeanos-dev@lists.grnet.gr',
|
|
177 |
|
|
178 |
packages=PACKAGES,
|
|
179 |
package_dir={'': PACKAGES_ROOT}, |
|
180 |
include_package_data=True,
|
|
181 |
package_data=find_package_data('.'),
|
|
182 |
zip_safe=False,
|
|
183 |
|
|
184 |
install_requires=INSTALL_REQUIRES,
|
|
185 |
|
|
186 |
entry_points={
|
|
185 | 187 |
'console_scripts': [ |
186 |
'devflow-version = devflow.versioning:main', |
|
188 |
'devflow-version=devflow.versioning:main', |
|
189 |
'devflow-autopkg=devflow.autopkg:main', |
|
187 | 190 |
], |
188 | 191 |
}, |
189 | 192 |
) |
b/tests/test_versioning.py | ||
---|---|---|
1 |
#!/usr/bin/env python |
|
2 |
# |
|
3 |
# Copyright 2012 GRNET S.A. All rights reserved. |
|
4 |
# |
|
5 |
# Redistribution and use in source and binary forms, with or |
|
6 |
# without modification, are permitted provided that the following |
|
7 |
# conditions are met: |
|
8 |
# |
|
9 |
# 1. Redistributions of source code must retain the above |
|
10 |
# copyright notice, this list of conditions and the following |
|
11 |
# disclaimer. |
|
12 |
# |
|
13 |
# 2. Redistributions in binary form must reproduce the above |
|
14 |
# copyright notice, this list of conditions and the following |
|
15 |
# disclaimer in the documentation and/or other materials |
|
16 |
# provided with the distribution. |
|
17 |
# |
|
18 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
19 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
20 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
21 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
22 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
23 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
24 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
25 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
26 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
27 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
28 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
29 |
# POSSIBILITY OF SUCH DAMAGE. |
|
30 |
# |
|
31 |
# The views and conclusions contained in the software and |
|
32 |
# documentation are those of the authors and should not be |
|
33 |
# interpreted as representing official policies, either expressed |
|
34 |
# or implied, of GRNET S.A. |
|
35 |
# |
|
36 |
# |
|
37 |
|
|
38 |
"""Unit Tests for devflow.versioning |
|
39 |
|
|
40 |
Provides unit tests for module devflow.versioning, |
|
41 |
for automatic generation of version strings. |
|
42 |
|
|
43 |
""" |
|
44 |
|
|
45 |
import os |
|
46 |
import unittest |
|
47 |
from pkg_resources import parse_version |
|
48 |
from devflow.versioning import debian_version_from_python_version |
|
49 |
|
|
50 |
|
|
51 |
class DebianVersionObject(object): |
|
52 |
"""Object representing a Debian Version.""" |
|
53 |
def __init__(self, pyver): |
|
54 |
self.version = debian_version_from_python_version(pyver) |
|
55 |
|
|
56 |
def __str__(self): |
|
57 |
return self.version |
|
58 |
|
|
59 |
|
|
60 |
def debian_compare_versions(a, op, b): |
|
61 |
i = os.system("dpkg --compare-versions %s %s %s" % (a, op, b)) |
|
62 |
return i == 0 |
|
63 |
|
|
64 |
# Set ordering between DebianVersionObject objects, by adding |
|
65 |
# debian_compare_versions |
|
66 |
for op in ["lt", "le", "eq", "ne", "gt", "ge"]: |
|
67 |
def gen(op): |
|
68 |
def operator_func(self, other): |
|
69 |
return debian_compare_versions(self.version, op, other.version) |
|
70 |
return operator_func |
|
71 |
setattr(DebianVersionObject, "__%s__" % op, gen(op)) |
|
72 |
|
|
73 |
|
|
74 |
def _random_commit(): |
|
75 |
import random |
|
76 |
import string |
|
77 |
return "".join(random.choice(string.hexdigits) for n in xrange(8)).lower() |
|
78 |
|
|
79 |
|
|
80 |
# Add a random commit number at the end of snapshot versions |
|
81 |
def version_with_commit(parse_func, v): |
|
82 |
if "_" in v: |
|
83 |
return parse_func(v + "_" + _random_commit()) |
|
84 |
else: |
|
85 |
return parse_func(v) |
|
86 |
|
|
87 |
V = lambda v: version_with_commit(parse_version, v) |
|
88 |
D = lambda v: version_with_commit(DebianVersionObject, v) |
|
89 |
|
|
90 |
|
|
91 |
class TestVersionFunctions(unittest.TestCase): |
|
92 |
def setUp(self): |
|
93 |
self.version_orderings = ( |
|
94 |
("0.14next", ">", "0.14"), |
|
95 |
("0.14next", ">", "0.14rc7"), |
|
96 |
("0.14next", "<", "0.14.1"), |
|
97 |
("0.14rc6", "<", "0.14"), |
|
98 |
("0.14.2rc6", ">", "0.14.1"), |
|
99 |
("0.14next_150", "<", "0.14next"), |
|
100 |
("0.14.1next_150", "<", "0.14.1next"), |
|
101 |
("0.14.1_149", "<", "0.14.1"), |
|
102 |
("0.14.1_149", "<", "0.14.1_150"), |
|
103 |
("0.13next_102", "<", "0.13next"), |
|
104 |
("0.13next", "<", "0.14rc5_120"), |
|
105 |
("0.14rc3_120", "<", "0.14rc3"), |
|
106 |
# The following test fails, but versioning.python_version |
|
107 |
# will never try to produce such a version: |
|
108 |
# ("0.14rc3", "<", "0.14_1"), |
|
109 |
("0.14_120", "<", "0.14"), |
|
110 |
("0.14", "<", "0.14next_20"), |
|
111 |
("0.14next_20", "<", "0.14next"), |
|
112 |
) |
|
113 |
|
|
114 |
def test_python_versions(self): |
|
115 |
for a, op, b in self.version_orderings: |
|
116 |
res = compare(V, a, op, b) |
|
117 |
self.assertTrue(res, "Python version: %s %s %s" |
|
118 |
" is not True" % (a, op, b)) |
|
119 |
|
|
120 |
def test_debian_versions(self): |
|
121 |
for a, op, b in self.version_orderings: |
|
122 |
res = compare(D, a, op, b) |
|
123 |
self.assertTrue(res, "Debian version %s %s %s" |
|
124 |
" is not True" % (a, op, b)) |
|
125 |
|
|
126 |
|
|
127 |
def compare(function, a, op, b): |
|
128 |
import operator |
|
129 |
str_to_op = {"<": operator.lt, |
|
130 |
"<=": operator.le, |
|
131 |
"==": operator.eq, |
|
132 |
">": operator.gt, |
|
133 |
">=": operator.ge} |
|
134 |
try: |
|
135 |
return str_to_op[op](function(a), function(b)) |
|
136 |
except KeyError: |
|
137 |
raise ValueError("Unknown operator '%s'" % op) |
|
138 |
|
|
139 |
if __name__ == '__main__': |
|
140 |
unittest.main() |
b/version | ||
---|---|---|
1 |
0.1next |
Also available in: Unified diff