| # Copyright 2014 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. |
| |
| |
| # pylint: disable=W0201 |
| |
| |
| import json |
| import os |
| import re |
| import sys |
| |
| from recipe_engine import recipe_api |
| from recipe_engine import config_types |
| |
| |
| class SkiaApi(recipe_api.RecipeApi): |
| |
| def setup(self, bot_update=True): |
| """Prepare the bot to run.""" |
| # Setup dependencies. |
| self.m.vars.setup() |
| |
| # Check out the Skia code. |
| if bot_update: |
| self.checkout_bot_update() |
| else: |
| self.checkout_git() |
| |
| if not self.m.path.exists(self.m.vars.tmp_dir): |
| self.m.run.run_once(self.m.file.ensure_directory, |
| 'makedirs tmp_dir', |
| self.m.vars.tmp_dir) |
| |
| self.m.flavor.setup() |
| |
| def patch_ref(self, issue, patchset): |
| """Build a ref for the given issue and patchset.""" |
| return 'refs/changes/%s/%s/%s' % (issue[-2:], issue, patchset) |
| |
| def checkout_git(self): |
| """Run the steps to perform a pure-git checkout without DEPS.""" |
| self.m.git.checkout( |
| self.m.properties['repository'], dir_path=self.m.vars.skia_dir, |
| ref=self.m.properties['revision'], submodules=False) |
| if self.m.vars.is_trybot: |
| ref = self.patch_ref(str(self.m.vars.issue), str(self.m.vars.patchset)) |
| self.m.git('fetch', 'origin', ref) |
| self.m.git('checkout', 'FETCH_HEAD') |
| self.m.git('rebase', self.m.properties['revision']) |
| |
| def checkout_bot_update(self): |
| """Run the steps to obtain a checkout using bot_update.""" |
| cfg_kwargs = {} |
| is_parent_revision = 'ParentRevision' in self.m.vars.extra_tokens |
| if not self.m.vars.persistent_checkout: |
| assert not is_parent_revision |
| # We should've obtained the Skia checkout through isolates, so we don't |
| # need to perform the checkout ourselves. |
| return |
| |
| # Use a persistent gclient cache for Swarming. |
| cfg_kwargs['CACHE_DIR'] = self.m.vars.gclient_cache |
| |
| # Create the checkout path if necessary. |
| if not self.m.path.exists(self.m.vars.checkout_root): |
| self.m.file.ensure_directory('makedirs checkout_path', |
| self.m.vars.checkout_root) |
| |
| # Initial cleanup. |
| gclient_cfg = self.m.gclient.make_config(**cfg_kwargs) |
| main_repo = self.m.properties['repository'] |
| if self.m.vars.need_pdfium_checkout: |
| main_repo = 'https://pdfium.googlesource.com/pdfium.git' |
| if self.m.vars.need_flutter_checkout: |
| main_repo = 'https://github.com/flutter/engine.git' |
| main_name = self.m.path.basename(main_repo) |
| if main_name.endswith('.git'): |
| main_name = main_name[:-len('.git')] |
| # Special case for flutter because it seems to need a very specific |
| # directory structure to successfully build. |
| if self.m.vars.need_flutter_checkout and main_name == 'engine': |
| main_name = 'src/flutter' |
| main = gclient_cfg.solutions.add() |
| main.name = main_name |
| main.managed = False |
| main.url = main_repo |
| main.revision = self.m.properties.get('revision') or 'origin/master' |
| m = gclient_cfg.got_revision_mapping |
| m[main_name] = 'got_revision' |
| patch_root = main_name |
| patch_repo = main.url |
| if self.m.properties.get('patch_repo'): |
| patch_repo = self.m.properties['patch_repo'] |
| patch_root = patch_repo.split('/')[-1] |
| if patch_root.endswith('.git'): |
| patch_root = patch_root[:-4] |
| |
| if self.m.vars.need_pdfium_checkout: |
| # Skia is a DEP of PDFium; the 'revision' property is a Skia revision, and |
| # any patch should be applied to Skia, not PDFium. |
| main.revision = 'origin/master' |
| main.managed = True |
| m[main_name] = 'got_%s_revision' % main_name |
| |
| skia_dep_path = 'pdfium/third_party/skia' |
| gclient_cfg.patch_projects['skia'] = (skia_dep_path, 'HEAD') |
| gclient_cfg.revisions[skia_dep_path] = self.m.properties['revision'] |
| m[skia_dep_path] = 'got_revision' |
| patch_repo = 'https://skia.googlesource.com/skia.git' |
| patch_root = skia_dep_path |
| |
| if self.m.vars.need_flutter_checkout: |
| # Skia is a DEP of Flutter; the 'revision' property is a Skia revision, |
| # and any patch should be applied to Skia, not Flutter. |
| main.revision = 'origin/master' |
| main.managed = True |
| m[main_name] = 'got_flutter_revision' |
| if 'Android' in self.m.vars.extra_tokens: |
| gclient_cfg.target_os.add('android') |
| |
| skia_dep_path = 'src/third_party/skia' |
| gclient_cfg.patch_projects['skia'] = (skia_dep_path, 'HEAD') |
| gclient_cfg.revisions[skia_dep_path] = self.m.properties['revision'] |
| m[skia_dep_path] = 'got_revision' |
| patch_repo = 'https://skia.googlesource.com/skia.git' |
| patch_root = skia_dep_path |
| |
| # TODO(rmistry): Remove the below block after there is a solution for |
| # crbug.com/616443 |
| entries_file = self.m.vars.checkout_root.join('.gclient_entries') |
| if self.m.path.exists(entries_file) or self._test_data.enabled: |
| self.m.file.remove('remove %s' % entries_file, |
| entries_file) |
| |
| if self.m.vars.need_chromium_checkout: |
| chromium = gclient_cfg.solutions.add() |
| chromium.name = 'src' |
| chromium.managed = False |
| chromium.url = 'https://chromium.googlesource.com/chromium/src.git' |
| chromium.revision = 'origin/lkcr' |
| |
| # Run bot_update. |
| |
| # TODO(borenet): Remove this hack after the transition to Kitchen: |
| # https://bugs.chromium.org/p/skia/issues/detail?id=7050 |
| if self.m.vars.need_chromium_checkout: |
| depot_tools = self.m.vars.checkout_root.join('depot_tools') |
| res = depot_tools.join( |
| 'recipes', 'recipe_modules', 'bot_update', 'resources') |
| self.m.git.checkout( |
| 'https://chromium.googlesource.com/chromium/tools/depot_tools.git', |
| dir_path=depot_tools, ref='06493714339009216197d59c5413da2a1efdf4a2') |
| def resource(r): |
| return res.join(r) |
| self.m.bot_update.resource = resource |
| |
| # Hack the patch ref if necessary. |
| if self.m.bot_update._issue and self.m.bot_update._patchset: |
| self.m.bot_update._gerrit_ref = self.patch_ref( |
| str(self.m.bot_update._issue), str(self.m.bot_update._patchset)) |
| self.m.bot_update._repository = patch_repo |
| |
| if not self.m.vars.is_trybot and is_parent_revision: |
| main.revision = main.revision + '^' |
| |
| self.m.gclient.c = gclient_cfg |
| with self.m.context(cwd=self.m.vars.checkout_root): |
| update_step = self.m.bot_update.ensure_checkout( |
| patch_root=patch_root, |
| # The logic in ensure_checkout for this arg is fairly naive, so if |
| # patch=False, we'll see "... (without patch)" in the step names, even |
| # for non-trybot runs, which is misleading and confusing. Therefore, |
| # always specify patch=True for non-trybot runs. |
| patch=not (self.m.vars.is_trybot and is_parent_revision) |
| ) |
| |
| self.m.vars.got_revision = ( |
| update_step.presentation.properties['got_revision']) |
| |
| if self.m.vars.need_chromium_checkout: |
| with self.m.context(cwd=self.m.vars.checkout_root, |
| env=self.m.vars.gclient_env): |
| # TODO(borenet): Replace this hack with 'self.m.gclient.runhooks' after |
| # the transition to Kitchen. |
| self.m.run(self.m.step, 'gclient runhooks', |
| cmd=[depot_tools.join('gclient'), 'runhooks']) |