1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#!/usr/bin/env python
from textwrap import dedent
import re
import subprocess
import sys
import urllib2
from bzrlib.branch import Branch
from bzrlib.plugin import load_plugins
from bzrlib.revisionspec import RevisionSpec
def parse_version(string):
return re.search('^const version = "(.*)"', string, re.M).group(1)
def ls_remote(repo_url, ref, head=False, tag=False):
"""Return a tuple fo the matching commit hash and ref.
None, None is returned when no matching commit was found.
:raise: an exception when more than one commit matched
:return: a tuple of commit, ref
"""
command = ['git', 'ls-remote']
if head:
command.append('--heads')
if tag:
command.append('--tags')
command.extend([repo_url, ref])
found = subprocess.check_output(command)
found = found.strip()
if len(found) == 0:
return None, None
if len(found.split('\n')) > 1:
raise Exception(
"More than one commit matched the branch or tag:\n{}".format(found))
commit, ref = found.split('\t')
return commit, ref
def get_git_revision_info(branch, revision_spec):
"""Find the commit and juju-core version of a branch.
Returns a tuple comparable to revno, revision-id, version.
The revno is always None. The revision-id is the commit hash.
:param branch: The location of the git branch.
:param revision_spec: a human-readable revision spec like 'HEAD', '1.18.0',
or '1dcf4e4fe1'
:return: a tuple of None, revision-id, version
"""
protocol, branch_name, repo_name = branch.split(':')
repo_url = 'https://{}.git'.format(repo_name)
if revision_spec in (None, '-1', 'HEAD'):
commit, ref = ls_remote(repo_url, branch_name, head=True)
else:
commit, ref = ls_remote(repo_url, revision_spec, tag=True)
if commit is None:
commit = revision_spec
domain, user, repo = repo_name.split('/')
template = 'https://raw.githubusercontent.com/{}/{}/{}/version/version.go'
file_url = template.format(user, repo, commit)
response = urllib2.urlopen(file_url)
version = parse_version(response.read())
return None, commit, version
def get_bzr_revision_info(branch, revision_spec):
"""Find the revision_id, revno and juju-core version of a branch.
:param branch: The location of the branch.
:param revision_spec: a human-readable revision spec like '-1', 'revno:5'
or 'revid:asdf'
:return: a tuple of revno, revision-id, version
"""
candidate = Branch.open(branch)
candidate.lock_read()
try:
info = RevisionSpec.from_string(revision_spec).in_history(candidate)
tree = candidate.repository.revision_tree(info.rev_id)
tree.lock_read()
try:
file_id = tree.path2id('version/version.go')
v_bytes = tree.get_file_text(file_id, path='version/version.go')
finally:
tree.unlock()
version = parse_version(v_bytes)
return info.revno, info.rev_id, version
finally:
candidate.unlock()
if __name__ == '__main__':
load_plugins()
branch = sys.argv[1]
if sys.argv[1].startswith('lp:'):
revision_spec = sys.argv[2] if len(sys.argv) > 2 else 'revno:-1'
revno, revision_id, version = get_bzr_revision_info(
branch, revision_spec)
else:
revision_spec = sys.argv[2] if len(sys.argv) > 2 else None
revno, revision_id, version = get_git_revision_info(
branch, revision_spec)
with open('buildvars.bash', 'w') as f:
f.write(dedent("""\
export BRANCH=%s
export REVISION_ID='%s'
export VERSION=%s
""" % (branch, revision_id, version)))
if revno is not None:
f.write('export REVNO=%s\n' % revno)
|