From 733aab53ce07c0b36a460eb55b5eb629197b4faa Mon Sep 17 00:00:00 2001 From: Phil Dawson Date: Thu, 6 Dec 2018 14:36:45 +0000 Subject: Add --force / -f option to source-checkout command --- buildstream/_frontend/cli.py | 5 ++++- buildstream/_stream.py | 12 +++++++----- tests/frontend/source_checkout.py | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/buildstream/_frontend/cli.py b/buildstream/_frontend/cli.py index ae640753d..048cce735 100644 --- a/buildstream/_frontend/cli.py +++ b/buildstream/_frontend/cli.py @@ -725,6 +725,8 @@ def checkout(app, element, location, force, deps, integrate, hardlinks, tar): # Source Checkout Command # ################################################################## @cli.command(name='source-checkout', short_help='Checkout sources for an element') +@click.option('--force', '-f', default=False, is_flag=True, + help="Allow files to be overwritten") @click.option('--except', 'except_', multiple=True, type=click.Path(readable=False), help="Except certain dependencies") @@ -740,7 +742,7 @@ def checkout(app, element, location, force, deps, integrate, hardlinks, tar): type=click.Path(readable=False)) @click.argument('location', type=click.Path(), required=False) @click.pass_obj -def source_checkout(app, element, location, deps, fetch_, except_, tar): +def source_checkout(app, element, location, force, deps, fetch_, except_, tar): """Checkout sources of an element to the specified location """ if not element and not location: @@ -760,6 +762,7 @@ def source_checkout(app, element, location, deps, fetch_, except_, tar): app.stream.source_checkout(element, location=location, + force=force, deps=deps, fetch=fetch_, except_targets=except_, diff --git a/buildstream/_stream.py b/buildstream/_stream.py index ce0780abb..03e189714 100644 --- a/buildstream/_stream.py +++ b/buildstream/_stream.py @@ -449,12 +449,13 @@ class Stream(): # def source_checkout(self, target, *, location=None, + force=False, deps='none', fetch=False, except_targets=(), tar=False): - self._check_location_writable(location, tar=tar) + self._check_location_writable(location, force=force, tar=tar) elements, _ = self._load((target,), (), selection=deps, @@ -468,7 +469,7 @@ class Stream(): # Stage all sources determined by scope try: - self._source_checkout(elements, location, deps, fetch, tar) + self._source_checkout(elements, location, force, deps, fetch, tar) except BstError as e: raise StreamError("Error while writing sources" ": '{}'".format(e), detail=e.detail, reason=e.reason) from e @@ -1193,6 +1194,7 @@ class Stream(): # Helper function for source_checkout() def _source_checkout(self, elements, location=None, + force=False, deps='none', fetch=False, tar=False): @@ -1208,7 +1210,7 @@ class Stream(): if tar: self._create_tarball(temp_source_dir.name, location) else: - self._move_directory(temp_source_dir.name, location) + self._move_directory(temp_source_dir.name, location, force) except OSError as e: raise StreamError("Failed to checkout sources to {}: {}" .format(location, e)) from e @@ -1218,7 +1220,7 @@ class Stream(): # Move a directory src to dest. This will work across devices and # may optionaly overwrite existing files. - def _move_directory(self, src, dest): + def _move_directory(self, src, dest, force=False): def is_empty_dir(path): return os.path.isdir(dest) and not os.listdir(dest) @@ -1228,7 +1230,7 @@ class Stream(): except OSError: pass - if is_empty_dir(dest): + if force or is_empty_dir(dest): try: utils.link_files(src, dest) except utils.UtilError as e: diff --git a/tests/frontend/source_checkout.py b/tests/frontend/source_checkout.py index 343448abc..0815d9b9c 100644 --- a/tests/frontend/source_checkout.py +++ b/tests/frontend/source_checkout.py @@ -1,6 +1,7 @@ import os import pytest import tarfile +from pathlib import Path from tests.testutils import cli @@ -56,6 +57,22 @@ def test_source_checkout(datafiles, cli, tmpdir_factory, with_workspace, guess_e assert os.path.exists(os.path.join(checkout, 'checkout-deps', 'etc', 'buildstream', 'config')) +@pytest.mark.datafiles(DATA_DIR) +@pytest.mark.parametrize('force_flag', ['--force', '-f']) +def test_source_checkout_force(datafiles, cli, force_flag): + project = os.path.join(datafiles.dirname, datafiles.basename) + checkout = os.path.join(cli.directory, 'source-checkout') + target = 'checkout-deps.bst' + + os.makedirs(os.path.join(checkout, 'some-thing')) + # Path(os.path.join(checkout, 'some-file')).touch() + + result = cli.run(project=project, args=['source-checkout', force_flag, target, '--deps', 'none', checkout]) + result.assert_success() + + assert os.path.exists(os.path.join(checkout, 'checkout-deps', 'etc', 'buildstream', 'config')) + + @pytest.mark.datafiles(DATA_DIR) def test_source_checkout_tar(datafiles, cli): project = os.path.join(datafiles.dirname, datafiles.basename) -- cgit v1.2.1