Merge lp:~niedbalski/juju-deployer/add-refspecs into lp:juju-deployer

Proposed by Jorge Niedbalski on 2016-03-02
Status: Merged
Merged at revision: 164
Proposed branch: lp:~niedbalski/juju-deployer/add-refspecs
Merge into: lp:juju-deployer
Diff against target: 128 lines (+59/-5)
3 files modified
deployer/charm.py (+9/-3)
deployer/tests/test_charm.py (+17/-0)
deployer/vcs.py (+33/-2)
To merge this branch: bzr merge lp:~niedbalski/juju-deployer/add-refspecs
Reviewer Review Type Date Requested Status
Tim Van Steenburgh 2016-03-02 Approve on 2016-03-02
Review via email: mp+287829@code.launchpad.net

Description of the Change

Dear Maintainer,

This change extends the VCS class for being able to handle extended options for a given branch. Extended options are passed as query string arguments following the branch name. As an example:

$ cat configs/changeref.yaml

refspec:
    series: trusty
    services:
        ceilometer:
            branch: https://review.openstack.org/openstack/charm-ceilometer#changeref=286669/1

On this case the #changeref parameter is used. Having extended options
allows to implement more fine grained VCS operations such as fetching a special change reference.

On this patch I also propose to extend the branch method of the Git base class in order to fetch any given changeref.

A Test and a sample config are also part of the change set.

Thanks.

To post a comment you must log in.
167. By Jorge Niedbalski on 2016-03-02

CHanged refspec to changeref

168. By Jorge Niedbalski on 2016-03-02

Added git.launchpad.net as well

Tim Van Steenburgh (tvansteenburgh) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'deployer/charm.py'
2--- deployer/charm.py 2015-09-16 19:54:35 +0000
3+++ deployer/charm.py 2016-03-02 19:04:13 +0000
4@@ -29,12 +29,18 @@
5 self._build = build
6 self.vcs = self.get_vcs()
7
8+ def is_git_branch(self):
9+ return self.branch.startswith('git') or \
10+ self.branch.find("review.openstack.org") != -1 or \
11+ "github.com" in self.branch or \
12+ "git.launchpad.net" in self.branch or \
13+ os.path.exists(os.path.join(self.branch, '.git'))
14+
15 def get_vcs(self):
16 if not self.branch:
17 return None
18- if self.branch.startswith('git') or 'github.com' in self.branch or \
19- 'git.launchpad.net' in self.branch or \
20- os.path.exists(os.path.join(self.branch, '.git')):
21+
22+ if self.is_git_branch():
23 return Git(self.path, self.branch, self.log)
24 elif self.branch.startswith("bzr") or self.branch.startswith('lp:') \
25 or os.path.exists(os.path.join(self.branch, '.bzr')) \
26
27=== modified file 'deployer/tests/test_charm.py'
28--- deployer/tests/test_charm.py 2015-07-29 21:19:32 +0000
29+++ deployer/tests/test_charm.py 2016-03-02 19:04:13 +0000
30@@ -291,6 +291,23 @@
31 charm.fetch()
32 self.assertEqual(charm.vcs.get_cur_rev(), self.tagged_revision)
33
34+ def test_vcs_fetch_with_refspec(self):
35+ self.setup_vcs_charm()
36+ params = dict(self.charm_data)
37+ params['branch'] = \
38+ "https://review.openstack.org/openstack/charm-ceilometer" + \
39+ "#changeref=286669/1"
40+
41+ charm = Charm.from_service(
42+ "scratch", self.repo_path, "trusty", params)
43+ charm.fetch()
44+
45+ self.assertEqual(charm.vcs.get_remote_origin(),
46+ "https://review.openstack.org/" +
47+ "openstack/charm-ceilometer")
48+ self.assertEqual(charm.vcs.extended_options,
49+ {'changeref': "286669/1"})
50+
51 def test_charm_vcs_unknown(self):
52 branch = self.mkdir()
53 params = {
54
55=== modified file 'deployer/vcs.py'
56--- deployer/vcs.py 2015-07-21 07:50:08 +0000
57+++ deployer/vcs.py 2016-03-02 19:04:13 +0000
58@@ -1,5 +1,6 @@
59 import subprocess
60 import os
61+import re
62
63 from bzrlib.workingtree import WorkingTree
64
65@@ -20,7 +21,12 @@
66 def __init__(self, path, origin, log):
67 self.path = path
68 self.log = log
69- self.origin = origin
70+ self.extended_options = self.get_extended_options(origin)
71+
72+ if self.extended_options:
73+ self.origin = origin.split("#")[0]
74+ else:
75+ self.origin = origin
76
77 def _call(self, args, error_msg, cwd=None, stderr=()):
78 try:
79@@ -29,7 +35,6 @@
80 output = subprocess.check_output(
81 args, cwd=cwd or self.path, stderr=stderr)
82 except subprocess.CalledProcessError, e:
83- #print "vcs err", " ".join(args), "[dir: %s]" % cwd, e.output
84 self.log.error(error_msg % self.get_err_msg_ctx(e))
85 raise ErrorExit()
86 return output.strip()
87@@ -42,6 +47,20 @@
88 'output': e.output,
89 'vcs': self.__class__.__name__.lower()}
90
91+ def get_extended_options(self, origin):
92+ regexp = re.compile(r"[\?#&](?P<name>[^&=]+)=(?P<value>[^&=]+)")
93+ matched = regexp.findall(origin)
94+
95+ if matched:
96+ ret = dict()
97+ for option in matched:
98+ (name, value) = option
99+ if name in ret:
100+ raise Exception("%s option already defined" % name)
101+ ret[name] = value
102+ return ret
103+ return {}
104+
105 def get_cur_rev(self):
106 raise NotImplementedError()
107
108@@ -103,8 +122,20 @@
109 cwd = os.path.dirname(os.path.dirname(self.path))
110 if not cwd:
111 cwd = "."
112+
113 self._call(params, self.err_branch, cwd)
114
115+ change_ref = self.extended_options.get('changeref', None)
116+ if change_ref:
117+ change_ref = 'refs/changes/{}/{}'.format(
118+ change_ref.split("/")[0][-2:], change_ref)
119+
120+ self._call(["git", "fetch", "--depth", "1",
121+ self.origin, change_ref],
122+ self.err_branch, self.path)
123+ self._call(["git", "checkout", "FETCH_HEAD"], self.err_branch,
124+ self.path)
125+
126 def is_modified(self):
127 params = ["git", "status", "-s"]
128 return bool(self._call(params, self.err_is_mod).strip())

Subscribers

People subscribed via source and target branches