| # Copyright 2020 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| REPOS = { |
| 'flutter': |
| 'https://chromium.googlesource.com/external/github.com/flutter/flutter', |
| 'engine': |
| 'https://chromium.googlesource.com/external/github.com/flutter/engine', |
| 'cocoon': |
| 'https://chromium.googlesource.com/external/github.com/flutter/cocoon', |
| 'packages': |
| 'https://github.com/flutter/packages', |
| 'plugins': |
| 'https://chromium.googlesource.com/external/github.com/flutter/plugins' |
| } |
| |
| import re |
| from recipe_engine import recipe_api |
| |
| |
| class RepoUtilApi(recipe_api.RecipeApi): |
| """Provides utilities to work with flutter repos.""" |
| |
| def engine_checkout(self, checkout_path, env, env_prefixes, clobber=True): |
| """Checkout code using gclient. |
| |
| Args: |
| checkout_path(Path): The path to checkout source code and dependencies. |
| env(dict): A dictionary with the environment variables to set. |
| env(dict): A dictionary with the paths to be added to environment variables. |
| clobber(bool): A boolean indicating whether the checkout folder should be cleaned. |
| """ |
| git_url = REPOS['engine'] |
| git_id = self.m.buildbucket.gitiles_commit.id |
| git_ref = self.m.buildbucket.gitiles_commit.ref |
| if 'git_url' in self.m.properties and 'git_ref' in self.m.properties: |
| git_url = self.m.properties['git_url'] |
| git_id = self.m.properties['git_ref'] |
| git_ref = self.m.properties['git_ref'] |
| |
| # Inner function to execute code a second time in case of failure. |
| def _InnerCheckout(): |
| with self.m.context(env=env, env_prefixes=env_prefixes, |
| cwd=checkout_path), self.m.depot_tools.on_path(): |
| src_cfg = self.m.gclient.make_config() |
| soln = src_cfg.solutions.add() |
| soln.name = 'src/flutter' |
| soln.url = git_url |
| soln.revision = git_id |
| src_cfg.parent_got_revision_mapping['parent_got_revision' |
| ] = 'got_revision' |
| src_cfg.repo_path_map[git_url] = ('src/flutter', git_ref) |
| self.m.gclient.c = src_cfg |
| self.m.gclient.c.got_revision_mapping['src/flutter' |
| ] = 'got_engine_revision' |
| self.m.bot_update.ensure_checkout() |
| self.m.gclient.runhooks() |
| |
| with self.m.step.nest('Checkout source code'): |
| try: |
| # Run this out of context |
| if clobber: |
| self.m.file.rmtree('Clobber cache', checkout_path) |
| self.m.file.ensure_directory('Ensure checkout cache', checkout_path) |
| _InnerCheckout() |
| except (self.m.step.StepFailure, self.m.step.InfraFailure): |
| # Run this out of context |
| |
| # Ensure depot tools is in the path to prevent problems with vpython not |
| # being found after a failure. |
| with self.m.depot_tools.on_path(): |
| self.m.file.rmtree('Clobber cache', checkout_path) |
| self.m.file.rmtree( |
| 'Clobber git cache', self.m.path['cache'].join('git') |
| ) |
| self.m.file.ensure_directory('Ensure checkout cache', checkout_path) |
| # Now try a second time |
| _InnerCheckout() |
| |
| def checkout(self, name, checkout_path, url=None, ref=None): |
| """Checks out a repo and returns sha1 of checked out revision. |
| |
| The supproted repository names and their urls are defined in the global |
| REPOS variable. |
| |
| Args: |
| name (str): name of the supported repository. |
| checkout_path (Path): directory to clone into. |
| url (str): optional url overwrite of the remote repo. |
| ref (str): optional ref overwrite to fetch and check out. |
| """ |
| if name not in REPOS: |
| raise ValueError('Unsupported repo: %s' % name) |
| with self.m.step.nest('Checkout flutter/%s' % name): |
| git_url = url or REPOS[name] |
| # gitiles_commit.id is more specific than gitiles_commit.ref, which is |
| # branch |
| git_ref = ref or self.m.buildbucket.gitiles_commit.id |
| return self.m.git.checkout( |
| git_url, |
| dir_path=checkout_path, |
| ref=git_ref, |
| recursive=True, |
| set_got_revision=True, |
| tags=True |
| ) |
| |
| def flutter_environment(self, checkout_path): |
| """Returns env and env_prefixes of an flutter/dart command environment.""" |
| dart_bin = checkout_path.join('bin', 'cache', 'dart-sdk', 'bin') |
| flutter_bin = checkout_path.join('bin') |
| # Fail if flutter bin folder does not exist. dart-sdk/bin folder will be |
| # available only after running "flutter doctor" and it needs to be run as |
| # the first command on the context using the environment. |
| if not self.m.path.exists(flutter_bin): |
| msg = ( |
| 'flutter bin folders do not exist,' |
| 'did you forget to checkout flutter repo?' |
| ) |
| self.m.python.failing_step('Flutter Environment', msg) |
| git_ref = self.m.properties.get('git_ref', '') |
| pub_cache_path = self.m.path['start_dir'].join('.pub-cache') |
| env = { |
| # Setup our own pub_cache to not affect other slaves on this machine, |
| # and so that the pre-populated pub cache is contained in the package. |
| 'PUB_CACHE': |
| pub_cache_path, |
| # Windows Packaging script assumes this is set. |
| 'DEPOT_TOOLS': |
| str(self.m.depot_tools.root), |
| 'SDK_CHECKOUT_PATH': |
| checkout_path, |
| 'LUCI_CI': |
| True, |
| 'LUCI_PR': |
| re.sub('refs\/pull\/|\/head', '', git_ref), |
| 'LUCI_BRANCH': |
| self.m.properties.get('release_ref', '').replace('refs/heads/', ''), |
| 'OS': |
| 'linux' if self.m.platform.name == 'linux' else |
| ('darwin' if self.m.platform.name == 'mac' else 'win') |
| } |
| env_prefixes = {'PATH': ['%s' % str(flutter_bin), '%s' % str(dart_bin)]} |
| return env, env_prefixes |
| |
| def sdk_checkout_path(self): |
| """Returns the checkoout path of the current flutter_environment. |
| |
| Returns(Path): A path object with the current checkout path. |
| """ |
| checkout_path = self.m.context.env.get('SDK_CHECKOUT_PATH') |
| assert checkout_path, 'Outside of a flutter_environment?' |
| return self.m.path.abs_to_path(checkout_path) |