| """Base class for build recipes.""" |
| import abc |
| import logging |
| import os |
| from pathlib import Path |
| import pprint |
| import six |
| from typing import Any, Dict, Optional |
| |
| from helpers import accelerator_utils |
| from slave.accelerator import no_accelerator |
| from slave.step import clean_sync_step |
| from slave.step import git_clean_step |
| from slave.step import license_manager_step |
| from slave.step import make_clean_step |
| from slave.step import platform_info_step |
| |
| |
| LOGGER = logging.getLogger(__name__) |
| |
| class BuildNameNotSupportedError(Exception): |
| """Raised when a recipe does not support the given build_name.""" |
| |
| |
| class BaseRecipe(six.with_metaclass(abc.ABCMeta, object)): |
| """Base class for recipes.""" |
| |
| def __init__(self, |
| executor: 'Executor', |
| eureka_root: str, |
| enable_build_accelerator: bool=False, |
| properties: Optional[Dict[str, Any]]=None, |
| **kwargs): |
| """Base constructor. |
| |
| Args: |
| **kwargs: The kwargs to pass to individual steps. |
| """ |
| LOGGER.info("Creating recipe %s", type(self)) |
| LOGGER.info("Properties: %s", pprint.pformat(properties)) |
| LOGGER.info("Eureka root: %s", eureka_root) |
| self._eureka_root = Path(eureka_root) |
| self._properties = properties or {} |
| self._build_accelerator = ( |
| accelerator_utils.get_build_accelerator() |
| if enable_build_accelerator else no_accelerator.NoAccelerator()) |
| self._executor = executor |
| self._remote_lookup = None |
| self._path_lookup = None |
| self._fix_floats() |
| self._skip_gclient = self._properties.get('skip_gclient', False) |
| self._git_clean = self._properties.get('git_clean', False) |
| self._make_clean = self.build_system == 'catabuilder' |
| self._make_distclean = self._properties.get('make_distclean', False) |
| self._manifest_branch = self._properties.get('manifest_branch') |
| self._patch_project = self._properties.get('patch_project') |
| self._env = self._properties.get('build_env', 'local') |
| self._manifest_url = self._properties.get('manifest_url') |
| self._check_android_license = ( |
| self._env != 'local' and kwargs.get('check_android_license', False)) |
| |
| self._step_kwargs = kwargs.copy() |
| self._step_kwargs['build_accelerator'] = self._build_accelerator |
| self._step_kwargs["executor"] = executor |
| self._step_kwargs["eureka_root"] = self._eureka_root |
| self._step_kwargs["enable_build_accelerator"] = enable_build_accelerator |
| self._step_kwargs["properties"] = properties |
| |
| @property |
| def build_system(self): |
| """Returns the name of current build system.""" |
| return self._properties.get('build_system', 'local') |
| |
| @property |
| def buildername(self): |
| """Returns the buildername of the current build.""" |
| return self._properties.get('buildername') |
| |
| def get_setup_steps(self): |
| """Returns a list of all steps that should be executed as part of setup. |
| |
| Returns: |
| List of slave.base_step.BaseStep commands to be executed. |
| """ |
| setup_steps = [] |
| setup_steps.append( |
| platform_info_step.PlatformInfoStep( |
| directory='', **self._step_kwargs)) |
| |
| if not self._skip_gclient: |
| setup_steps.append( |
| clean_sync_step.GclientSyncStep( |
| directory='', **self._step_kwargs)) |
| |
| if self._check_android_license: |
| setup_steps.append(license_manager_step.AndroidSdkLicenseCheckAccept( |
| directory='', **self._step_kwargs)) |
| |
| setup_steps.extend( |
| self. _get_build_accelerator().setup_steps(self._step_kwargs)) |
| |
| if self._make_clean: |
| setup_steps += self.get_clean_steps() |
| |
| if self._make_distclean: |
| setup_steps.append( |
| make_clean_step.MakeDistCleanStep(**self._step_kwargs)) |
| |
| if self._git_clean: |
| setup_steps.append( |
| git_clean_step.GitCleanStep(**self._step_kwargs)) |
| |
| return setup_steps |
| |
| def _get_build_accelerator(self): |
| return self._build_accelerator |
| |
| def get_teardown_steps(self): |
| """Returns a list of all steps that should be executed as part of teardown. |
| |
| Returns: |
| List of slave.base_step.BaseStep commands to be executed. |
| """ |
| return self._get_build_accelerator().tear_down_steps(self._step_kwargs) |
| |
| @property |
| def build_number(self): |
| """Construct BUILD_NUMBER string in unified way between all systems. |
| |
| This property is matching the same property in the BaseStep, should be |
| altered together. |
| |
| Returns: |
| CL number (from 'issue' porperty) for CQ, buildset number for CB or 0 |
| """ |
| return str(self._properties.get( |
| 'issue', self._properties.get('buildset', '0'))) |
| |
| @abc.abstractmethod |
| def get_steps(self): |
| """Builds a list of all steps that should be executed by this recipe. |
| |
| Returns: |
| List of slave.base_step.BaseStep commands to be executed. |
| """ |
| return [] |
| |
| def get_clean_steps(self): |
| """Builds a list of all clean steps that should be executed by this recipe. |
| |
| Returns: |
| List of slave.base_step.BaseStep commands to be executed. |
| """ |
| return [] |
| |
| def _fix_floats(self): |
| """Buildbucket is enforcing floats, but we want ints.""" |
| for key, value in self._properties.items(): |
| if isinstance(value, float): |
| self._properties[key] = int(value) |
| |
| def _getcwd(self): |
| """Helper function to make it easy to mock os.getcwd() for tests.""" |
| return os.getcwd() |