From 9244b2bff86961c896c2f2325b7c7f30b461819c Mon Sep 17 00:00:00 2001 From: Carlos Camacho Date: Wed, 20 Sep 2023 20:18:37 +0200 Subject: [PATCH] Make sure paths are treated correctly when building collection files manifest (#81619) * Make sure paths are correct when building collection files manifest This commit makes sure the path of the files part of the collection build manifest are correct. This commit uses os.path.commonprefix instead of dealing with strings. Signed-off-by: Carlos Camacho Bugfix Pull Request Fixes: #81618 * Revert the change note type to `minor_changes` * Clarify the change note with user-oriented details --------- Signed-off-by: Carlos Camacho Co-authored-by: Sviatoslav Sydorenko --- .../fix-build-files-manifest-walk.yml | 4 ++++ lib/ansible/galaxy/collection/__init__.py | 9 +++++++- test/units/galaxy/test_collection.py | 23 +++++++++++++++---- 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/fix-build-files-manifest-walk.yml diff --git a/changelogs/fragments/fix-build-files-manifest-walk.yml b/changelogs/fragments/fix-build-files-manifest-walk.yml new file mode 100644 index 00000000000..3d1000698bf --- /dev/null +++ b/changelogs/fragments/fix-build-files-manifest-walk.yml @@ -0,0 +1,4 @@ +minor_changes: + - >- + ansible-galaxy - Started normalizing build directory with a trailing separator when building collections, internally. + (https://github.com/ansible/ansible/pull/81619). diff --git a/lib/ansible/galaxy/collection/__init__.py b/lib/ansible/galaxy/collection/__init__.py index 60c9c94ba24..9bb9e941a47 100644 --- a/lib/ansible/galaxy/collection/__init__.py +++ b/lib/ansible/galaxy/collection/__init__.py @@ -1203,10 +1203,17 @@ def _build_files_manifest_walk(b_collection_path, namespace, name, ignore_patter manifest = _make_manifest() + def _discover_relative_base_directory(b_path: bytes, b_top_level_dir: bytes) -> bytes: + if b_path == b_top_level_dir: + return b'' + common_prefix = os.path.commonpath((b_top_level_dir, b_path)) + b_rel_base_dir = os.path.relpath(b_path, common_prefix) + return b_rel_base_dir.lstrip(os.path.sep.encode()) + def _walk(b_path, b_top_level_dir): + b_rel_base_dir = _discover_relative_base_directory(b_path, b_top_level_dir) for b_item in os.listdir(b_path): b_abs_path = os.path.join(b_path, b_item) - b_rel_base_dir = b'' if b_path == b_top_level_dir else b_path[len(b_top_level_dir) + 1:] b_rel_path = os.path.join(b_rel_base_dir, b_item) rel_path = to_text(b_rel_path, errors='surrogate_or_strict') diff --git a/test/units/galaxy/test_collection.py b/test/units/galaxy/test_collection.py index 991184aec1e..e8230d21073 100644 --- a/test/units/galaxy/test_collection.py +++ b/test/units/galaxy/test_collection.py @@ -39,10 +39,17 @@ def reset_cli_args(): co.GlobalCLIArgs._Singleton__instance = None -@pytest.fixture() -def collection_input(tmp_path_factory): - ''' Creates a collection skeleton directory for build tests ''' - test_dir = to_text(tmp_path_factory.mktemp('test-ÅÑŚÌβŁÈ Collections Input')) +@pytest.fixture +def collection_path_suffix(request): + """Return test collection path suffix or the default.""" + return getattr(request, 'param', 'test-ÅÑŚÌβŁÈ Collections Input') + + +@pytest.fixture +def collection_input(tmp_path_factory, collection_path_suffix): + """Create a collection skeleton directory for build tests.""" + test_dir = to_text(tmp_path_factory.mktemp(collection_path_suffix)) + namespace = 'ansible_namespace' collection = 'collection' skeleton = os.path.join(os.path.dirname(os.path.split(__file__)[0]), 'cli', 'test_data', 'collection_skeleton') @@ -467,6 +474,14 @@ def test_build_existing_output_without_force(collection_input): collection.build_collection(to_text(input_dir, errors='surrogate_or_strict'), to_text(output_dir, errors='surrogate_or_strict'), False) +@pytest.mark.parametrize( + 'collection_path_suffix', + ( + 'test-ÅÑŚÌβŁÈ Collections Input 1 with_slash/', + 'test-ÅÑŚÌβŁÈ Collections Input 2 no slash', + ), + indirect=('collection_path_suffix', ), +) def test_build_existing_output_with_force(collection_input): input_dir, output_dir = collection_input