1395
by Łukasz 'sil2100' Zemczak
Make branch-seeds python3 |
1 |
#! /usr/bin/python3
|
407
by Colin Watson
add new branch-seeds script to branch a set of seed collections when opening a new series |
2 |
|
3 |
# Copyright (C) 2012 Canonical Ltd.
|
|
4 |
# Author: Colin Watson <cjwatson@ubuntu.com>
|
|
5 |
||
6 |
# This program is free software: you can redistribute it and/or modify
|
|
7 |
# it under the terms of the GNU General Public License as published by
|
|
8 |
# the Free Software Foundation; version 3 of the License.
|
|
9 |
#
|
|
10 |
# This program is distributed in the hope that it will be useful,
|
|
11 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 |
# GNU General Public License for more details.
|
|
14 |
#
|
|
15 |
# You should have received a copy of the GNU General Public License
|
|
16 |
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17 |
||
18 |
"""Branch a set of Ubuntu seeds for the next release."""
|
|
19 |
||
20 |
from __future__ import print_function |
|
21 |
||
22 |
from optparse import OptionParser |
|
23 |
import os |
|
24 |
import re |
|
1314
by Łukasz 'sil2100' Zemczak
Make branch-seeds wait a bit for the new git refs to appear before attempting to set the default_branch |
25 |
import time |
407
by Colin Watson
add new branch-seeds script to branch a set of seed collections when opening a new series |
26 |
import subprocess |
27 |
try: |
|
28 |
from urllib.parse import urlparse |
|
29 |
except ImportError: |
|
30 |
from urlparse import urlparse |
|
31 |
||
32 |
from launchpadlib.launchpad import Launchpad |
|
1142.1.2
by Simon Quigley
Refactor some changes after feedback from slangasek. |
33 |
from enum import Enum |
34 |
||
35 |
class VCS(Enum): |
|
36 |
Git = 1 |
|
37 |
Bazaar = 2 |
|
38 |
||
39 |
@staticmethod
|
|
40 |
def detect_vcs(source): |
|
41 |
if os.path.exists(os.path.join(source, ".git")): |
|
42 |
return VCS.Git |
|
43 |
elif os.path.exists(os.path.join(source, ".bzr")): |
|
44 |
return VCS.Bazaar |
|
45 |
else: |
|
46 |
return None |
|
1142.1.1
by Simon Quigley
Add Git support to branch-seeds. |
47 |
|
48 |
||
1143.1.2
by Simon Quigley
Split remote_branch into two different functions dependent on the VCS. |
49 |
def remote_bzr_branch(source): |
50 |
# TODO: should really use bzrlib instead
|
|
51 |
info = subprocess.check_output( |
|
52 |
["bzr", "info", source], universal_newlines=True) |
|
53 |
for line in info.splitlines(): |
|
54 |
if "checkout of branch:" in line: |
|
55 |
return line.split(": ")[1].rstrip("/") |
|
56 |
else: |
|
57 |
raise Exception("Unable to find remote branch for %s" % source) |
|
58 |
||
1150
by Colin Watson
branch-seeds: whitespace nits |
59 |
|
1143.1.4
by Simon Quigley
Add additional code tweaks. |
60 |
def remote_git_repository(source, srcbranch): |
1143.1.3
by Simon Quigley
Make adjustments from Colin's suggestions. |
61 |
fullbranch = subprocess.check_output( |
1150
by Colin Watson
branch-seeds: whitespace nits |
62 |
["git", "rev-parse", "--symbolic-full-name", |
63 |
srcbranch + "@{upstream}"], |
|
1143.1.3
by Simon Quigley
Make adjustments from Colin's suggestions. |
64 |
universal_newlines=True, cwd=source) |
65 |
return subprocess.check_output( |
|
66 |
["git", "ls-remote", "--get-url", fullbranch.split("/")[2]], |
|
1149
by Colin Watson
branch-seeds: move rstrip("\n") to a clearer place |
67 |
universal_newlines=True, cwd=source).rstrip("\n") |
407
by Colin Watson
add new branch-seeds script to branch a set of seed collections when opening a new series |
68 |
|
69 |
||
70 |
def lp_branch(options, url): |
|
71 |
return options.launchpad.branches.getByUniqueName( |
|
72 |
unique_name=urlparse(url).path.lstrip("/")) |
|
73 |
||
74 |
||
75 |
def branch(options, collection): |
|
76 |
source = "%s.%s" % (collection, options.source_series) |
|
77 |
dest = "%s.%s" % (collection, options.dest_series) |
|
1142.1.2
by Simon Quigley
Refactor some changes after feedback from slangasek. |
78 |
vcs = VCS.detect_vcs(source) |
1142.1.3
by Simon Quigley
Reduce to if vcs, rest of that if/else isn't needed. |
79 |
if vcs: |
1142.1.2
by Simon Quigley
Refactor some changes after feedback from slangasek. |
80 |
if vcs is VCS.Bazaar: |
1142.1.1
by Simon Quigley
Add Git support to branch-seeds. |
81 |
subprocess.check_call(["bzr", "up", source]) |
1143.1.2
by Simon Quigley
Split remote_branch into two different functions dependent on the VCS. |
82 |
remote_source = remote_bzr_branch(source) |
1142.1.1
by Simon Quigley
Add Git support to branch-seeds. |
83 |
remote_dest = os.path.join(os.path.dirname(remote_source), dest) |
84 |
subprocess.check_call(["bzr", "branch", source, dest]) |
|
85 |
subprocess.check_call(["bzr", "push", "-d", dest, remote_dest]) |
|
86 |
subprocess.check_call(["bzr", "bind", ":push"], cwd=dest) |
|
87 |
||
88 |
lp_source = lp_branch(options, remote_source) |
|
89 |
lp_source.lifecycle_status = "Mature" |
|
90 |
lp_source.lp_save() |
|
91 |
||
92 |
lp_dest = lp_branch(options, remote_dest) |
|
93 |
lp_dest.lifecycle_status = "Development" |
|
94 |
lp_dest.lp_save() |
|
1142.1.2
by Simon Quigley
Refactor some changes after feedback from slangasek. |
95 |
elif vcs is VCS.Git: |
1142.1.1
by Simon Quigley
Add Git support to branch-seeds. |
96 |
subprocess.check_call(["git", "fetch"], cwd=source) |
1142.1.2
by Simon Quigley
Refactor some changes after feedback from slangasek. |
97 |
subprocess.check_call(["git", "reset", "--hard", "FETCH_HEAD"], cwd=source) |
1142.1.1
by Simon Quigley
Add Git support to branch-seeds. |
98 |
os.rename(source, dest) |
99 |
subprocess.check_call(["git", "checkout", "-b", options.dest_series], cwd=dest) |
|
407
by Colin Watson
add new branch-seeds script to branch a set of seed collections when opening a new series |
100 |
|
101 |
re_include_source = re.compile( |
|
102 |
r"^(include )(.*)\.%s" % options.source_series) |
|
103 |
new_lines = [] |
|
104 |
message = [] |
|
105 |
with open(os.path.join(dest, "STRUCTURE")) as structure: |
|
106 |
for line in structure: |
|
107 |
match = re_include_source.match(line) |
|
108 |
if match: |
|
109 |
new_lines.append(re_include_source.sub( |
|
110 |
r"\1\2.%s" % options.dest_series, line)) |
|
111 |
message.append( |
|
112 |
"%s.%s -> %s.%s" % |
|
113 |
(match.group(2), options.source_series, |
|
114 |
match.group(2), options.dest_series)) |
|
115 |
else: |
|
116 |
new_lines.append(line) |
|
117 |
if message: |
|
118 |
with open(os.path.join(dest, "STRUCTURE.new"), "w") as structure: |
|
119 |
for line in new_lines: |
|
120 |
print(line, end="", file=structure) |
|
121 |
os.rename( |
|
122 |
os.path.join(dest, "STRUCTURE.new"), |
|
123 |
os.path.join(dest, "STRUCTURE")) |
|
1142.1.2
by Simon Quigley
Refactor some changes after feedback from slangasek. |
124 |
if vcs is VCS.Bazaar: |
1142.1.1
by Simon Quigley
Add Git support to branch-seeds. |
125 |
subprocess.check_call( |
126 |
["bzr", "commit", "-m", "; ".join(message)], cwd=dest) |
|
1142.1.2
by Simon Quigley
Refactor some changes after feedback from slangasek. |
127 |
elif vcs is VCS.Git: |
1142.1.1
by Simon Quigley
Add Git support to branch-seeds. |
128 |
subprocess.check_call(["git", "add", "STRUCTURE"], cwd=dest) |
129 |
subprocess.check_call( |
|
1142.1.2
by Simon Quigley
Refactor some changes after feedback from slangasek. |
130 |
["git", "commit", "-m", "; ".join(message)], cwd=dest) |
1142.1.1
by Simon Quigley
Add Git support to branch-seeds. |
131 |
subprocess.check_call( |
132 |
["git", "push", "origin", options.dest_series], cwd=dest) |
|
407
by Colin Watson
add new branch-seeds script to branch a set of seed collections when opening a new series |
133 |
|
1143.1.4
by Simon Quigley
Add additional code tweaks. |
134 |
remote = remote_git_repository(dest, options.source_series) |
1143.1.3
by Simon Quigley
Make adjustments from Colin's suggestions. |
135 |
if "git.launchpad.net" in remote: |
136 |
lp_git_repo = options.launchpad.git_repositories.getByPath( |
|
1150
by Colin Watson
branch-seeds: whitespace nits |
137 |
path=urlparse(remote).path.lstrip("/")) |
1314
by Łukasz 'sil2100' Zemczak
Make branch-seeds wait a bit for the new git refs to appear before attempting to set the default_branch |
138 |
new_ref = "refs/heads/%s" % options.dest_series |
139 |
# Sometimes it takes LP a while to notice the new ref
|
|
140 |
for i in range(10): |
|
141 |
if lp_git_repo.getRefByPath(path=new_ref): |
|
142 |
lp_git_repo.default_branch = new_ref |
|
143 |
lp_git_repo.lp_save() |
|
144 |
break
|
|
145 |
time.sleep(1) |
|
146 |
else: |
|
147 |
raise Exception( |
|
148 |
"Was unable to set default_branch of %s after " |
|
149 |
"multiple retries - proceed manually." % remote) |
|
1143.1.3
by Simon Quigley
Make adjustments from Colin's suggestions. |
150 |
else: |
1150
by Colin Watson
branch-seeds: whitespace nits |
151 |
raise Exception( |
152 |
"Git remote URL must be on git.launchpad.net.") |
|
1143.1.1
by Simon Quigley
Automatically change the default branch in Launchpad once the new branch is made. |
153 |
|
407
by Colin Watson
add new branch-seeds script to branch a set of seed collections when opening a new series |
154 |
|
155 |
def main(): |
|
156 |
parser = OptionParser(usage="usage: %prog [options] collection ...") |
|
157 |
parser.add_option( |
|
158 |
"-l", "--launchpad", dest="launchpad_instance", default="production") |
|
559
by Colin Watson
Remove some hardcoded series names, picking them up by status from Launchpad instead. |
159 |
parser.add_option( |
160 |
"--source-series", |
|
161 |
help="source series (default: current stable release)") |
|
162 |
parser.add_option( |
|
163 |
"--dest-series", |
|
164 |
help="destination series (default: series in pre-release freeze)") |
|
407
by Colin Watson
add new branch-seeds script to branch a set of seed collections when opening a new series |
165 |
options, args = parser.parse_args() |
166 |
if not args: |
|
167 |
parser.error("You must specify at least one seed collection.") |
|
168 |
||
169 |
options.launchpad = Launchpad.login_with( |
|
1143.1.1
by Simon Quigley
Automatically change the default branch in Launchpad once the new branch is made. |
170 |
"branch-seeds", options.launchpad_instance, version="devel") |
407
by Colin Watson
add new branch-seeds script to branch a set of seed collections when opening a new series |
171 |
|
559
by Colin Watson
Remove some hardcoded series names, picking them up by status from Launchpad instead. |
172 |
distro = options.launchpad.distributions["ubuntu"] |
173 |
if options.source_series is None: |
|
174 |
options.source_series = [ |
|
175 |
series.name for series in distro.series |
|
176 |
if series.status == "Current Stable Release"][0] |
|
177 |
if options.dest_series is None: |
|
178 |
options.dest_series = [ |
|
179 |
series.name for series in distro.series |
|
180 |
if series.status == "Pre-release Freeze"][0] |
|
181 |
||
407
by Colin Watson
add new branch-seeds script to branch a set of seed collections when opening a new series |
182 |
for collection in args: |
183 |
branch(options, collection) |
|
184 |
||
185 |
||
186 |
main() |