|
1 """ |
|
2 Figuring out the project version |
|
3 |
|
4 Currently this only supports mercurial |
|
5 """ |
|
6 |
|
7 # only load this once |
|
8 _VERSION = None |
|
9 |
|
10 def version_mercurial (path) : |
|
11 """ |
|
12 Returns a (branch, tags, parents, modified) tuple for the given repo's working copy |
|
13 """ |
|
14 |
|
15 global _VERSION |
|
16 |
|
17 # cached? |
|
18 if _VERSION : |
|
19 return _VERSION |
|
20 |
|
21 # code adapted from mercurial.commands.identify |
|
22 from mercurial import ui, hg, encoding |
|
23 from mercurial.node import short |
|
24 |
|
25 # open the repo |
|
26 repo = hg.repository(ui.ui(), path) |
|
27 |
|
28 # the working copy change context |
|
29 ctx = repo[None] |
|
30 |
|
31 # branch |
|
32 branch = encoding.tolocal(ctx.branch()) |
|
33 |
|
34 # map default -> None |
|
35 if branch == 'default' : |
|
36 branch = None |
|
37 |
|
38 # list of tags, without 'tip' tag |
|
39 tags = [tag for tag in ctx.tags() if tag != 'tip'] |
|
40 |
|
41 # ctx's parents |
|
42 parents = [short(p.node()) for p in ctx.parents()] |
|
43 |
|
44 # local modifications? |
|
45 modified = bool(ctx.files() + ctx.deleted()) |
|
46 |
|
47 # done |
|
48 _VERSION = (branch, tags, parents, modified) |
|
49 return _VERSION |
|
50 |
|
51 def version_string (path='.') : |
|
52 """ |
|
53 Return a version string representing the version of the software at the given path. |
|
54 |
|
55 Currently, this assumes that the given path points to a local Mercurial repo. |
|
56 """ |
|
57 |
|
58 try : |
|
59 # get info |
|
60 branch, tags, parents, modified = version_mercurial(path) |
|
61 |
|
62 except : |
|
63 # XXX: ignore |
|
64 raise |
|
65 |
|
66 # tags: <tag> [ "-" <tag> [ ... ]] |
|
67 if tags : |
|
68 return '-'.join(tags) |
|
69 |
|
70 # revision: <parent> [ "+" <parent> [ ... ]] [ "+" ] |
|
71 revision = '+'.join(p for p in parents) + ('+' if modified else '') |
|
72 |
|
73 if branch : |
|
74 # branch: "(" <branch> ")" <revision> |
|
75 return '(%s)%s' % (branch, revision) |
|
76 |
|
77 else : |
|
78 # plain: <revision> |
|
79 return revision |
|
80 |
|
81 def version_link_hg (hgweb_url, path='.') : |
|
82 """ |
|
83 Returns a link to a hgweb page for this version |
|
84 """ |
|
85 |
|
86 # URL for revision ID |
|
87 rev_url = lambda rev: '<a href="%(url)s/rev/%(rev)s">%(rev)s</a>' % dict(url=hgweb_url, rev=rev) |
|
88 |
|
89 # get info |
|
90 branch, tags, parents, modified = version_mercurial(path) |
|
91 |
|
92 # tags: <tag> [ "-" <tag> [ ... ]] [ "+" ] |
|
93 if tags : |
|
94 return '-'.join(rev_url(tag) for tag in tags) + ('+' if modified else '') |
|
95 |
|
96 # revision: <parent> [ "+" <parent> [ ... ]] [ "+" ] |
|
97 revision = '+'.join(rev_url(p) for p in parents) + ('+' if modified else '') |
|
98 |
|
99 if branch : |
|
100 # branch: "(" <branch> ")" <revision> [ "+" ] |
|
101 return '(%s)%s' % (rev_url(branch), revision) + ('+' if modified else '') |
|
102 |
|
103 else : |
|
104 # plain: <revision> |
|
105 return revision |
|
106 |