blob: 37601ec43bfbe9f89cda214d3d5ae7baa8891748 [file] [log] [blame]
Mike Frysingere58c0e22017-10-04 15:43:30 -04001# -*- coding: utf-8 -*-
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
Mike Frysinger383367e2014-09-16 15:06:17 -040018from __future__ import print_function
19
Stefan Zagerd49d9ff2014-08-15 21:33:37 -070020import base64
Mike Frysingera94f1252019-09-12 02:39:28 -040021import distutils.version # pylint: disable=import-error,no-name-in-module
Chris Sosa8be39132011-04-14 12:09:24 -070022import filecmp
Chris Sosadad0d322011-01-31 16:37:33 -080023import os
24import re
Mike Frysinger3dcacee2019-08-23 17:09:11 -040025
26from six.moves import urllib
Chris Sosadad0d322011-01-31 16:37:33 -080027
Aviv Keshetb7519e12016-10-04 00:50:00 -070028from chromite.lib import constants
Mike Frysingera13c04f2016-09-01 00:35:17 -040029from chromite.lib import commandline
David James1b363582012-12-17 11:53:11 -080030from chromite.lib import cros_build_lib
Ralph Nathan03047282015-03-23 11:09:32 -070031from chromite.lib import cros_logging as logging
David James97d95872012-11-16 15:09:56 -080032from chromite.lib import git
Stefan Zagerd49d9ff2014-08-15 21:33:37 -070033from chromite.lib import gob_util
Alex Deymo075c2292014-09-04 18:31:50 -070034from chromite.lib import portage_util
Stefan Zagerd49d9ff2014-08-15 21:33:37 -070035from chromite.lib import timeout_util
Mike Frysinger6cb624a2012-05-24 18:17:38 -040036from chromite.scripts import cros_mark_as_stable
Chris Sosadad0d322011-01-31 16:37:33 -080037
Mike Frysinger750c5f52014-09-16 16:16:57 -040038
Chris Sosadad0d322011-01-31 16:37:33 -080039# Helper regex's for finding ebuilds.
David James7c352bc2013-03-15 14:19:57 -070040_CHROME_VERSION_REGEX = r'\d+\.\d+\.\d+\.\d+'
41_NON_STICKY_REGEX = r'%s[(_rc.*)|(_alpha.*)]+' % _CHROME_VERSION_REGEX
Chris Sosadad0d322011-01-31 16:37:33 -080042
43# Dir where all the action happens.
David Zeuthen665d3132014-08-25 15:27:02 -040044_OVERLAY_DIR = '%(srcroot)s/third_party/chromiumos-overlay/'
Chris Sosadad0d322011-01-31 16:37:33 -080045
David Zeuthen665d3132014-08-25 15:27:02 -040046_GIT_COMMIT_MESSAGE = ('Marking %(chrome_rev)s for %(chrome_pn)s ebuild '
47 'with version %(chrome_version)s as stable.')
Chris Sosadad0d322011-01-31 16:37:33 -080048
Chris Masone592cab52011-08-02 14:05:48 -070049# URLs that print lists of chrome revisions between two versions of the browser.
50_CHROME_VERSION_URL = ('http://omahaproxy.appspot.com/changelog?'
51 'old_version=%(old)s&new_version=%(new)s')
Chris Sosadd611df2012-02-03 15:26:23 -080052
53# Only print links when we rev these types.
54_REV_TYPES_FOR_LINKS = [constants.CHROME_REV_LATEST,
55 constants.CHROME_REV_STICKY]
Chris Masone592cab52011-08-02 14:05:48 -070056
ChromeOS Developer03118eb2013-02-12 14:27:09 -080057
petermayo@chromium.org163b3372011-09-12 02:06:05 -040058def _GetVersionContents(chrome_version_info):
Peter Mayo177500f2011-09-09 17:25:23 -040059 """Returns the current Chromium version, from the contents of a VERSION file.
Chris Sosadad0d322011-01-31 16:37:33 -080060
Peter Mayo177500f2011-09-09 17:25:23 -040061 Args:
Mike Frysinger6f3c48e2015-05-06 02:38:51 -040062 chrome_version_info: The contents of a chromium VERSION file.
Peter Mayo177500f2011-09-09 17:25:23 -040063 """
Chris Sosadad0d322011-01-31 16:37:33 -080064 chrome_version_array = []
Chris Sosadad0d322011-01-31 16:37:33 -080065 for line in chrome_version_info.splitlines():
66 chrome_version_array.append(line.rpartition('=')[2])
67
68 return '.'.join(chrome_version_array)
69
Mike Frysingercc838832014-05-24 13:10:30 -040070
Stefan Zagerd49d9ff2014-08-15 21:33:37 -070071def _GetSpecificVersionUrl(git_url, revision, time_to_wait=600):
petermayo@chromium.org163b3372011-09-12 02:06:05 -040072 """Returns the Chromium version, from a repository URL and version.
Peter Mayo177500f2011-09-09 17:25:23 -040073
74 Args:
Mike Frysinger6f3c48e2015-05-06 02:38:51 -040075 git_url: Repository URL for chromium.
76 revision: the git 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 """
Mike Frysinger3dcacee2019-08-23 17:09:11 -040080 parsed_url = urllib.parse.urlparse(git_url)
Stefan Zagerd49d9ff2014-08-15 21:33:37 -070081 host = parsed_url[1]
82 path = parsed_url[2].rstrip('/') + (
83 '/+/%s/chrome/VERSION?format=text' % revision)
petermayo@chromium.org163b3372011-09-12 02:06:05 -040084
Stefan Zagerd49d9ff2014-08-15 21:33:37 -070085 # Allow for git repository replication lag with sleep/retry loop.
86 def _fetch():
Jack Rosenthal61e67832019-09-16 12:48:38 -060087 return gob_util.FetchUrl(host, path, ignore_404=True)
petermayo@chromium.org163b3372011-09-12 02:06:05 -040088
Mike Frysingercc55c782014-12-03 22:32:08 -050089 def _wait_msg(_remaining):
Ralph Nathan03047282015-03-23 11:09:32 -070090 logging.info('Repository does not yet have revision %s. Sleeping...',
91 revision)
petermayo@chromium.org163b3372011-09-12 02:06:05 -040092
Stefan Zagerd49d9ff2014-08-15 21:33:37 -070093 content = timeout_util.WaitForSuccess(
94 retry_check=lambda x: not bool(x),
95 func=_fetch,
96 timeout=time_to_wait,
97 period=30,
98 side_effect_func=_wait_msg)
Jack Rosenthal61e67832019-09-16 12:48:38 -060099 return _GetVersionContents(base64.b64decode(content).decode('utf-8'))
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400100
Peter Mayo177500f2011-09-09 17:25:23 -0400101
102def _GetTipOfTrunkVersionFile(root):
103 """Returns the current Chromium version, from a file in a checkout.
104
105 Args:
Mike Frysinger6f3c48e2015-05-06 02:38:51 -0400106 root: path to the root of the chromium checkout.
Peter Mayo177500f2011-09-09 17:25:23 -0400107 """
108 version_file = os.path.join(root, 'src', 'chrome', 'VERSION')
Mike Frysinger94a459c2019-09-29 23:43:05 -0400109 try:
110 chrome_version_info = cros_build_lib.run(
111 ['cat', version_file],
112 redirect_stdout=True).stdout
113 except cros_build_lib.RunCommandError as e:
114 e.msg += '\nCould not read version file at %s.' % version_file
115 raise e
Peter Mayo177500f2011-09-09 17:25:23 -0400116
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400117 return _GetVersionContents(chrome_version_info)
Peter Mayo177500f2011-09-09 17:25:23 -0400118
ChromeOS Developer03118eb2013-02-12 14:27:09 -0800119
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700120def CheckIfChromeRightForOS(deps_content):
Dharani Govindan4beb94c2014-07-18 13:31:47 -0700121 """Checks if DEPS is right for Chrome OS.
122
123 This function checks for a variable called 'buildspec_platforms' to
124 find out if its 'chromeos' or 'all'. If any of those values,
125 then it chooses that DEPS.
126
127 Args:
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700128 deps_content: Content of release buildspec DEPS file.
Dharani Govindan4beb94c2014-07-18 13:31:47 -0700129
130 Returns:
131 True if DEPS is the right Chrome for Chrome OS.
132 """
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700133 platforms_search = re.search(r'buildspec_platforms.*\s.*\s', deps_content)
Dharani Govindancbbf69c2014-07-29 15:37:39 -0700134
135 if platforms_search:
136 platforms = platforms_search.group()
137 if 'chromeos' in platforms or 'all' in platforms:
138 return True
Dharani Govindan4beb94c2014-07-18 13:31:47 -0700139
140 return False
141
142
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700143def GetLatestRelease(git_url, branch=None):
144 """Gets the latest release version from the release tags in the repository.
Chris Sosadad0d322011-01-31 16:37:33 -0800145
146 Args:
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700147 git_url: URL of git repository.
Mike Frysingerad8c6ca2014-02-03 11:28:45 -0500148 branch: If set, gets the latest release for branch, otherwise latest
Chris Sosadad0d322011-01-31 16:37:33 -0800149 release.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500150
Chris Sosadad0d322011-01-31 16:37:33 -0800151 Returns:
152 Latest version string.
153 """
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700154 # TODO(szager): This only works for public release buildspecs in the chromium
155 # src repository. Internal buildspecs are tracked differently. At the time
156 # of writing, I can't find any callers that use this method to scan for
157 # internal buildspecs. But there may be something lurking...
158
Mike Frysinger3dcacee2019-08-23 17:09:11 -0400159 parsed_url = urllib.parse.urlparse(git_url)
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700160 path = parsed_url[2].rstrip('/') + '/+refs/tags?format=JSON'
161 j = gob_util.FetchUrlJson(parsed_url[1], path, ignore_404=False)
Chris Sosadad0d322011-01-31 16:37:33 -0800162 if branch:
David James7c352bc2013-03-15 14:19:57 -0700163 chrome_version_re = re.compile(r'^%s\.\d+.*' % branch)
Chris Sosadad0d322011-01-31 16:37:33 -0800164 else:
David James7c352bc2013-03-15 14:19:57 -0700165 chrome_version_re = re.compile(r'^[0-9]+\..*')
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700166 matching_versions = [key for key in j.keys() if chrome_version_re.match(key)]
167 matching_versions.sort(key=distutils.version.LooseVersion)
168 for chrome_version in reversed(matching_versions):
169 path = parsed_url[2].rstrip() + (
170 '/+/refs/tags/%s/DEPS?format=text' % chrome_version)
Jack Rosenthal61e67832019-09-16 12:48:38 -0600171 content = gob_util.FetchUrl(parsed_url[1], path, ignore_404=False)
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700172 if content:
Jack Rosenthal61e67832019-09-16 12:48:38 -0600173 deps_content = base64.b64decode(content).decode('utf-8')
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700174 if CheckIfChromeRightForOS(deps_content):
175 return chrome_version
Peter Mayoad8173d2011-11-08 16:18:23 -0500176
177 return None
Chris Sosadad0d322011-01-31 16:37:33 -0800178
179
180def _GetStickyEBuild(stable_ebuilds):
181 """Returns the sticky ebuild."""
182 sticky_ebuilds = []
183 non_sticky_re = re.compile(_NON_STICKY_REGEX)
184 for ebuild in stable_ebuilds:
185 if not non_sticky_re.match(ebuild.version):
186 sticky_ebuilds.append(ebuild)
187
188 if not sticky_ebuilds:
189 raise Exception('No sticky ebuilds found')
190 elif len(sticky_ebuilds) > 1:
Mike Frysinger6c2a6242019-03-20 20:37:24 -0400191 logging.warning('More than one sticky ebuild found:')
192 for ebuild in sticky_ebuilds:
193 logging.warning(' %s', ebuild.ebuild_path)
194 logging.warning('Make sure to *not* create xxx.0-r1.ebuilds')
Chris Sosadad0d322011-01-31 16:37:33 -0800195
Alex Deymo075c2292014-09-04 18:31:50 -0700196 return portage_util.BestEBuild(sticky_ebuilds)
Chris Sosadad0d322011-01-31 16:37:33 -0800197
198
Alex Deymo075c2292014-09-04 18:31:50 -0700199class ChromeEBuild(portage_util.EBuild):
Chris Sosadad0d322011-01-31 16:37:33 -0800200 """Thin sub-class of EBuild that adds a chrome_version field."""
David Zeuthen665d3132014-08-25 15:27:02 -0400201 chrome_version_re = re.compile(r'.*-(%s|9999).*' % (
202 _CHROME_VERSION_REGEX))
Chris Sosadad0d322011-01-31 16:37:33 -0800203 chrome_version = ''
204
205 def __init__(self, path):
Alex Deymo075c2292014-09-04 18:31:50 -0700206 portage_util.EBuild.__init__(self, path)
Chris Sosadad0d322011-01-31 16:37:33 -0800207 re_match = self.chrome_version_re.match(self.ebuild_path_no_revision)
208 if re_match:
209 self.chrome_version = re_match.group(1)
210
Chris Sosadad0d322011-01-31 16:37:33 -0800211 def __str__(self):
212 return self.ebuild_path
213
214
David Zeuthen665d3132014-08-25 15:27:02 -0400215def FindChromeCandidates(package_dir):
Chris Sosadad0d322011-01-31 16:37:33 -0800216 """Return a tuple of chrome's unstable ebuild and stable ebuilds.
217
218 Args:
David Zeuthen665d3132014-08-25 15:27:02 -0400219 package_dir: The path to where the package ebuild is stored.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500220
Chris Sosadad0d322011-01-31 16:37:33 -0800221 Returns:
222 Tuple [unstable_ebuild, stable_ebuilds].
Mike Frysinger1a736a82013-12-12 01:50:59 -0500223
Chris Sosadad0d322011-01-31 16:37:33 -0800224 Raises:
225 Exception: if no unstable ebuild exists for Chrome.
226 """
227 stable_ebuilds = []
228 unstable_ebuilds = []
229 for path in [
David Zeuthen665d3132014-08-25 15:27:02 -0400230 os.path.join(package_dir, entry) for entry in os.listdir(package_dir)]:
Chris Sosadad0d322011-01-31 16:37:33 -0800231 if path.endswith('.ebuild'):
232 ebuild = ChromeEBuild(path)
233 if not ebuild.chrome_version:
Lann Martinffb95162018-08-28 12:02:54 -0600234 logging.warning('Poorly formatted ebuild found at %s', path)
Chris Sosadad0d322011-01-31 16:37:33 -0800235 else:
236 if '9999' in ebuild.version:
237 unstable_ebuilds.append(ebuild)
238 else:
239 stable_ebuilds.append(ebuild)
240
241 # Apply some sanity checks.
242 if not unstable_ebuilds:
David Zeuthen665d3132014-08-25 15:27:02 -0400243 raise Exception('Missing 9999 ebuild for %s' % package_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800244 if not stable_ebuilds:
Lann Martinffb95162018-08-28 12:02:54 -0600245 logging.warning('Missing stable ebuild for %s', package_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800246
Alex Deymo075c2292014-09-04 18:31:50 -0700247 return portage_util.BestEBuild(unstable_ebuilds), stable_ebuilds
Chris Sosadad0d322011-01-31 16:37:33 -0800248
249
250def FindChromeUprevCandidate(stable_ebuilds, chrome_rev, sticky_branch):
251 """Finds the Chrome uprev candidate for the given chrome_rev.
252
253 Using the pre-flight logic, this means the stable ebuild you are uprevving
254 from. The difference here is that the version could be different and in
255 that case we want to find it to delete it.
256
257 Args:
258 stable_ebuilds: A list of stable ebuilds.
259 chrome_rev: The chrome_rev designating which candidate to find.
Mike Frysingerad8c6ca2014-02-03 11:28:45 -0500260 sticky_branch: The the branch that is currently sticky with Major/Minor
Chris Sosa9ba47752012-02-27 15:27:37 -0800261 components. For example: 9.0.553. Can be None but not if chrome_rev
262 is CHROME_REV_STICKY.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500263
Chris Sosadad0d322011-01-31 16:37:33 -0800264 Returns:
Mike Frysinger1a736a82013-12-12 01:50:59 -0500265 The EBuild, otherwise None if none found.
Chris Sosadad0d322011-01-31 16:37:33 -0800266 """
267 candidates = []
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400268 if chrome_rev in [constants.CHROME_REV_LOCAL, constants.CHROME_REV_TOT,
269 constants.CHROME_REV_SPEC]:
270 # These are labelled alpha, for historic reasons,
Peter Mayo177500f2011-09-09 17:25:23 -0400271 # not just for the fun of confusion.
David James7c352bc2013-03-15 14:19:57 -0700272 chrome_branch_re = re.compile(r'%s.*_alpha.*' % _CHROME_VERSION_REGEX)
Chris Sosadad0d322011-01-31 16:37:33 -0800273 for ebuild in stable_ebuilds:
274 if chrome_branch_re.search(ebuild.version):
275 candidates.append(ebuild)
276
Ryan Cuic6e097d2011-06-16 12:23:14 -0700277 elif chrome_rev == constants.CHROME_REV_STICKY:
Chris Sosa9ba47752012-02-27 15:27:37 -0800278 assert sticky_branch is not None
David James7c352bc2013-03-15 14:19:57 -0700279 chrome_branch_re = re.compile(r'%s\..*' % sticky_branch)
Chris Sosadad0d322011-01-31 16:37:33 -0800280 for ebuild in stable_ebuilds:
281 if chrome_branch_re.search(ebuild.version):
282 candidates.append(ebuild)
283
284 else:
David James7c352bc2013-03-15 14:19:57 -0700285 chrome_branch_re = re.compile(r'%s.*_rc.*' % _CHROME_VERSION_REGEX)
Chris Sosadad0d322011-01-31 16:37:33 -0800286 for ebuild in stable_ebuilds:
Chris Sosa9ba47752012-02-27 15:27:37 -0800287 if chrome_branch_re.search(ebuild.version):
Chris Sosadad0d322011-01-31 16:37:33 -0800288 candidates.append(ebuild)
289
290 if candidates:
Alex Deymo075c2292014-09-04 18:31:50 -0700291 return portage_util.BestEBuild(candidates)
Chris Sosadad0d322011-01-31 16:37:33 -0800292 else:
293 return None
294
Mike Frysingercc838832014-05-24 13:10:30 -0400295
Chris Masone592cab52011-08-02 14:05:48 -0700296def GetChromeRevisionLinkFromVersions(old_chrome_version, chrome_version):
297 """Return appropriately formatted link to revision info, given versions
298
299 Given two chrome version strings (e.g. 9.0.533.0), generate a link to a
300 page that prints the Chromium revisions between those two versions.
301
302 Args:
303 old_chrome_version: version to diff from
304 chrome_version: version to which to diff
Mike Frysinger1a736a82013-12-12 01:50:59 -0500305
Chris Masone592cab52011-08-02 14:05:48 -0700306 Returns:
307 The desired URL.
308 """
Mike Frysingerd6e2df02014-11-26 02:55:04 -0500309 return _CHROME_VERSION_URL % {'old': old_chrome_version,
310 'new': chrome_version}
Chris Masone592cab52011-08-02 14:05:48 -0700311
Mike Frysinger750c5f52014-09-16 16:16:57 -0400312
Chris Masone592cab52011-08-02 14:05:48 -0700313def GetChromeRevisionListLink(old_chrome, new_chrome, chrome_rev):
314 """Returns a link to the list of revisions between two Chromium versions
315
316 Given two ChromeEBuilds and the kind of rev we're doing, generate a
317 link to a page that prints the Chromium changes between those two
318 revisions, inclusive.
319
320 Args:
321 old_chrome: ebuild for the version to diff from
322 new_chrome: ebuild for the version to which to diff
323 chrome_rev: one of constants.VALID_CHROME_REVISIONS
Mike Frysinger1a736a82013-12-12 01:50:59 -0500324
Chris Masone592cab52011-08-02 14:05:48 -0700325 Returns:
326 The desired URL.
327 """
Chris Sosadd611df2012-02-03 15:26:23 -0800328 assert chrome_rev in _REV_TYPES_FOR_LINKS
329 return GetChromeRevisionLinkFromVersions(old_chrome.chrome_version,
330 new_chrome.chrome_version)
Chris Sosadad0d322011-01-31 16:37:33 -0800331
Mike Frysingercc838832014-05-24 13:10:30 -0400332
David Zeuthen665d3132014-08-25 15:27:02 -0400333def MarkChromeEBuildAsStable(stable_candidate, unstable_ebuild, chrome_pn,
Mike Frysinger93ad2262018-08-30 18:42:14 -0400334 chrome_rev, chrome_version, package_dir):
David James7c352bc2013-03-15 14:19:57 -0700335 r"""Uprevs the chrome ebuild specified by chrome_rev.
Chris Sosadad0d322011-01-31 16:37:33 -0800336
337 This is the main function that uprevs the chrome_rev from a stable candidate
338 to its new version.
339
340 Args:
341 stable_candidate: ebuild that corresponds to the stable ebuild we are
342 revving from. If None, builds the a new ebuild given the version
343 and logic for chrome_rev type with revision set to 1.
Mike Frysingerad8c6ca2014-02-03 11:28:45 -0500344 unstable_ebuild: ebuild corresponding to the unstable ebuild for chrome.
David Zeuthen665d3132014-08-25 15:27:02 -0400345 chrome_pn: package name.
Peter Mayo177500f2011-09-09 17:25:23 -0400346 chrome_rev: one of constants.VALID_CHROME_REVISIONS or LOCAL
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400347 constants.CHROME_REV_SPEC - Requires commit value. Revs the ebuild for
348 the specified version and uses the portage suffix of _alpha.
Ryan Cuic6e097d2011-06-16 12:23:14 -0700349 constants.CHROME_REV_TOT - Requires commit value. Revs the ebuild for
350 the TOT version and uses the portage suffix of _alpha.
Peter Mayo177500f2011-09-09 17:25:23 -0400351 constants.CHROME_REV_LOCAL - Requires a chrome_root. Revs the ebuild for
352 the local version and uses the portage suffix of _alpha.
Ryan Cuic6e097d2011-06-16 12:23:14 -0700353 constants.CHROME_REV_LATEST - This uses the portage suffix of _rc as they
354 are release candidates for the next sticky version.
355 constants.CHROME_REV_STICKY - Revs the sticky version.
Mike Frysingerad8c6ca2014-02-03 11:28:45 -0500356 chrome_version: The \d.\d.\d.\d version of Chrome.
David Zeuthen665d3132014-08-25 15:27:02 -0400357 package_dir: Path to the chromeos-chrome package dir.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500358
Chris Sosadad0d322011-01-31 16:37:33 -0800359 Returns:
360 Full portage version atom (including rc's, etc) that was revved.
361 """
Chris Sosa8be39132011-04-14 12:09:24 -0700362 def IsTheNewEBuildRedundant(new_ebuild, stable_ebuild):
363 """Returns True if the new ebuild is redundant.
364
365 This is True if there if the current stable ebuild is the exact same copy
David James89608f92012-11-03 14:14:12 -0700366 of the new one.
Chris Sosa8be39132011-04-14 12:09:24 -0700367 """
368 if not stable_ebuild:
369 return False
370
371 if stable_candidate.chrome_version == new_ebuild.chrome_version:
David James89608f92012-11-03 14:14:12 -0700372 return filecmp.cmp(
373 new_ebuild.ebuild_path, stable_ebuild.ebuild_path, shallow=False)
Chris Sosa8be39132011-04-14 12:09:24 -0700374
David James629febb2012-11-25 13:07:34 -0800375 # Mark latest release and sticky branches as stable.
376 mark_stable = chrome_rev not in [constants.CHROME_REV_TOT,
377 constants.CHROME_REV_SPEC,
378 constants.CHROME_REV_LOCAL]
379
Chris Sosadad0d322011-01-31 16:37:33 -0800380 # Case where we have the last stable candidate with same version just rev.
381 if stable_candidate and stable_candidate.chrome_version == chrome_version:
382 new_ebuild_path = '%s-r%d.ebuild' % (
383 stable_candidate.ebuild_path_no_revision,
384 stable_candidate.current_revision + 1)
385 else:
David James629febb2012-11-25 13:07:34 -0800386 suffix = 'rc' if mark_stable else 'alpha'
David Zeuthen665d3132014-08-25 15:27:02 -0400387 pf = '%s-%s_%s-r1' % (chrome_pn, chrome_version, suffix)
388 new_ebuild_path = os.path.join(package_dir, '%s.ebuild' % pf)
Chris Sosadad0d322011-01-31 16:37:33 -0800389
Alex Deymo075c2292014-09-04 18:31:50 -0700390 portage_util.EBuild.MarkAsStable(
David James065b2012012-04-01 14:51:11 -0700391 unstable_ebuild.ebuild_path, new_ebuild_path,
Mike Frysinger93ad2262018-08-30 18:42:14 -0400392 {}, make_stable=mark_stable)
Chris Sosadad0d322011-01-31 16:37:33 -0800393 new_ebuild = ChromeEBuild(new_ebuild_path)
Chris Sosa8be39132011-04-14 12:09:24 -0700394
395 # Determine whether this is ebuild is redundant.
396 if IsTheNewEBuildRedundant(new_ebuild, stable_candidate):
David James1b363582012-12-17 11:53:11 -0800397 msg = 'Previous ebuild with same version found and ebuild is redundant.'
Ralph Nathan03047282015-03-23 11:09:32 -0700398 logging.info(msg)
Chris Sosa8be39132011-04-14 12:09:24 -0700399 os.unlink(new_ebuild_path)
400 return None
Chris Sosadad0d322011-01-31 16:37:33 -0800401
Chris Sosadd611df2012-02-03 15:26:23 -0800402 if stable_candidate and chrome_rev in _REV_TYPES_FOR_LINKS:
David Riley3e3f64e2016-02-03 08:17:55 -0800403 logging.PrintBuildbotLink('Chromium revisions',
404 GetChromeRevisionListLink(stable_candidate,
405 new_ebuild, chrome_rev))
Chris Masone592cab52011-08-02 14:05:48 -0700406
David Zeuthen665d3132014-08-25 15:27:02 -0400407 git.RunGit(package_dir, ['add', new_ebuild_path])
Chris Sosa9ba47752012-02-27 15:27:37 -0800408 if stable_candidate and not stable_candidate.IsSticky():
David Zeuthen665d3132014-08-25 15:27:02 -0400409 git.RunGit(package_dir, ['rm', stable_candidate.ebuild_path])
Chris Sosadad0d322011-01-31 16:37:33 -0800410
Alex Deymo075c2292014-09-04 18:31:50 -0700411 portage_util.EBuild.CommitChange(
David Zeuthen665d3132014-08-25 15:27:02 -0400412 _GIT_COMMIT_MESSAGE % {'chrome_pn': chrome_pn,
413 'chrome_rev': chrome_rev,
Mike Frysinger2ebe3732012-05-08 17:04:12 -0400414 'chrome_version': chrome_version},
David Zeuthen665d3132014-08-25 15:27:02 -0400415 package_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800416
Chris Sosadad0d322011-01-31 16:37:33 -0800417 return '%s-%s' % (new_ebuild.package, new_ebuild.version)
418
419
Mike Frysingera13c04f2016-09-01 00:35:17 -0400420def GetParser():
421 """Return a command line parser."""
422 parser = commandline.ArgumentParser(description=__doc__)
423 parser.add_argument('-b', '--boards')
424 parser.add_argument('-c', '--chrome_url',
425 default=constants.CHROMIUM_GOB_URL)
426 parser.add_argument('-f', '--force_version',
427 help='Chrome version or git revision hash to use')
428 parser.add_argument('-s', '--srcroot',
429 default=os.path.join(os.environ['HOME'], 'trunk', 'src'),
430 help='Path to the src directory')
431 parser.add_argument('-t', '--tracking_branch', default='cros/master',
432 help='Branch we are tracking changes against')
433 parser.add_argument('revision', choices=constants.VALID_CHROME_REVISIONS)
434 return parser
Chris Sosadad0d322011-01-31 16:37:33 -0800435
Chris Sosadad0d322011-01-31 16:37:33 -0800436
Mike Frysingera13c04f2016-09-01 00:35:17 -0400437def main(argv):
438 parser = GetParser()
439 options = parser.parse_args(argv)
440 options.Freeze()
441 chrome_rev = options.revision
442
443 if options.force_version and chrome_rev not in (constants.CHROME_REV_SPEC,
444 constants.CHROME_REV_LATEST):
David Jamesfb160012014-07-01 10:00:57 -0700445 parser.error('--force_version is not compatible with the %r '
Mike Frysingera13c04f2016-09-01 00:35:17 -0400446 'option.' % (chrome_rev,))
David Jamesfb160012014-07-01 10:00:57 -0700447
David Zeuthen665d3132014-08-25 15:27:02 -0400448 overlay_dir = os.path.abspath(_OVERLAY_DIR % {'srcroot': options.srcroot})
449 chrome_package_dir = os.path.join(overlay_dir, constants.CHROME_CP)
Chris Sosadad0d322011-01-31 16:37:33 -0800450 version_to_uprev = None
Chris Sosa9ba47752012-02-27 15:27:37 -0800451 sticky_branch = None
Chris Sosadad0d322011-01-31 16:37:33 -0800452
David Zeuthen665d3132014-08-25 15:27:02 -0400453 (unstable_ebuild, stable_ebuilds) = FindChromeCandidates(chrome_package_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800454
Peter Mayo177500f2011-09-09 17:25:23 -0400455 if chrome_rev == constants.CHROME_REV_LOCAL:
456 if 'CHROME_ROOT' in os.environ:
457 chrome_root = os.environ['CHROME_ROOT']
458 else:
459 chrome_root = os.path.join(os.environ['HOME'], 'chrome_root')
460
461 version_to_uprev = _GetTipOfTrunkVersionFile(chrome_root)
Ralph Nathan03047282015-03-23 11:09:32 -0700462 logging.info('Using local source, versioning is untrustworthy.')
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400463 elif chrome_rev == constants.CHROME_REV_SPEC:
David Jamesfb160012014-07-01 10:00:57 -0700464 if '.' in options.force_version:
465 version_to_uprev = options.force_version
466 else:
467 commit_to_use = options.force_version
468 if '@' in commit_to_use:
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700469 commit_to_use = commit_to_use.rpartition('@')[2]
David Jamesfb160012014-07-01 10:00:57 -0700470 version_to_uprev = _GetSpecificVersionUrl(options.chrome_url,
471 commit_to_use)
Peter Mayo177500f2011-09-09 17:25:23 -0400472 elif chrome_rev == constants.CHROME_REV_TOT:
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700473 commit_to_use = gob_util.GetTipOfTrunkRevision(options.chrome_url)
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400474 version_to_uprev = _GetSpecificVersionUrl(options.chrome_url,
475 commit_to_use)
Ryan Cuic6e097d2011-06-16 12:23:14 -0700476 elif chrome_rev == constants.CHROME_REV_LATEST:
David James9a5980e2014-07-16 09:37:00 -0700477 if options.force_version:
478 if '.' not in options.force_version:
479 parser.error('%s only accepts released Chrome versions, not SVN or '
480 'Git revisions.' % (chrome_rev,))
481 version_to_uprev = options.force_version
482 else:
483 version_to_uprev = GetLatestRelease(options.chrome_url)
Chris Sosadad0d322011-01-31 16:37:33 -0800484 else:
Chris Sosa9ba47752012-02-27 15:27:37 -0800485 sticky_ebuild = _GetStickyEBuild(stable_ebuilds)
486 sticky_version = sticky_ebuild.chrome_version
487 sticky_branch = sticky_version.rpartition('.')[0]
Yu-Ju Hong39806322014-06-24 16:46:32 -0700488 version_to_uprev = GetLatestRelease(options.chrome_url, sticky_branch)
Chris Sosadad0d322011-01-31 16:37:33 -0800489
490 stable_candidate = FindChromeUprevCandidate(stable_ebuilds, chrome_rev,
491 sticky_branch)
492
493 if stable_candidate:
Lann Martinffb95162018-08-28 12:02:54 -0600494 logging.info('Stable candidate found %s', stable_candidate)
Chris Sosadad0d322011-01-31 16:37:33 -0800495 else:
Ralph Nathan03047282015-03-23 11:09:32 -0700496 logging.info('No stable candidate found.')
Chris Sosadad0d322011-01-31 16:37:33 -0800497
Chris Sosa8049f3b2011-05-02 20:09:28 -0700498 tracking_branch = 'remotes/m/%s' % os.path.basename(options.tracking_branch)
David Zeuthen665d3132014-08-25 15:27:02 -0400499 existing_branch = git.GetCurrentBranch(chrome_package_dir)
Ryan Cui05a31ba2011-05-31 17:47:37 -0700500 work_branch = cros_mark_as_stable.GitBranch(constants.STABLE_EBUILD_BRANCH,
David Zeuthen665d3132014-08-25 15:27:02 -0400501 tracking_branch,
502 chrome_package_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800503 work_branch.CreateBranch()
David Jamesd6708c02012-03-22 10:49:15 -0700504
505 # In the case of uprevving overlays that have patches applied to them,
506 # include the patched changes in the stabilizing branch.
507 if existing_branch:
David Zeuthen665d3132014-08-25 15:27:02 -0400508 git.RunGit(chrome_package_dir, ['rebase', existing_branch])
David Jamesd6708c02012-03-22 10:49:15 -0700509
Chris Sosadad0d322011-01-31 16:37:33 -0800510 chrome_version_atom = MarkChromeEBuildAsStable(
David Zeuthen665d3132014-08-25 15:27:02 -0400511 stable_candidate, unstable_ebuild, 'chromeos-chrome', chrome_rev,
Mike Frysinger93ad2262018-08-30 18:42:14 -0400512 version_to_uprev, chrome_package_dir)
Yu-Ju Hong078c9ec2014-08-06 18:25:16 -0700513 if chrome_version_atom:
514 if options.boards:
David James96c2c992015-07-14 10:21:50 -0700515 cros_mark_as_stable.CleanStalePackages(options.srcroot,
516 options.boards.split(':'),
Yu-Ju Hong078c9ec2014-08-06 18:25:16 -0700517 [chrome_version_atom])
David Zeuthen665d3132014-08-25 15:27:02 -0400518
519 # If we did rev Chrome, now is a good time to uprev other packages.
520 for other_ebuild in constants.OTHER_CHROME_PACKAGES:
521 other_ebuild_name = os.path.basename(other_ebuild)
522 other_package_dir = os.path.join(overlay_dir, other_ebuild)
523 (other_unstable_ebuild, other_stable_ebuilds) = FindChromeCandidates(
524 other_package_dir)
525 other_stable_candidate = FindChromeUprevCandidate(other_stable_ebuilds,
526 chrome_rev,
527 sticky_branch)
528 revved_atom = MarkChromeEBuildAsStable(other_stable_candidate,
529 other_unstable_ebuild,
530 other_ebuild_name,
531 chrome_rev, version_to_uprev,
Mike Frysinger93ad2262018-08-30 18:42:14 -0400532 other_package_dir)
David Zeuthen665d3132014-08-25 15:27:02 -0400533 if revved_atom and options.boards:
David James96c2c992015-07-14 10:21:50 -0700534 cros_mark_as_stable.CleanStalePackages(options.srcroot,
535 options.boards.split(':'),
David Zeuthen665d3132014-08-25 15:27:02 -0400536 [revved_atom])
537
538 # Explicit print to communicate to caller.
539 if chrome_version_atom:
Mike Frysinger383367e2014-09-16 15:06:17 -0400540 print('CHROME_VERSION_ATOM=%s' % chrome_version_atom)