blob: 250a55a4e3612b44c7e05cda6a9fbe72ec906551 [file] [log] [blame] [edit]
"""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()