diff options
-rw-r--r-- | buildstream/_frontend/cli.py | 12 | ||||
-rw-r--r-- | buildstream/_stream.py | 6 | ||||
-rw-r--r-- | buildstream/element.py | 27 | ||||
-rw-r--r-- | buildstream/types.py | 6 | ||||
-rw-r--r-- | tests/frontend/buildcheckout.py | 24 |
5 files changed, 47 insertions, 28 deletions
diff --git a/buildstream/_frontend/cli.py b/buildstream/_frontend/cli.py index b845d00eb..ef0dadb13 100644 --- a/buildstream/_frontend/cli.py +++ b/buildstream/_frontend/cli.py @@ -640,7 +640,7 @@ def shell(app, element, sysroot, mount, isolate, build_, command): @click.option('--force', '-f', default=False, is_flag=True, help="Allow files to be overwritten") @click.option('--deps', '-d', default='run', - type=click.Choice(['run', 'none']), + type=click.Choice(['run', 'build', 'none']), help='The dependencies to checkout (default: run)') @click.option('--integrate/--no-integrate', default=True, is_flag=True, help="Whether to run integration commands") @@ -657,16 +657,24 @@ def shell(app, element, sysroot, mount, isolate, build_, command): def checkout(app, element, location, force, deps, integrate, hardlinks, tar): """Checkout a built artifact to the specified location """ + from ..element import Scope if hardlinks and tar: click.echo("ERROR: options --hardlinks and --tar conflict", err=True) sys.exit(-1) + if deps == "run": + scope = Scope.RUN + elif deps == "build": + scope = Scope.BUILD + elif deps == "none": + scope = Scope.NONE + with app.initialized(): app.stream.checkout(element, location=location, force=force, - deps=deps, + scope=scope, integrate=integrate, hardlinks=hardlinks, tar=tar) diff --git a/buildstream/_stream.py b/buildstream/_stream.py index 2f9799178..6a3d2c7fc 100644 --- a/buildstream/_stream.py +++ b/buildstream/_stream.py @@ -370,7 +370,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 - # deps (str): The dependencies to checkout + # scope (str): The scope of dependencies to checkout # integrate (bool): Whether to run integration commands # hardlinks (bool): Whether checking out files hardlinked to # their artifacts is acceptable @@ -383,7 +383,7 @@ class Stream(): def checkout(self, target, *, location=None, force=False, - deps='run', + scope=Scope.RUN, integrate=True, hardlinks=False, tar=False): @@ -396,7 +396,7 @@ class Stream(): # Stage deps into a temporary sandbox first try: - with target._prepare_sandbox(Scope.RUN, None, deps=deps, + with target._prepare_sandbox(scope=scope, directory=None, integrate=integrate) as sandbox: # Copy or move the sandbox to the target directory diff --git a/buildstream/element.py b/buildstream/element.py index d7072dc8c..2f724f49d 100644 --- a/buildstream/element.py +++ b/buildstream/element.py @@ -438,7 +438,7 @@ class Element(Plugin): visited=visited, recursed=True) # Yeild self only at the end, after anything needed has been traversed - if should_yield and (recurse or recursed) and (scope in (Scope.ALL, Scope.RUN)): + if should_yield and (recurse or recursed) and scope != Scope.BUILD: yield self def search(self, scope, name): @@ -1339,7 +1339,7 @@ class Element(Plugin): # is used to stage things by the `bst checkout` codepath # @contextmanager - def _prepare_sandbox(self, scope, directory, deps='run', integrate=True): + def _prepare_sandbox(self, scope, directory, shell=False, integrate=True): # bst shell and bst checkout require a local sandbox. bare_directory = True if directory else False with self.__sandbox(directory, config=self.__sandbox_config, allow_remote=False, @@ -1350,20 +1350,19 @@ class Element(Plugin): # Stage something if we need it if not directory: - if scope == Scope.BUILD: + if shell and scope == Scope.BUILD: self.stage(sandbox) - elif scope == Scope.RUN: + else: # Stage deps in the sandbox root - if deps == 'run': - with self.timed_activity("Staging dependencies", silent_nested=True): - self.stage_dependency_artifacts(sandbox, scope) + with self.timed_activity("Staging dependencies", silent_nested=True): + self.stage_dependency_artifacts(sandbox, scope) - # Run any integration commands provided by the dependencies - # once they are all staged and ready - if integrate: - with self.timed_activity("Integrating sandbox"): - for dep in self.dependencies(scope): - dep.integrate(sandbox) + # Run any integration commands provided by the dependencies + # once they are all staged and ready + if integrate: + with self.timed_activity("Integrating sandbox"): + for dep in self.dependencies(scope): + dep.integrate(sandbox) yield sandbox @@ -1858,7 +1857,7 @@ class Element(Plugin): # If directory is not specified, one will be staged using scope def _shell(self, scope=None, directory=None, *, mounts=None, isolate=False, prompt=None, command=None): - with self._prepare_sandbox(scope, directory) as sandbox: + with self._prepare_sandbox(scope, directory, shell=True) as sandbox: environment = self.get_environment() environment = copy.copy(environment) flags = SandboxFlags.INTERACTIVE | SandboxFlags.ROOT_READ_ONLY diff --git a/buildstream/types.py b/buildstream/types.py index 7bc7a1664..3eb4a9110 100644 --- a/buildstream/types.py +++ b/buildstream/types.py @@ -48,6 +48,12 @@ class Scope(Enum): itself. """ + NONE = 4 + """Just the element itself, no dependencies. + + *Since: 1.4* + """ + class Consistency(): """Defines the various consistency states of a :class:`.Source`. diff --git a/tests/frontend/buildcheckout.py b/tests/frontend/buildcheckout.py index 1299fa190..03bba0b26 100644 --- a/tests/frontend/buildcheckout.py +++ b/tests/frontend/buildcheckout.py @@ -86,13 +86,14 @@ def test_build_invalid_suffix_dep(datafiles, cli, strict, hardlinks): @pytest.mark.datafiles(DATA_DIR) -@pytest.mark.parametrize("deps", [("run"), ("none")]) +@pytest.mark.parametrize("deps", [("run"), ("none"), ("build")]) def test_build_checkout_deps(datafiles, cli, deps): project = os.path.join(datafiles.dirname, datafiles.basename) checkout = os.path.join(cli.directory, 'checkout') + element_name = "checkout-deps.bst" # First build it - result = cli.run(project=project, args=['build', 'target.bst']) + result = cli.run(project=project, args=['build', element_name]) result.assert_success() # Assert that after a successful build, the builddir is empty @@ -101,20 +102,25 @@ def test_build_checkout_deps(datafiles, cli, deps): assert not os.listdir(builddir) # Now check it out - result = cli.run(project=project, args=['checkout', 'target.bst', '--deps', deps, checkout]) + result = cli.run(project=project, args=['checkout', element_name, '--deps', deps, checkout]) result.assert_success() - # Check that the executable hello file is found in the checkout - filename = os.path.join(checkout, 'usr', 'bin', 'hello') + # Verify output of this element + filename = os.path.join(checkout, 'etc', 'buildstream', 'config') + if deps == "build": + assert not os.path.exists(filename) + else: + assert os.path.exists(filename) - if deps == "run": + # Verify output of this element's build dependencies + filename = os.path.join(checkout, 'usr', 'include', 'pony.h') + if deps == "build": assert os.path.exists(filename) else: assert not os.path.exists(filename) - # Check that the executable hello file is found in the checkout - filename = os.path.join(checkout, 'usr', 'include', 'pony.h') - + # Verify output of this element's runtime dependencies + filename = os.path.join(checkout, 'usr', 'bin', 'hello') if deps == "run": assert os.path.exists(filename) else: |