blob: 7e1e18048d074fc8f0efdadda37c4464b7b7317f [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
21import distutils.version
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():
87 fh = gob_util.FetchUrl(host, path, ignore_404=True)
88 return fh.read() if fh else None
petermayo@chromium.org163b3372011-09-12 02:06:05 -040089
Mike Frysingercc55c782014-12-03 22:32:08 -050090 def _wait_msg(_remaining):
Ralph Nathan03047282015-03-23 11:09:32 -070091 logging.info('Repository does not yet have revision %s. Sleeping...',
92 revision)
petermayo@chromium.org163b3372011-09-12 02:06:05 -040093
Stefan Zagerd49d9ff2014-08-15 21:33:37 -070094 content = timeout_util.WaitForSuccess(
95 retry_check=lambda x: not bool(x),
96 func=_fetch,
97 timeout=time_to_wait,
98 period=30,
99 side_effect_func=_wait_msg)
100 return _GetVersionContents(base64.b64decode(content))
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400101
Peter Mayo177500f2011-09-09 17:25:23 -0400102
103def _GetTipOfTrunkVersionFile(root):
104 """Returns the current Chromium version, from a file in a checkout.
105
106 Args:
Mike Frysinger6f3c48e2015-05-06 02:38:51 -0400107 root: path to the root of the chromium checkout.
Peter Mayo177500f2011-09-09 17:25:23 -0400108 """
109 version_file = os.path.join(root, 'src', 'chrome', 'VERSION')
ChromeOS Developer03118eb2013-02-12 14:27:09 -0800110 chrome_version_info = cros_build_lib.RunCommand(
Peter Mayo177500f2011-09-09 17:25:23 -0400111 ['cat', version_file],
112 redirect_stdout=True,
J. Richard Barnetted422f622011-11-17 09:39:46 -0800113 error_message='Could not read version file at %s.' % version_file).output
Peter Mayo177500f2011-09-09 17:25:23 -0400114
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400115 return _GetVersionContents(chrome_version_info)
Peter Mayo177500f2011-09-09 17:25:23 -0400116
ChromeOS Developer03118eb2013-02-12 14:27:09 -0800117
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700118def CheckIfChromeRightForOS(deps_content):
Dharani Govindan4beb94c2014-07-18 13:31:47 -0700119 """Checks if DEPS is right for Chrome OS.
120
121 This function checks for a variable called 'buildspec_platforms' to
122 find out if its 'chromeos' or 'all'. If any of those values,
123 then it chooses that DEPS.
124
125 Args:
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700126 deps_content: Content of release buildspec DEPS file.
Dharani Govindan4beb94c2014-07-18 13:31:47 -0700127
128 Returns:
129 True if DEPS is the right Chrome for Chrome OS.
130 """
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700131 platforms_search = re.search(r'buildspec_platforms.*\s.*\s', deps_content)
Dharani Govindancbbf69c2014-07-29 15:37:39 -0700132
133 if platforms_search:
134 platforms = platforms_search.group()
135 if 'chromeos' in platforms or 'all' in platforms:
136 return True
Dharani Govindan4beb94c2014-07-18 13:31:47 -0700137
138 return False
139
140
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700141def GetLatestRelease(git_url, branch=None):
142 """Gets the latest release version from the release tags in the repository.
Chris Sosadad0d322011-01-31 16:37:33 -0800143
144 Args:
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700145 git_url: URL of git repository.
Mike Frysingerad8c6ca2014-02-03 11:28:45 -0500146 branch: If set, gets the latest release for branch, otherwise latest
Chris Sosadad0d322011-01-31 16:37:33 -0800147 release.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500148
Chris Sosadad0d322011-01-31 16:37:33 -0800149 Returns:
150 Latest version string.
151 """
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700152 # TODO(szager): This only works for public release buildspecs in the chromium
153 # src repository. Internal buildspecs are tracked differently. At the time
154 # of writing, I can't find any callers that use this method to scan for
155 # internal buildspecs. But there may be something lurking...
156
Mike Frysinger3dcacee2019-08-23 17:09:11 -0400157 parsed_url = urllib.parse.urlparse(git_url)
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700158 path = parsed_url[2].rstrip('/') + '/+refs/tags?format=JSON'
159 j = gob_util.FetchUrlJson(parsed_url[1], path, ignore_404=False)
Chris Sosadad0d322011-01-31 16:37:33 -0800160 if branch:
David James7c352bc2013-03-15 14:19:57 -0700161 chrome_version_re = re.compile(r'^%s\.\d+.*' % branch)
Chris Sosadad0d322011-01-31 16:37:33 -0800162 else:
David James7c352bc2013-03-15 14:19:57 -0700163 chrome_version_re = re.compile(r'^[0-9]+\..*')
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700164 matching_versions = [key for key in j.keys() if chrome_version_re.match(key)]
165 matching_versions.sort(key=distutils.version.LooseVersion)
166 for chrome_version in reversed(matching_versions):
167 path = parsed_url[2].rstrip() + (
168 '/+/refs/tags/%s/DEPS?format=text' % chrome_version)
169 fh = gob_util.FetchUrl(parsed_url[1], path, ignore_404=False)
170 content = fh.read() if fh else None
171 if content:
172 deps_content = base64.b64decode(content)
173 if CheckIfChromeRightForOS(deps_content):
174 return chrome_version
Peter Mayoad8173d2011-11-08 16:18:23 -0500175
176 return None
Chris Sosadad0d322011-01-31 16:37:33 -0800177
178
179def _GetStickyEBuild(stable_ebuilds):
180 """Returns the sticky ebuild."""
181 sticky_ebuilds = []
182 non_sticky_re = re.compile(_NON_STICKY_REGEX)
183 for ebuild in stable_ebuilds:
184 if not non_sticky_re.match(ebuild.version):
185 sticky_ebuilds.append(ebuild)
186
187 if not sticky_ebuilds:
188 raise Exception('No sticky ebuilds found')
189 elif len(sticky_ebuilds) > 1:
Mike Frysinger6c2a6242019-03-20 20:37:24 -0400190 logging.warning('More than one sticky ebuild found:')
191 for ebuild in sticky_ebuilds:
192 logging.warning(' %s', ebuild.ebuild_path)
193 logging.warning('Make sure to *not* create xxx.0-r1.ebuilds')
Chris Sosadad0d322011-01-31 16:37:33 -0800194
Alex Deymo075c2292014-09-04 18:31:50 -0700195 return portage_util.BestEBuild(sticky_ebuilds)
Chris Sosadad0d322011-01-31 16:37:33 -0800196
197
Alex Deymo075c2292014-09-04 18:31:50 -0700198class ChromeEBuild(portage_util.EBuild):
Chris Sosadad0d322011-01-31 16:37:33 -0800199 """Thin sub-class of EBuild that adds a chrome_version field."""
David Zeuthen665d3132014-08-25 15:27:02 -0400200 chrome_version_re = re.compile(r'.*-(%s|9999).*' % (
201 _CHROME_VERSION_REGEX))
Chris Sosadad0d322011-01-31 16:37:33 -0800202 chrome_version = ''
203
204 def __init__(self, path):
Alex Deymo075c2292014-09-04 18:31:50 -0700205 portage_util.EBuild.__init__(self, path)
Chris Sosadad0d322011-01-31 16:37:33 -0800206 re_match = self.chrome_version_re.match(self.ebuild_path_no_revision)
207 if re_match:
208 self.chrome_version = re_match.group(1)
209
Chris Sosadad0d322011-01-31 16:37:33 -0800210 def __str__(self):
211 return self.ebuild_path
212
213
David Zeuthen665d3132014-08-25 15:27:02 -0400214def FindChromeCandidates(package_dir):
Chris Sosadad0d322011-01-31 16:37:33 -0800215 """Return a tuple of chrome's unstable ebuild and stable ebuilds.
216
217 Args:
David Zeuthen665d3132014-08-25 15:27:02 -0400218 package_dir: The path to where the package ebuild is stored.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500219
Chris Sosadad0d322011-01-31 16:37:33 -0800220 Returns:
221 Tuple [unstable_ebuild, stable_ebuilds].
Mike Frysinger1a736a82013-12-12 01:50:59 -0500222
Chris Sosadad0d322011-01-31 16:37:33 -0800223 Raises:
224 Exception: if no unstable ebuild exists for Chrome.
225 """
226 stable_ebuilds = []
227 unstable_ebuilds = []
228 for path in [
David Zeuthen665d3132014-08-25 15:27:02 -0400229 os.path.join(package_dir, entry) for entry in os.listdir(package_dir)]:
Chris Sosadad0d322011-01-31 16:37:33 -0800230 if path.endswith('.ebuild'):
231 ebuild = ChromeEBuild(path)
232 if not ebuild.chrome_version:
Lann Martinffb95162018-08-28 12:02:54 -0600233 logging.warning('Poorly formatted ebuild found at %s', path)
Chris Sosadad0d322011-01-31 16:37:33 -0800234 else:
235 if '9999' in ebuild.version:
236 unstable_ebuilds.append(ebuild)
237 else:
238 stable_ebuilds.append(ebuild)
239
240 # Apply some sanity checks.
241 if not unstable_ebuilds:
David Zeuthen665d3132014-08-25 15:27:02 -0400242 raise Exception('Missing 9999 ebuild for %s' % package_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800243 if not stable_ebuilds:
Lann Martinffb95162018-08-28 12:02:54 -0600244 logging.warning('Missing stable ebuild for %s', package_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800245
Alex Deymo075c2292014-09-04 18:31:50 -0700246 return portage_util.BestEBuild(unstable_ebuilds), stable_ebuilds
Chris Sosadad0d322011-01-31 16:37:33 -0800247
248
249def FindChromeUprevCandidate(stable_ebuilds, chrome_rev, sticky_branch):
250 """Finds the Chrome uprev candidate for the given chrome_rev.
251
252 Using the pre-flight logic, this means the stable ebuild you are uprevving
253 from. The difference here is that the version could be different and in
254 that case we want to find it to delete it.
255
256 Args:
257 stable_ebuilds: A list of stable ebuilds.
258 chrome_rev: The chrome_rev designating which candidate to find.
Mike Frysingerad8c6ca2014-02-03 11:28:45 -0500259 sticky_branch: The the branch that is currently sticky with Major/Minor
Chris Sosa9ba47752012-02-27 15:27:37 -0800260 components. For example: 9.0.553. Can be None but not if chrome_rev
261 is CHROME_REV_STICKY.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500262
Chris Sosadad0d322011-01-31 16:37:33 -0800263 Returns:
Mike Frysinger1a736a82013-12-12 01:50:59 -0500264 The EBuild, otherwise None if none found.
Chris Sosadad0d322011-01-31 16:37:33 -0800265 """
266 candidates = []
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400267 if chrome_rev in [constants.CHROME_REV_LOCAL, constants.CHROME_REV_TOT,
268 constants.CHROME_REV_SPEC]:
269 # These are labelled alpha, for historic reasons,
Peter Mayo177500f2011-09-09 17:25:23 -0400270 # not just for the fun of confusion.
David James7c352bc2013-03-15 14:19:57 -0700271 chrome_branch_re = re.compile(r'%s.*_alpha.*' % _CHROME_VERSION_REGEX)
Chris Sosadad0d322011-01-31 16:37:33 -0800272 for ebuild in stable_ebuilds:
273 if chrome_branch_re.search(ebuild.version):
274 candidates.append(ebuild)
275
Ryan Cuic6e097d2011-06-16 12:23:14 -0700276 elif chrome_rev == constants.CHROME_REV_STICKY:
Chris Sosa9ba47752012-02-27 15:27:37 -0800277 assert sticky_branch is not None
David James7c352bc2013-03-15 14:19:57 -0700278 chrome_branch_re = re.compile(r'%s\..*' % sticky_branch)
Chris Sosadad0d322011-01-31 16:37:33 -0800279 for ebuild in stable_ebuilds:
280 if chrome_branch_re.search(ebuild.version):
281 candidates.append(ebuild)
282
283 else:
David James7c352bc2013-03-15 14:19:57 -0700284 chrome_branch_re = re.compile(r'%s.*_rc.*' % _CHROME_VERSION_REGEX)
Chris Sosadad0d322011-01-31 16:37:33 -0800285 for ebuild in stable_ebuilds:
Chris Sosa9ba47752012-02-27 15:27:37 -0800286 if chrome_branch_re.search(ebuild.version):
Chris Sosadad0d322011-01-31 16:37:33 -0800287 candidates.append(ebuild)
288
289 if candidates:
Alex Deymo075c2292014-09-04 18:31:50 -0700290 return portage_util.BestEBuild(candidates)
Chris Sosadad0d322011-01-31 16:37:33 -0800291 else:
292 return None
293
Mike Frysingercc838832014-05-24 13:10:30 -0400294
Chris Masone592cab52011-08-02 14:05:48 -0700295def GetChromeRevisionLinkFromVersions(old_chrome_version, chrome_version):
296 """Return appropriately formatted link to revision info, given versions
297
298 Given two chrome version strings (e.g. 9.0.533.0), generate a link to a
299 page that prints the Chromium revisions between those two versions.
300
301 Args:
302 old_chrome_version: version to diff from
303 chrome_version: version to which to diff
Mike Frysinger1a736a82013-12-12 01:50:59 -0500304
Chris Masone592cab52011-08-02 14:05:48 -0700305 Returns:
306 The desired URL.
307 """
Mike Frysingerd6e2df02014-11-26 02:55:04 -0500308 return _CHROME_VERSION_URL % {'old': old_chrome_version,
309 'new': chrome_version}
Chris Masone592cab52011-08-02 14:05:48 -0700310
Mike Frysinger750c5f52014-09-16 16:16:57 -0400311
Chris Masone592cab52011-08-02 14:05:48 -0700312def GetChromeRevisionListLink(old_chrome, new_chrome, chrome_rev):
313 """Returns a link to the list of revisions between two Chromium versions
314
315 Given two ChromeEBuilds and the kind of rev we're doing, generate a
316 link to a page that prints the Chromium changes between those two
317 revisions, inclusive.
318
319 Args:
320 old_chrome: ebuild for the version to diff from
321 new_chrome: ebuild for the version to which to diff
322 chrome_rev: one of constants.VALID_CHROME_REVISIONS
Mike Frysinger1a736a82013-12-12 01:50:59 -0500323
Chris Masone592cab52011-08-02 14:05:48 -0700324 Returns:
325 The desired URL.
326 """
Chris Sosadd611df2012-02-03 15:26:23 -0800327 assert chrome_rev in _REV_TYPES_FOR_LINKS
328 return GetChromeRevisionLinkFromVersions(old_chrome.chrome_version,
329 new_chrome.chrome_version)
Chris Sosadad0d322011-01-31 16:37:33 -0800330
Mike Frysingercc838832014-05-24 13:10:30 -0400331
David Zeuthen665d3132014-08-25 15:27:02 -0400332def MarkChromeEBuildAsStable(stable_candidate, unstable_ebuild, chrome_pn,
Mike Frysinger93ad2262018-08-30 18:42:14 -0400333 chrome_rev, chrome_version, package_dir):
David James7c352bc2013-03-15 14:19:57 -0700334 r"""Uprevs the chrome ebuild specified by chrome_rev.
Chris Sosadad0d322011-01-31 16:37:33 -0800335
336 This is the main function that uprevs the chrome_rev from a stable candidate
337 to its new version.
338
339 Args:
340 stable_candidate: ebuild that corresponds to the stable ebuild we are
341 revving from. If None, builds the a new ebuild given the version
342 and logic for chrome_rev type with revision set to 1.
Mike Frysingerad8c6ca2014-02-03 11:28:45 -0500343 unstable_ebuild: ebuild corresponding to the unstable ebuild for chrome.
David Zeuthen665d3132014-08-25 15:27:02 -0400344 chrome_pn: package name.
Peter Mayo177500f2011-09-09 17:25:23 -0400345 chrome_rev: one of constants.VALID_CHROME_REVISIONS or LOCAL
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400346 constants.CHROME_REV_SPEC - Requires commit value. Revs the ebuild for
347 the specified version and uses the portage suffix of _alpha.
Ryan Cuic6e097d2011-06-16 12:23:14 -0700348 constants.CHROME_REV_TOT - Requires commit value. Revs the ebuild for
349 the TOT version and uses the portage suffix of _alpha.
Peter Mayo177500f2011-09-09 17:25:23 -0400350 constants.CHROME_REV_LOCAL - Requires a chrome_root. Revs the ebuild for
351 the local version and uses the portage suffix of _alpha.
Ryan Cuic6e097d2011-06-16 12:23:14 -0700352 constants.CHROME_REV_LATEST - This uses the portage suffix of _rc as they
353 are release candidates for the next sticky version.
354 constants.CHROME_REV_STICKY - Revs the sticky version.
Mike Frysingerad8c6ca2014-02-03 11:28:45 -0500355 chrome_version: The \d.\d.\d.\d version of Chrome.
David Zeuthen665d3132014-08-25 15:27:02 -0400356 package_dir: Path to the chromeos-chrome package dir.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500357
Chris Sosadad0d322011-01-31 16:37:33 -0800358 Returns:
359 Full portage version atom (including rc's, etc) that was revved.
360 """
Chris Sosa8be39132011-04-14 12:09:24 -0700361 def IsTheNewEBuildRedundant(new_ebuild, stable_ebuild):
362 """Returns True if the new ebuild is redundant.
363
364 This is True if there if the current stable ebuild is the exact same copy
David James89608f92012-11-03 14:14:12 -0700365 of the new one.
Chris Sosa8be39132011-04-14 12:09:24 -0700366 """
367 if not stable_ebuild:
368 return False
369
370 if stable_candidate.chrome_version == new_ebuild.chrome_version:
David James89608f92012-11-03 14:14:12 -0700371 return filecmp.cmp(
372 new_ebuild.ebuild_path, stable_ebuild.ebuild_path, shallow=False)
Chris Sosa8be39132011-04-14 12:09:24 -0700373
David James629febb2012-11-25 13:07:34 -0800374 # Mark latest release and sticky branches as stable.
375 mark_stable = chrome_rev not in [constants.CHROME_REV_TOT,
376 constants.CHROME_REV_SPEC,
377 constants.CHROME_REV_LOCAL]
378
Chris Sosadad0d322011-01-31 16:37:33 -0800379 # Case where we have the last stable candidate with same version just rev.
380 if stable_candidate and stable_candidate.chrome_version == chrome_version:
381 new_ebuild_path = '%s-r%d.ebuild' % (
382 stable_candidate.ebuild_path_no_revision,
383 stable_candidate.current_revision + 1)
384 else:
David James629febb2012-11-25 13:07:34 -0800385 suffix = 'rc' if mark_stable else 'alpha'
David Zeuthen665d3132014-08-25 15:27:02 -0400386 pf = '%s-%s_%s-r1' % (chrome_pn, chrome_version, suffix)
387 new_ebuild_path = os.path.join(package_dir, '%s.ebuild' % pf)
Chris Sosadad0d322011-01-31 16:37:33 -0800388
Alex Deymo075c2292014-09-04 18:31:50 -0700389 portage_util.EBuild.MarkAsStable(
David James065b2012012-04-01 14:51:11 -0700390 unstable_ebuild.ebuild_path, new_ebuild_path,
Mike Frysinger93ad2262018-08-30 18:42:14 -0400391 {}, make_stable=mark_stable)
Chris Sosadad0d322011-01-31 16:37:33 -0800392 new_ebuild = ChromeEBuild(new_ebuild_path)
Chris Sosa8be39132011-04-14 12:09:24 -0700393
394 # Determine whether this is ebuild is redundant.
395 if IsTheNewEBuildRedundant(new_ebuild, stable_candidate):
David James1b363582012-12-17 11:53:11 -0800396 msg = 'Previous ebuild with same version found and ebuild is redundant.'
Ralph Nathan03047282015-03-23 11:09:32 -0700397 logging.info(msg)
Chris Sosa8be39132011-04-14 12:09:24 -0700398 os.unlink(new_ebuild_path)
399 return None
Chris Sosadad0d322011-01-31 16:37:33 -0800400
Chris Sosadd611df2012-02-03 15:26:23 -0800401 if stable_candidate and chrome_rev in _REV_TYPES_FOR_LINKS:
David Riley3e3f64e2016-02-03 08:17:55 -0800402 logging.PrintBuildbotLink('Chromium revisions',
403 GetChromeRevisionListLink(stable_candidate,
404 new_ebuild, chrome_rev))
Chris Masone592cab52011-08-02 14:05:48 -0700405
David Zeuthen665d3132014-08-25 15:27:02 -0400406 git.RunGit(package_dir, ['add', new_ebuild_path])
Chris Sosa9ba47752012-02-27 15:27:37 -0800407 if stable_candidate and not stable_candidate.IsSticky():
David Zeuthen665d3132014-08-25 15:27:02 -0400408 git.RunGit(package_dir, ['rm', stable_candidate.ebuild_path])
Chris Sosadad0d322011-01-31 16:37:33 -0800409
Alex Deymo075c2292014-09-04 18:31:50 -0700410 portage_util.EBuild.CommitChange(
David Zeuthen665d3132014-08-25 15:27:02 -0400411 _GIT_COMMIT_MESSAGE % {'chrome_pn': chrome_pn,
412 'chrome_rev': chrome_rev,
Mike Frysinger2ebe3732012-05-08 17:04:12 -0400413 'chrome_version': chrome_version},
David Zeuthen665d3132014-08-25 15:27:02 -0400414 package_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800415
Chris Sosadad0d322011-01-31 16:37:33 -0800416 return '%s-%s' % (new_ebuild.package, new_ebuild.version)
417
418
Mike Frysingera13c04f2016-09-01 00:35:17 -0400419def GetParser():
420 """Return a command line parser."""
421 parser = commandline.ArgumentParser(description=__doc__)
422 parser.add_argument('-b', '--boards')
423 parser.add_argument('-c', '--chrome_url',
424 default=constants.CHROMIUM_GOB_URL)
425 parser.add_argument('-f', '--force_version',
426 help='Chrome version or git revision hash to use')
427 parser.add_argument('-s', '--srcroot',
428 default=os.path.join(os.environ['HOME'], 'trunk', 'src'),
429 help='Path to the src directory')
430 parser.add_argument('-t', '--tracking_branch', default='cros/master',
431 help='Branch we are tracking changes against')
432 parser.add_argument('revision', choices=constants.VALID_CHROME_REVISIONS)
433 return parser
Chris Sosadad0d322011-01-31 16:37:33 -0800434
Chris Sosadad0d322011-01-31 16:37:33 -0800435
Mike Frysingera13c04f2016-09-01 00:35:17 -0400436def main(argv):
437 parser = GetParser()
438 options = parser.parse_args(argv)
439 options.Freeze()
440 chrome_rev = options.revision
441
442 if options.force_version and chrome_rev not in (constants.CHROME_REV_SPEC,
443 constants.CHROME_REV_LATEST):
David Jamesfb160012014-07-01 10:00:57 -0700444 parser.error('--force_version is not compatible with the %r '
Mike Frysingera13c04f2016-09-01 00:35:17 -0400445 'option.' % (chrome_rev,))
David Jamesfb160012014-07-01 10:00:57 -0700446
David Zeuthen665d3132014-08-25 15:27:02 -0400447 overlay_dir = os.path.abspath(_OVERLAY_DIR % {'srcroot': options.srcroot})
448 chrome_package_dir = os.path.join(overlay_dir, constants.CHROME_CP)
Chris Sosadad0d322011-01-31 16:37:33 -0800449 version_to_uprev = None
Chris Sosa9ba47752012-02-27 15:27:37 -0800450 sticky_branch = None
Chris Sosadad0d322011-01-31 16:37:33 -0800451
David Zeuthen665d3132014-08-25 15:27:02 -0400452 (unstable_ebuild, stable_ebuilds) = FindChromeCandidates(chrome_package_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800453
Peter Mayo177500f2011-09-09 17:25:23 -0400454 if chrome_rev == constants.CHROME_REV_LOCAL:
455 if 'CHROME_ROOT' in os.environ:
456 chrome_root = os.environ['CHROME_ROOT']
457 else:
458 chrome_root = os.path.join(os.environ['HOME'], 'chrome_root')
459
460 version_to_uprev = _GetTipOfTrunkVersionFile(chrome_root)
Ralph Nathan03047282015-03-23 11:09:32 -0700461 logging.info('Using local source, versioning is untrustworthy.')
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400462 elif chrome_rev == constants.CHROME_REV_SPEC:
David Jamesfb160012014-07-01 10:00:57 -0700463 if '.' in options.force_version:
464 version_to_uprev = options.force_version
465 else:
466 commit_to_use = options.force_version
467 if '@' in commit_to_use:
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700468 commit_to_use = commit_to_use.rpartition('@')[2]
David Jamesfb160012014-07-01 10:00:57 -0700469 version_to_uprev = _GetSpecificVersionUrl(options.chrome_url,
470 commit_to_use)
Peter Mayo177500f2011-09-09 17:25:23 -0400471 elif chrome_rev == constants.CHROME_REV_TOT:
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700472 commit_to_use = gob_util.GetTipOfTrunkRevision(options.chrome_url)
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400473 version_to_uprev = _GetSpecificVersionUrl(options.chrome_url,
474 commit_to_use)
Ryan Cuic6e097d2011-06-16 12:23:14 -0700475 elif chrome_rev == constants.CHROME_REV_LATEST:
David James9a5980e2014-07-16 09:37:00 -0700476 if options.force_version:
477 if '.' not in options.force_version:
478 parser.error('%s only accepts released Chrome versions, not SVN or '
479 'Git revisions.' % (chrome_rev,))
480 version_to_uprev = options.force_version
481 else:
482 version_to_uprev = GetLatestRelease(options.chrome_url)
Chris Sosadad0d322011-01-31 16:37:33 -0800483 else:
Chris Sosa9ba47752012-02-27 15:27:37 -0800484 sticky_ebuild = _GetStickyEBuild(stable_ebuilds)
485 sticky_version = sticky_ebuild.chrome_version
486 sticky_branch = sticky_version.rpartition('.')[0]
Yu-Ju Hong39806322014-06-24 16:46:32 -0700487 version_to_uprev = GetLatestRelease(options.chrome_url, sticky_branch)
Chris Sosadad0d322011-01-31 16:37:33 -0800488
489 stable_candidate = FindChromeUprevCandidate(stable_ebuilds, chrome_rev,
490 sticky_branch)
491
492 if stable_candidate:
Lann Martinffb95162018-08-28 12:02:54 -0600493 logging.info('Stable candidate found %s', stable_candidate)
Chris Sosadad0d322011-01-31 16:37:33 -0800494 else:
Ralph Nathan03047282015-03-23 11:09:32 -0700495 logging.info('No stable candidate found.')
Chris Sosadad0d322011-01-31 16:37:33 -0800496
Chris Sosa8049f3b2011-05-02 20:09:28 -0700497 tracking_branch = 'remotes/m/%s' % os.path.basename(options.tracking_branch)
David Zeuthen665d3132014-08-25 15:27:02 -0400498 existing_branch = git.GetCurrentBranch(chrome_package_dir)
Ryan Cui05a31ba2011-05-31 17:47:37 -0700499 work_branch = cros_mark_as_stable.GitBranch(constants.STABLE_EBUILD_BRANCH,
David Zeuthen665d3132014-08-25 15:27:02 -0400500 tracking_branch,
501 chrome_package_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800502 work_branch.CreateBranch()
David Jamesd6708c02012-03-22 10:49:15 -0700503
504 # In the case of uprevving overlays that have patches applied to them,
505 # include the patched changes in the stabilizing branch.
506 if existing_branch:
David Zeuthen665d3132014-08-25 15:27:02 -0400507 git.RunGit(chrome_package_dir, ['rebase', existing_branch])
David Jamesd6708c02012-03-22 10:49:15 -0700508
Chris Sosadad0d322011-01-31 16:37:33 -0800509 chrome_version_atom = MarkChromeEBuildAsStable(
David Zeuthen665d3132014-08-25 15:27:02 -0400510 stable_candidate, unstable_ebuild, 'chromeos-chrome', chrome_rev,
Mike Frysinger93ad2262018-08-30 18:42:14 -0400511 version_to_uprev, chrome_package_dir)
Yu-Ju Hong078c9ec2014-08-06 18:25:16 -0700512 if chrome_version_atom:
513 if options.boards:
David James96c2c992015-07-14 10:21:50 -0700514 cros_mark_as_stable.CleanStalePackages(options.srcroot,
515 options.boards.split(':'),
Yu-Ju Hong078c9ec2014-08-06 18:25:16 -0700516 [chrome_version_atom])
David Zeuthen665d3132014-08-25 15:27:02 -0400517
518 # If we did rev Chrome, now is a good time to uprev other packages.
519 for other_ebuild in constants.OTHER_CHROME_PACKAGES:
520 other_ebuild_name = os.path.basename(other_ebuild)
521 other_package_dir = os.path.join(overlay_dir, other_ebuild)
522 (other_unstable_ebuild, other_stable_ebuilds) = FindChromeCandidates(
523 other_package_dir)
524 other_stable_candidate = FindChromeUprevCandidate(other_stable_ebuilds,
525 chrome_rev,
526 sticky_branch)
527 revved_atom = MarkChromeEBuildAsStable(other_stable_candidate,
528 other_unstable_ebuild,
529 other_ebuild_name,
530 chrome_rev, version_to_uprev,
Mike Frysinger93ad2262018-08-30 18:42:14 -0400531 other_package_dir)
David Zeuthen665d3132014-08-25 15:27:02 -0400532 if revved_atom and options.boards:
David James96c2c992015-07-14 10:21:50 -0700533 cros_mark_as_stable.CleanStalePackages(options.srcroot,
534 options.boards.split(':'),
David Zeuthen665d3132014-08-25 15:27:02 -0400535 [revved_atom])
536
537 # Explicit print to communicate to caller.
538 if chrome_version_atom:
Mike Frysinger383367e2014-09-16 15:06:17 -0400539 print('CHROME_VERSION_ATOM=%s' % chrome_version_atom)