Ignore collection build release files in the root collection directory (#59121)

This commit is contained in:
Jordan Borean 2019-07-23 07:52:30 +10:00 committed by GitHub
parent 199c97728f
commit aa0de421d2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 9 deletions

View file

@ -358,7 +358,7 @@ def build_collection(collection_path, output_path, force):
raise AnsibleError("The collection galaxy.yml path '%s' does not exist." % to_native(b_galaxy_path))
collection_meta = _get_galaxy_yml(b_galaxy_path)
file_manifest = _build_files_manifest(b_collection_path)
file_manifest = _build_files_manifest(b_collection_path, collection_meta['namespace'], collection_meta['name'])
collection_manifest = _build_manifest(**collection_meta)
collection_output = os.path.join(output_path, "%s-%s-%s.tar.gz" % (collection_meta['namespace'],
@ -587,9 +587,12 @@ def _get_galaxy_yml(b_galaxy_yml_path):
return galaxy_yml
def _build_files_manifest(b_collection_path):
b_ignore_files = frozenset([b'*.pyc', b'*.retry'])
b_ignore_dirs = frozenset([b'CVS', b'.bzr', b'.hg', b'.git', b'.svn', b'__pycache__', b'.tox'])
def _build_files_manifest(b_collection_path, namespace, name):
# Contains tuple of (b_filename, only root) where 'only root' means to only ignore the file in the root dir
b_ignore_files = frozenset([(b'*.pyc', False), (b'*.retry', False),
(to_bytes('{0}-{1}-*.tar.gz'.format(namespace, name)), True)])
b_ignore_dirs = frozenset([(b'CVS', False), (b'.bzr', False), (b'.hg', False), (b'.git', False), (b'.svn', False),
(b'__pycache__', False), (b'.tox', False)])
entry_template = {
'name': None,
@ -612,13 +615,16 @@ def _build_files_manifest(b_collection_path):
}
def _walk(b_path, b_top_level_dir):
is_root = 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:]
rel_path = to_text(os.path.join(b_rel_base_dir, b_item), errors='surrogate_or_strict')
if os.path.isdir(b_abs_path):
if b_item in b_ignore_dirs:
if any(b_item == b_path for b_path, root_only in b_ignore_dirs
if not root_only or root_only == is_root):
display.vvv("Skipping '%s' for collection build" % to_text(b_abs_path))
continue
@ -640,7 +646,8 @@ def _build_files_manifest(b_collection_path):
else:
if b_item == b'galaxy.yml':
continue
elif any(fnmatch.fnmatch(b_item, b_pattern) for b_pattern in b_ignore_files):
elif any(fnmatch.fnmatch(b_item, b_pattern) for b_pattern, root_only in b_ignore_files
if not root_only or root_only == is_root):
display.vvv("Skipping '%s' for collection build" % to_text(b_abs_path))
continue

View file

@ -263,7 +263,7 @@ def test_build_ignore_files_and_folders(collection_input, monkeypatch):
ignore_file.write('random')
ignore_file.flush()
actual = collection._build_files_manifest(to_bytes(input_dir))
actual = collection._build_files_manifest(to_bytes(input_dir), 'namespace', 'collection')
assert actual['format'] == 1
for manifest_entry in actual['files']:
@ -278,6 +278,38 @@ def test_build_ignore_files_and_folders(collection_input, monkeypatch):
assert mock_display.mock_calls[1][1][0] in expected_msgs
def test_build_ignore_older_release_in_root(collection_input, monkeypatch):
input_dir = collection_input[0]
mock_display = MagicMock()
monkeypatch.setattr(Display, 'vvv', mock_display)
# This is expected to be ignored because it is in the root collection dir.
release_file = os.path.join(input_dir, 'namespace-collection-0.0.0.tar.gz')
# This is not expected to be ignored because it is not in the root collection dir.
fake_release_file = os.path.join(input_dir, 'plugins', 'namespace-collection-0.0.0.tar.gz')
for filename in [release_file, fake_release_file]:
with open(filename, 'w+') as file_obj:
file_obj.write('random')
file_obj.flush()
actual = collection._build_files_manifest(to_bytes(input_dir), 'namespace', 'collection')
assert actual['format'] == 1
plugin_release_found = False
for manifest_entry in actual['files']:
assert manifest_entry['name'] != 'namespace-collection-0.0.0.tar.gz'
if manifest_entry['name'] == 'plugins/namespace-collection-0.0.0.tar.gz':
plugin_release_found = True
assert plugin_release_found
assert mock_display.call_count == 1
assert mock_display.mock_calls[0][1][0] == "Skipping '%s' for collection build" % to_text(release_file)
def test_build_ignore_symlink_target_outside_collection(collection_input, monkeypatch):
input_dir, outside_dir = collection_input
@ -287,7 +319,7 @@ def test_build_ignore_symlink_target_outside_collection(collection_input, monkey
link_path = os.path.join(input_dir, 'plugins', 'connection')
os.symlink(outside_dir, link_path)
actual = collection._build_files_manifest(to_bytes(input_dir))
actual = collection._build_files_manifest(to_bytes(input_dir), 'namespace', 'collection')
for manifest_entry in actual['files']:
assert manifest_entry['name'] != 'plugins/connection'
@ -311,7 +343,7 @@ def test_build_copy_symlink_target_inside_collection(collection_input):
os.symlink(roles_target, roles_link)
actual = collection._build_files_manifest(to_bytes(input_dir))
actual = collection._build_files_manifest(to_bytes(input_dir), 'namespace', 'collection')
linked_entries = [e for e in actual['files'] if e['name'].startswith('playbooks/roles/linked')]
assert len(linked_entries) == 3