root / devflow / versioning.py @ 866bb9c1
History | View | Annotate | Download (14.7 kB)
1 | 55775645 | Vangelis Koukis | #!/usr/bin/env python
|
---|---|---|---|
2 | 55775645 | Vangelis Koukis | #
|
3 | 55775645 | Vangelis Koukis | # Copyright (C) 2010, 2011, 2012 GRNET S.A. All rights reserved.
|
4 | 55775645 | Vangelis Koukis | #
|
5 | 55775645 | Vangelis Koukis | # Redistribution and use in source and binary forms, with or
|
6 | 55775645 | Vangelis Koukis | # without modification, are permitted provided that the following
|
7 | 55775645 | Vangelis Koukis | # conditions are met:
|
8 | 55775645 | Vangelis Koukis | #
|
9 | 55775645 | Vangelis Koukis | # 1. Redistributions of source code must retain the above
|
10 | 55775645 | Vangelis Koukis | # copyright notice, this list of conditions and the following
|
11 | 55775645 | Vangelis Koukis | # disclaimer.
|
12 | 55775645 | Vangelis Koukis | #
|
13 | 55775645 | Vangelis Koukis | # 2. Redistributions in binary form must reproduce the above
|
14 | 55775645 | Vangelis Koukis | # copyright notice, this list of conditions and the following
|
15 | 55775645 | Vangelis Koukis | # disclaimer in the documentation and/or other materials
|
16 | 55775645 | Vangelis Koukis | # provided with the distribution.
|
17 | 55775645 | Vangelis Koukis | #
|
18 | 55775645 | Vangelis Koukis | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
19 | 55775645 | Vangelis Koukis | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
20 | 55775645 | Vangelis Koukis | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
21 | 55775645 | Vangelis Koukis | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
22 | 55775645 | Vangelis Koukis | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
23 | 55775645 | Vangelis Koukis | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
24 | 55775645 | Vangelis Koukis | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
25 | 55775645 | Vangelis Koukis | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
26 | 55775645 | Vangelis Koukis | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
27 | 55775645 | Vangelis Koukis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
28 | 55775645 | Vangelis Koukis | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29 | 55775645 | Vangelis Koukis | # POSSIBILITY OF SUCH DAMAGE.
|
30 | 55775645 | Vangelis Koukis | #
|
31 | 55775645 | Vangelis Koukis | # The views and conclusions contained in the software and
|
32 | 55775645 | Vangelis Koukis | # documentation are those of the authors and should not be
|
33 | 55775645 | Vangelis Koukis | # interpreted as representing official policies, either expressed
|
34 | 55775645 | Vangelis Koukis | # or implied, of GRNET S.A.
|
35 | 55775645 | Vangelis Koukis | |
36 | 55775645 | Vangelis Koukis | |
37 | 55775645 | Vangelis Koukis | import os |
38 | 55775645 | Vangelis Koukis | import re |
39 | 55775645 | Vangelis Koukis | import sys |
40 | 55775645 | Vangelis Koukis | import pprint |
41 | 55775645 | Vangelis Koukis | import subprocess |
42 | 55775645 | Vangelis Koukis | import git |
43 | 55775645 | Vangelis Koukis | |
44 | 55775645 | Vangelis Koukis | from distutils import log |
45 | 55775645 | Vangelis Koukis | from collections import namedtuple |
46 | 55775645 | Vangelis Koukis | |
47 | 55775645 | Vangelis Koukis | |
48 | 55775645 | Vangelis Koukis | # Branch types:
|
49 | 55775645 | Vangelis Koukis | # builds_snapshot: Whether the branch can produce snapshot builds
|
50 | 55775645 | Vangelis Koukis | # builds_release: Whether the branch can produce release builds
|
51 | 55775645 | Vangelis Koukis | # versioned: Whether the name of the branch defines a specific version
|
52 | 55775645 | Vangelis Koukis | # allowed_version_re: A regular expression describing allowed values for
|
53 | 55775645 | Vangelis Koukis | # base_version in this branch
|
54 | 55775645 | Vangelis Koukis | branch_type = namedtuple("branch_type", ["builds_snapshot", "builds_release", |
55 | 55775645 | Vangelis Koukis | "versioned", "allowed_version_re"]) |
56 | 55775645 | Vangelis Koukis | VERSION_RE = "[0-9]+\.[0-9]+"
|
57 | 55775645 | Vangelis Koukis | BRANCH_TYPES = { |
58 | 55775645 | Vangelis Koukis | "feature": branch_type(True, False, False, "^%snext$" % VERSION_RE), |
59 | 55775645 | Vangelis Koukis | "develop": branch_type(True, False, False, "^%snext$" % VERSION_RE), |
60 | 55775645 | Vangelis Koukis | "release": branch_type(True, True, True, |
61 | 55775645 | Vangelis Koukis | "^(?P<bverstr>%s)rc[1-9][0-9]*$" % VERSION_RE),
|
62 | 55775645 | Vangelis Koukis | "master": branch_type(False, True, False, |
63 | 55775645 | Vangelis Koukis | "^%s$" % VERSION_RE),
|
64 | 55775645 | Vangelis Koukis | "hotfix": branch_type(True, True, True, |
65 | 55775645 | Vangelis Koukis | "^(?P<bverstr>^%s\.[1-9][0-9]*)$" % VERSION_RE)}
|
66 | 55775645 | Vangelis Koukis | BASE_VERSION_FILE = "version"
|
67 | 55775645 | Vangelis Koukis | |
68 | 55775645 | Vangelis Koukis | |
69 | 55775645 | Vangelis Koukis | def get_commit_id(commit, current_branch): |
70 | 55775645 | Vangelis Koukis | """Return the commit ID
|
71 | 55775645 | Vangelis Koukis |
|
72 | 55775645 | Vangelis Koukis | If the commit is a 'merge' commit, and one of the parents is a
|
73 | 55775645 | Vangelis Koukis | debian branch we return a compination of the parents commits.
|
74 | 55775645 | Vangelis Koukis |
|
75 | 55775645 | Vangelis Koukis | """
|
76 | 55775645 | Vangelis Koukis | def short_id(commit): |
77 | 55775645 | Vangelis Koukis | return commit.hexsha[0:7] |
78 | 55775645 | Vangelis Koukis | |
79 | 55775645 | Vangelis Koukis | parents = commit.parents |
80 | 55775645 | Vangelis Koukis | cur_br_name = current_branch.name |
81 | 55775645 | Vangelis Koukis | if len(parents) == 1: |
82 | 55775645 | Vangelis Koukis | return short_id(commit)
|
83 | 55775645 | Vangelis Koukis | elif len(parents) == 2: |
84 | 55775645 | Vangelis Koukis | if cur_br_name.startswith("debian-") or cur_br_name == "debian": |
85 | 55775645 | Vangelis Koukis | pr1, pr2 = parents |
86 | 866bb9c1 | Christos Stavrakakis | return short_id(pr1) + "-" + short_id(pr2) |
87 | 55775645 | Vangelis Koukis | else:
|
88 | 55775645 | Vangelis Koukis | return short_id(commit)
|
89 | 55775645 | Vangelis Koukis | else:
|
90 | 55775645 | Vangelis Koukis | raise RuntimeError("Commit %s has more than 2 parents!" % commit) |
91 | 55775645 | Vangelis Koukis | |
92 | 55775645 | Vangelis Koukis | |
93 | 55775645 | Vangelis Koukis | def vcs_info(): |
94 | 55775645 | Vangelis Koukis | """
|
95 | 55775645 | Vangelis Koukis | Return current git HEAD commit information.
|
96 | 55775645 | Vangelis Koukis |
|
97 | 55775645 | Vangelis Koukis | Returns a tuple containing
|
98 | 55775645 | Vangelis Koukis | - branch name
|
99 | 55775645 | Vangelis Koukis | - commit id
|
100 | 55775645 | Vangelis Koukis | - commit count
|
101 | 55775645 | Vangelis Koukis | - git describe output
|
102 | 55775645 | Vangelis Koukis | - path of git toplevel directory
|
103 | 55775645 | Vangelis Koukis |
|
104 | 55775645 | Vangelis Koukis | """
|
105 | 55775645 | Vangelis Koukis | try:
|
106 | 55775645 | Vangelis Koukis | repo = git.Repo(".")
|
107 | 55775645 | Vangelis Koukis | branch = repo.head.reference |
108 | 55775645 | Vangelis Koukis | revid = get_commit_id(branch.commit, branch) |
109 | 55775645 | Vangelis Koukis | revno = len(list(repo.iter_commits())) |
110 | 55775645 | Vangelis Koukis | toplevel = repo.working_dir |
111 | 55775645 | Vangelis Koukis | except git.InvalidGitRepositoryError:
|
112 | 55775645 | Vangelis Koukis | log.error("Could not retrieve git information. " +
|
113 | 55775645 | Vangelis Koukis | "Current directory not a git repository?")
|
114 | 55775645 | Vangelis Koukis | return None |
115 | 55775645 | Vangelis Koukis | |
116 | 55775645 | Vangelis Koukis | info = namedtuple("vcs_info", ["branch", "revid", "revno", |
117 | 866bb9c1 | Christos Stavrakakis | "toplevel"])
|
118 | 55775645 | Vangelis Koukis | |
119 | 866bb9c1 | Christos Stavrakakis | return info(branch=branch.name, revid=revid, revno=revno,
|
120 | 55775645 | Vangelis Koukis | toplevel=toplevel) |
121 | 55775645 | Vangelis Koukis | |
122 | 55775645 | Vangelis Koukis | |
123 | 55775645 | Vangelis Koukis | def base_version(vcs_info): |
124 | 55775645 | Vangelis Koukis | """Determine the base version from a file in the repository"""
|
125 | 55775645 | Vangelis Koukis | |
126 | 55775645 | Vangelis Koukis | f = open(os.path.join(vcs_info.toplevel, BASE_VERSION_FILE))
|
127 | 55775645 | Vangelis Koukis | lines = [l.strip() for l in f.readlines()] |
128 | 55775645 | Vangelis Koukis | l = [l for l in lines if not l.startswith("#")] |
129 | 55775645 | Vangelis Koukis | if len(l) != 1: |
130 | 55775645 | Vangelis Koukis | raise ValueError("File '%s' should contain a single non-comment line.") |
131 | 55775645 | Vangelis Koukis | return l[0] |
132 | 55775645 | Vangelis Koukis | |
133 | 55775645 | Vangelis Koukis | |
134 | 55775645 | Vangelis Koukis | def build_mode(): |
135 | 55775645 | Vangelis Koukis | """Determine the build mode from the value of $GITFLOW_BUILD_MODE"""
|
136 | 55775645 | Vangelis Koukis | try:
|
137 | 55775645 | Vangelis Koukis | mode = os.environ["GITFLOW_BUILD_MODE"]
|
138 | 55775645 | Vangelis Koukis | assert mode == "release" or mode == "snapshot" |
139 | 866bb9c1 | Christos Stavrakakis | except KeyError: |
140 | 866bb9c1 | Christos Stavrakakis | raise ValueError("GITFLOW_BUILD_MODE environment variable is not set." |
141 | 866bb9c1 | Christos Stavrakakis | " Set this variable to 'release' or 'snapshot'")
|
142 | 866bb9c1 | Christos Stavrakakis | except AssertionError: |
143 | 866bb9c1 | Christos Stavrakakis | raise ValueError("GITFLOW_BUILD_MODE environment variable must be" |
144 | 866bb9c1 | Christos Stavrakakis | " 'release' or 'snapshot'")
|
145 | 55775645 | Vangelis Koukis | return mode
|
146 | 55775645 | Vangelis Koukis | |
147 | 55775645 | Vangelis Koukis | |
148 | 55775645 | Vangelis Koukis | def python_version(base_version, vcs_info, mode): |
149 | 55775645 | Vangelis Koukis | """Generate a Python distribution version following devtools conventions.
|
150 | 55775645 | Vangelis Koukis |
|
151 | 55775645 | Vangelis Koukis | This helper generates a Python distribution version from a repository
|
152 | 55775645 | Vangelis Koukis | commit, following devtools conventions. The input data are:
|
153 | 55775645 | Vangelis Koukis | * base_version: a base version number, presumably stored in text file
|
154 | 55775645 | Vangelis Koukis | inside the repository, e.g., /version
|
155 | 55775645 | Vangelis Koukis | * vcs_info: vcs information: current branch name and revision no
|
156 | 55775645 | Vangelis Koukis | * mode: "snapshot", or "release"
|
157 | 55775645 | Vangelis Koukis |
|
158 | 55775645 | Vangelis Koukis | This helper assumes a git branching model following:
|
159 | 55775645 | Vangelis Koukis | http://nvie.com/posts/a-successful-git-branching-model/
|
160 | 55775645 | Vangelis Koukis |
|
161 | 55775645 | Vangelis Koukis | with 'master', 'develop', 'release-X', 'hotfix-X' and 'feature-X' branches.
|
162 | 55775645 | Vangelis Koukis |
|
163 | 55775645 | Vangelis Koukis | General rules:
|
164 | 55775645 | Vangelis Koukis | a) any repository commit can get as a Python version
|
165 | 55775645 | Vangelis Koukis | b) a version is generated either in 'release' or in 'snapshot' mode
|
166 | 55775645 | Vangelis Koukis | c) the choice of mode depends on the branch, see following table.
|
167 | 55775645 | Vangelis Koukis |
|
168 | 55775645 | Vangelis Koukis | A python version is of the form A_NNN,
|
169 | 55775645 | Vangelis Koukis | where A: X.Y.Z{,next,rcW} and NNN: a revision number for the commit,
|
170 | 55775645 | Vangelis Koukis | as returned by vcs_info().
|
171 | 55775645 | Vangelis Koukis |
|
172 | 55775645 | Vangelis Koukis | For every combination of branch and mode, releases are numbered as follows:
|
173 | 55775645 | Vangelis Koukis |
|
174 | 55775645 | Vangelis Koukis | BRANCH: / MODE: snapshot release
|
175 | 55775645 | Vangelis Koukis | -------- ------------------------------
|
176 | 55775645 | Vangelis Koukis | feature 0.14next_150 N/A
|
177 | 55775645 | Vangelis Koukis | develop 0.14next_151 N/A
|
178 | 55775645 | Vangelis Koukis | release 0.14rc2_249 0.14rc2
|
179 | 55775645 | Vangelis Koukis | master N/A 0.14
|
180 | 55775645 | Vangelis Koukis | hotfix 0.14.1rc6_121 0.14.1rc6
|
181 | 55775645 | Vangelis Koukis | N/A 0.14.1
|
182 | 55775645 | Vangelis Koukis |
|
183 | 55775645 | Vangelis Koukis | The suffix 'next' in a version name is used to denote the upcoming version,
|
184 | 55775645 | Vangelis Koukis | the one being under development in the develop and release branches.
|
185 | 55775645 | Vangelis Koukis | Version '0.14next' is the version following 0.14, and only lives on the
|
186 | 55775645 | Vangelis Koukis | develop and feature branches.
|
187 | 55775645 | Vangelis Koukis |
|
188 | 55775645 | Vangelis Koukis | The suffix 'rc' is used to denote release candidates. 'rc' versions live
|
189 | 55775645 | Vangelis Koukis | only in release and hotfix branches.
|
190 | 55775645 | Vangelis Koukis |
|
191 | 55775645 | Vangelis Koukis | Suffixes 'next' and 'rc' have been chosen to ensure proper ordering
|
192 | 55775645 | Vangelis Koukis | according to setuptools rules:
|
193 | 55775645 | Vangelis Koukis |
|
194 | 55775645 | Vangelis Koukis | http://www.python.org/dev/peps/pep-0386/#setuptools
|
195 | 55775645 | Vangelis Koukis |
|
196 | 55775645 | Vangelis Koukis | Every branch uses a value for A so that all releases are ordered based
|
197 | 55775645 | Vangelis Koukis | on the branch they came from, so:
|
198 | 55775645 | Vangelis Koukis |
|
199 | 55775645 | Vangelis Koukis | So
|
200 | 55775645 | Vangelis Koukis | 0.13next < 0.14rcW < 0.14 < 0.14next < 0.14.1
|
201 | 55775645 | Vangelis Koukis |
|
202 | 55775645 | Vangelis Koukis | and
|
203 | 55775645 | Vangelis Koukis |
|
204 | 55775645 | Vangelis Koukis | >>> V("0.14next") > V("0.14")
|
205 | 55775645 | Vangelis Koukis | True
|
206 | 55775645 | Vangelis Koukis | >>> V("0.14next") > V("0.14rc7")
|
207 | 55775645 | Vangelis Koukis | True
|
208 | 55775645 | Vangelis Koukis | >>> V("0.14next") > V("0.14.1")
|
209 | 55775645 | Vangelis Koukis | False
|
210 | 55775645 | Vangelis Koukis | >>> V("0.14rc6") > V("0.14")
|
211 | 55775645 | Vangelis Koukis | False
|
212 | 55775645 | Vangelis Koukis | >>> V("0.14.2rc6") > V("0.14.1")
|
213 | 55775645 | Vangelis Koukis | True
|
214 | 55775645 | Vangelis Koukis |
|
215 | 55775645 | Vangelis Koukis | The value for _NNN is chosen based of the revision number of the specific
|
216 | 55775645 | Vangelis Koukis | commit. It is used to ensure ascending ordering of consecutive releases
|
217 | 55775645 | Vangelis Koukis | from the same branch. Every version of the form A_NNN comes *before*
|
218 | 55775645 | Vangelis Koukis | than A: All snapshots are ordered so they come before the corresponding
|
219 | 55775645 | Vangelis Koukis | release.
|
220 | 55775645 | Vangelis Koukis |
|
221 | 55775645 | Vangelis Koukis | So
|
222 | 55775645 | Vangelis Koukis | 0.14next_* < 0.14
|
223 | 55775645 | Vangelis Koukis | 0.14.1_* < 0.14.1
|
224 | 55775645 | Vangelis Koukis | etc
|
225 | 55775645 | Vangelis Koukis |
|
226 | 55775645 | Vangelis Koukis | and
|
227 | 55775645 | Vangelis Koukis |
|
228 | 55775645 | Vangelis Koukis | >>> V("0.14next_150") < V("0.14next")
|
229 | 55775645 | Vangelis Koukis | True
|
230 | 55775645 | Vangelis Koukis | >>> V("0.14.1next_150") < V("0.14.1next")
|
231 | 55775645 | Vangelis Koukis | True
|
232 | 55775645 | Vangelis Koukis | >>> V("0.14.1_149") < V("0.14.1")
|
233 | 55775645 | Vangelis Koukis | True
|
234 | 55775645 | Vangelis Koukis | >>> V("0.14.1_149") < V("0.14.1_150")
|
235 | 55775645 | Vangelis Koukis | True
|
236 | 55775645 | Vangelis Koukis |
|
237 | 55775645 | Vangelis Koukis | Combining both of the above, we get
|
238 | 55775645 | Vangelis Koukis | 0.13next_* < 0.13next < 0.14rcW_* < 0.14rcW < 0.14_* < 0.14
|
239 | 55775645 | Vangelis Koukis | < 0.14next_* < 0.14next < 0.14.1_* < 0.14.1
|
240 | 55775645 | Vangelis Koukis |
|
241 | 55775645 | Vangelis Koukis | and
|
242 | 55775645 | Vangelis Koukis |
|
243 | 55775645 | Vangelis Koukis | >>> V("0.13next_102") < V("0.13next")
|
244 | 55775645 | Vangelis Koukis | True
|
245 | 55775645 | Vangelis Koukis | >>> V("0.13next") < V("0.14rc5_120")
|
246 | 55775645 | Vangelis Koukis | True
|
247 | 55775645 | Vangelis Koukis | >>> V("0.14rc3_120") < V("0.14rc3")
|
248 | 55775645 | Vangelis Koukis | True
|
249 | 55775645 | Vangelis Koukis | >>> V("0.14rc3") < V("0.14_1")
|
250 | 55775645 | Vangelis Koukis | True
|
251 | 55775645 | Vangelis Koukis | >>> V("0.14_120") < V("0.14")
|
252 | 55775645 | Vangelis Koukis | True
|
253 | 55775645 | Vangelis Koukis | >>> V("0.14") < V("0.14next_20")
|
254 | 55775645 | Vangelis Koukis | True
|
255 | 55775645 | Vangelis Koukis | >>> V("0.14next_20") < V("0.14next")
|
256 | 55775645 | Vangelis Koukis | True
|
257 | 55775645 | Vangelis Koukis |
|
258 | 55775645 | Vangelis Koukis | Note: one of the tests above fails because of constraints in the way
|
259 | 55775645 | Vangelis Koukis | setuptools parses version numbers. It does not affect us because the
|
260 | 55775645 | Vangelis Koukis | specific version format that triggers the problem is not contained in the
|
261 | 55775645 | Vangelis Koukis | table showing allowed branch / mode combinations, above.
|
262 | 55775645 | Vangelis Koukis |
|
263 | 55775645 | Vangelis Koukis |
|
264 | 55775645 | Vangelis Koukis | """
|
265 | 55775645 | Vangelis Koukis | |
266 | 55775645 | Vangelis Koukis | branch = vcs_info.branch |
267 | 55775645 | Vangelis Koukis | |
268 | 55775645 | Vangelis Koukis | # If it's a debian branch, ignore starting "debian-"
|
269 | 55775645 | Vangelis Koukis | brnorm = branch |
270 | 55775645 | Vangelis Koukis | if brnorm == "debian": |
271 | 55775645 | Vangelis Koukis | brnorm = "debian-master"
|
272 | 55775645 | Vangelis Koukis | if brnorm.startswith("debian-"): |
273 | 55775645 | Vangelis Koukis | brnorm = brnorm.replace("debian-", "", 1) |
274 | 55775645 | Vangelis Koukis | |
275 | 55775645 | Vangelis Koukis | # Sanity checks
|
276 | 55775645 | Vangelis Koukis | if "-" in brnorm: |
277 | 55775645 | Vangelis Koukis | btypestr = brnorm.split("-")[0] |
278 | 55775645 | Vangelis Koukis | else:
|
279 | 55775645 | Vangelis Koukis | btypestr = brnorm |
280 | 55775645 | Vangelis Koukis | |
281 | 55775645 | Vangelis Koukis | try:
|
282 | 55775645 | Vangelis Koukis | btype = BRANCH_TYPES[btypestr] |
283 | 55775645 | Vangelis Koukis | except KeyError: |
284 | 55775645 | Vangelis Koukis | allowed_branches = ", ".join(x for x in BRANCH_TYPES.keys()) |
285 | 55775645 | Vangelis Koukis | raise ValueError("Malformed branch name '%s', cannot classify as one " |
286 | 55775645 | Vangelis Koukis | "of %s" % (btypestr, allowed_branches))
|
287 | 55775645 | Vangelis Koukis | |
288 | 55775645 | Vangelis Koukis | if btype.versioned:
|
289 | 55775645 | Vangelis Koukis | try:
|
290 | 55775645 | Vangelis Koukis | bverstr = brnorm.split("-")[1] |
291 | 55775645 | Vangelis Koukis | except IndexError: |
292 | 55775645 | Vangelis Koukis | # No version
|
293 | 55775645 | Vangelis Koukis | raise ValueError("Branch name '%s' should contain version" % |
294 | 55775645 | Vangelis Koukis | branch) |
295 | 55775645 | Vangelis Koukis | |
296 | 55775645 | Vangelis Koukis | # Check that version is well-formed
|
297 | 55775645 | Vangelis Koukis | if not re.match(VERSION_RE, bverstr): |
298 | 55775645 | Vangelis Koukis | raise ValueError("Malformed version '%s' in branch name '%s'" % |
299 | 55775645 | Vangelis Koukis | (bverstr, branch)) |
300 | 55775645 | Vangelis Koukis | |
301 | 55775645 | Vangelis Koukis | m = re.match(btype.allowed_version_re, base_version) |
302 | 55775645 | Vangelis Koukis | if not m or (btype.versioned and m.groupdict()["bverstr"] != bverstr): |
303 | 55775645 | Vangelis Koukis | raise ValueError("Base version '%s' unsuitable for branch name '%s'" % |
304 | 55775645 | Vangelis Koukis | (base_version, branch)) |
305 | 55775645 | Vangelis Koukis | |
306 | 55775645 | Vangelis Koukis | if mode not in ["snapshot", "release"]: |
307 | 55775645 | Vangelis Koukis | raise ValueError("Specified mode '%s' should be one of 'snapshot' or " |
308 | 55775645 | Vangelis Koukis | "'release'" % mode)
|
309 | 55775645 | Vangelis Koukis | snap = (mode == "snapshot")
|
310 | 55775645 | Vangelis Koukis | |
311 | 55775645 | Vangelis Koukis | if ((snap and not btype.builds_snapshot) or |
312 | 55775645 | Vangelis Koukis | (not snap and not btype.builds_release)): |
313 | 55775645 | Vangelis Koukis | raise ValueError("Invalid mode '%s' in branch type '%s'" % |
314 | 55775645 | Vangelis Koukis | (mode, btypestr)) |
315 | 55775645 | Vangelis Koukis | |
316 | 55775645 | Vangelis Koukis | if snap:
|
317 | 55775645 | Vangelis Koukis | v = "%s_%d_%s" % (base_version, vcs_info.revno, vcs_info.revid)
|
318 | 55775645 | Vangelis Koukis | else:
|
319 | 55775645 | Vangelis Koukis | v = base_version |
320 | 55775645 | Vangelis Koukis | return v
|
321 | 55775645 | Vangelis Koukis | |
322 | 55775645 | Vangelis Koukis | |
323 | 55775645 | Vangelis Koukis | def debian_version_from_python_version(pyver): |
324 | 55775645 | Vangelis Koukis | """Generate a debian package version from a Python version.
|
325 | 55775645 | Vangelis Koukis |
|
326 | 55775645 | Vangelis Koukis | This helper generates a Debian package version from a Python version,
|
327 | 55775645 | Vangelis Koukis | following devtools conventions.
|
328 | 55775645 | Vangelis Koukis |
|
329 | 55775645 | Vangelis Koukis | Debian sorts version strings differently compared to setuptools:
|
330 | 55775645 | Vangelis Koukis | http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version
|
331 | 55775645 | Vangelis Koukis |
|
332 | 55775645 | Vangelis Koukis | Initial tests:
|
333 | 55775645 | Vangelis Koukis |
|
334 | 55775645 | Vangelis Koukis | >>> debian_version("3") < debian_version("6")
|
335 | 55775645 | Vangelis Koukis | True
|
336 | 55775645 | Vangelis Koukis | >>> debian_version("3") < debian_version("2")
|
337 | 55775645 | Vangelis Koukis | False
|
338 | 55775645 | Vangelis Koukis | >>> debian_version("1") == debian_version("1")
|
339 | 55775645 | Vangelis Koukis | True
|
340 | 55775645 | Vangelis Koukis | >>> debian_version("1") != debian_version("1")
|
341 | 55775645 | Vangelis Koukis | False
|
342 | 55775645 | Vangelis Koukis | >>> debian_version("1") >= debian_version("1")
|
343 | 55775645 | Vangelis Koukis | True
|
344 | 55775645 | Vangelis Koukis | >>> debian_version("1") <= debian_version("1")
|
345 | 55775645 | Vangelis Koukis | True
|
346 | 55775645 | Vangelis Koukis |
|
347 | 55775645 | Vangelis Koukis | This helper defines a 1-1 mapping between Python and Debian versions,
|
348 | 55775645 | Vangelis Koukis | with the same ordering.
|
349 | 55775645 | Vangelis Koukis |
|
350 | 55775645 | Vangelis Koukis | Debian versions are ordered in the same way as Python versions:
|
351 | 55775645 | Vangelis Koukis |
|
352 | 55775645 | Vangelis Koukis | >>> D("0.14next") > D("0.14")
|
353 | 55775645 | Vangelis Koukis | True
|
354 | 55775645 | Vangelis Koukis | >>> D("0.14next") > D("0.14rc7")
|
355 | 55775645 | Vangelis Koukis | True
|
356 | 55775645 | Vangelis Koukis | >>> D("0.14next") > D("0.14.1")
|
357 | 55775645 | Vangelis Koukis | False
|
358 | 55775645 | Vangelis Koukis | >>> D("0.14rc6") > D("0.14")
|
359 | 55775645 | Vangelis Koukis | False
|
360 | 55775645 | Vangelis Koukis | >>> D("0.14.2rc6") > D("0.14.1")
|
361 | 55775645 | Vangelis Koukis | True
|
362 | 55775645 | Vangelis Koukis |
|
363 | 55775645 | Vangelis Koukis | and
|
364 | 55775645 | Vangelis Koukis |
|
365 | 55775645 | Vangelis Koukis | >>> D("0.14next_150") < D("0.14next")
|
366 | 55775645 | Vangelis Koukis | True
|
367 | 55775645 | Vangelis Koukis | >>> D("0.14.1next_150") < D("0.14.1next")
|
368 | 55775645 | Vangelis Koukis | True
|
369 | 55775645 | Vangelis Koukis | >>> D("0.14.1_149") < D("0.14.1")
|
370 | 55775645 | Vangelis Koukis | True
|
371 | 55775645 | Vangelis Koukis | >>> D("0.14.1_149") < D("0.14.1_150")
|
372 | 55775645 | Vangelis Koukis | True
|
373 | 55775645 | Vangelis Koukis |
|
374 | 55775645 | Vangelis Koukis | and
|
375 | 55775645 | Vangelis Koukis |
|
376 | 55775645 | Vangelis Koukis | >>> D("0.13next_102") < D("0.13next")
|
377 | 55775645 | Vangelis Koukis | True
|
378 | 55775645 | Vangelis Koukis | >>> D("0.13next") < D("0.14rc5_120")
|
379 | 55775645 | Vangelis Koukis | True
|
380 | 55775645 | Vangelis Koukis | >>> D("0.14rc3_120") < D("0.14rc3")
|
381 | 55775645 | Vangelis Koukis | True
|
382 | 55775645 | Vangelis Koukis | >>> D("0.14rc3") < D("0.14_1")
|
383 | 55775645 | Vangelis Koukis | True
|
384 | 55775645 | Vangelis Koukis | >>> D("0.14_120") < D("0.14")
|
385 | 55775645 | Vangelis Koukis | True
|
386 | 55775645 | Vangelis Koukis | >>> D("0.14") < D("0.14next_20")
|
387 | 55775645 | Vangelis Koukis | True
|
388 | 55775645 | Vangelis Koukis | >>> D("0.14next_20") < D("0.14next")
|
389 | 55775645 | Vangelis Koukis | True
|
390 | 55775645 | Vangelis Koukis |
|
391 | 55775645 | Vangelis Koukis | """
|
392 | 55775645 | Vangelis Koukis | return pyver.replace("_", "~").replace("rc", "~rc") + "-1" |
393 | 55775645 | Vangelis Koukis | |
394 | 55775645 | Vangelis Koukis | |
395 | 866bb9c1 | Christos Stavrakakis | def get_python_version(): |
396 | 866bb9c1 | Christos Stavrakakis | v = vcs_info() |
397 | 866bb9c1 | Christos Stavrakakis | b = base_version(v) |
398 | 866bb9c1 | Christos Stavrakakis | mode = build_mode() |
399 | 866bb9c1 | Christos Stavrakakis | return python_version(b, v, mode)
|
400 | 866bb9c1 | Christos Stavrakakis | |
401 | 866bb9c1 | Christos Stavrakakis | |
402 | 55775645 | Vangelis Koukis | def debian_version(base_version, vcs_info, mode): |
403 | 55775645 | Vangelis Koukis | p = python_version(base_version, vcs_info, mode) |
404 | 55775645 | Vangelis Koukis | return debian_version_from_python_version(p)
|
405 | 55775645 | Vangelis Koukis | |
406 | 55775645 | Vangelis Koukis | |
407 | 866bb9c1 | Christos Stavrakakis | def get_debian_version(): |
408 | 866bb9c1 | Christos Stavrakakis | v = vcs_info() |
409 | 866bb9c1 | Christos Stavrakakis | b = base_version(v) |
410 | 866bb9c1 | Christos Stavrakakis | mode = build_mode() |
411 | 866bb9c1 | Christos Stavrakakis | return debian_version(b, v, mode)
|
412 | 866bb9c1 | Christos Stavrakakis | |
413 | 866bb9c1 | Christos Stavrakakis | |
414 | 55775645 | Vangelis Koukis | def user_info(): |
415 | 55775645 | Vangelis Koukis | import getpass |
416 | 55775645 | Vangelis Koukis | import socket |
417 | 55775645 | Vangelis Koukis | return "%s@%s" % (getpass.getuser(), socket.getfqdn()) |
418 | 55775645 | Vangelis Koukis | |
419 | 55775645 | Vangelis Koukis | |
420 | 55775645 | Vangelis Koukis | def update_version(module, name="version", root="."): |
421 | 55775645 | Vangelis Koukis | """
|
422 | 55775645 | Vangelis Koukis | Generate or replace version.py as a submodule of `module`.
|
423 | 55775645 | Vangelis Koukis |
|
424 | 55775645 | Vangelis Koukis | This is a helper to generate/replace a version.py file containing version
|
425 | 55775645 | Vangelis Koukis | information as a submodule of passed `module`.
|
426 | 55775645 | Vangelis Koukis |
|
427 | 55775645 | Vangelis Koukis | """
|
428 | 55775645 | Vangelis Koukis | |
429 | 866bb9c1 | Christos Stavrakakis | paths = [root] + module.split(".") + ["%s.py" % name] |
430 | 866bb9c1 | Christos Stavrakakis | module_filename = os.path.join(*paths) |
431 | 866bb9c1 | Christos Stavrakakis | |
432 | 55775645 | Vangelis Koukis | v = vcs_info() |
433 | 55775645 | Vangelis Koukis | if not v: |
434 | 55775645 | Vangelis Koukis | # Return early if not in development environment
|
435 | 866bb9c1 | Christos Stavrakakis | log.error("Can not compute version outside of a git repository."
|
436 | 866bb9c1 | Christos Stavrakakis | " Will not update %s version file" % module_filename)
|
437 | 55775645 | Vangelis Koukis | return
|
438 | 55775645 | Vangelis Koukis | b = base_version(v) |
439 | 55775645 | Vangelis Koukis | mode = build_mode() |
440 | 55775645 | Vangelis Koukis | version = python_version(b, v, mode) |
441 | 55775645 | Vangelis Koukis | content = """
|
442 | 55775645 | Vangelis Koukis | __version__ = "%(version)s"
|
443 | 55775645 | Vangelis Koukis | __version_info__ = %(version_info)s
|
444 | 55775645 | Vangelis Koukis | __version_vcs_info__ = %(vcs_info)s
|
445 | 55775645 | Vangelis Koukis | __version_user_info__ = "%(user_info)s"
|
446 | 866bb9c1 | Christos Stavrakakis | """ % dict(version=version, version_info=version.split("."), |
447 | 55775645 | Vangelis Koukis | vcs_info=pprint.PrettyPrinter().pformat(dict(v._asdict())),
|
448 | 55775645 | Vangelis Koukis | user_info=user_info()) |
449 | 55775645 | Vangelis Koukis | |
450 | 55775645 | Vangelis Koukis | module_file = file(module_filename, "w+") |
451 | 55775645 | Vangelis Koukis | module_file.write(content) |
452 | 55775645 | Vangelis Koukis | module_file.close() |
453 | 866bb9c1 | Christos Stavrakakis | return module_filename
|
454 | 55775645 | Vangelis Koukis | |
455 | 55775645 | Vangelis Koukis | |
456 | 866bb9c1 | Christos Stavrakakis | def main(): |
457 | 55775645 | Vangelis Koukis | v = vcs_info() |
458 | 55775645 | Vangelis Koukis | b = base_version(v) |
459 | 55775645 | Vangelis Koukis | mode = build_mode() |
460 | 55775645 | Vangelis Koukis | |
461 | 55775645 | Vangelis Koukis | try:
|
462 | 55775645 | Vangelis Koukis | arg = sys.argv[1]
|
463 | 55775645 | Vangelis Koukis | assert arg == "python" or arg == "debian" |
464 | 55775645 | Vangelis Koukis | except IndexError: |
465 | 55775645 | Vangelis Koukis | raise ValueError("A single argument, 'python' or 'debian is required") |
466 | 55775645 | Vangelis Koukis | |
467 | 55775645 | Vangelis Koukis | if arg == "python": |
468 | 55775645 | Vangelis Koukis | print python_version(b, v, mode)
|
469 | 55775645 | Vangelis Koukis | elif arg == "debian": |
470 | 55775645 | Vangelis Koukis | print debian_version(b, v, mode)
|
471 | 866bb9c1 | Christos Stavrakakis | |
472 | 866bb9c1 | Christos Stavrakakis | if __name__ == "__main__": |
473 | 866bb9c1 | Christos Stavrakakis | sys.exit(main()) |