diff options
author | Tristan Maat <tristan.maat@codethink.co.uk> | 2019-12-31 16:15:09 +0000 |
---|---|---|
committer | Tristan Maat <tm@tlater.net> | 2020-01-08 17:22:54 +0000 |
commit | 3c1936ab225cce954428a962effbf47c8f43728c (patch) | |
tree | 7047359ca54ae4ea189a2e715daef8ce553cabdb | |
parent | 2855243b80e6b549e338f438b89a6867cfd7ff45 (diff) | |
download | buildstream-3c1936ab225cce954428a962effbf47c8f43728c.tar.gz |
Make PipelineSelection a proper enum type
PipelineSelection is one of the few stringy types that weren't
converted to FastEnum, presumably because we lacked a mechanism for
only allowing a sub-set of options as CLI arguments.
We've re-designed this since, and as part of the UI/UX refactor we'd
like to generally clean this, but that is probably still a while out.
Since that hasn't happened, for now, this adds a feature to the
FastEnumType that allows specifying only a subset of values is allowed
for a specific command, so that we can use the type as a proper
enum.
We also get rid of a number of accidental uses of strings, and move
PipelineSelection to buildstream.types so that we don't have a
significant import overhead for it.
-rw-r--r-- | src/buildstream/_context.py | 7 | ||||
-rw-r--r-- | src/buildstream/_frontend/cli.py | 109 | ||||
-rw-r--r-- | src/buildstream/_pipeline.py | 46 | ||||
-rw-r--r-- | src/buildstream/_stream.py | 71 | ||||
-rw-r--r-- | src/buildstream/types.py | 30 |
5 files changed, 153 insertions, 110 deletions
diff --git a/src/buildstream/_context.py b/src/buildstream/_context.py index 47001440a..9642edd49 100644 --- a/src/buildstream/_context.py +++ b/src/buildstream/_context.py @@ -29,7 +29,7 @@ from ._platform import Platform from ._artifactcache import ArtifactCache from ._sourcecache import SourceCache from ._cas import CASCache, CASLogLevel -from .types import _CacheBuildTrees, _SchedulerErrorAction +from .types import _CacheBuildTrees, _PipelineSelection, _SchedulerErrorAction from ._workspaces import Workspaces, WorkspaceProjectCache from .node import Node from .sandbox import SandboxRemote @@ -361,13 +361,14 @@ class Context: build.validate_keys(["max-jobs", "dependencies"]) self.build_max_jobs = build.get_int("max-jobs") - self.build_dependencies = build.get_str("dependencies") - if self.build_dependencies not in ["plan", "all"]: + dependencies = build.get_str("dependencies") + if dependencies not in ["plan", "all"]: provenance = build.get_scalar("dependencies").get_provenance() raise LoadError( "{}: Invalid value for 'dependencies'. Choose 'plan' or 'all'.".format(provenance), LoadErrorReason.INVALID_DATA, ) + self.build_dependencies = _PipelineSelection(dependencies) # Load per-projects overrides self._project_overrides = defaults.get_mapping("projects", default={}) diff --git a/src/buildstream/_frontend/cli.py b/src/buildstream/_frontend/cli.py index 051f5d7f7..365f5c421 100644 --- a/src/buildstream/_frontend/cli.py +++ b/src/buildstream/_frontend/cli.py @@ -9,7 +9,7 @@ from .. import _yaml from .._exceptions import BstError, LoadError, AppError from .._versions import BST_FORMAT_VERSION from .complete import main_bashcomplete, complete_path, CompleteUnhandled -from ..types import _CacheBuildTrees, _SchedulerErrorAction +from ..types import _CacheBuildTrees, _SchedulerErrorAction, _PipelineSelection from ..utils import _get_compression, UtilError @@ -19,11 +19,22 @@ from ..utils import _get_compression, UtilError class FastEnumType(click.Choice): - def __init__(self, enum): + def __init__(self, enum, options=None): self._enum = enum - super().__init__(enum.values()) + + if options is None: + options = enum.values() + else: + options = [option.value for option in options] + + super().__init__(options) def convert(self, value, param, ctx): + # This allows specifying default values as instances of the + # enum + if isinstance(value, self._enum): + value = value.value + return self._enum(super().convert(value, param, ctx)) @@ -438,7 +449,13 @@ def init(app, project_name, format_version, element_path, force, target_director # Build Command # ################################################################## @cli.command(short_help="Build elements in a pipeline") -@click.option("--deps", "-d", default=None, type=click.Choice(["plan", "all"]), help="The dependencies to build") +@click.option( + "--deps", + "-d", + default=None, + type=FastEnumType(_PipelineSelection, [_PipelineSelection.PLAN, _PipelineSelection.ALL]), + help="The dependencies to build", +) @click.option( "--remote", "-r", default=None, help="The URL of the remote cache (defaults to the first configured cache)" ) @@ -484,9 +501,18 @@ def build(app, elements, deps, remote): @click.option( "--deps", "-d", - default="all", + default=_PipelineSelection.ALL, show_default=True, - type=click.Choice(["none", "plan", "run", "build", "all"]), + type=FastEnumType( + _PipelineSelection, + [ + _PipelineSelection.NONE, + _PipelineSelection.PLAN, + _PipelineSelection.RUN, + _PipelineSelection.BUILD, + _PipelineSelection.ALL, + ], + ), help="The dependencies to show", ) @click.option( @@ -641,12 +667,11 @@ def shell(app, element, sysroot, mount, isolate, build_, cli_buildtree, pull_, c """ from ..element import Scope from .._project import HostMount - from .._pipeline import PipelineSelection scope = Scope.BUILD if build_ else Scope.RUN # We may need to fetch dependency artifacts if we're pulling the artifact - selection = PipelineSelection.ALL if pull_ else PipelineSelection.NONE + selection = _PipelineSelection.ALL if pull_ else _PipelineSelection.NONE use_buildtree = None with app.initialized(): @@ -750,9 +775,9 @@ def source(): @click.option( "--deps", "-d", - default="plan", + default=_PipelineSelection.PLAN, show_default=True, - type=click.Choice(["none", "plan", "all"]), + type=FastEnumType(_PipelineSelection, [_PipelineSelection.NONE, _PipelineSelection.PLAN, _PipelineSelection.ALL]), help="The dependencies to fetch", ) @click.option( @@ -803,9 +828,9 @@ def source_fetch(app, elements, deps, except_, remote): @click.option( "--deps", "-d", - default="none", + default=_PipelineSelection.NONE, show_default=True, - type=click.Choice(["none", "all"]), + type=FastEnumType(_PipelineSelection, [_PipelineSelection.NONE, _PipelineSelection.ALL]), help="The dependencies to track", ) @click.option("--cross-junctions", "-J", is_flag=True, help="Allow crossing junction boundaries") @@ -839,8 +864,8 @@ def source_track(app, elements, deps, except_, cross_junctions): # Substitute 'none' for 'redirect' so that element redirections # will be done - if deps == "none": - deps = "redirect" + if deps == _PipelineSelection.NONE: + deps = _PipelineSelection.REDIRECT app.stream.track(elements, selection=deps, except_targets=except_, cross_junctions=cross_junctions) @@ -855,9 +880,12 @@ def source_track(app, elements, deps, except_, cross_junctions): @click.option( "--deps", "-d", - default="none", + default=_PipelineSelection.NONE, show_default=True, - type=click.Choice(["build", "none", "run", "all"]), + type=FastEnumType( + _PipelineSelection, + [_PipelineSelection.BUILD, _PipelineSelection.NONE, _PipelineSelection.RUN, _PipelineSelection.ALL], + ), help="The dependencies whose sources to checkout", ) @click.option( @@ -1097,9 +1125,12 @@ def artifact(): @click.option( "--deps", "-d", - default="none", + default=_PipelineSelection.NONE, show_default=True, - type=click.Choice(["build", "run", "all", "none"]), + type=FastEnumType( + _PipelineSelection, + [_PipelineSelection.BUILD, _PipelineSelection.RUN, _PipelineSelection.ALL, _PipelineSelection.NONE], + ), help="The dependencies we also want to show", ) @click.argument("artifacts", type=click.Path(), nargs=-1) @@ -1120,9 +1151,12 @@ def artifact_show(app, deps, artifacts): @click.option( "--deps", "-d", - default="run", + default=_PipelineSelection.RUN, show_default=True, - type=click.Choice(["run", "build", "none", "all"]), + type=FastEnumType( + _PipelineSelection, + [_PipelineSelection.RUN, _PipelineSelection.BUILD, _PipelineSelection.NONE, _PipelineSelection.ALL], + ), help="The dependencies to checkout", ) @click.option("--integrate/--no-integrate", default=None, is_flag=True, help="Whether to run integration commands") @@ -1216,9 +1250,9 @@ def artifact_checkout(app, force, deps, integrate, hardlinks, tar, compression, @click.option( "--deps", "-d", - default="none", + default=_PipelineSelection.NONE, show_default=True, - type=click.Choice(["none", "all"]), + type=FastEnumType(_PipelineSelection, [_PipelineSelection.NONE, _PipelineSelection.ALL]), help="The dependency artifacts to pull", ) @click.option( @@ -1265,9 +1299,9 @@ def artifact_pull(app, artifacts, deps, remote): @click.option( "--deps", "-d", - default="none", + default=_PipelineSelection.NONE, show_default=True, - type=click.Choice(["none", "all"]), + type=FastEnumType(_PipelineSelection, [_PipelineSelection.NONE, _PipelineSelection.ALL]), help="The dependencies to push", ) @click.option( @@ -1389,9 +1423,12 @@ def artifact_list_contents(app, artifacts, long_): @click.option( "--deps", "-d", - default="none", + default=_PipelineSelection.NONE, show_default=True, - type=click.Choice(["none", "run", "build", "all"]), + type=FastEnumType( + _PipelineSelection, + [_PipelineSelection.NONE, _PipelineSelection.RUN, _PipelineSelection.BUILD, _PipelineSelection.ALL], + ), help="The dependencies to delete", ) @click.argument("artifacts", type=click.Path(), nargs=-1) @@ -1425,9 +1462,9 @@ def artifact_delete(app, artifacts, deps): @click.option( "--deps", "-d", - default="plan", + default=_PipelineSelection.PLAN, show_default=True, - type=click.Choice(["none", "plan", "all"]), + type=FastEnumType(_PipelineSelection, [_PipelineSelection.NONE, _PipelineSelection.PLAN, _PipelineSelection.ALL]), help="The dependencies to fetch", ) @click.argument("elements", nargs=-1, type=click.Path(readable=False)) @@ -1451,9 +1488,9 @@ def fetch(app, elements, deps, except_): @click.option( "--deps", "-d", - default="none", + default=_PipelineSelection.NONE, show_default=True, - type=click.Choice(["none", "all"]), + type=FastEnumType(_PipelineSelection, [_PipelineSelection.NONE, _PipelineSelection.ALL]), help="The dependencies to track", ) @click.option("--cross-junctions", "-J", is_flag=True, help="Allow crossing junction boundaries") @@ -1472,9 +1509,9 @@ def track(app, elements, deps, except_, cross_junctions): @click.option( "--deps", "-d", - default="run", + default=_PipelineSelection.RUN, show_default=True, - type=click.Choice(["run", "build", "none"]), + type=FastEnumType(_PipelineSelection, [_PipelineSelection.RUN, _PipelineSelection.BUILD, _PipelineSelection.NONE]), help="The dependencies to checkout", ) @click.option("--integrate/--no-integrate", default=True, help="Run integration commands (default is to run commands)") @@ -1505,9 +1542,9 @@ def checkout(app, element, location, force, deps, integrate, hardlinks, tar): @click.option( "--deps", "-d", - default="none", + default=_PipelineSelection.NONE, show_default=True, - type=click.Choice(["none", "all"]), + type=FastEnumType(_PipelineSelection, [_PipelineSelection.NONE, _PipelineSelection.ALL]), help="The dependency artifacts to pull", ) @click.option("--remote", "-r", help="The URL of the remote cache (defaults to the first configured cache)") @@ -1525,9 +1562,9 @@ def pull(app, elements, deps, remote): @click.option( "--deps", "-d", - default="none", + default=_PipelineSelection.NONE, show_default=True, - type=click.Choice(["none", "all"]), + type=FastEnumType(_PipelineSelection, [_PipelineSelection.NONE, _PipelineSelection.ALL]), help="The dependencies to push", ) @click.option( diff --git a/src/buildstream/_pipeline.py b/src/buildstream/_pipeline.py index aee0c55da..8f356e9b1 100644 --- a/src/buildstream/_pipeline.py +++ b/src/buildstream/_pipeline.py @@ -31,36 +31,7 @@ from ._message import Message, MessageType from ._profile import Topics, PROFILER from . import Scope, Consistency from ._project import ProjectRefStorage - - -# PipelineSelection() -# -# Defines the kind of pipeline selection to make when the pipeline -# is provided a list of targets, for whichever purpose. -# -# These values correspond to the CLI `--deps` arguments for convenience. -# -class PipelineSelection: - - # Select only the target elements in the associated targets - NONE = "none" - - # As NONE, but redirect elements that are capable of it - REDIRECT = "redirect" - - # Select elements which must be built for the associated targets to be built - PLAN = "plan" - - # All dependencies of all targets, including the targets - ALL = "all" - - # All direct build dependencies and their recursive runtime dependencies, - # excluding the targets - BUILD = "build" - - # All direct runtime dependencies and their recursive runtime dependencies, - # including the targets - RUN = "run" +from .types import _PipelineSelection # Pipeline() @@ -219,7 +190,7 @@ class Pipeline: # # Args: # targets (list of Element): The target Elements - # mode (PipelineSelection): The PipelineSelection mode + # mode (_PipelineSelection): The PipelineSelection mode # # Various commands define a --deps option to specify what elements to # use in the result, this function reports a list that is appropriate for @@ -227,10 +198,9 @@ class Pipeline: # def get_selection(self, targets, mode, *, silent=True): - elements = None - if mode == PipelineSelection.NONE: + if mode == _PipelineSelection.NONE: elements = targets - elif mode == PipelineSelection.REDIRECT: + elif mode == _PipelineSelection.REDIRECT: # Redirect and log if permitted elements = [] for t in targets: @@ -239,14 +209,14 @@ class Pipeline: self._message(MessageType.INFO, "Element '{}' redirected to '{}'".format(t.name, new_elm.name)) if new_elm not in elements: elements.append(new_elm) - elif mode == PipelineSelection.PLAN: + elif mode == _PipelineSelection.PLAN: elements = self.plan(targets) else: - if mode == PipelineSelection.ALL: + if mode == _PipelineSelection.ALL: scope = Scope.ALL - elif mode == PipelineSelection.BUILD: + elif mode == _PipelineSelection.BUILD: scope = Scope.BUILD - elif mode == PipelineSelection.RUN: + elif mode == _PipelineSelection.RUN: scope = Scope.RUN elements = list(self.dependencies(targets, scope)) diff --git a/src/buildstream/_stream.py b/src/buildstream/_stream.py index c2945a2f6..db9794c45 100644 --- a/src/buildstream/_stream.py +++ b/src/buildstream/_stream.py @@ -48,10 +48,10 @@ from ._scheduler import ( JobStatus, ) from .element import Element -from ._pipeline import Pipeline, PipelineSelection +from ._pipeline import Pipeline from ._profile import Topics, PROFILER from ._state import State -from .types import _KeyStrength, _SchedulerErrorAction +from .types import _KeyStrength, _PipelineSelection, _SchedulerErrorAction from .plugin import Plugin from . import utils, _yaml, _site from . import Scope @@ -143,7 +143,7 @@ class Stream: # # Args: # targets (list of str): Targets to pull - # selection (PipelineSelection): The selection mode for the specified targets + # selection (_PipelineSelection): The selection mode for the specified targets # except_targets (list of str): Specified targets to except from fetching # use_artifact_config (bool): If artifact remote configs should be loaded # @@ -153,7 +153,7 @@ class Stream: self, targets, *, - selection=PipelineSelection.NONE, + selection=_PipelineSelection.NONE, except_targets=(), use_artifact_config=False, load_refs=False @@ -267,14 +267,14 @@ class Stream: # # Args: # targets (list of str): Targets to build - # selection (PipelineSelection): The selection mode for the specified targets + # selection (_PipelineSelection): The selection mode for the specified targets # ignore_junction_targets (bool): Whether junction targets should be filtered out # remote (str): The URL of a specific remote server to push to, or None # # If `remote` specified as None, then regular configuration will be used # to determine where to push artifacts to. # - def build(self, targets, *, selection=PipelineSelection.PLAN, ignore_junction_targets=False, remote=None): + def build(self, targets, *, selection=_PipelineSelection.PLAN, ignore_junction_targets=False, remote=None): use_config = True if remote: @@ -300,7 +300,7 @@ class Stream: # fetch blobs of targets if options set if self._context.pull_artifact_files: - scope = Scope.ALL if selection == PipelineSelection.ALL else Scope.RUN + scope = Scope.ALL if selection == _PipelineSelection.ALL else Scope.RUN for element in self.targets: element._set_artifact_files_required(scope=scope) @@ -331,11 +331,11 @@ class Stream: # # Args: # targets (list of str): Targets to fetch - # selection (PipelineSelection): The selection mode for the specified targets + # selection (_PipelineSelection): The selection mode for the specified targets # except_targets (list of str): Specified targets to except from fetching # remote (str|None): The URL of a specific remote server to pull from. # - def fetch(self, targets, *, selection=PipelineSelection.PLAN, except_targets=None, remote=None): + def fetch(self, targets, *, selection=_PipelineSelection.PLAN, except_targets=None, remote=None): use_source_config = True if remote: @@ -358,14 +358,14 @@ class Stream: # # Args: # targets (list of str): Targets to track - # selection (PipelineSelection): The selection mode for the specified targets + # selection (_PipelineSelection): The selection mode for the specified targets # except_targets (list of str): Specified targets to except from tracking # cross_junctions (bool): Whether tracking should cross junction boundaries # # If no error is encountered while tracking, then the project files # are rewritten inline. # - def track(self, targets, *, selection=PipelineSelection.REDIRECT, except_targets=None, cross_junctions=False): + def track(self, targets, *, selection=_PipelineSelection.REDIRECT, except_targets=None, cross_junctions=False): elements = self._load_tracking( targets, selection=selection, except_targets=except_targets, cross_junctions=cross_junctions @@ -389,14 +389,14 @@ class Stream: # # Args: # targets (list of str): Targets to pull - # selection (PipelineSelection): The selection mode for the specified targets + # selection (_PipelineSelection): The selection mode for the specified targets # ignore_junction_targets (bool): Whether junction targets should be filtered out # remote (str): The URL of a specific remote server to pull from, or None # # If `remote` specified as None, then regular configuration will be used # to determine where to pull artifacts from. # - def pull(self, targets, *, selection=PipelineSelection.NONE, ignore_junction_targets=False, remote=None): + def pull(self, targets, *, selection=_PipelineSelection.NONE, ignore_junction_targets=False, remote=None): use_config = True if remote: @@ -426,7 +426,7 @@ class Stream: # # Args: # targets (list of str): Targets to push - # selection (PipelineSelection): The selection mode for the specified targets + # selection (_PipelineSelection): The selection mode for the specified targets # ignore_junction_targets (bool): Whether junction targets should be filtered out # remote (str): The URL of a specific remote server to push to, or None # @@ -437,7 +437,7 @@ class Stream: # a pull queue will be created if user context and available remotes allow for # attempting to fetch them. # - def push(self, targets, *, selection=PipelineSelection.NONE, ignore_junction_targets=False, remote=None): + def push(self, targets, *, selection=_PipelineSelection.NONE, ignore_junction_targets=False, remote=None): use_config = True if remote: @@ -509,7 +509,7 @@ class Stream: # target (str): Target to checkout # location (str): Location to checkout the artifact to # force (bool): Whether files can be overwritten if necessary - # selection (PipelineSelection): The selection mode for the specified targets + # selection (_PipelineSelection): The selection mode for the specified targets # integrate (bool): Whether to run integration commands # hardlinks (bool): Whether checking out files hardlinked to # their artifacts is acceptable @@ -527,7 +527,7 @@ class Stream: *, location=None, force=False, - selection=PipelineSelection.RUN, + selection=_PipelineSelection.RUN, integrate=True, hardlinks=False, compression="", @@ -554,7 +554,12 @@ class Stream: self._run() try: - scope = {"run": Scope.RUN, "build": Scope.BUILD, "none": Scope.NONE, "all": Scope.ALL} + scope = { + _PipelineSelection.RUN: Scope.RUN, + _PipelineSelection.BUILD: Scope.BUILD, + _PipelineSelection.NONE: Scope.NONE, + _PipelineSelection.ALL: Scope.ALL, + } with target._prepare_sandbox(scope=scope[selection], directory=None, integrate=integrate) as sandbox: # Copy or move the sandbox to the target directory virdir = sandbox.get_virtual_directory() @@ -612,7 +617,7 @@ class Stream: # Args: # targets (str): Targets to show the cached state of # - def artifact_show(self, targets, *, selection=PipelineSelection.NONE): + def artifact_show(self, targets, *, selection=_PipelineSelection.NONE): # Obtain list of Element and/or ArtifactElement objects target_objects = self.load_selection(targets, selection=selection, use_artifact_config=True, load_refs=True) @@ -639,7 +644,7 @@ class Stream: # def artifact_log(self, targets): # Return list of Element and/or ArtifactElement objects - target_objects = self.load_selection(targets, selection=PipelineSelection.NONE, load_refs=True) + target_objects = self.load_selection(targets, selection=_PipelineSelection.NONE, load_refs=True) artifact_logs = {} for obj in target_objects: @@ -667,7 +672,7 @@ class Stream: # def artifact_list_contents(self, targets): # Return list of Element and/or ArtifactElement objects - target_objects = self.load_selection(targets, selection=PipelineSelection.NONE, load_refs=True) + target_objects = self.load_selection(targets, selection=_PipelineSelection.NONE, load_refs=True) elements_to_files = {} for obj in target_objects: @@ -689,7 +694,7 @@ class Stream: # Args: # targets (str): Targets to remove # - def artifact_delete(self, targets, *, selection=PipelineSelection.NONE): + def artifact_delete(self, targets, *, selection=_PipelineSelection.NONE): # Return list of Element and/or ArtifactElement objects target_objects = self.load_selection(targets, selection=selection, load_refs=True) @@ -773,7 +778,7 @@ class Stream: def workspace_open(self, targets, *, no_checkout, force, custom_dir): # This function is a little funny but it is trying to be as atomic as possible. - elements = self._load(targets, selection=PipelineSelection.REDIRECT) + elements = self._load(targets, selection=_PipelineSelection.REDIRECT) workspaces = self._context.get_workspaces() @@ -910,7 +915,7 @@ class Stream: # def workspace_reset(self, targets, *, soft): - elements = self._load(targets, selection=PipelineSelection.REDIRECT) + elements = self._load(targets, selection=_PipelineSelection.REDIRECT) nonexisting = [] for element in elements: @@ -1013,7 +1018,7 @@ class Stream: else: output_elements.add(e) if load_elements: - loaded_elements = self._load(load_elements, selection=PipelineSelection.REDIRECT) + loaded_elements = self._load(load_elements, selection=_PipelineSelection.REDIRECT) for e in loaded_elements: output_elements.add(e.name) @@ -1183,16 +1188,16 @@ class Stream: # # Args: # targets (list of str): Targets to load - # selection (PipelineSelection): The selection mode for the specified targets + # selection (_PipelineSelection): The selection mode for the specified targets # except_targets (list of str): Specified targets to except # cross_junctions (bool): Whether tracking should cross junction boundaries # # Returns: # (list of Element): The tracking element selection # - def _load_tracking(self, targets, *, selection=PipelineSelection.NONE, except_targets=(), cross_junctions=False): + def _load_tracking(self, targets, *, selection=_PipelineSelection.NONE, except_targets=(), cross_junctions=False): # We never want to use a PLAN selection when tracking elements - assert selection != PipelineSelection.PLAN + assert selection != _PipelineSelection.PLAN elements, except_elements, artifacts = self.__load_elements_from_targets( targets, except_targets, rewritable=True @@ -1234,7 +1239,7 @@ class Stream: # # Args: # targets (list of str): Main targets to load - # selection (PipelineSelection): The selection mode for the specified targets + # selection (_PipelineSelection): The selection mode for the specified targets # except_targets (list of str): Specified targets to except from fetching # ignore_junction_targets (bool): Whether junction targets should be filtered out # use_artifact_config (bool): Whether to initialize artifacts with the config @@ -1249,7 +1254,7 @@ class Stream: self, targets, *, - selection=PipelineSelection.NONE, + selection=_PipelineSelection.NONE, except_targets=(), ignore_junction_targets=False, use_artifact_config=False, @@ -1267,8 +1272,8 @@ class Stream: if not load_refs: detail = "\n".join(artifact.get_artifact_name() for artifact in artifacts) raise ArtifactElementError("Cannot perform this operation with artifact refs:", detail=detail) - if selection in (PipelineSelection.ALL, PipelineSelection.RUN): - raise StreamError("Error: '--deps {}' is not supported for artifact refs".format(selection)) + if selection in (_PipelineSelection.ALL, _PipelineSelection.RUN): + raise StreamError("Error: '--deps {}' is not supported for artifact refs".format(selection.value)) if ignore_junction_targets: elements = [e for e in elements if e.get_kind() != "junction"] @@ -1285,7 +1290,7 @@ class Stream: selected = self._pipeline.get_selection(self.targets, selection, silent=False) selected = self._pipeline.except_elements(self.targets, selected, except_elements) - if selection == PipelineSelection.PLAN and dynamic_plan: + if selection == _PipelineSelection.PLAN and dynamic_plan: # We use a dynamic build plan, only request artifacts of top-level targets, # others are requested dynamically as needed. # This avoids pulling, fetching, or building unneeded build-only dependencies. diff --git a/src/buildstream/types.py b/src/buildstream/types.py index 180044dbd..0e596bddb 100644 --- a/src/buildstream/types.py +++ b/src/buildstream/types.py @@ -230,6 +230,36 @@ class _CacheBuildTrees(FastEnum): NEVER = "never" +# _PipelineSelection() +# +# Defines the kind of pipeline selection to make when the pipeline +# is provided a list of targets, for whichever purpose. +# +# These values correspond to the CLI `--deps` arguments for convenience. +# +class _PipelineSelection(FastEnum): + + # Select only the target elements in the associated targets + NONE = "none" + + # As NONE, but redirect elements that are capable of it + REDIRECT = "redirect" + + # Select elements which must be built for the associated targets to be built + PLAN = "plan" + + # All dependencies of all targets, including the targets + ALL = "all" + + # All direct build dependencies and their recursive runtime dependencies, + # excluding the targets + BUILD = "build" + + # All direct runtime dependencies and their recursive runtime dependencies, + # including the targets + RUN = "run" + + ######################################## # Type aliases # ######################################## |