blob: 2287d09d9a11cd7261f7fe7838854828c3533268 [file] [log] [blame]
Chris Sosadad0d322011-01-31 16:37:33 -08001#!/usr/bin/python
2
Chris Sosa9ba47752012-02-27 15:27:37 -08003# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Sosadad0d322011-01-31 16:37:33 -08004# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""This module uprevs Chrome for cbuildbot.
8
9After calling, it prints outs CHROME_VERSION_ATOM=(version atom string). A
10caller could then use this atom with emerge to build the newly uprevved version
11of Chrome e.g.
12
13./cros_mark_chrome_as_stable tot
14Returns chrome-base/chromeos-chrome-8.0.552.0_alpha_r1
15
16emerge-x86-generic =chrome-base/chromeos-chrome-8.0.552.0_alpha_r1
17"""
18
Chris Sosa8be39132011-04-14 12:09:24 -070019import filecmp
Chris Sosadad0d322011-01-31 16:37:33 -080020import optparse
21import os
22import re
Chris Masone592cab52011-08-02 14:05:48 -070023import sys
petermayo@chromium.org163b3372011-09-12 02:06:05 -040024import time
Chris Sosadad0d322011-01-31 16:37:33 -080025
Mike Frysinger6cb624a2012-05-24 18:17:38 -040026from chromite.buildbot import constants
J. Richard Barnettef6697cf2011-11-18 12:42:08 -080027from chromite.buildbot import portage_utilities
David James1b363582012-12-17 11:53:11 -080028from chromite.lib import cros_build_lib
David Jamesef74b1c2012-11-12 07:47:47 -080029from chromite.lib import gclient
David James97d95872012-11-16 15:09:56 -080030from chromite.lib import git
Mike Frysinger6cb624a2012-05-24 18:17:38 -040031from chromite.scripts import cros_mark_as_stable
Chris Sosadad0d322011-01-31 16:37:33 -080032
Chris Sosadad0d322011-01-31 16:37:33 -080033# Helper regex's for finding ebuilds.
David James7c352bc2013-03-15 14:19:57 -070034_CHROME_VERSION_REGEX = r'\d+\.\d+\.\d+\.\d+'
35_NON_STICKY_REGEX = r'%s[(_rc.*)|(_alpha.*)]+' % _CHROME_VERSION_REGEX
Chris Sosadad0d322011-01-31 16:37:33 -080036
37# Dir where all the action happens.
David James629febb2012-11-25 13:07:34 -080038_CHROME_OVERLAY_DIR = ('%(srcroot)s/third_party/chromiumos-overlay/' +
39 constants.CHROME_CP)
Chris Sosadad0d322011-01-31 16:37:33 -080040
41_GIT_COMMIT_MESSAGE = ('Marking %(chrome_rev)s for chrome ebuild with version '
42 '%(chrome_version)s as stable.')
43
Chris Masone592cab52011-08-02 14:05:48 -070044# URLs that print lists of chrome revisions between two versions of the browser.
45_CHROME_VERSION_URL = ('http://omahaproxy.appspot.com/changelog?'
46 'old_version=%(old)s&new_version=%(new)s')
Chris Sosadd611df2012-02-03 15:26:23 -080047
48# Only print links when we rev these types.
49_REV_TYPES_FOR_LINKS = [constants.CHROME_REV_LATEST,
50 constants.CHROME_REV_STICKY]
Chris Masone592cab52011-08-02 14:05:48 -070051
52_CHROME_SVN_TAG = 'CROS_SVN_COMMIT'
Chris Sosadad0d322011-01-31 16:37:33 -080053
ChromeOS Developer03118eb2013-02-12 14:27:09 -080054
Peter Mayof65b8412011-08-26 01:22:21 -040055def _GetSvnUrl(base_url):
Chris Sosadad0d322011-01-31 16:37:33 -080056 """Returns the path to the svn url for the given chrome branch."""
Peter Mayof65b8412011-08-26 01:22:21 -040057 return os.path.join(base_url, 'trunk')
Chris Sosadad0d322011-01-31 16:37:33 -080058
59
petermayo@chromium.org163b3372011-09-12 02:06:05 -040060def _GetVersionContents(chrome_version_info):
Peter Mayo177500f2011-09-09 17:25:23 -040061 """Returns the current Chromium version, from the contents of a VERSION file.
Chris Sosadad0d322011-01-31 16:37:33 -080062
Peter Mayo177500f2011-09-09 17:25:23 -040063 Args:
64 chrome_version_info: The contents of a chromium VERSION file.
65 """
Chris Sosadad0d322011-01-31 16:37:33 -080066 chrome_version_array = []
Chris Sosadad0d322011-01-31 16:37:33 -080067 for line in chrome_version_info.splitlines():
68 chrome_version_array.append(line.rpartition('=')[2])
69
70 return '.'.join(chrome_version_array)
71
petermayo@chromium.org163b3372011-09-12 02:06:05 -040072def _GetSpecificVersionUrl(base_url, revision, time_to_wait=600):
73 """Returns the Chromium version, from a repository URL and version.
Peter Mayo177500f2011-09-09 17:25:23 -040074
75 Args:
76 base_url: URL for the root of the chromium checkout.
petermayo@chromium.org163b3372011-09-12 02:06:05 -040077 revision: the SVN revision we want to use.
78 time_to_wait: the minimum period before abandoning our wait for the
79 desired revision to be present.
Peter Mayo177500f2011-09-09 17:25:23 -040080 """
petermayo@chromium.org163b3372011-09-12 02:06:05 -040081 svn_url = os.path.join(_GetSvnUrl(base_url), 'src', 'chrome', 'VERSION')
petermayo@chromium.org163b3372011-09-12 02:06:05 -040082 if not revision or not (int(revision) > 0):
83 raise Exception('Revision must be positive, got %s' % revision)
84
85 start = time.time()
86 # Use the fact we are SVN, hence ordered.
87 # Dodge the fact it will silently ignore the revision if it is not
88 # yet known. (i.e. too high)
ChromeOS Developer03118eb2013-02-12 14:27:09 -080089 repo_version = gclient.GetTipOfTrunkSvnRevision(base_url)
petermayo@chromium.org163b3372011-09-12 02:06:05 -040090 while revision > repo_version:
91 if time.time() - start > time_to_wait:
92 raise Exception('Timeout Exceeeded')
93
David James1b363582012-12-17 11:53:11 -080094 msg = 'Repository only has version %s, looking for %s. Sleeping...'
95 cros_build_lib.Info(msg, repo_version, revision)
petermayo@chromium.org163b3372011-09-12 02:06:05 -040096 time.sleep(30)
ChromeOS Developer03118eb2013-02-12 14:27:09 -080097 repo_version = gclient.GetTipOfTrunkSvnRevision(base_url)
petermayo@chromium.org163b3372011-09-12 02:06:05 -040098
ChromeOS Developer03118eb2013-02-12 14:27:09 -080099 chrome_version_info = cros_build_lib.RunCommand(
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400100 ['svn', 'cat', '-r', revision, svn_url],
101 redirect_stdout=True,
102 error_message='Could not read version file at %s revision %s.' %
J. Richard Barnetted422f622011-11-17 09:39:46 -0800103 (svn_url, revision)).output
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400104
105 return _GetVersionContents(chrome_version_info)
106
Peter Mayo177500f2011-09-09 17:25:23 -0400107
108def _GetTipOfTrunkVersionFile(root):
109 """Returns the current Chromium version, from a file in a checkout.
110
111 Args:
112 root: path to the root of the chromium checkout.
113 """
114 version_file = os.path.join(root, 'src', 'chrome', 'VERSION')
ChromeOS Developer03118eb2013-02-12 14:27:09 -0800115 chrome_version_info = cros_build_lib.RunCommand(
Peter Mayo177500f2011-09-09 17:25:23 -0400116 ['cat', version_file],
117 redirect_stdout=True,
J. Richard Barnetted422f622011-11-17 09:39:46 -0800118 error_message='Could not read version file at %s.' % version_file).output
Peter Mayo177500f2011-09-09 17:25:23 -0400119
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400120 return _GetVersionContents(chrome_version_info)
Peter Mayo177500f2011-09-09 17:25:23 -0400121
ChromeOS Developer03118eb2013-02-12 14:27:09 -0800122
Peter Mayof65b8412011-08-26 01:22:21 -0400123def _GetLatestRelease(base_url, branch=None):
Chris Sosadad0d322011-01-31 16:37:33 -0800124 """Gets the latest release version from the buildspec_url for the branch.
125
126 Args:
127 branch: If set, gets the latest release for branch, otherwise latest
128 release.
129 Returns:
130 Latest version string.
131 """
Peter Mayof65b8412011-08-26 01:22:21 -0400132 buildspec_url = os.path.join(base_url, 'releases')
ChromeOS Developer03118eb2013-02-12 14:27:09 -0800133 svn_ls = cros_build_lib.RunCommand(['svn', 'ls', buildspec_url],
134 redirect_stdout=True).output
135 sorted_ls = cros_build_lib.RunCommand(['sort', '--version-sort', '-r'],
136 input=svn_ls,
137 redirect_stdout=True).output
Chris Sosadad0d322011-01-31 16:37:33 -0800138 if branch:
David James7c352bc2013-03-15 14:19:57 -0700139 chrome_version_re = re.compile(r'^%s\.\d+.*' % branch)
Chris Sosadad0d322011-01-31 16:37:33 -0800140 else:
David James7c352bc2013-03-15 14:19:57 -0700141 chrome_version_re = re.compile(r'^[0-9]+\..*')
Chris Sosadad0d322011-01-31 16:37:33 -0800142
Peter Mayoad8173d2011-11-08 16:18:23 -0500143 for chrome_version in sorted_ls.splitlines():
J. Richard Barnetted422f622011-11-17 09:39:46 -0800144 if chrome_version_re.match(chrome_version):
145 deps_url = os.path.join(buildspec_url, chrome_version, 'DEPS')
ChromeOS Developer03118eb2013-02-12 14:27:09 -0800146 deps_check = cros_build_lib.RunCommand(['svn', 'ls', deps_url],
147 error_code_ok=True,
148 redirect_stdout=True).output
J. Richard Barnetted422f622011-11-17 09:39:46 -0800149 if deps_check == 'DEPS\n':
150 return chrome_version.rstrip('/')
Peter Mayoad8173d2011-11-08 16:18:23 -0500151
152 return None
Chris Sosadad0d322011-01-31 16:37:33 -0800153
154
155def _GetStickyEBuild(stable_ebuilds):
156 """Returns the sticky ebuild."""
157 sticky_ebuilds = []
158 non_sticky_re = re.compile(_NON_STICKY_REGEX)
159 for ebuild in stable_ebuilds:
160 if not non_sticky_re.match(ebuild.version):
161 sticky_ebuilds.append(ebuild)
162
163 if not sticky_ebuilds:
164 raise Exception('No sticky ebuilds found')
165 elif len(sticky_ebuilds) > 1:
David James1b363582012-12-17 11:53:11 -0800166 cros_build_lib.Warning('More than one sticky ebuild found')
Chris Sosadad0d322011-01-31 16:37:33 -0800167
J. Richard Barnettef6697cf2011-11-18 12:42:08 -0800168 return portage_utilities.BestEBuild(sticky_ebuilds)
Chris Sosadad0d322011-01-31 16:37:33 -0800169
170
J. Richard Barnettef6697cf2011-11-18 12:42:08 -0800171class ChromeEBuild(portage_utilities.EBuild):
Chris Sosadad0d322011-01-31 16:37:33 -0800172 """Thin sub-class of EBuild that adds a chrome_version field."""
David James7c352bc2013-03-15 14:19:57 -0700173 chrome_version_re = re.compile(r'.*%s-(%s|9999).*' % (
David James629febb2012-11-25 13:07:34 -0800174 constants.CHROME_PN, _CHROME_VERSION_REGEX))
Chris Sosadad0d322011-01-31 16:37:33 -0800175 chrome_version = ''
176
177 def __init__(self, path):
J. Richard Barnettef6697cf2011-11-18 12:42:08 -0800178 portage_utilities.EBuild.__init__(self, path)
Chris Sosadad0d322011-01-31 16:37:33 -0800179 re_match = self.chrome_version_re.match(self.ebuild_path_no_revision)
180 if re_match:
181 self.chrome_version = re_match.group(1)
182
Chris Sosadad0d322011-01-31 16:37:33 -0800183 def __str__(self):
184 return self.ebuild_path
185
186
187def FindChromeCandidates(overlay_dir):
188 """Return a tuple of chrome's unstable ebuild and stable ebuilds.
189
190 Args:
191 overlay_dir: The path to chrome's portage overlay dir.
192 Returns:
193 Tuple [unstable_ebuild, stable_ebuilds].
194 Raises:
195 Exception: if no unstable ebuild exists for Chrome.
196 """
197 stable_ebuilds = []
198 unstable_ebuilds = []
199 for path in [
200 os.path.join(overlay_dir, entry) for entry in os.listdir(overlay_dir)]:
201 if path.endswith('.ebuild'):
202 ebuild = ChromeEBuild(path)
203 if not ebuild.chrome_version:
David James1b363582012-12-17 11:53:11 -0800204 cros_build_lib.Warning('Poorly formatted ebuild found at %s' % path)
Chris Sosadad0d322011-01-31 16:37:33 -0800205 else:
206 if '9999' in ebuild.version:
207 unstable_ebuilds.append(ebuild)
208 else:
209 stable_ebuilds.append(ebuild)
210
211 # Apply some sanity checks.
212 if not unstable_ebuilds:
213 raise Exception('Missing 9999 ebuild for %s' % overlay_dir)
214 if not stable_ebuilds:
David James1b363582012-12-17 11:53:11 -0800215 cros_build_lib.Warning('Missing stable ebuild for %s' % overlay_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800216
J. Richard Barnettef6697cf2011-11-18 12:42:08 -0800217 return portage_utilities.BestEBuild(unstable_ebuilds), stable_ebuilds
Chris Sosadad0d322011-01-31 16:37:33 -0800218
219
220def FindChromeUprevCandidate(stable_ebuilds, chrome_rev, sticky_branch):
221 """Finds the Chrome uprev candidate for the given chrome_rev.
222
223 Using the pre-flight logic, this means the stable ebuild you are uprevving
224 from. The difference here is that the version could be different and in
225 that case we want to find it to delete it.
226
227 Args:
228 stable_ebuilds: A list of stable ebuilds.
229 chrome_rev: The chrome_rev designating which candidate to find.
230 sticky_branch: The the branch that is currently sticky with Major/Minor
Chris Sosa9ba47752012-02-27 15:27:37 -0800231 components. For example: 9.0.553. Can be None but not if chrome_rev
232 is CHROME_REV_STICKY.
Chris Sosadad0d322011-01-31 16:37:33 -0800233 Returns:
234 Returns the EBuild, otherwise None if none found.
235 """
236 candidates = []
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400237 if chrome_rev in [constants.CHROME_REV_LOCAL, constants.CHROME_REV_TOT,
238 constants.CHROME_REV_SPEC]:
239 # These are labelled alpha, for historic reasons,
Peter Mayo177500f2011-09-09 17:25:23 -0400240 # not just for the fun of confusion.
David James7c352bc2013-03-15 14:19:57 -0700241 chrome_branch_re = re.compile(r'%s.*_alpha.*' % _CHROME_VERSION_REGEX)
Chris Sosadad0d322011-01-31 16:37:33 -0800242 for ebuild in stable_ebuilds:
243 if chrome_branch_re.search(ebuild.version):
244 candidates.append(ebuild)
245
Ryan Cuic6e097d2011-06-16 12:23:14 -0700246 elif chrome_rev == constants.CHROME_REV_STICKY:
Chris Sosa9ba47752012-02-27 15:27:37 -0800247 assert sticky_branch is not None
David James7c352bc2013-03-15 14:19:57 -0700248 chrome_branch_re = re.compile(r'%s\..*' % sticky_branch)
Chris Sosadad0d322011-01-31 16:37:33 -0800249 for ebuild in stable_ebuilds:
250 if chrome_branch_re.search(ebuild.version):
251 candidates.append(ebuild)
252
253 else:
David James7c352bc2013-03-15 14:19:57 -0700254 chrome_branch_re = re.compile(r'%s.*_rc.*' % _CHROME_VERSION_REGEX)
Chris Sosadad0d322011-01-31 16:37:33 -0800255 for ebuild in stable_ebuilds:
Chris Sosa9ba47752012-02-27 15:27:37 -0800256 if chrome_branch_re.search(ebuild.version):
Chris Sosadad0d322011-01-31 16:37:33 -0800257 candidates.append(ebuild)
258
259 if candidates:
J. Richard Barnettef6697cf2011-11-18 12:42:08 -0800260 return portage_utilities.BestEBuild(candidates)
Chris Sosadad0d322011-01-31 16:37:33 -0800261 else:
262 return None
263
Chris Masone592cab52011-08-02 14:05:48 -0700264def _AnnotateAndPrint(text, url):
265 """Add buildbot trappings to print <a href='url'>text</a> in the waterfall.
266
267 Args:
268 text: Anchor text for the link
269 url: the URL to which to link
270 """
Don Garrette60de902011-10-17 18:52:05 -0700271 print >> sys.stderr, '\n@@@STEP_LINK@%(text)s@%(url)s@@@' % { 'text': text,
Chris Masone592cab52011-08-02 14:05:48 -0700272 'url': url }
273
274def GetChromeRevisionLinkFromVersions(old_chrome_version, chrome_version):
275 """Return appropriately formatted link to revision info, given versions
276
277 Given two chrome version strings (e.g. 9.0.533.0), generate a link to a
278 page that prints the Chromium revisions between those two versions.
279
280 Args:
281 old_chrome_version: version to diff from
282 chrome_version: version to which to diff
283 Returns:
284 The desired URL.
285 """
286 return _CHROME_VERSION_URL % { 'old': old_chrome_version,
287 'new': chrome_version }
288
Chris Masone592cab52011-08-02 14:05:48 -0700289def GetChromeRevisionListLink(old_chrome, new_chrome, chrome_rev):
290 """Returns a link to the list of revisions between two Chromium versions
291
292 Given two ChromeEBuilds and the kind of rev we're doing, generate a
293 link to a page that prints the Chromium changes between those two
294 revisions, inclusive.
295
296 Args:
297 old_chrome: ebuild for the version to diff from
298 new_chrome: ebuild for the version to which to diff
299 chrome_rev: one of constants.VALID_CHROME_REVISIONS
300 Returns:
301 The desired URL.
302 """
Chris Sosadd611df2012-02-03 15:26:23 -0800303 assert chrome_rev in _REV_TYPES_FOR_LINKS
304 return GetChromeRevisionLinkFromVersions(old_chrome.chrome_version,
305 new_chrome.chrome_version)
Chris Sosadad0d322011-01-31 16:37:33 -0800306
307def MarkChromeEBuildAsStable(stable_candidate, unstable_ebuild, chrome_rev,
Chris Sosa9ba47752012-02-27 15:27:37 -0800308 chrome_version, commit, overlay_dir):
David James7c352bc2013-03-15 14:19:57 -0700309 r"""Uprevs the chrome ebuild specified by chrome_rev.
Chris Sosadad0d322011-01-31 16:37:33 -0800310
311 This is the main function that uprevs the chrome_rev from a stable candidate
312 to its new version.
313
314 Args:
315 stable_candidate: ebuild that corresponds to the stable ebuild we are
316 revving from. If None, builds the a new ebuild given the version
317 and logic for chrome_rev type with revision set to 1.
318 unstable_ebuild: ebuild corresponding to the unstable ebuild for chrome.
Peter Mayo177500f2011-09-09 17:25:23 -0400319 chrome_rev: one of constants.VALID_CHROME_REVISIONS or LOCAL
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400320 constants.CHROME_REV_SPEC - Requires commit value. Revs the ebuild for
321 the specified version and uses the portage suffix of _alpha.
Ryan Cuic6e097d2011-06-16 12:23:14 -0700322 constants.CHROME_REV_TOT - Requires commit value. Revs the ebuild for
323 the TOT version and uses the portage suffix of _alpha.
Peter Mayo177500f2011-09-09 17:25:23 -0400324 constants.CHROME_REV_LOCAL - Requires a chrome_root. Revs the ebuild for
325 the local version and uses the portage suffix of _alpha.
Ryan Cuic6e097d2011-06-16 12:23:14 -0700326 constants.CHROME_REV_LATEST - This uses the portage suffix of _rc as they
327 are release candidates for the next sticky version.
328 constants.CHROME_REV_STICKY - Revs the sticky version.
Chris Sosadad0d322011-01-31 16:37:33 -0800329 chrome_version: The \d.\d.\d.\d version of Chrome.
Ryan Cuic6e097d2011-06-16 12:23:14 -0700330 commit: Used with constants.CHROME_REV_TOT. The svn revision of chrome.
Chris Sosadad0d322011-01-31 16:37:33 -0800331 overlay_dir: Path to the chromeos-chrome package dir.
Chris Sosadad0d322011-01-31 16:37:33 -0800332 Returns:
333 Full portage version atom (including rc's, etc) that was revved.
334 """
Chris Sosa8be39132011-04-14 12:09:24 -0700335 def IsTheNewEBuildRedundant(new_ebuild, stable_ebuild):
336 """Returns True if the new ebuild is redundant.
337
338 This is True if there if the current stable ebuild is the exact same copy
David James89608f92012-11-03 14:14:12 -0700339 of the new one.
Chris Sosa8be39132011-04-14 12:09:24 -0700340 """
341 if not stable_ebuild:
342 return False
343
344 if stable_candidate.chrome_version == new_ebuild.chrome_version:
David James89608f92012-11-03 14:14:12 -0700345 return filecmp.cmp(
346 new_ebuild.ebuild_path, stable_ebuild.ebuild_path, shallow=False)
Chris Sosa8be39132011-04-14 12:09:24 -0700347
David James629febb2012-11-25 13:07:34 -0800348 # Mark latest release and sticky branches as stable.
349 mark_stable = chrome_rev not in [constants.CHROME_REV_TOT,
350 constants.CHROME_REV_SPEC,
351 constants.CHROME_REV_LOCAL]
352
Chris Sosadad0d322011-01-31 16:37:33 -0800353 # Case where we have the last stable candidate with same version just rev.
354 if stable_candidate and stable_candidate.chrome_version == chrome_version:
355 new_ebuild_path = '%s-r%d.ebuild' % (
356 stable_candidate.ebuild_path_no_revision,
357 stable_candidate.current_revision + 1)
358 else:
David James629febb2012-11-25 13:07:34 -0800359 suffix = 'rc' if mark_stable else 'alpha'
360 pf = '%s-%s_%s-r1' % (constants.CHROME_PN, chrome_version, suffix)
361 new_ebuild_path = os.path.join(overlay_dir, '%s.ebuild' % pf)
Chris Sosadad0d322011-01-31 16:37:33 -0800362
David Jamesa6792552012-04-03 10:05:35 -0700363 chrome_variables = dict()
364 if commit:
365 chrome_variables[_CHROME_SVN_TAG] = commit
366
J. Richard Barnette0cfc5052011-11-28 14:31:39 -0800367 portage_utilities.EBuild.MarkAsStable(
David James065b2012012-04-01 14:51:11 -0700368 unstable_ebuild.ebuild_path, new_ebuild_path,
David Jamesa6792552012-04-03 10:05:35 -0700369 chrome_variables, make_stable=mark_stable)
Chris Sosadad0d322011-01-31 16:37:33 -0800370 new_ebuild = ChromeEBuild(new_ebuild_path)
Chris Sosa8be39132011-04-14 12:09:24 -0700371
372 # Determine whether this is ebuild is redundant.
373 if IsTheNewEBuildRedundant(new_ebuild, stable_candidate):
David James1b363582012-12-17 11:53:11 -0800374 msg = 'Previous ebuild with same version found and ebuild is redundant.'
375 cros_build_lib.Info(msg)
Chris Sosa8be39132011-04-14 12:09:24 -0700376 os.unlink(new_ebuild_path)
377 return None
Chris Sosadad0d322011-01-31 16:37:33 -0800378
Chris Sosadd611df2012-02-03 15:26:23 -0800379 if stable_candidate and chrome_rev in _REV_TYPES_FOR_LINKS:
Chris Masone592cab52011-08-02 14:05:48 -0700380 _AnnotateAndPrint('Chromium revisions',
381 GetChromeRevisionListLink(stable_candidate,
382 new_ebuild,
383 chrome_rev))
384
David James67d73252013-09-19 17:33:12 -0700385 git.RunGit(overlay_dir, ['add', new_ebuild_path])
Chris Sosa9ba47752012-02-27 15:27:37 -0800386 if stable_candidate and not stable_candidate.IsSticky():
David James67d73252013-09-19 17:33:12 -0700387 git.RunGit(overlay_dir, ['rm', stable_candidate.ebuild_path])
Chris Sosadad0d322011-01-31 16:37:33 -0800388
J. Richard Barnette0cfc5052011-11-28 14:31:39 -0800389 portage_utilities.EBuild.CommitChange(
Chris Sosadad0d322011-01-31 16:37:33 -0800390 _GIT_COMMIT_MESSAGE % {'chrome_rev': chrome_rev,
Mike Frysinger2ebe3732012-05-08 17:04:12 -0400391 'chrome_version': chrome_version},
392 overlay_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800393
Chris Sosadad0d322011-01-31 16:37:33 -0800394 return '%s-%s' % (new_ebuild.package, new_ebuild.version)
395
396
Chris Sosad53f8fd2011-10-21 15:15:19 -0700397def ParseMaxRevision(revision_list):
398 """Returns the max revision from a list of url@revision string."""
David James7c352bc2013-03-15 14:19:57 -0700399 revision_re = re.compile(r'.*@(\d+)')
Chris Sosad53f8fd2011-10-21 15:15:19 -0700400
401 def RevisionKey(revision):
402 return revision_re.match(revision).group(1)
403
404 max_revision = max(revision_list.split(), key=RevisionKey)
405 return max_revision.rpartition('@')[2]
406
407
David James1b363582012-12-17 11:53:11 -0800408def main(_argv):
Chris Sosa0f295aa2011-10-21 14:10:28 -0700409 usage_options = '|'.join(constants.VALID_CHROME_REVISIONS)
Ryan Cuic6e097d2011-06-16 12:23:14 -0700410 usage = '%s OPTIONS [%s]' % (__file__, usage_options)
Chris Sosadad0d322011-01-31 16:37:33 -0800411 parser = optparse.OptionParser(usage)
David Jamescc09c9b2012-01-26 22:10:13 -0800412 parser.add_option('-b', '--boards', default='x86-generic')
David Jamesef74b1c2012-11-12 07:47:47 -0800413 parser.add_option('-c', '--chrome_url', default=gclient.GetBaseURLs()[0])
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400414 parser.add_option('-f', '--force_revision', default=None)
Chris Sosadad0d322011-01-31 16:37:33 -0800415 parser.add_option('-s', '--srcroot', default=os.path.join(os.environ['HOME'],
416 'trunk', 'src'),
417 help='Path to the src directory')
418 parser.add_option('-t', '--tracking_branch', default='cros/master',
419 help='Branch we are tracking changes against')
420 (options, args) = parser.parse_args()
421
Ryan Cuic6e097d2011-06-16 12:23:14 -0700422 if len(args) != 1 or args[0] not in constants.VALID_CHROME_REVISIONS:
423 parser.error('Commit requires arg set to one of %s.'
424 % constants.VALID_CHROME_REVISIONS)
Chris Sosadad0d322011-01-31 16:37:33 -0800425
426 overlay_dir = os.path.abspath(_CHROME_OVERLAY_DIR %
427 {'srcroot': options.srcroot})
428 chrome_rev = args[0]
429 version_to_uprev = None
430 commit_to_use = None
Chris Sosa9ba47752012-02-27 15:27:37 -0800431 sticky_branch = None
Chris Sosadad0d322011-01-31 16:37:33 -0800432
433 (unstable_ebuild, stable_ebuilds) = FindChromeCandidates(overlay_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800434
Peter Mayo177500f2011-09-09 17:25:23 -0400435 if chrome_rev == constants.CHROME_REV_LOCAL:
436 if 'CHROME_ROOT' in os.environ:
437 chrome_root = os.environ['CHROME_ROOT']
438 else:
439 chrome_root = os.path.join(os.environ['HOME'], 'chrome_root')
440
441 version_to_uprev = _GetTipOfTrunkVersionFile(chrome_root)
442 commit_to_use = 'Unknown'
David James1b363582012-12-17 11:53:11 -0800443 cros_build_lib.Info('Using local source, versioning is untrustworthy.')
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400444 elif chrome_rev == constants.CHROME_REV_SPEC:
445 commit_to_use = options.force_revision
Chris Sosad53f8fd2011-10-21 15:15:19 -0700446 if '@' in commit_to_use: commit_to_use = ParseMaxRevision(commit_to_use)
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400447 version_to_uprev = _GetSpecificVersionUrl(options.chrome_url,
448 commit_to_use)
Peter Mayo177500f2011-09-09 17:25:23 -0400449 elif chrome_rev == constants.CHROME_REV_TOT:
ChromeOS Developer03118eb2013-02-12 14:27:09 -0800450 commit_to_use = gclient.GetTipOfTrunkSvnRevision(options.chrome_url)
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400451 version_to_uprev = _GetSpecificVersionUrl(options.chrome_url,
452 commit_to_use)
Ryan Cuic6e097d2011-06-16 12:23:14 -0700453 elif chrome_rev == constants.CHROME_REV_LATEST:
Peter Mayof65b8412011-08-26 01:22:21 -0400454 version_to_uprev = _GetLatestRelease(options.chrome_url)
Chris Sosadad0d322011-01-31 16:37:33 -0800455 else:
Chris Sosa9ba47752012-02-27 15:27:37 -0800456 sticky_ebuild = _GetStickyEBuild(stable_ebuilds)
457 sticky_version = sticky_ebuild.chrome_version
458 sticky_branch = sticky_version.rpartition('.')[0]
Peter Mayof65b8412011-08-26 01:22:21 -0400459 version_to_uprev = _GetLatestRelease(options.chrome_url, sticky_branch)
Chris Sosadad0d322011-01-31 16:37:33 -0800460
461 stable_candidate = FindChromeUprevCandidate(stable_ebuilds, chrome_rev,
462 sticky_branch)
463
464 if stable_candidate:
David James1b363582012-12-17 11:53:11 -0800465 cros_build_lib.Info('Stable candidate found %s' % stable_candidate)
Chris Sosadad0d322011-01-31 16:37:33 -0800466 else:
David James1b363582012-12-17 11:53:11 -0800467 cros_build_lib.Info('No stable candidate found.')
Chris Sosadad0d322011-01-31 16:37:33 -0800468
Chris Sosa8049f3b2011-05-02 20:09:28 -0700469 tracking_branch = 'remotes/m/%s' % os.path.basename(options.tracking_branch)
David James97d95872012-11-16 15:09:56 -0800470 existing_branch = git.GetCurrentBranch(overlay_dir)
Ryan Cui05a31ba2011-05-31 17:47:37 -0700471 work_branch = cros_mark_as_stable.GitBranch(constants.STABLE_EBUILD_BRANCH,
Mike Frysinger2ebe3732012-05-08 17:04:12 -0400472 tracking_branch, overlay_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800473 work_branch.CreateBranch()
David Jamesd6708c02012-03-22 10:49:15 -0700474
475 # In the case of uprevving overlays that have patches applied to them,
476 # include the patched changes in the stabilizing branch.
477 if existing_branch:
David James67d73252013-09-19 17:33:12 -0700478 git.RunGit(overlay_dir, ['rebase', existing_branch])
David Jamesd6708c02012-03-22 10:49:15 -0700479
Chris Sosadad0d322011-01-31 16:37:33 -0800480 chrome_version_atom = MarkChromeEBuildAsStable(
481 stable_candidate, unstable_ebuild, chrome_rev, version_to_uprev,
Chris Sosa9ba47752012-02-27 15:27:37 -0800482 commit_to_use, overlay_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800483 # Explicit print to communicate to caller.
484 if chrome_version_atom:
David Jamescc09c9b2012-01-26 22:10:13 -0800485 cros_mark_as_stable.CleanStalePackages(options.boards.split(':'),
486 [chrome_version_atom])
Chris Sosadad0d322011-01-31 16:37:33 -0800487 print 'CHROME_VERSION_ATOM=%s' % chrome_version_atom