continuous-delivery-scripts 4.4.1__tar.gz → 4.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. {continuous_delivery_scripts-4.4.1/continuous_delivery_scripts.egg-info → continuous_delivery_scripts-4.4.2}/PKG-INFO +2 -2
  2. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/_version.py +3 -3
  3. continuous_delivery_scripts-4.4.2/continuous_delivery_scripts/check_licence_compliance.py +124 -0
  4. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/generate_news.py +1 -1
  5. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/plugins/golang.py +88 -25
  6. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/spdx_report/spdx_helpers.py +8 -0
  7. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2/continuous_delivery_scripts.egg-info}/PKG-INFO +2 -2
  8. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts.egg-info/SOURCES.txt +0 -2
  9. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts.egg-info/requires.txt +1 -1
  10. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/setup.py +1 -1
  11. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/GitPython.spdx +1 -1
  12. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/Jinja2.spdx +1 -1
  13. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/Mako.spdx +1 -1
  14. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/Markdown.spdx +1 -1
  15. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/MarkupSafe.spdx +1 -1
  16. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/PyYAML.spdx +1 -1
  17. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/Pygments.spdx +1 -1
  18. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/SecretStorage.spdx +1 -1
  19. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/boolean.py.spdx +1 -1
  20. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/boto3.spdx +4 -4
  21. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/botocore.spdx +4 -4
  22. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/bracex.spdx +1 -1
  23. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/certifi.spdx +1 -1
  24. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/cffi.spdx +1 -1
  25. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/charset-normalizer.spdx +1 -1
  26. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/click.spdx +1 -1
  27. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/continuous-delivery-scripts.spdx +74 -76
  28. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/cryptography.spdx +1 -1
  29. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/detect-secrets.spdx +1 -1
  30. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/docutils.spdx +1 -1
  31. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/gibberish-detector.spdx +1 -1
  32. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/gitdb.spdx +1 -1
  33. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/id.spdx +1 -1
  34. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/idna.spdx +1 -1
  35. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/jaraco.classes.spdx +1 -1
  36. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/jaraco.context.spdx +1 -1
  37. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/jaraco.functools.spdx +1 -1
  38. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/jeepney.spdx +1 -1
  39. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/jellyfish.spdx +1 -1
  40. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/jmespath.spdx +1 -1
  41. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/keyring.spdx +1 -1
  42. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/license-expression.spdx +1 -1
  43. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/licenseheaders.spdx +1 -1
  44. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/markdown-it-py.spdx +1 -1
  45. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/mdurl.spdx +1 -1
  46. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/more-itertools.spdx +1 -1
  47. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/nh3.spdx +1 -1
  48. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/packaging.spdx +1 -1
  49. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/pdoc3.spdx +1 -1
  50. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/ply.spdx +1 -1
  51. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/pyautoversion.spdx +1 -1
  52. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/pycparser.spdx +1 -1
  53. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/pyparsing.spdx +1 -1
  54. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/python-dateutil.spdx +1 -1
  55. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/python-dotenv.spdx +1 -1
  56. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/rdflib.spdx +1 -1
  57. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/readme_renderer.spdx +1 -1
  58. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/regex.spdx +1 -1
  59. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/requests-toolbelt.spdx +1 -1
  60. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/requests.spdx +1 -1
  61. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/rfc3986.spdx +1 -1
  62. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/rich.spdx +1 -1
  63. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/s3transfer.spdx +1 -1
  64. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/semver.spdx +1 -1
  65. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/setuptools.spdx +1 -1
  66. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/six.spdx +1 -1
  67. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/smmap.spdx +1 -1
  68. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/spdx-tools.spdx +1 -1
  69. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/toml.spdx +1 -1
  70. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/towncrier.spdx +5 -5
  71. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/twine.spdx +1 -1
  72. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/urllib3.spdx +1 -1
  73. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/wcmatch.spdx +1 -1
  74. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/spdx-tmp/xmltodict.spdx +1 -1
  75. continuous_delivery_scripts-4.4.1/continuous_delivery_scripts/check_licence_compliance.py +0 -68
  76. continuous_delivery_scripts-4.4.1/spdx-tmp/Incremental.spdx +0 -50
  77. continuous_delivery_scripts-4.4.1/spdx-tmp/click-default-group.spdx +0 -50
  78. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/LICENSE +0 -0
  79. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/MANIFEST.in +0 -0
  80. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/README.md +0 -0
  81. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/__init__.py +0 -0
  82. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/assert_news.py +0 -0
  83. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/create_news_file.py +0 -0
  84. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/detect_secrets.py +0 -0
  85. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/generate_docs.py +0 -0
  86. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/get_config.py +0 -0
  87. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/get_version.py +0 -0
  88. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/language_specifics.py +0 -0
  89. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/license_files.py +0 -0
  90. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/plugins/BASIC.MD +0 -0
  91. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/plugins/CI.MD +0 -0
  92. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/plugins/GITHUB_ACTIONS.MD +0 -0
  93. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/plugins/GOLAND.MD +0 -0
  94. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/plugins/NOOP.MD +0 -0
  95. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/plugins/PYTHON.MD +0 -0
  96. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/plugins/__init__.py +0 -0
  97. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/plugins/basic.py +0 -0
  98. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/plugins/ci.py +0 -0
  99. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/plugins/docker.py +0 -0
  100. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/plugins/github_actions.py +0 -0
  101. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/plugins/noop.py +0 -0
  102. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/plugins/python.py +0 -0
  103. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/report_third_party_ip.py +0 -0
  104. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/spdx_report/__init__.py +0 -0
  105. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/spdx_report/data/licence_assessment.toml +0 -0
  106. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/spdx_report/licence_assessment.py +0 -0
  107. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/spdx_report/scancode_licence_db.py +0 -0
  108. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/spdx_report/spdx_dependency.py +0 -0
  109. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/spdx_report/spdx_document.py +0 -0
  110. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/spdx_report/spdx_file.py +0 -0
  111. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/spdx_report/spdx_package.py +0 -0
  112. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/spdx_report/spdx_project.py +0 -0
  113. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/spdx_report/spdx_summary.py +0 -0
  114. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/spdx_report/templates/third_party_IP_report.csv.jinja2 +0 -0
  115. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/spdx_report/templates/third_party_IP_report.html.jinja2 +0 -0
  116. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/spdx_report/templates/third_party_IP_report.txt.jinja2 +0 -0
  117. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/tag_and_release.py +0 -0
  118. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/update_secrets_registry.py +0 -0
  119. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/__init__.py +0 -0
  120. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/aws_helpers.py +0 -0
  121. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/configuration.py +0 -0
  122. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/definitions.py +0 -0
  123. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/filesystem_helpers.py +0 -0
  124. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/git_helpers.py +0 -0
  125. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/hash_helpers.py +0 -0
  126. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/language_specifics_base.py +0 -0
  127. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/logging.py +0 -0
  128. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/news_file.py +0 -0
  129. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/noop/__init__.py +0 -0
  130. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/noop/package_helpers.py +0 -0
  131. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/package_helpers.py +0 -0
  132. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/python/__init__.py +0 -0
  133. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/python/package_helpers.py +0 -0
  134. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/python/python_helpers.py +0 -0
  135. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/string_helpers.py +0 -0
  136. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/third_party_licences.py +0 -0
  137. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts/utils/versioning.py +0 -0
  138. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts.egg-info/dependency_links.txt +0 -0
  139. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts.egg-info/entry_points.txt +0 -0
  140. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/continuous_delivery_scripts.egg-info/top_level.txt +0 -0
  141. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/pyproject.toml +0 -0
  142. {continuous_delivery_scripts-4.4.1 → continuous_delivery_scripts-4.4.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: continuous-delivery-scripts
3
- Version: 4.4.1
3
+ Version: 4.4.2
4
4
  Summary: Git-based CI/CD tools for releases, changelogs, SPDX SBOMs and licence reporting
5
5
  Home-page: https://github.com/ARMmbed/continuous-delivery-scripts
6
6
  Author: Arm
@@ -27,7 +27,7 @@ Description-Content-Type: text/markdown
27
27
  License-File: LICENSE
28
28
  Requires-Dist: setuptools
29
29
  Requires-Dist: gitpython
30
- Requires-Dist: towncrier==22.12.0
30
+ Requires-Dist: towncrier==26.9.0
31
31
  Requires-Dist: pyautoversion~=1.2.0
32
32
  Requires-Dist: pdoc3==0.11.6
33
33
  Requires-Dist: toml
@@ -11,8 +11,8 @@ References
11
11
  This file is autogenerated, do not modify by hand.
12
12
  """
13
13
 
14
- __version__ = "4.4.1"
15
- COMMIT = "f1eb92251a8a3eaa65ca4bc27ca12e46a5e6a5d3"
14
+ __version__ = "4.4.2"
15
+ COMMIT = "2c6e20cf305e75f9cce5b43a3b64f76416e14db7"
16
16
  MAJOR = 4
17
17
  MINOR = 4
18
- PATCH = 1
18
+ PATCH = 2
@@ -0,0 +1,124 @@
1
+ #
2
+ # Copyright (C) 2020-2026 Arm Limited or its affiliates and Contributors. All rights reserved.
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ #
5
+ """Check project and dependency licences without generating SPDX documents."""
6
+
7
+ import argparse
8
+ import logging
9
+ import sys
10
+ from pathlib import Path
11
+ from typing import TYPE_CHECKING
12
+
13
+ from continuous_delivery_scripts.language_specifics import get_language_specifics
14
+ from continuous_delivery_scripts.spdx_report.licence_assessment import LicenceAssessment
15
+ from continuous_delivery_scripts.spdx_report.spdx_summary import _configured_licence_policy
16
+ from continuous_delivery_scripts.utils.configuration import configuration, ConfigurationVariable
17
+ from continuous_delivery_scripts.utils.logging import log_exception, set_log_level
18
+
19
+ if TYPE_CHECKING:
20
+ from continuous_delivery_scripts.spdx_report.spdx_project import SpdxProject
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+
25
+ def _log_assessment_details(project: "SpdxProject") -> None:
26
+ """Log per-dependency assessment details for statuses that need attention."""
27
+ if not logger.isEnabledFor(logging.WARNING):
28
+ return
29
+ attention = [
30
+ (name, result)
31
+ for name, result in sorted(project.licence_assessments.items())
32
+ if result.status in (LicenceAssessment.REVIEW, LicenceAssessment.UNKNOWN, LicenceAssessment.DENY)
33
+ ]
34
+ if not attention:
35
+ return
36
+ logger.warning("Dependencies needing attention:")
37
+ for name, result in attention:
38
+ discovered = result.discovered_licence or result.dependency_licence
39
+ details = [
40
+ f"status={result.status.value}",
41
+ f"discovered_licence={discovered}",
42
+ f"assessed_licence={result.dependency_licence}",
43
+ f"rule={result.rule}",
44
+ f"reason={result.reason}",
45
+ ]
46
+ if result.selected_licence:
47
+ details.append(f"selected_licence={result.selected_licence}")
48
+ logger.warning("- %s: %s", name, "; ".join(details))
49
+
50
+
51
+ def _print_policy_summary(project: "SpdxProject") -> None:
52
+ """Print a human-readable summary of the configured licence policy and outcome."""
53
+ counts = {
54
+ status.value: sum(result.status is status for result in project.licence_assessments.values())
55
+ for status in LicenceAssessment
56
+ }
57
+ accepted = _configured_licence_policy()
58
+ fail_on = sorted(status.value for status in project.licence_assessor.policy.fail_on)
59
+ fail_on_incomplete = bool(configuration.get_value(ConfigurationVariable.FAIL_ON_INCOMPLETE_LICENCE_AUDIT))
60
+ dependency_count = len(project.dependency_documents)
61
+ policy_result = "PASS"
62
+ policy_error = None
63
+ try:
64
+ project.check_licence_compliance()
65
+ except Exception as error:
66
+ policy_result = "FAIL"
67
+ policy_error = error
68
+
69
+ print(f"Dependencies screened: {dependency_count}")
70
+ print("Accepted third-party licences: " + (", ".join(accepted) if accepted else "<none configured>"))
71
+ print("Assessment fail-on statuses: " + (", ".join(fail_on) if fail_on else "<disabled>"))
72
+ print(f"Fail on incomplete licence audit: {'enabled' if fail_on_incomplete else 'disabled'}")
73
+ print("Dependency licence assessment: " + ", ".join(f"{name}: {count}" for name, count in counts.items()))
74
+ print(f"Compliance with configured licence policy: {policy_result}")
75
+ if policy_error:
76
+ raise policy_error
77
+
78
+
79
+ def main() -> int:
80
+ """Check licence compliance and optionally write third-party IP summaries."""
81
+ parser = argparse.ArgumentParser(description="Check project and dependency licence compliance.")
82
+ parser.add_argument(
83
+ "-o",
84
+ "--output-dir",
85
+ type=Path,
86
+ help="Write third-party IP summaries to this existing directory (no SPDX documents).",
87
+ )
88
+ parser.add_argument(
89
+ "--lookup-scancode",
90
+ action="store_true",
91
+ help="Consult ScanCode LicenseDB for unclassified licences or missing assessment rules.",
92
+ )
93
+ parser.add_argument("-v", "--verbose", action="count", default=0, help="Increase logging verbosity.")
94
+ args = parser.parse_args()
95
+ set_log_level(args.verbose)
96
+
97
+ try:
98
+ plugin = get_language_specifics()
99
+ if not plugin.can_get_project_metadata():
100
+ raise ValueError("The selected language plugin cannot provide metadata for licence compliance checks.")
101
+ project = plugin.get_current_spdx_project()
102
+ if project is None:
103
+ raise ValueError("The selected language plugin did not return a project for licence compliance checks.")
104
+ if args.lookup_scancode:
105
+ project.enable_scancode_lookup()
106
+ if args.output_dir is not None:
107
+ project.generate_licensing_summary(args.output_dir)
108
+ _print_policy_summary(project)
109
+ _log_assessment_details(project)
110
+ if args.lookup_scancode:
111
+ for name, result in project.licence_assessments.items():
112
+ for info in result.scancode_licences:
113
+ print(f"{name}: ScanCode LicenseDB: {info.identifier} ({info.category}): {info.url}")
114
+ if args.lookup_scancode:
115
+ for warning in project.scancode_follow_up_warnings():
116
+ print(f"WARNING: {warning}", file=sys.stderr)
117
+ return 0
118
+ except Exception as error:
119
+ log_exception(logger, error)
120
+ return 1
121
+
122
+
123
+ if __name__ == "__main__":
124
+ sys.exit(main())
@@ -50,7 +50,7 @@ def _generate_changelog(version: Optional[str], use_news_files: bool) -> None:
50
50
  logger.info(":: Generating a new changelog")
51
51
  project_config_path = configuration.get_value(ConfigurationVariable.PROJECT_CONFIG)
52
52
  with cd(os.path.dirname(project_config_path)):
53
- subprocess.check_call(["towncrier", "build", "--yes", '--name=""', f'--version="{version}"'])
53
+ subprocess.check_call(["towncrier", "build", "--yes", "--name", "", "--version", str(version)])
54
54
 
55
55
 
56
56
  def main() -> None:
@@ -10,10 +10,11 @@ import json
10
10
  import logging
11
11
  import os
12
12
  import shutil
13
+ from contextlib import contextmanager
13
14
  from pathlib import Path
14
- from subprocess import check_call, check_output
15
+ from subprocess import check_call, check_output, run, CalledProcessError
15
16
  from tempfile import TemporaryDirectory
16
- from typing import Optional, List, Dict, MutableMapping
17
+ from typing import Optional, List, Dict, MutableMapping, Iterator
17
18
 
18
19
  from continuous_delivery_scripts.spdx_report.spdx_project import SpdxProject
19
20
  from continuous_delivery_scripts.utils.configuration import (
@@ -47,6 +48,7 @@ GO_MOD_ON_VALUE = "on"
47
48
  # go-licenses report --template receives Name, Version, LicenseURL and LicenseName for each library.
48
49
  # https://github.com/google/go-licenses/blob/master/README.md#reports-with-custom-templates
49
50
  GO_LICENSES_TEMPLATE = "{{range .}}{{.Name}}\t{{.Version}}\t{{.LicenseURL}}\t{{.LicenseName}}\n{{end}}"
51
+ LICENCE_FILE_PREFIXES = ("LICENSE", "LICENCE", "COPYING")
50
52
 
51
53
 
52
54
  def _generate_doc2go_command_list(output_directory: Path, module: str) -> List[str]:
@@ -156,6 +158,71 @@ def _parse_go_licences(output: str) -> List[PackageMetadata]:
156
158
  return packages
157
159
 
158
160
 
161
+ def _log_go_licenses_stderr(module_dir: Path, stderr_output: str) -> None:
162
+ """Report go-licenses diagnostics through CDS logging instead of leaking raw stderr."""
163
+ diagnostics = stderr_output.strip()
164
+ if not diagnostics:
165
+ return
166
+ logger.warning(
167
+ "go-licenses emitted diagnostics while scanning [%s]. Re-run with -vv for the captured stderr.",
168
+ module_dir,
169
+ )
170
+ logger.info("go-licenses stderr for [%s]:\n%s", module_dir, diagnostics)
171
+
172
+
173
+ def _run_go_licenses_report(
174
+ executable: str, module_dir: Path, template_path: Path, env: MutableMapping[str, str]
175
+ ) -> str:
176
+ """Run go-licenses with captured stderr so CDS controls when diagnostics are shown."""
177
+ result = run(
178
+ [executable, "report", "./...", "--template", str(template_path)],
179
+ cwd=module_dir,
180
+ env=env,
181
+ encoding="utf8",
182
+ capture_output=True,
183
+ check=False,
184
+ )
185
+ _log_go_licenses_stderr(module_dir, result.stderr)
186
+ if result.returncode != 0:
187
+ error_message = result.stderr.strip() or result.stdout.strip() or f"exit code {result.returncode}"
188
+ raise CalledProcessError(result.returncode, result.args, output=result.stdout, stderr=error_message)
189
+ return result.stdout
190
+
191
+
192
+ def _find_licence_file(directory: Path) -> Optional[Path]:
193
+ """Return the first recognised licence file in a directory."""
194
+ for path in sorted(directory.iterdir()):
195
+ if path.is_file() and path.name.upper().startswith(LICENCE_FILE_PREFIXES):
196
+ return path
197
+ return None
198
+
199
+
200
+ @contextmanager
201
+ def _stage_root_licence_files_for_modules(module_directories: List[Path]) -> Iterator[None]:
202
+ """Temporarily copy the root licence into module directories that do not already have one."""
203
+ root_licence_file = _find_licence_file(ROOT_DIR)
204
+ if not root_licence_file:
205
+ yield
206
+ return
207
+
208
+ staged_files: List[Path] = []
209
+ try:
210
+ for module_directory in module_directories:
211
+ if module_directory == ROOT_DIR or _find_licence_file(module_directory):
212
+ continue
213
+ # go-licenses only searches for licence files up to the module root, so
214
+ # nested modules cannot see a repository-level LICENSE on their own.
215
+ destination = module_directory / root_licence_file.name
216
+ shutil.copy2(root_licence_file, destination)
217
+ staged_files.append(destination)
218
+ yield
219
+ finally:
220
+ # Remove only the temporary copies we created so existing module-specific
221
+ # licence files remain untouched and the worktree stays clean.
222
+ for staged_file in staged_files:
223
+ staged_file.unlink(missing_ok=True)
224
+
225
+
159
226
  class GoProjectMetadataFetcher(ProjectMetadataFetcher):
160
227
  """Retrieve Go dependency licences for the shared SPDX and compliance report."""
161
228
 
@@ -185,29 +252,25 @@ class GoProjectMetadataFetcher(ProjectMetadataFetcher):
185
252
  with TemporaryDirectory() as temporary_dir:
186
253
  template_path = Path(temporary_dir) / "go-licenses.tpl"
187
254
  template_path.write_text(GO_LICENSES_TEMPLATE, encoding="utf8")
188
- for module_dir, _ in modules:
189
- output = check_output(
190
- [executable, "report", "./...", "--template", str(template_path)],
191
- cwd=module_dir,
192
- env=env,
193
- encoding="utf8",
194
- )
195
- for package in _parse_go_licences(output):
196
- if any(package.name == name or package.name.startswith(f"{name}/") for _, name in modules):
197
- continue
198
- existing = dependencies.get(package.name)
199
- if existing and (existing.version, existing.licence) != (package.version, package.licence):
200
- candidates = existing.licence_candidates or [existing.licence]
201
- dependencies[package.name] = PackageMetadata.from_fields(
202
- name=package.name,
203
- version=UNKNOWN if existing.version != package.version else package.version,
204
- licence=UNKNOWN,
205
- licence_source=LicenceSource.UNKNOWN,
206
- licence_candidates=sorted(set(candidates + [package.licence])),
207
- licence_evidence=existing.licence_evidence + package.licence_evidence,
208
- )
209
- elif existing is None:
210
- dependencies[package.name] = package
255
+ with _stage_root_licence_files_for_modules(module_directories):
256
+ for module_dir, _ in modules:
257
+ output = _run_go_licenses_report(executable, module_dir, template_path, env)
258
+ for package in _parse_go_licences(output):
259
+ if any(package.name == name or package.name.startswith(f"{name}/") for _, name in modules):
260
+ continue
261
+ existing = dependencies.get(package.name)
262
+ if existing and (existing.version, existing.licence) != (package.version, package.licence):
263
+ candidates = existing.licence_candidates or [existing.licence]
264
+ dependencies[package.name] = PackageMetadata.from_fields(
265
+ name=package.name,
266
+ version=UNKNOWN if existing.version != package.version else package.version,
267
+ licence=UNKNOWN,
268
+ licence_source=LicenceSource.UNKNOWN,
269
+ licence_candidates=sorted(set(candidates + [package.licence])),
270
+ licence_evidence=existing.licence_evidence + package.licence_evidence,
271
+ )
272
+ elif existing is None:
273
+ dependencies[package.name] = package
211
274
  for dependency in dependencies.values():
212
275
  project.add_dependency_metadata(dependency)
213
276
  return project
@@ -95,6 +95,14 @@ def determine_file_licence(path: Path) -> Optional[str]:
95
95
  return None
96
96
  licence = match.group(1).strip()
97
97
  return str(simplify_licence_expression(licence))
98
+ except UnicodeDecodeError as e:
99
+ logger.warning(
100
+ "Could not screen file [%s] for an embedded SPDX licence identifier because it appears to be binary. "
101
+ "Binary files cannot be screened for inline licence metadata.",
102
+ path,
103
+ )
104
+ logger.info("Binary screening failure for [%s]: %s", path, e)
105
+ return None
98
106
  except Exception as e:
99
107
  logger.error(f"Could not determine the licence of file [{path}] from identifier '{licence}'. Reason: {e}.")
100
108
  return None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: continuous-delivery-scripts
3
- Version: 4.4.1
3
+ Version: 4.4.2
4
4
  Summary: Git-based CI/CD tools for releases, changelogs, SPDX SBOMs and licence reporting
5
5
  Home-page: https://github.com/ARMmbed/continuous-delivery-scripts
6
6
  Author: Arm
@@ -27,7 +27,7 @@ Description-Content-Type: text/markdown
27
27
  License-File: LICENSE
28
28
  Requires-Dist: setuptools
29
29
  Requires-Dist: gitpython
30
- Requires-Dist: towncrier==22.12.0
30
+ Requires-Dist: towncrier==26.9.0
31
31
  Requires-Dist: pyautoversion~=1.2.0
32
32
  Requires-Dist: pdoc3==0.11.6
33
33
  Requires-Dist: toml
@@ -73,7 +73,6 @@ continuous_delivery_scripts/utils/python/__init__.py
73
73
  continuous_delivery_scripts/utils/python/package_helpers.py
74
74
  continuous_delivery_scripts/utils/python/python_helpers.py
75
75
  spdx-tmp/GitPython.spdx
76
- spdx-tmp/Incremental.spdx
77
76
  spdx-tmp/Jinja2.spdx
78
77
  spdx-tmp/Mako.spdx
79
78
  spdx-tmp/Markdown.spdx
@@ -88,7 +87,6 @@ spdx-tmp/bracex.spdx
88
87
  spdx-tmp/certifi.spdx
89
88
  spdx-tmp/cffi.spdx
90
89
  spdx-tmp/charset-normalizer.spdx
91
- spdx-tmp/click-default-group.spdx
92
90
  spdx-tmp/click.spdx
93
91
  spdx-tmp/continuous-delivery-scripts.spdx
94
92
  spdx-tmp/cryptography.spdx
@@ -1,6 +1,6 @@
1
1
  setuptools
2
2
  gitpython
3
- towncrier==22.12.0
3
+ towncrier==26.9.0
4
4
  pyautoversion~=1.2.0
5
5
  pdoc3==0.11.6
6
6
  toml
@@ -74,7 +74,7 @@ setup(
74
74
  install_requires=[
75
75
  "setuptools",
76
76
  "gitpython",
77
- "towncrier==22.12.0",
77
+ "towncrier==26.9.0",
78
78
  "pyautoversion~=1.2.0",
79
79
  # FIXME change when https://github.com/pdoc3/pdoc/issues/299 is fixed
80
80
  "pdoc3==0.11.6",
@@ -12,7 +12,7 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Tool: mbed-spdx-generator
14
14
  Creator: Person: unknown (Sebastian Thiel <byronimo@gmail.com>, Michael Trier <mtrier@gmail.com>)
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
@@ -12,7 +12,7 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Tool: mbed-spdx-generator
14
14
  Creator: Person: unknown (unknown)
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
@@ -12,7 +12,7 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Tool: mbed-spdx-generator
14
14
  Creator: Person: unknown (Mike Bayer <mike@zzzcomputing.com>)
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
@@ -12,7 +12,7 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Person: Manfred Stienstra, Yuri Takhteyev (Waylan limberg <python.markdown@gmail.com>)
14
14
  Creator: Tool: mbed-spdx-generator
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
@@ -12,7 +12,7 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Tool: mbed-spdx-generator
14
14
  Creator: Person: unknown (unknown)
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
@@ -12,7 +12,7 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Person: Kirill Simonov (xi@resolvent.net)
14
14
  Creator: Tool: mbed-spdx-generator
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
@@ -12,7 +12,7 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Tool: mbed-spdx-generator
14
14
  Creator: Person: unknown (Georg Brandl <georg@python.org>)
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
@@ -12,7 +12,7 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Tool: mbed-spdx-generator
14
14
  Creator: Person: unknown (Dmitry Shachnev <mitya57@gmail.com>)
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
@@ -12,7 +12,7 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Person: Sebastian Kraemer (basti.kr@gmail.com)
14
14
  Creator: Tool: mbed-spdx-generator
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
@@ -2,9 +2,9 @@
2
2
 
3
3
  SPDXVersion: SPDX-1.2
4
4
  DataLicense: CC0-1.0
5
- DocumentName: boto3-1.43.106
5
+ DocumentName: boto3-1.43.107
6
6
  SPDXID: SPDXRef-DOCUMENT
7
- DocumentNamespace: http://spdx.org/spdxdocs/boto3-1.43.106-5312fb83-fdd6-b8dc-38af-244f66958ad3
7
+ DocumentNamespace: http://spdx.org/spdxdocs/boto3-1.43.107-dcf81462-50d3-c383-4ac2-18223e312508
8
8
  DocumentComment: <text>This document was created automatically using available project and dependency information.</text>
9
9
 
10
10
 
@@ -12,14 +12,14 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Person: Amazon Web Services (unknown)
14
14
  Creator: Tool: mbed-spdx-generator
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
19
19
 
20
20
  PackageName: boto3
21
21
  SPDXID: SPDXRef-boto3
22
- PackageVersion: 1.43.106
22
+ PackageVersion: 1.43.107
23
23
  PackageDownloadLocation: NONE
24
24
  PackageSummary: <text>The AWS SDK for Python (Boto3)</text>
25
25
  PackageFileName: boto3
@@ -2,9 +2,9 @@
2
2
 
3
3
  SPDXVersion: SPDX-1.2
4
4
  DataLicense: CC0-1.0
5
- DocumentName: botocore-1.43.106
5
+ DocumentName: botocore-1.43.107
6
6
  SPDXID: SPDXRef-DOCUMENT
7
- DocumentNamespace: http://spdx.org/spdxdocs/botocore-1.43.106-10e147fd-3ba0-1292-77d7-1e630c192997
7
+ DocumentNamespace: http://spdx.org/spdxdocs/botocore-1.43.107-2c8cb107-9ef7-266b-af71-33942212a107
8
8
  DocumentComment: <text>This document was created automatically using available project and dependency information.</text>
9
9
 
10
10
 
@@ -12,14 +12,14 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Person: Amazon Web Services (unknown)
14
14
  Creator: Tool: mbed-spdx-generator
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
19
19
 
20
20
  PackageName: botocore
21
21
  SPDXID: SPDXRef-botocore
22
- PackageVersion: 1.43.106
22
+ PackageVersion: 1.43.107
23
23
  PackageDownloadLocation: NONE
24
24
  PackageSummary: <text>Low-level, data-driven core of boto 3.</text>
25
25
  PackageFileName: botocore
@@ -12,7 +12,7 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Tool: mbed-spdx-generator
14
14
  Creator: Person: unknown (Isaac Muse <Isaac.Muse@gmail.com>)
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
@@ -12,7 +12,7 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Person: Kenneth Reitz (me@kennethreitz.com)
14
14
  Creator: Tool: mbed-spdx-generator
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
@@ -12,7 +12,7 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Person: Armin Rigo, Maciej Fijalkowski (unknown)
14
14
  Creator: Tool: mbed-spdx-generator
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
@@ -12,7 +12,7 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Tool: mbed-spdx-generator
14
14
  Creator: Person: unknown ("Ahmed R. TAHRI" <tahri.ahmed@proton.me>)
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package
@@ -12,7 +12,7 @@ DocumentComment: <text>This document was created automatically using available p
12
12
 
13
13
  Creator: Tool: mbed-spdx-generator
14
14
  Creator: Person: unknown (unknown)
15
- Created: 2026-10-01T16:56:04Z
15
+ Created: 2026-10-02T12:56:08Z
16
16
 
17
17
 
18
18
  # Package