summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxwell G <gotmax@e.email>2022-11-29 09:12:47 -0600
committerGitHub <noreply@github.com>2022-11-29 16:12:47 +0100
commitab76916b14784f92fbd7aee6e8d6fc5ee84b0e75 (patch)
tree0df5ac62245d1d5d1246abaf1881085e52b27535
parent5f3a6b78db093f8d1b062bbd70ac6bf375fdca04 (diff)
downloadansible-ab76916b14784f92fbd7aee6e8d6fc5ee84b0e75.tar.gz
galaxy: Add license_file to manifest directives (#79420)
* galaxy: Add license_file to manifest directives * ag collection build: Test license handling This adds tests to ensure that - REUSE licensing files: .reuse/dep5, LICENSES/*, anyfile.license - galaxy.yml license_file are always included in the manifest.
-rw-r--r--changelogs/fragments/79420-galaxy-manifest-license.yaml4
-rw-r--r--lib/ansible/galaxy/collection/__init__.py17
-rw-r--r--test/integration/targets/ansible-galaxy-collection-cli/files/expected.txt6
-rw-r--r--test/integration/targets/ansible-galaxy-collection-cli/files/galaxy.yml1
-rw-r--r--test/integration/targets/ansible-galaxy-collection-cli/files/make_collection_dir.py4
-rw-r--r--test/units/galaxy/test_collection.py10
6 files changed, 32 insertions, 10 deletions
diff --git a/changelogs/fragments/79420-galaxy-manifest-license.yaml b/changelogs/fragments/79420-galaxy-manifest-license.yaml
new file mode 100644
index 0000000000..3c95cda425
--- /dev/null
+++ b/changelogs/fragments/79420-galaxy-manifest-license.yaml
@@ -0,0 +1,4 @@
+---
+minor_changes:
+ - galaxy - include ``license_file`` in the default manifest directives
+ (https://github.com/ansible/ansible/pull-request/79420)
diff --git a/lib/ansible/galaxy/collection/__init__.py b/lib/ansible/galaxy/collection/__init__.py
index 1a0720c0b9..ffeba77dea 100644
--- a/lib/ansible/galaxy/collection/__init__.py
+++ b/lib/ansible/galaxy/collection/__init__.py
@@ -479,6 +479,7 @@ def build_collection(u_collection_path, u_output_path, force):
collection_meta['name'], # type: ignore[arg-type]
collection_meta['build_ignore'], # type: ignore[arg-type]
collection_meta['manifest'], # type: ignore[arg-type]
+ collection_meta['license_file'], # type: ignore[arg-type]
)
artifact_tarball_file_name = '{ns!s}-{name!s}-{ver!s}.tar.gz'.format(
@@ -1062,8 +1063,9 @@ def _make_entry(name, ftype, chksum_type='sha256', chksum=None):
}
-def _build_files_manifest(b_collection_path, namespace, name, ignore_patterns, manifest_control):
- # type: (bytes, str, str, list[str], dict[str, t.Any]) -> FilesManifestType
+def _build_files_manifest(b_collection_path, namespace, name, ignore_patterns,
+ manifest_control, license_file):
+ # type: (bytes, str, str, list[str], dict[str, t.Any], t.Optional[str]) -> FilesManifestType
if ignore_patterns and manifest_control is not Sentinel:
raise AnsibleError('"build_ignore" and "manifest" are mutually exclusive')
@@ -1073,14 +1075,15 @@ def _build_files_manifest(b_collection_path, namespace, name, ignore_patterns, m
namespace,
name,
manifest_control,
+ license_file,
)
return _build_files_manifest_walk(b_collection_path, namespace, name, ignore_patterns)
-def _build_files_manifest_distlib(b_collection_path, namespace, name, manifest_control):
- # type: (bytes, str, str, dict[str, t.Any]) -> FilesManifestType
-
+def _build_files_manifest_distlib(b_collection_path, namespace, name, manifest_control,
+ license_file):
+ # type: (bytes, str, str, dict[str, t.Any], t.Optional[str]) -> FilesManifestType
if not HAS_DISTLIB:
raise AnsibleError('Use of "manifest" requires the python "distlib" library')
@@ -1124,6 +1127,9 @@ def _build_files_manifest_distlib(b_collection_path, namespace, name, manifest_c
'recursive-include plugins */**.py */**.license',
])
+ if license_file:
+ directives.append(f'include {license_file}')
+
plugins = set(l.package.split('.')[-1] for d, l in get_all_plugin_loaders())
for plugin in sorted(plugins):
if plugin in ('modules', 'module_utils'):
@@ -1585,6 +1591,7 @@ def install_src(collection, b_collection_path, b_collection_output_path, artifac
collection_meta['namespace'], collection_meta['name'],
collection_meta['build_ignore'],
collection_meta['manifest'],
+ collection_meta['license_file'],
)
collection_output_path = _build_collection_dir(
diff --git a/test/integration/targets/ansible-galaxy-collection-cli/files/expected.txt b/test/integration/targets/ansible-galaxy-collection-cli/files/expected.txt
index 110009e385..6921829050 100644
--- a/test/integration/targets/ansible-galaxy-collection-cli/files/expected.txt
+++ b/test/integration/targets/ansible-galaxy-collection-cli/files/expected.txt
@@ -1,6 +1,11 @@
MANIFEST.json
FILES.json
README.rst
+GPL
+LICENSES/
+LICENSES/MIT.txt
+.reuse/
+.reuse/dep5
changelogs/
docs/
playbooks/
@@ -88,6 +93,7 @@ plugins/test/bar.yml
plugins/test/baz.yaml
plugins/test/test.py
plugins/vars/bar.yml
+plugins/vars/bar.yml.license
plugins/vars/baz.yaml
plugins/vars/test.py
roles/foo/
diff --git a/test/integration/targets/ansible-galaxy-collection-cli/files/galaxy.yml b/test/integration/targets/ansible-galaxy-collection-cli/files/galaxy.yml
index 8f0ada0b82..140bf2a73a 100644
--- a/test/integration/targets/ansible-galaxy-collection-cli/files/galaxy.yml
+++ b/test/integration/targets/ansible-galaxy-collection-cli/files/galaxy.yml
@@ -2,6 +2,7 @@ namespace: ns
name: col
version: 1.0.0
readme: README.rst
+license_file: GPL
authors:
- Ansible
manifest:
diff --git a/test/integration/targets/ansible-galaxy-collection-cli/files/make_collection_dir.py b/test/integration/targets/ansible-galaxy-collection-cli/files/make_collection_dir.py
index 913a6f79e8..60c43cc70f 100644
--- a/test/integration/targets/ansible-galaxy-collection-cli/files/make_collection_dir.py
+++ b/test/integration/targets/ansible-galaxy-collection-cli/files/make_collection_dir.py
@@ -5,8 +5,12 @@ paths = [
'ns-col-1.0.0.tar.gz',
'foo.txt',
'README.rst',
+ 'GPL',
+ 'LICENSES/MIT.txt',
+ '.reuse/dep5',
'artifacts/.gitkeep',
'plugins/vars/bar.yml',
+ 'plugins/vars/bar.yml.license',
'plugins/vars/baz.yaml',
'plugins/vars/test.py',
'plugins/vars/docs.md',
diff --git a/test/units/galaxy/test_collection.py b/test/units/galaxy/test_collection.py
index 28a69b2814..fa319835fb 100644
--- a/test/units/galaxy/test_collection.py
+++ b/test/units/galaxy/test_collection.py
@@ -596,7 +596,7 @@ def test_build_ignore_files_and_folders(collection_input, monkeypatch):
tests_file.write('random')
tests_file.flush()
- actual = collection._build_files_manifest(to_bytes(input_dir), 'namespace', 'collection', [], Sentinel)
+ actual = collection._build_files_manifest(to_bytes(input_dir), 'namespace', 'collection', [], Sentinel, None)
assert actual['format'] == 1
for manifest_entry in actual['files']:
@@ -632,7 +632,7 @@ def test_build_ignore_older_release_in_root(collection_input, monkeypatch):
file_obj.write('random')
file_obj.flush()
- actual = collection._build_files_manifest(to_bytes(input_dir), 'namespace', 'collection', [], Sentinel)
+ actual = collection._build_files_manifest(to_bytes(input_dir), 'namespace', 'collection', [], Sentinel, None)
assert actual['format'] == 1
plugin_release_found = False
@@ -660,7 +660,7 @@ def test_build_ignore_patterns(collection_input, monkeypatch):
actual = collection._build_files_manifest(to_bytes(input_dir), 'namespace', 'collection',
['*.md', 'plugins/action', 'playbooks/*.j2'],
- Sentinel)
+ Sentinel, None)
assert actual['format'] == 1
expected_missing = [
@@ -711,7 +711,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), 'namespace', 'collection', [], Sentinel)
+ actual = collection._build_files_manifest(to_bytes(input_dir), 'namespace', 'collection', [], Sentinel, None)
for manifest_entry in actual['files']:
assert manifest_entry['name'] != 'plugins/connection'
@@ -735,7 +735,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), 'namespace', 'collection', [], Sentinel)
+ actual = collection._build_files_manifest(to_bytes(input_dir), 'namespace', 'collection', [], Sentinel, None)
linked_entries = [e for e in actual['files'] if e['name'].startswith('playbooks/roles/linked')]
assert len(linked_entries) == 1