blob: db7878fd04bd6de93272d6ab61785fd726ebda99 [file] [log] [blame]
Chris Sosadad0d322011-01-31 16:37:33 -08001#!/usr/bin/python
Chris Sosa9ba47752012-02-27 15:27:37 -08002# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Sosadad0d322011-01-31 16:37:33 -08003# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""This module uprevs Chrome for cbuildbot.
7
8After calling, it prints outs CHROME_VERSION_ATOM=(version atom string). A
9caller could then use this atom with emerge to build the newly uprevved version
10of Chrome e.g.
11
12./cros_mark_chrome_as_stable tot
13Returns chrome-base/chromeos-chrome-8.0.552.0_alpha_r1
14
15emerge-x86-generic =chrome-base/chromeos-chrome-8.0.552.0_alpha_r1
16"""
17
Chris Sosa8be39132011-04-14 12:09:24 -070018import filecmp
Chris Sosadad0d322011-01-31 16:37:33 -080019import optparse
20import os
21import re
Chris Masone592cab52011-08-02 14:05:48 -070022import sys
petermayo@chromium.org163b3372011-09-12 02:06:05 -040023import time
Chris Sosadad0d322011-01-31 16:37:33 -080024
Mike Frysinger6cb624a2012-05-24 18:17:38 -040025from chromite.buildbot import constants
J. Richard Barnettef6697cf2011-11-18 12:42:08 -080026from chromite.buildbot import portage_utilities
David James1b363582012-12-17 11:53:11 -080027from chromite.lib import cros_build_lib
David Jamesef74b1c2012-11-12 07:47:47 -080028from chromite.lib import gclient
David James97d95872012-11-16 15:09:56 -080029from chromite.lib import git
Mike Frysinger6cb624a2012-05-24 18:17:38 -040030from chromite.scripts import cros_mark_as_stable
Chris Sosadad0d322011-01-31 16:37:33 -080031
Chris Sosadad0d322011-01-31 16:37:33 -080032# Helper regex's for finding ebuilds.
David James7c352bc2013-03-15 14:19:57 -070033_CHROME_VERSION_REGEX = r'\d+\.\d+\.\d+\.\d+'
34_NON_STICKY_REGEX = r'%s[(_rc.*)|(_alpha.*)]+' % _CHROME_VERSION_REGEX
Chris Sosadad0d322011-01-31 16:37:33 -080035
36# Dir where all the action happens.
David James629febb2012-11-25 13:07:34 -080037_CHROME_OVERLAY_DIR = ('%(srcroot)s/third_party/chromiumos-overlay/' +
38 constants.CHROME_CP)
Chris Sosadad0d322011-01-31 16:37:33 -080039
40_GIT_COMMIT_MESSAGE = ('Marking %(chrome_rev)s for chrome ebuild with version '
41 '%(chrome_version)s as stable.')
42
Chris Masone592cab52011-08-02 14:05:48 -070043# URLs that print lists of chrome revisions between two versions of the browser.
44_CHROME_VERSION_URL = ('http://omahaproxy.appspot.com/changelog?'
45 'old_version=%(old)s&new_version=%(new)s')
Chris Sosadd611df2012-02-03 15:26:23 -080046
47# Only print links when we rev these types.
48_REV_TYPES_FOR_LINKS = [constants.CHROME_REV_LATEST,
49 constants.CHROME_REV_STICKY]
Chris Masone592cab52011-08-02 14:05:48 -070050
51_CHROME_SVN_TAG = 'CROS_SVN_COMMIT'
Chris Sosadad0d322011-01-31 16:37:33 -080052
ChromeOS Developer03118eb2013-02-12 14:27:09 -080053
Peter Mayof65b8412011-08-26 01:22:21 -040054def _GetSvnUrl(base_url):
Chris Sosadad0d322011-01-31 16:37:33 -080055 """Returns the path to the svn url for the given chrome branch."""
Peter Mayof65b8412011-08-26 01:22:21 -040056 return os.path.join(base_url, 'trunk')
Chris Sosadad0d322011-01-31 16:37:33 -080057
58
petermayo@chromium.org163b3372011-09-12 02:06:05 -040059def _GetVersionContents(chrome_version_info):
Peter Mayo177500f2011-09-09 17:25:23 -040060 """Returns the current Chromium version, from the contents of a VERSION file.
Chris Sosadad0d322011-01-31 16:37:33 -080061
Peter Mayo177500f2011-09-09 17:25:23 -040062 Args:
63 chrome_version_info: The contents of a chromium VERSION file.
64 """
Chris Sosadad0d322011-01-31 16:37:33 -080065 chrome_version_array = []
Chris Sosadad0d322011-01-31 16:37:33 -080066 for line in chrome_version_info.splitlines():
67 chrome_version_array.append(line.rpartition('=')[2])
68
69 return '.'.join(chrome_version_array)
70
petermayo@chromium.org163b3372011-09-12 02:06:05 -040071def _GetSpecificVersionUrl(base_url, revision, time_to_wait=600):
72 """Returns the Chromium version, from a repository URL and version.
Peter Mayo177500f2011-09-09 17:25:23 -040073
74 Args:
75 base_url: URL for the root of the chromium checkout.
petermayo@chromium.org163b3372011-09-12 02:06:05 -040076 revision: the SVN revision we want to use.
77 time_to_wait: the minimum period before abandoning our wait for the
78 desired revision to be present.
Peter Mayo177500f2011-09-09 17:25:23 -040079 """
petermayo@chromium.org163b3372011-09-12 02:06:05 -040080 svn_url = os.path.join(_GetSvnUrl(base_url), 'src', 'chrome', 'VERSION')
petermayo@chromium.org163b3372011-09-12 02:06:05 -040081 if not revision or not (int(revision) > 0):
82 raise Exception('Revision must be positive, got %s' % revision)
83
84 start = time.time()
85 # Use the fact we are SVN, hence ordered.
86 # Dodge the fact it will silently ignore the revision if it is not
87 # yet known. (i.e. too high)
ChromeOS Developer03118eb2013-02-12 14:27:09 -080088 repo_version = gclient.GetTipOfTrunkSvnRevision(base_url)
petermayo@chromium.org163b3372011-09-12 02:06:05 -040089 while revision > repo_version:
90 if time.time() - start > time_to_wait:
91 raise Exception('Timeout Exceeeded')
92
David James1b363582012-12-17 11:53:11 -080093 msg = 'Repository only has version %s, looking for %s. Sleeping...'
94 cros_build_lib.Info(msg, repo_version, revision)
petermayo@chromium.org163b3372011-09-12 02:06:05 -040095 time.sleep(30)
ChromeOS Developer03118eb2013-02-12 14:27:09 -080096 repo_version = gclient.GetTipOfTrunkSvnRevision(base_url)
petermayo@chromium.org163b3372011-09-12 02:06:05 -040097
ChromeOS Developer03118eb2013-02-12 14:27:09 -080098 chrome_version_info = cros_build_lib.RunCommand(
petermayo@chromium.org163b3372011-09-12 02:06:05 -040099 ['svn', 'cat', '-r', revision, svn_url],
100 redirect_stdout=True,
101 error_message='Could not read version file at %s revision %s.' %
J. Richard Barnetted422f622011-11-17 09:39:46 -0800102 (svn_url, revision)).output
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400103
104 return _GetVersionContents(chrome_version_info)
105
Peter Mayo177500f2011-09-09 17:25:23 -0400106
107def _GetTipOfTrunkVersionFile(root):
108 """Returns the current Chromium version, from a file in a checkout.
109
110 Args:
111 root: path to the root of the chromium checkout.
112 """
113 version_file = os.path.join(root, 'src', 'chrome', 'VERSION')
ChromeOS Developer03118eb2013-02-12 14:27:09 -0800114 chrome_version_info = cros_build_lib.RunCommand(
Peter Mayo177500f2011-09-09 17:25:23 -0400115 ['cat', version_file],
116 redirect_stdout=True,
J. Richard Barnetted422f622011-11-17 09:39:46 -0800117 error_message='Could not read version file at %s.' % version_file).output
Peter Mayo177500f2011-09-09 17:25:23 -0400118
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400119 return _GetVersionContents(chrome_version_info)
Peter Mayo177500f2011-09-09 17:25:23 -0400120
ChromeOS Developer03118eb2013-02-12 14:27:09 -0800121
Peter Mayof65b8412011-08-26 01:22:21 -0400122def _GetLatestRelease(base_url, branch=None):
Chris Sosadad0d322011-01-31 16:37:33 -0800123 """Gets the latest release version from the buildspec_url for the branch.
124
125 Args:
Don Garrett25f309a2014-03-19 14:02:12 -0700126 base_url: Base URL for the SVN repository.
Mike Frysingerad8c6ca2014-02-03 11:28:45 -0500127 branch: If set, gets the latest release for branch, otherwise latest
Chris Sosadad0d322011-01-31 16:37:33 -0800128 release.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500129
Chris Sosadad0d322011-01-31 16:37:33 -0800130 Returns:
131 Latest version string.
132 """
Peter Mayof65b8412011-08-26 01:22:21 -0400133 buildspec_url = os.path.join(base_url, 'releases')
ChromeOS Developer03118eb2013-02-12 14:27:09 -0800134 svn_ls = cros_build_lib.RunCommand(['svn', 'ls', buildspec_url],
135 redirect_stdout=True).output
136 sorted_ls = cros_build_lib.RunCommand(['sort', '--version-sort', '-r'],
137 input=svn_ls,
138 redirect_stdout=True).output
Chris Sosadad0d322011-01-31 16:37:33 -0800139 if branch:
David James7c352bc2013-03-15 14:19:57 -0700140 chrome_version_re = re.compile(r'^%s\.\d+.*' % branch)
Chris Sosadad0d322011-01-31 16:37:33 -0800141 else:
David James7c352bc2013-03-15 14:19:57 -0700142 chrome_version_re = re.compile(r'^[0-9]+\..*')
Chris Sosadad0d322011-01-31 16:37:33 -0800143
Peter Mayoad8173d2011-11-08 16:18:23 -0500144 for chrome_version in sorted_ls.splitlines():
J. Richard Barnetted422f622011-11-17 09:39:46 -0800145 if chrome_version_re.match(chrome_version):
146 deps_url = os.path.join(buildspec_url, chrome_version, 'DEPS')
ChromeOS Developer03118eb2013-02-12 14:27:09 -0800147 deps_check = cros_build_lib.RunCommand(['svn', 'ls', deps_url],
148 error_code_ok=True,
149 redirect_stdout=True).output
J. Richard Barnetted422f622011-11-17 09:39:46 -0800150 if deps_check == 'DEPS\n':
151 return chrome_version.rstrip('/')
Peter Mayoad8173d2011-11-08 16:18:23 -0500152
153 return None
Chris Sosadad0d322011-01-31 16:37:33 -0800154
155
156def _GetStickyEBuild(stable_ebuilds):
157 """Returns the sticky ebuild."""
158 sticky_ebuilds = []
159 non_sticky_re = re.compile(_NON_STICKY_REGEX)
160 for ebuild in stable_ebuilds:
161 if not non_sticky_re.match(ebuild.version):
162 sticky_ebuilds.append(ebuild)
163
164 if not sticky_ebuilds:
165 raise Exception('No sticky ebuilds found')
166 elif len(sticky_ebuilds) > 1:
David James1b363582012-12-17 11:53:11 -0800167 cros_build_lib.Warning('More than one sticky ebuild found')
Chris Sosadad0d322011-01-31 16:37:33 -0800168
J. Richard Barnettef6697cf2011-11-18 12:42:08 -0800169 return portage_utilities.BestEBuild(sticky_ebuilds)
Chris Sosadad0d322011-01-31 16:37:33 -0800170
171
J. Richard Barnettef6697cf2011-11-18 12:42:08 -0800172class ChromeEBuild(portage_utilities.EBuild):
Chris Sosadad0d322011-01-31 16:37:33 -0800173 """Thin sub-class of EBuild that adds a chrome_version field."""
David James7c352bc2013-03-15 14:19:57 -0700174 chrome_version_re = re.compile(r'.*%s-(%s|9999).*' % (
David James629febb2012-11-25 13:07:34 -0800175 constants.CHROME_PN, _CHROME_VERSION_REGEX))
Chris Sosadad0d322011-01-31 16:37:33 -0800176 chrome_version = ''
177
178 def __init__(self, path):
J. Richard Barnettef6697cf2011-11-18 12:42:08 -0800179 portage_utilities.EBuild.__init__(self, path)
Chris Sosadad0d322011-01-31 16:37:33 -0800180 re_match = self.chrome_version_re.match(self.ebuild_path_no_revision)
181 if re_match:
182 self.chrome_version = re_match.group(1)
183
Chris Sosadad0d322011-01-31 16:37:33 -0800184 def __str__(self):
185 return self.ebuild_path
186
187
188def FindChromeCandidates(overlay_dir):
189 """Return a tuple of chrome's unstable ebuild and stable ebuilds.
190
191 Args:
192 overlay_dir: The path to chrome's portage overlay dir.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500193
Chris Sosadad0d322011-01-31 16:37:33 -0800194 Returns:
195 Tuple [unstable_ebuild, stable_ebuilds].
Mike Frysinger1a736a82013-12-12 01:50:59 -0500196
Chris Sosadad0d322011-01-31 16:37:33 -0800197 Raises:
198 Exception: if no unstable ebuild exists for Chrome.
199 """
200 stable_ebuilds = []
201 unstable_ebuilds = []
202 for path in [
203 os.path.join(overlay_dir, entry) for entry in os.listdir(overlay_dir)]:
204 if path.endswith('.ebuild'):
205 ebuild = ChromeEBuild(path)
206 if not ebuild.chrome_version:
David James1b363582012-12-17 11:53:11 -0800207 cros_build_lib.Warning('Poorly formatted ebuild found at %s' % path)
Chris Sosadad0d322011-01-31 16:37:33 -0800208 else:
209 if '9999' in ebuild.version:
210 unstable_ebuilds.append(ebuild)
211 else:
212 stable_ebuilds.append(ebuild)
213
214 # Apply some sanity checks.
215 if not unstable_ebuilds:
216 raise Exception('Missing 9999 ebuild for %s' % overlay_dir)
217 if not stable_ebuilds:
David James1b363582012-12-17 11:53:11 -0800218 cros_build_lib.Warning('Missing stable ebuild for %s' % overlay_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800219
J. Richard Barnettef6697cf2011-11-18 12:42:08 -0800220 return portage_utilities.BestEBuild(unstable_ebuilds), stable_ebuilds
Chris Sosadad0d322011-01-31 16:37:33 -0800221
222
223def FindChromeUprevCandidate(stable_ebuilds, chrome_rev, sticky_branch):
224 """Finds the Chrome uprev candidate for the given chrome_rev.
225
226 Using the pre-flight logic, this means the stable ebuild you are uprevving
227 from. The difference here is that the version could be different and in
228 that case we want to find it to delete it.
229
230 Args:
231 stable_ebuilds: A list of stable ebuilds.
232 chrome_rev: The chrome_rev designating which candidate to find.
Mike Frysingerad8c6ca2014-02-03 11:28:45 -0500233 sticky_branch: The the branch that is currently sticky with Major/Minor
Chris Sosa9ba47752012-02-27 15:27:37 -0800234 components. For example: 9.0.553. Can be None but not if chrome_rev
235 is CHROME_REV_STICKY.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500236
Chris Sosadad0d322011-01-31 16:37:33 -0800237 Returns:
Mike Frysinger1a736a82013-12-12 01:50:59 -0500238 The EBuild, otherwise None if none found.
Chris Sosadad0d322011-01-31 16:37:33 -0800239 """
240 candidates = []
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400241 if chrome_rev in [constants.CHROME_REV_LOCAL, constants.CHROME_REV_TOT,
242 constants.CHROME_REV_SPEC]:
243 # These are labelled alpha, for historic reasons,
Peter Mayo177500f2011-09-09 17:25:23 -0400244 # not just for the fun of confusion.
David James7c352bc2013-03-15 14:19:57 -0700245 chrome_branch_re = re.compile(r'%s.*_alpha.*' % _CHROME_VERSION_REGEX)
Chris Sosadad0d322011-01-31 16:37:33 -0800246 for ebuild in stable_ebuilds:
247 if chrome_branch_re.search(ebuild.version):
248 candidates.append(ebuild)
249
Ryan Cuic6e097d2011-06-16 12:23:14 -0700250 elif chrome_rev == constants.CHROME_REV_STICKY:
Chris Sosa9ba47752012-02-27 15:27:37 -0800251 assert sticky_branch is not None
David James7c352bc2013-03-15 14:19:57 -0700252 chrome_branch_re = re.compile(r'%s\..*' % sticky_branch)
Chris Sosadad0d322011-01-31 16:37:33 -0800253 for ebuild in stable_ebuilds:
254 if chrome_branch_re.search(ebuild.version):
255 candidates.append(ebuild)
256
257 else:
David James7c352bc2013-03-15 14:19:57 -0700258 chrome_branch_re = re.compile(r'%s.*_rc.*' % _CHROME_VERSION_REGEX)
Chris Sosadad0d322011-01-31 16:37:33 -0800259 for ebuild in stable_ebuilds:
Chris Sosa9ba47752012-02-27 15:27:37 -0800260 if chrome_branch_re.search(ebuild.version):
Chris Sosadad0d322011-01-31 16:37:33 -0800261 candidates.append(ebuild)
262
263 if candidates:
J. Richard Barnettef6697cf2011-11-18 12:42:08 -0800264 return portage_utilities.BestEBuild(candidates)
Chris Sosadad0d322011-01-31 16:37:33 -0800265 else:
266 return None
267
Chris Masone592cab52011-08-02 14:05:48 -0700268def _AnnotateAndPrint(text, url):
269 """Add buildbot trappings to print <a href='url'>text</a> in the waterfall.
270
271 Args:
272 text: Anchor text for the link
273 url: the URL to which to link
274 """
Don Garrette60de902011-10-17 18:52:05 -0700275 print >> sys.stderr, '\n@@@STEP_LINK@%(text)s@%(url)s@@@' % { 'text': text,
Chris Masone592cab52011-08-02 14:05:48 -0700276 'url': url }
277
278def GetChromeRevisionLinkFromVersions(old_chrome_version, chrome_version):
279 """Return appropriately formatted link to revision info, given versions
280
281 Given two chrome version strings (e.g. 9.0.533.0), generate a link to a
282 page that prints the Chromium revisions between those two versions.
283
284 Args:
285 old_chrome_version: version to diff from
286 chrome_version: version to which to diff
Mike Frysinger1a736a82013-12-12 01:50:59 -0500287
Chris Masone592cab52011-08-02 14:05:48 -0700288 Returns:
289 The desired URL.
290 """
291 return _CHROME_VERSION_URL % { 'old': old_chrome_version,
292 'new': chrome_version }
293
Chris Masone592cab52011-08-02 14:05:48 -0700294def GetChromeRevisionListLink(old_chrome, new_chrome, chrome_rev):
295 """Returns a link to the list of revisions between two Chromium versions
296
297 Given two ChromeEBuilds and the kind of rev we're doing, generate a
298 link to a page that prints the Chromium changes between those two
299 revisions, inclusive.
300
301 Args:
302 old_chrome: ebuild for the version to diff from
303 new_chrome: ebuild for the version to which to diff
304 chrome_rev: one of constants.VALID_CHROME_REVISIONS
Mike Frysinger1a736a82013-12-12 01:50:59 -0500305
Chris Masone592cab52011-08-02 14:05:48 -0700306 Returns:
307 The desired URL.
308 """
Chris Sosadd611df2012-02-03 15:26:23 -0800309 assert chrome_rev in _REV_TYPES_FOR_LINKS
310 return GetChromeRevisionLinkFromVersions(old_chrome.chrome_version,
311 new_chrome.chrome_version)
Chris Sosadad0d322011-01-31 16:37:33 -0800312
313def MarkChromeEBuildAsStable(stable_candidate, unstable_ebuild, chrome_rev,
Chris Sosa9ba47752012-02-27 15:27:37 -0800314 chrome_version, commit, overlay_dir):
David James7c352bc2013-03-15 14:19:57 -0700315 r"""Uprevs the chrome ebuild specified by chrome_rev.
Chris Sosadad0d322011-01-31 16:37:33 -0800316
317 This is the main function that uprevs the chrome_rev from a stable candidate
318 to its new version.
319
320 Args:
321 stable_candidate: ebuild that corresponds to the stable ebuild we are
322 revving from. If None, builds the a new ebuild given the version
323 and logic for chrome_rev type with revision set to 1.
Mike Frysingerad8c6ca2014-02-03 11:28:45 -0500324 unstable_ebuild: ebuild corresponding to the unstable ebuild for chrome.
Peter Mayo177500f2011-09-09 17:25:23 -0400325 chrome_rev: one of constants.VALID_CHROME_REVISIONS or LOCAL
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400326 constants.CHROME_REV_SPEC - Requires commit value. Revs the ebuild for
327 the specified version and uses the portage suffix of _alpha.
Ryan Cuic6e097d2011-06-16 12:23:14 -0700328 constants.CHROME_REV_TOT - Requires commit value. Revs the ebuild for
329 the TOT version and uses the portage suffix of _alpha.
Peter Mayo177500f2011-09-09 17:25:23 -0400330 constants.CHROME_REV_LOCAL - Requires a chrome_root. Revs the ebuild for
331 the local version and uses the portage suffix of _alpha.
Ryan Cuic6e097d2011-06-16 12:23:14 -0700332 constants.CHROME_REV_LATEST - This uses the portage suffix of _rc as they
333 are release candidates for the next sticky version.
334 constants.CHROME_REV_STICKY - Revs the sticky version.
Mike Frysingerad8c6ca2014-02-03 11:28:45 -0500335 chrome_version: The \d.\d.\d.\d version of Chrome.
336 commit: Used with constants.CHROME_REV_TOT. The svn revision of chrome.
337 overlay_dir: Path to the chromeos-chrome package dir.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500338
Chris Sosadad0d322011-01-31 16:37:33 -0800339 Returns:
340 Full portage version atom (including rc's, etc) that was revved.
341 """
Chris Sosa8be39132011-04-14 12:09:24 -0700342 def IsTheNewEBuildRedundant(new_ebuild, stable_ebuild):
343 """Returns True if the new ebuild is redundant.
344
345 This is True if there if the current stable ebuild is the exact same copy
David James89608f92012-11-03 14:14:12 -0700346 of the new one.
Chris Sosa8be39132011-04-14 12:09:24 -0700347 """
348 if not stable_ebuild:
349 return False
350
351 if stable_candidate.chrome_version == new_ebuild.chrome_version:
David James89608f92012-11-03 14:14:12 -0700352 return filecmp.cmp(
353 new_ebuild.ebuild_path, stable_ebuild.ebuild_path, shallow=False)
Chris Sosa8be39132011-04-14 12:09:24 -0700354
David James629febb2012-11-25 13:07:34 -0800355 # Mark latest release and sticky branches as stable.
356 mark_stable = chrome_rev not in [constants.CHROME_REV_TOT,
357 constants.CHROME_REV_SPEC,
358 constants.CHROME_REV_LOCAL]
359
Chris Sosadad0d322011-01-31 16:37:33 -0800360 # Case where we have the last stable candidate with same version just rev.
361 if stable_candidate and stable_candidate.chrome_version == chrome_version:
362 new_ebuild_path = '%s-r%d.ebuild' % (
363 stable_candidate.ebuild_path_no_revision,
364 stable_candidate.current_revision + 1)
365 else:
David James629febb2012-11-25 13:07:34 -0800366 suffix = 'rc' if mark_stable else 'alpha'
367 pf = '%s-%s_%s-r1' % (constants.CHROME_PN, chrome_version, suffix)
368 new_ebuild_path = os.path.join(overlay_dir, '%s.ebuild' % pf)
Chris Sosadad0d322011-01-31 16:37:33 -0800369
David Jamesa6792552012-04-03 10:05:35 -0700370 chrome_variables = dict()
371 if commit:
372 chrome_variables[_CHROME_SVN_TAG] = commit
373
J. Richard Barnette0cfc5052011-11-28 14:31:39 -0800374 portage_utilities.EBuild.MarkAsStable(
David James065b2012012-04-01 14:51:11 -0700375 unstable_ebuild.ebuild_path, new_ebuild_path,
David Jamesa6792552012-04-03 10:05:35 -0700376 chrome_variables, make_stable=mark_stable)
Chris Sosadad0d322011-01-31 16:37:33 -0800377 new_ebuild = ChromeEBuild(new_ebuild_path)
Chris Sosa8be39132011-04-14 12:09:24 -0700378
379 # Determine whether this is ebuild is redundant.
380 if IsTheNewEBuildRedundant(new_ebuild, stable_candidate):
David James1b363582012-12-17 11:53:11 -0800381 msg = 'Previous ebuild with same version found and ebuild is redundant.'
382 cros_build_lib.Info(msg)
Chris Sosa8be39132011-04-14 12:09:24 -0700383 os.unlink(new_ebuild_path)
384 return None
Chris Sosadad0d322011-01-31 16:37:33 -0800385
Chris Sosadd611df2012-02-03 15:26:23 -0800386 if stable_candidate and chrome_rev in _REV_TYPES_FOR_LINKS:
Chris Masone592cab52011-08-02 14:05:48 -0700387 _AnnotateAndPrint('Chromium revisions',
388 GetChromeRevisionListLink(stable_candidate,
389 new_ebuild,
390 chrome_rev))
391
David James67d73252013-09-19 17:33:12 -0700392 git.RunGit(overlay_dir, ['add', new_ebuild_path])
Chris Sosa9ba47752012-02-27 15:27:37 -0800393 if stable_candidate and not stable_candidate.IsSticky():
David James67d73252013-09-19 17:33:12 -0700394 git.RunGit(overlay_dir, ['rm', stable_candidate.ebuild_path])
Chris Sosadad0d322011-01-31 16:37:33 -0800395
J. Richard Barnette0cfc5052011-11-28 14:31:39 -0800396 portage_utilities.EBuild.CommitChange(
Chris Sosadad0d322011-01-31 16:37:33 -0800397 _GIT_COMMIT_MESSAGE % {'chrome_rev': chrome_rev,
Mike Frysinger2ebe3732012-05-08 17:04:12 -0400398 'chrome_version': chrome_version},
399 overlay_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800400
Chris Sosadad0d322011-01-31 16:37:33 -0800401 return '%s-%s' % (new_ebuild.package, new_ebuild.version)
402
403
Chris Sosad53f8fd2011-10-21 15:15:19 -0700404def ParseMaxRevision(revision_list):
405 """Returns the max revision from a list of url@revision string."""
David James7c352bc2013-03-15 14:19:57 -0700406 revision_re = re.compile(r'.*@(\d+)')
Chris Sosad53f8fd2011-10-21 15:15:19 -0700407
408 def RevisionKey(revision):
409 return revision_re.match(revision).group(1)
410
411 max_revision = max(revision_list.split(), key=RevisionKey)
412 return max_revision.rpartition('@')[2]
413
414
David James1b363582012-12-17 11:53:11 -0800415def main(_argv):
Chris Sosa0f295aa2011-10-21 14:10:28 -0700416 usage_options = '|'.join(constants.VALID_CHROME_REVISIONS)
Ryan Cuic6e097d2011-06-16 12:23:14 -0700417 usage = '%s OPTIONS [%s]' % (__file__, usage_options)
Chris Sosadad0d322011-01-31 16:37:33 -0800418 parser = optparse.OptionParser(usage)
David Jamescc09c9b2012-01-26 22:10:13 -0800419 parser.add_option('-b', '--boards', default='x86-generic')
David Jamesef74b1c2012-11-12 07:47:47 -0800420 parser.add_option('-c', '--chrome_url', default=gclient.GetBaseURLs()[0])
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400421 parser.add_option('-f', '--force_revision', default=None)
Chris Sosadad0d322011-01-31 16:37:33 -0800422 parser.add_option('-s', '--srcroot', default=os.path.join(os.environ['HOME'],
423 'trunk', 'src'),
424 help='Path to the src directory')
425 parser.add_option('-t', '--tracking_branch', default='cros/master',
426 help='Branch we are tracking changes against')
427 (options, args) = parser.parse_args()
428
Ryan Cuic6e097d2011-06-16 12:23:14 -0700429 if len(args) != 1 or args[0] not in constants.VALID_CHROME_REVISIONS:
430 parser.error('Commit requires arg set to one of %s.'
431 % constants.VALID_CHROME_REVISIONS)
Chris Sosadad0d322011-01-31 16:37:33 -0800432
433 overlay_dir = os.path.abspath(_CHROME_OVERLAY_DIR %
434 {'srcroot': options.srcroot})
435 chrome_rev = args[0]
436 version_to_uprev = None
437 commit_to_use = None
Chris Sosa9ba47752012-02-27 15:27:37 -0800438 sticky_branch = None
Chris Sosadad0d322011-01-31 16:37:33 -0800439
440 (unstable_ebuild, stable_ebuilds) = FindChromeCandidates(overlay_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800441
Peter Mayo177500f2011-09-09 17:25:23 -0400442 if chrome_rev == constants.CHROME_REV_LOCAL:
443 if 'CHROME_ROOT' in os.environ:
444 chrome_root = os.environ['CHROME_ROOT']
445 else:
446 chrome_root = os.path.join(os.environ['HOME'], 'chrome_root')
447
448 version_to_uprev = _GetTipOfTrunkVersionFile(chrome_root)
449 commit_to_use = 'Unknown'
David James1b363582012-12-17 11:53:11 -0800450 cros_build_lib.Info('Using local source, versioning is untrustworthy.')
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400451 elif chrome_rev == constants.CHROME_REV_SPEC:
452 commit_to_use = options.force_revision
Mike Frysingerf02736e2013-11-08 15:27:00 -0500453 if '@' in commit_to_use:
454 commit_to_use = ParseMaxRevision(commit_to_use)
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400455 version_to_uprev = _GetSpecificVersionUrl(options.chrome_url,
456 commit_to_use)
Peter Mayo177500f2011-09-09 17:25:23 -0400457 elif chrome_rev == constants.CHROME_REV_TOT:
ChromeOS Developer03118eb2013-02-12 14:27:09 -0800458 commit_to_use = gclient.GetTipOfTrunkSvnRevision(options.chrome_url)
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400459 version_to_uprev = _GetSpecificVersionUrl(options.chrome_url,
460 commit_to_use)
Ryan Cuic6e097d2011-06-16 12:23:14 -0700461 elif chrome_rev == constants.CHROME_REV_LATEST:
Peter Mayof65b8412011-08-26 01:22:21 -0400462 version_to_uprev = _GetLatestRelease(options.chrome_url)
Chris Sosadad0d322011-01-31 16:37:33 -0800463 else:
Chris Sosa9ba47752012-02-27 15:27:37 -0800464 sticky_ebuild = _GetStickyEBuild(stable_ebuilds)
465 sticky_version = sticky_ebuild.chrome_version
466 sticky_branch = sticky_version.rpartition('.')[0]
Peter Mayof65b8412011-08-26 01:22:21 -0400467 version_to_uprev = _GetLatestRelease(options.chrome_url, sticky_branch)
Chris Sosadad0d322011-01-31 16:37:33 -0800468
469 stable_candidate = FindChromeUprevCandidate(stable_ebuilds, chrome_rev,
470 sticky_branch)
471
472 if stable_candidate:
David James1b363582012-12-17 11:53:11 -0800473 cros_build_lib.Info('Stable candidate found %s' % stable_candidate)
Chris Sosadad0d322011-01-31 16:37:33 -0800474 else:
David James1b363582012-12-17 11:53:11 -0800475 cros_build_lib.Info('No stable candidate found.')
Chris Sosadad0d322011-01-31 16:37:33 -0800476
Chris Sosa8049f3b2011-05-02 20:09:28 -0700477 tracking_branch = 'remotes/m/%s' % os.path.basename(options.tracking_branch)
David James97d95872012-11-16 15:09:56 -0800478 existing_branch = git.GetCurrentBranch(overlay_dir)
Ryan Cui05a31ba2011-05-31 17:47:37 -0700479 work_branch = cros_mark_as_stable.GitBranch(constants.STABLE_EBUILD_BRANCH,
Mike Frysinger2ebe3732012-05-08 17:04:12 -0400480 tracking_branch, overlay_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800481 work_branch.CreateBranch()
David Jamesd6708c02012-03-22 10:49:15 -0700482
483 # In the case of uprevving overlays that have patches applied to them,
484 # include the patched changes in the stabilizing branch.
485 if existing_branch:
David James67d73252013-09-19 17:33:12 -0700486 git.RunGit(overlay_dir, ['rebase', existing_branch])
David Jamesd6708c02012-03-22 10:49:15 -0700487
Chris Sosadad0d322011-01-31 16:37:33 -0800488 chrome_version_atom = MarkChromeEBuildAsStable(
489 stable_candidate, unstable_ebuild, chrome_rev, version_to_uprev,
Chris Sosa9ba47752012-02-27 15:27:37 -0800490 commit_to_use, overlay_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800491 # Explicit print to communicate to caller.
492 if chrome_version_atom:
David Jamescc09c9b2012-01-26 22:10:13 -0800493 cros_mark_as_stable.CleanStalePackages(options.boards.split(':'),
494 [chrome_version_atom])
Chris Sosadad0d322011-01-31 16:37:33 -0800495 print 'CHROME_VERSION_ATOM=%s' % chrome_version_atom