From df9dbaedbdbdcca5c0c76eeac10338581d299de6 Mon Sep 17 00:00:00 2001 From: Valentin David Date: Thu, 4 Oct 2018 00:28:53 +0200 Subject: Make link_files and copy_files and behave independently to staging order If a dependency creates a symbolic link where another creates a directory for the same name, files from the latter should be placed following the symbolic link of the former. The issue was that this behaved that way only if dependencies creating symbolic links were staged before the ones creating directories. We now move directories so that we support the case when staging is done in the reversed order. Fixes #647. --- buildstream/utils.py | 13 +++++++++---- tests/integration/compose-symlinks.py | 8 +++++--- .../project/elements/compose-symlinks/a-overlay.bst | 5 +++++ .../project/elements/compose-symlinks/compose-reverse.bst | 11 +++++++++++ 4 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 tests/integration/project/elements/compose-symlinks/a-overlay.bst create mode 100644 tests/integration/project/elements/compose-symlinks/compose-reverse.bst diff --git a/buildstream/utils.py b/buildstream/utils.py index 5c11a363c..4d0c4c67e 100644 --- a/buildstream/utils.py +++ b/buildstream/utils.py @@ -821,12 +821,17 @@ def _process_list(srcdir, destdir, filelist, actionfunc, result, permissions.append((destpath, os.stat(srcpath).st_mode)) elif stat.S_ISLNK(mode): - if not safe_remove(destpath): - result.ignored.append(path) - continue - target = os.readlink(srcpath) target = _relative_symlink_target(destdir, destpath, target) + + if os.path.isdir(destpath): + shutil.move(destpath, + os.path.join(os.path.dirname(destpath), target)) + else: + if not safe_remove(destpath): + result.ignored.append(path) + continue + os.symlink(target, destpath) elif stat.S_ISREG(mode): diff --git a/tests/integration/compose-symlinks.py b/tests/integration/compose-symlinks.py index bf279fa6f..b437e26b1 100644 --- a/tests/integration/compose-symlinks.py +++ b/tests/integration/compose-symlinks.py @@ -22,7 +22,9 @@ DATA_DIR = os.path.join( # # Regression test for https://gitlab.com/BuildStream/buildstream/issues/270 @pytest.mark.datafiles(DATA_DIR) -def test_compose_symlinks(cli, tmpdir, datafiles): +@pytest.mark.parametrize("element", ["compose-symlinks/compose.bst", + "compose-symlinks/compose-reverse.bst"]) +def test_compose_symlinks(cli, tmpdir, datafiles, element): project = os.path.join(datafiles.dirname, datafiles.basename) checkout = os.path.join(cli.directory, 'checkout') element_path = os.path.join(project, 'elements') @@ -33,10 +35,10 @@ def test_compose_symlinks(cli, tmpdir, datafiles): symlink_file = os.path.join(project_files, 'sbin') os.symlink(os.path.join('usr', 'sbin'), symlink_file, target_is_directory=True) - result = cli.run(project=project, args=['build', 'compose-symlinks/compose.bst']) + result = cli.run(project=project, args=['build', element]) result.assert_success() - result = cli.run(project=project, args=['checkout', 'compose-symlinks/compose.bst', checkout]) + result = cli.run(project=project, args=['checkout', element, checkout]) result.assert_success() assert set(walk_dir(checkout)) == set(['/sbin', '/usr', '/usr/sbin', diff --git a/tests/integration/project/elements/compose-symlinks/a-overlay.bst b/tests/integration/project/elements/compose-symlinks/a-overlay.bst new file mode 100644 index 000000000..67e01caf6 --- /dev/null +++ b/tests/integration/project/elements/compose-symlinks/a-overlay.bst @@ -0,0 +1,5 @@ +kind: import + +sources: +- kind: local + path: files/compose-symlinks/overlay diff --git a/tests/integration/project/elements/compose-symlinks/compose-reverse.bst b/tests/integration/project/elements/compose-symlinks/compose-reverse.bst new file mode 100644 index 000000000..88c229cd7 --- /dev/null +++ b/tests/integration/project/elements/compose-symlinks/compose-reverse.bst @@ -0,0 +1,11 @@ +kind: compose + +depends: +- filename: compose-symlinks/a-overlay.bst + type: build +- filename: compose-symlinks/base.bst + type: build + +config: + include: + - runtime -- cgit v1.2.1