continuous-delivery-scripts 4.1.0__tar.gz → 4.3.0__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.
- {continuous_delivery_scripts-4.1.0/continuous_delivery_scripts.egg-info → continuous_delivery_scripts-4.3.0}/PKG-INFO +13 -12
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/README.md +12 -11
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/_version.py +3 -3
- continuous_delivery_scripts-4.3.0/continuous_delivery_scripts/check_licence_compliance.py +48 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/generate_docs.py +5 -2
- continuous_delivery_scripts-4.3.0/continuous_delivery_scripts/plugins/GOLAND.MD +52 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/plugins/golang.py +146 -20
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/spdx_report/spdx_document.py +34 -4
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/spdx_report/spdx_helpers.py +2 -1
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/spdx_report/spdx_package.py +17 -5
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/spdx_report/spdx_project.py +17 -7
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/spdx_report/spdx_summary.py +67 -13
- continuous_delivery_scripts-4.3.0/continuous_delivery_scripts/spdx_report/templates/third_party_IP_report.html.jinja2 +301 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/tag_and_release.py +13 -4
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/configuration.py +3 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/language_specifics_base.py +4 -1
- continuous_delivery_scripts-4.3.0/continuous_delivery_scripts/utils/package_helpers.py +280 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/third_party_licences.py +35 -3
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0/continuous_delivery_scripts.egg-info}/PKG-INFO +13 -12
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts.egg-info/SOURCES.txt +1 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts.egg-info/entry_points.txt +1 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/pyproject.toml +1 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/setup.py +4 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/GitPython.spdx +8 -8
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/Incremental.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/Jinja2.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/Mako.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/Markdown.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/MarkupSafe.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/PyYAML.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/Pygments.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/SecretStorage.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/boolean.py.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/boto3.spdx +5 -5
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/botocore.spdx +5 -5
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/bracex.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/certifi.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/cffi.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/charset-normalizer.spdx +5 -5
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/click-default-group.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/click.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/continuous-delivery-scripts.spdx +100 -87
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/cryptography.spdx +5 -5
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/detect-secrets.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/docutils.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/gibberish-detector.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/gitdb.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/id.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/idna.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/jaraco.classes.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/jaraco.context.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/jaraco.functools.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/jeepney.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/jellyfish.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/jmespath.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/keyring.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/license-expression.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/licenseheaders.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/markdown-it-py.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/mdurl.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/more-itertools.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/nh3.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/packaging.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/pdoc3.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/ply.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/pyautoversion.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/pycparser.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/pyparsing.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/python-dateutil.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/python-dotenv.spdx +5 -5
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/rdflib.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/readme_renderer.spdx +3 -3
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/regex.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/requests-toolbelt.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/requests.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/rfc3986.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/rich.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/s3transfer.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/semver.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/setuptools.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/six.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/smmap.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/spdx-tools.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/toml.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/towncrier.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/twine.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/urllib3.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/wcmatch.spdx +2 -2
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/spdx-tmp/xmltodict.spdx +2 -2
- continuous_delivery_scripts-4.1.0/continuous_delivery_scripts/plugins/GOLAND.MD +0 -12
- continuous_delivery_scripts-4.1.0/continuous_delivery_scripts/spdx_report/templates/third_party_IP_report.html.jinja2 +0 -148
- continuous_delivery_scripts-4.1.0/continuous_delivery_scripts/utils/package_helpers.py +0 -194
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/LICENSE +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/MANIFEST.in +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/__init__.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/assert_news.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/create_news_file.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/detect_secrets.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/generate_news.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/get_config.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/get_version.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/language_specifics.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/license_files.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/plugins/BASIC.MD +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/plugins/CI.MD +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/plugins/GITHUB_ACTIONS.MD +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/plugins/NOOP.MD +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/plugins/PYTHON.MD +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/plugins/__init__.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/plugins/basic.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/plugins/ci.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/plugins/docker.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/plugins/github_actions.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/plugins/noop.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/plugins/python.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/report_third_party_ip.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/spdx_report/__init__.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/spdx_report/spdx_dependency.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/spdx_report/spdx_file.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/spdx_report/templates/third_party_IP_report.csv.jinja2 +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/spdx_report/templates/third_party_IP_report.txt.jinja2 +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/update_secrets_registry.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/__init__.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/aws_helpers.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/definitions.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/filesystem_helpers.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/git_helpers.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/hash_helpers.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/logging.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/news_file.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/noop/__init__.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/noop/package_helpers.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/python/__init__.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/python/package_helpers.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/python/python_helpers.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/string_helpers.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts/utils/versioning.py +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts.egg-info/dependency_links.txt +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts.egg-info/requires.txt +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/continuous_delivery_scripts.egg-info/top_level.txt +0 -0
- {continuous_delivery_scripts-4.1.0 → continuous_delivery_scripts-4.3.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: continuous-delivery-scripts
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.0
|
|
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
|
|
@@ -239,17 +239,18 @@ same commands whichever CI system the team chooses.
|
|
|
239
239
|
|
|
240
240
|
| Command | What it does | Key arguments | Typical environment |
|
|
241
241
|
| --- | --- | --- | --- |
|
|
242
|
-
| `cd-assert-news` | Validates a branch's news files; can add a missing file for a configured dependency-update branch. | `--current-branch` (`-b`), `--local` (`-l`) | CI; `--local` for developer checks |
|
|
243
|
-
| `cd-create-news-file` | Creates a one-line news fragment in the configured news directory. | Required news text; `--type` (`-t`), `--ref-number` (`-n`) | Developer |
|
|
244
|
-
| `cd-determine-version` | Calculates and prints the **project's prospective release version** without generating a changelog. | Required `--release-type` (`-t`) | Developer preview or CI |
|
|
245
|
-
| `cd-generate-news` | Updates the project version and, for beta or production releases, builds the changelog from news fragments; prints the resulting version. | Required `--release-type` (`-t`) | CI release flow |
|
|
246
|
-
| `cd-get-config` | Prints a project configuration value. | Either `--key` (`-k`) or `--config-variable` (`-c`) | Developer or CI |
|
|
247
|
-
| `cd-tag-and-release` | Runs the release flow, including documentation, licensing summaries, Git tagging, packaging and publication through the selected [language plugin](./continuous_delivery_scripts/plugins). | Required `--release-type` (`-t`); optional `--current-branch` (`-b`) | CI release flow |
|
|
248
|
-
| `cd-generate-docs` | Generates code documentation in the configured output directory (or one specified on the command line). | `--output_directory` | Developer preview or CI |
|
|
249
|
-
| `cd-generate-spdx` | Generates SPDX documents and third-party licence summaries, then checks licence compliance when project metadata is available. | Required `--output-dir` (`-o`); create the directory first | CI audit; developer review also possible |
|
|
250
|
-
| `cd-
|
|
251
|
-
| `cd-
|
|
252
|
-
| `cd-
|
|
242
|
+
| [`cd-assert-news`](./guides/checking-news-fragments.md) | Validates a branch's news files; can add a missing file for a configured dependency-update branch. | `--current-branch` (`-b`), `--local` (`-l`) | CI; `--local` for developer checks |
|
|
243
|
+
| [`cd-create-news-file`](./guides/creating-news-fragments.md) | Creates a one-line news fragment in the configured news directory. | Required news text; `--type` (`-t`), `--ref-number` (`-n`) | Developer |
|
|
244
|
+
| [`cd-determine-version`](./guides/previewing-versions.md) | Calculates and prints the **project's prospective release version** without generating a changelog. | Required `--release-type` (`-t`) | Developer preview or CI |
|
|
245
|
+
| [`cd-generate-news`](./guides/managing-changelogs.md) | Updates the project version and, for beta or production releases, builds the changelog from news fragments; prints the resulting version. | Required `--release-type` (`-t`) | CI release flow |
|
|
246
|
+
| [`cd-get-config`](./guides/reading-project-configuration.md) | Prints a project configuration value. | Either `--key` (`-k`) or `--config-variable` (`-c`) | Developer or CI |
|
|
247
|
+
| [`cd-tag-and-release`](./guides/automating-releases.md) | Runs the release flow, including documentation, licensing summaries, Git tagging, packaging and publication through the selected [language plugin](./continuous_delivery_scripts/plugins). | Required `--release-type` (`-t`); optional `--current-branch` (`-b`) | CI release flow |
|
|
248
|
+
| [`cd-generate-docs`](./guides/generating-code-documentation.md) | Generates code documentation in the configured output directory (or one specified on the command line). | `--output_directory` | Developer preview or CI |
|
|
249
|
+
| [`cd-generate-spdx`](./guides/generating-an-spdx-sbom.md) | Generates SPDX documents and third-party licence summaries, then checks licence compliance when project metadata is available. | Required `--output-dir` (`-o`); create the directory first | CI audit; developer review also possible |
|
|
250
|
+
| [`cd-check-licence-compliance`](./guides/checking-licence-compliance.md) | Checks project and dependency licences without creating SPDX documents; optionally writes third-party IP summaries. | Optional `--output-dir` (`-o`) for reports | CI gate or developer review |
|
|
251
|
+
| [`cd-license-files`](./guides/licence-header-management.md) | Adds or updates source-file licence and copyright headers when the language plugin supports them. | `--verbose` (`-v`) | Developer or CI |
|
|
252
|
+
| [`cd-record-secrets`](./guides/recording-secrets.md) | Records accepted findings in the project's [detect-secrets](https://github.com/Yelp/detect-secrets) registry. | `--registry-file` (`-r`); defaults to the configured registry | Developer (registry maintenance) |
|
|
253
|
+
| [`cd-detect-secrets`](./guides/checking-for-secrets.md) | Checks Git-tracked files against that registry and fails if new secrets are found. | `--registry-file` (`-r`); defaults to the configured registry | CI; developer checks also possible |
|
|
253
254
|
|
|
254
255
|
For example, `cd-create-news-file "Fix dependency resolution" --type bugfix`
|
|
255
256
|
adds a news fragment. For release workflow details, see the
|
|
@@ -178,17 +178,18 @@ same commands whichever CI system the team chooses.
|
|
|
178
178
|
|
|
179
179
|
| Command | What it does | Key arguments | Typical environment |
|
|
180
180
|
| --- | --- | --- | --- |
|
|
181
|
-
| `cd-assert-news` | Validates a branch's news files; can add a missing file for a configured dependency-update branch. | `--current-branch` (`-b`), `--local` (`-l`) | CI; `--local` for developer checks |
|
|
182
|
-
| `cd-create-news-file` | Creates a one-line news fragment in the configured news directory. | Required news text; `--type` (`-t`), `--ref-number` (`-n`) | Developer |
|
|
183
|
-
| `cd-determine-version` | Calculates and prints the **project's prospective release version** without generating a changelog. | Required `--release-type` (`-t`) | Developer preview or CI |
|
|
184
|
-
| `cd-generate-news` | Updates the project version and, for beta or production releases, builds the changelog from news fragments; prints the resulting version. | Required `--release-type` (`-t`) | CI release flow |
|
|
185
|
-
| `cd-get-config` | Prints a project configuration value. | Either `--key` (`-k`) or `--config-variable` (`-c`) | Developer or CI |
|
|
186
|
-
| `cd-tag-and-release` | Runs the release flow, including documentation, licensing summaries, Git tagging, packaging and publication through the selected [language plugin](./continuous_delivery_scripts/plugins). | Required `--release-type` (`-t`); optional `--current-branch` (`-b`) | CI release flow |
|
|
187
|
-
| `cd-generate-docs` | Generates code documentation in the configured output directory (or one specified on the command line). | `--output_directory` | Developer preview or CI |
|
|
188
|
-
| `cd-generate-spdx` | Generates SPDX documents and third-party licence summaries, then checks licence compliance when project metadata is available. | Required `--output-dir` (`-o`); create the directory first | CI audit; developer review also possible |
|
|
189
|
-
| `cd-
|
|
190
|
-
| `cd-
|
|
191
|
-
| `cd-
|
|
181
|
+
| [`cd-assert-news`](./guides/checking-news-fragments.md) | Validates a branch's news files; can add a missing file for a configured dependency-update branch. | `--current-branch` (`-b`), `--local` (`-l`) | CI; `--local` for developer checks |
|
|
182
|
+
| [`cd-create-news-file`](./guides/creating-news-fragments.md) | Creates a one-line news fragment in the configured news directory. | Required news text; `--type` (`-t`), `--ref-number` (`-n`) | Developer |
|
|
183
|
+
| [`cd-determine-version`](./guides/previewing-versions.md) | Calculates and prints the **project's prospective release version** without generating a changelog. | Required `--release-type` (`-t`) | Developer preview or CI |
|
|
184
|
+
| [`cd-generate-news`](./guides/managing-changelogs.md) | Updates the project version and, for beta or production releases, builds the changelog from news fragments; prints the resulting version. | Required `--release-type` (`-t`) | CI release flow |
|
|
185
|
+
| [`cd-get-config`](./guides/reading-project-configuration.md) | Prints a project configuration value. | Either `--key` (`-k`) or `--config-variable` (`-c`) | Developer or CI |
|
|
186
|
+
| [`cd-tag-and-release`](./guides/automating-releases.md) | Runs the release flow, including documentation, licensing summaries, Git tagging, packaging and publication through the selected [language plugin](./continuous_delivery_scripts/plugins). | Required `--release-type` (`-t`); optional `--current-branch` (`-b`) | CI release flow |
|
|
187
|
+
| [`cd-generate-docs`](./guides/generating-code-documentation.md) | Generates code documentation in the configured output directory (or one specified on the command line). | `--output_directory` | Developer preview or CI |
|
|
188
|
+
| [`cd-generate-spdx`](./guides/generating-an-spdx-sbom.md) | Generates SPDX documents and third-party licence summaries, then checks licence compliance when project metadata is available. | Required `--output-dir` (`-o`); create the directory first | CI audit; developer review also possible |
|
|
189
|
+
| [`cd-check-licence-compliance`](./guides/checking-licence-compliance.md) | Checks project and dependency licences without creating SPDX documents; optionally writes third-party IP summaries. | Optional `--output-dir` (`-o`) for reports | CI gate or developer review |
|
|
190
|
+
| [`cd-license-files`](./guides/licence-header-management.md) | Adds or updates source-file licence and copyright headers when the language plugin supports them. | `--verbose` (`-v`) | Developer or CI |
|
|
191
|
+
| [`cd-record-secrets`](./guides/recording-secrets.md) | Records accepted findings in the project's [detect-secrets](https://github.com/Yelp/detect-secrets) registry. | `--registry-file` (`-r`); defaults to the configured registry | Developer (registry maintenance) |
|
|
192
|
+
| [`cd-detect-secrets`](./guides/checking-for-secrets.md) | Checks Git-tracked files against that registry and fails if new secrets are found. | `--registry-file` (`-r`); defaults to the configured registry | CI; developer checks also possible |
|
|
192
193
|
|
|
193
194
|
For example, `cd-create-news-file "Fix dependency resolution" --type bugfix`
|
|
194
195
|
adds a news fragment. For release workflow details, see the
|
|
@@ -11,8 +11,8 @@ References
|
|
|
11
11
|
This file is autogenerated, do not modify by hand.
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
-
__version__ = "4.
|
|
15
|
-
COMMIT = "
|
|
14
|
+
__version__ = "4.3.0"
|
|
15
|
+
COMMIT = "3e8ffc7bd8472928ca195f17fb278d40476ef8a2"
|
|
16
16
|
MAJOR = 4
|
|
17
|
-
MINOR =
|
|
17
|
+
MINOR = 3
|
|
18
18
|
PATCH = 0
|
|
@@ -0,0 +1,48 @@
|
|
|
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
|
+
|
|
12
|
+
from continuous_delivery_scripts.language_specifics import get_language_specifics
|
|
13
|
+
from continuous_delivery_scripts.utils.logging import log_exception, set_log_level
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def main() -> int:
|
|
19
|
+
"""Check licence compliance and optionally write third-party IP summaries."""
|
|
20
|
+
parser = argparse.ArgumentParser(description="Check project and dependency licence compliance.")
|
|
21
|
+
parser.add_argument(
|
|
22
|
+
"-o",
|
|
23
|
+
"--output-dir",
|
|
24
|
+
type=Path,
|
|
25
|
+
help="Write third-party IP summaries to this existing directory (no SPDX documents).",
|
|
26
|
+
)
|
|
27
|
+
parser.add_argument("-v", "--verbose", action="count", default=0, help="Increase logging verbosity.")
|
|
28
|
+
args = parser.parse_args()
|
|
29
|
+
set_log_level(args.verbose)
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
plugin = get_language_specifics()
|
|
33
|
+
if not plugin.can_get_project_metadata():
|
|
34
|
+
raise ValueError("The selected language plugin cannot provide metadata for licence compliance checks.")
|
|
35
|
+
project = plugin.get_current_spdx_project()
|
|
36
|
+
if project is None:
|
|
37
|
+
raise ValueError("The selected language plugin did not return a project for licence compliance checks.")
|
|
38
|
+
if args.output_dir is not None:
|
|
39
|
+
project.generate_licensing_summary(args.output_dir)
|
|
40
|
+
project.check_licence_compliance()
|
|
41
|
+
return 0
|
|
42
|
+
except Exception as error:
|
|
43
|
+
log_exception(logger, error)
|
|
44
|
+
return 1
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
if __name__ == "__main__":
|
|
48
|
+
sys.exit(main())
|
|
@@ -93,7 +93,7 @@ def _guide_settings() -> tuple[Path, Path, Path, str] | None:
|
|
|
93
93
|
def _render_guide(source: Path, destination: Path, project_name: str, nav_prefix: str, has_api_index: bool) -> str:
|
|
94
94
|
"""Render one Markdown guide to an HTML page and return its title."""
|
|
95
95
|
text = source.read_text(encoding="utf8")
|
|
96
|
-
title = text.splitlines()
|
|
96
|
+
title = next((line[2:].strip() for line in text.splitlines() if line.startswith("# ")), source.stem)
|
|
97
97
|
body: str = markdown.markdown(text, extensions=["fenced_code", "tables"])
|
|
98
98
|
body = re.sub(r'href="([a-z0-9-]+)\.md(#[^"]*)?"', _html_guide_link, body)
|
|
99
99
|
description = f"{title} — {project_name}."
|
|
@@ -124,10 +124,13 @@ def _write_guide_index(
|
|
|
124
124
|
) -> None:
|
|
125
125
|
"""Write the project-specific landing page for the published guides."""
|
|
126
126
|
guide_prefix = guide_folder.as_posix()
|
|
127
|
+
licence = configuration.get_value_or_default(ConfigurationVariable.FILE_LICENCE_IDENTIFIER, None)
|
|
128
|
+
licence_details = f"<p>Project licence: {escape(str(licence))}</p>" if licence else ""
|
|
127
129
|
overview = (
|
|
128
130
|
f"<h1>{escape(project_name)}</h1>"
|
|
129
131
|
f"<p>Task guides for {escape(project_name)}, with setup, examples and project workflows.</p>"
|
|
130
|
-
|
|
132
|
+
+ licence_details
|
|
133
|
+
+ f'<p><a href="{escape(guide_prefix)}/index.html">All task guides</a>'
|
|
131
134
|
+ (' · <a href="api.html">API reference</a>' if has_api_index else "")
|
|
132
135
|
+ "</p><ul>"
|
|
133
136
|
+ "".join(links)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Golang plugin
|
|
2
|
+
|
|
3
|
+
This plugin is used for golang projects when `PROGRAMMING_LANGUAGE` is set to `golang`.
|
|
4
|
+
|
|
5
|
+
In order to work, `go > 1.18` is required.
|
|
6
|
+
|
|
7
|
+
## Release
|
|
8
|
+
The plugin leverages [goreleaser](https://goreleaser.com/) to package and release projects.
|
|
9
|
+
Therefore, a `.goreleaser.yml` file must be present in the go source directory i.e. where the mod file lies.
|
|
10
|
+
|
|
11
|
+
## Documentation
|
|
12
|
+
The plugin uses [doc2go](https://abhinav.github.io/doc2go) to generate the code reference documentation.
|
|
13
|
+
|
|
14
|
+
## SPDX and third-party IP reporting
|
|
15
|
+
|
|
16
|
+
The Go plugin uses [go-licenses v2](https://github.com/google/go-licenses) to
|
|
17
|
+
discover the licences of packages imported by Go modules. It checks for a
|
|
18
|
+
usable `go-licenses` binary on `PATH` before installing
|
|
19
|
+
`github.com/google/go-licenses/v2@latest` with `go install`. The Go toolchain
|
|
20
|
+
must be available; an installed binary can also be located under `GOBIN` or
|
|
21
|
+
the first `GOPATH` entry's `bin` directory.
|
|
22
|
+
|
|
23
|
+
Set `PROGRAMMING_LANGUAGE = "golang"`, `PROJECT_NAME`, `PROJECT_ROOT` and
|
|
24
|
+
`SOURCE_DIR` in `[ProjectConfig]`. Put a `go.mod` under the source or project
|
|
25
|
+
root; `go.work` modules and nested Go modules are also considered. Supply
|
|
26
|
+
`FILE_LICENCE_IDENTIFIER` for the project licence and set `PROJECT_UUID`
|
|
27
|
+
and `[spdx]` namespace fields as explained in the
|
|
28
|
+
[SPDX configuration guide](../../DEVELOPMENT.md#spdx-document-identity).
|
|
29
|
+
|
|
30
|
+
With the project and its Go dependencies available, run:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
mkdir -p licensing
|
|
34
|
+
cd-generate-spdx --output-dir licensing
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
For each module, the plugin runs `go-licenses report ./...` with a template
|
|
38
|
+
to collect dependency package names, versions, licence URLs and SPDX licence
|
|
39
|
+
names. The [go-licenses custom-template documentation](https://github.com/google/go-licenses/blob/master/README.md#reports-with-custom-templates)
|
|
40
|
+
defines the `Name`, `Version`, `LicenseURL` and `LicenseName` fields used by the
|
|
41
|
+
plugin; the default CSV report has no `Version` field. The metadata then enters
|
|
42
|
+
the **shared** SPDX writer, HTML/CSV/text/JSON
|
|
43
|
+
third-party IP report and accepted-licence policy used by other plugins.
|
|
44
|
+
To include the shared licence summary in release documentation, set
|
|
45
|
+
`GENERATE_LICENSING_SUMMARY_ON_RELEASE = true` in `[ProjectConfig]` (the default
|
|
46
|
+
is `false`).
|
|
47
|
+
The Go tool's own `check` policy is not used; configure
|
|
48
|
+
`ACCEPTED_THIRD_PARTY_LICENCES` and documented exceptions in
|
|
49
|
+
`PACKAGES_WITH_CHECKED_LICENCE` in `pyproject.toml` instead. Unknown licences
|
|
50
|
+
remain unknown so that the shared audit can flag them. The report reflects
|
|
51
|
+
dependencies built for the current Go environment and excludes test-only
|
|
52
|
+
imports unless the Go tool is invoked separately with `--include_tests`.
|
|
@@ -4,19 +4,23 @@
|
|
|
4
4
|
#
|
|
5
5
|
"""Plugin for Golang projects."""
|
|
6
6
|
|
|
7
|
+
import csv
|
|
8
|
+
import io
|
|
7
9
|
import json
|
|
8
10
|
import logging
|
|
9
11
|
import os
|
|
10
12
|
import shutil
|
|
11
13
|
from pathlib import Path
|
|
12
14
|
from subprocess import check_call, check_output
|
|
13
|
-
from
|
|
15
|
+
from tempfile import TemporaryDirectory
|
|
16
|
+
from typing import Optional, List, Dict, MutableMapping
|
|
14
17
|
|
|
18
|
+
from continuous_delivery_scripts.spdx_report.spdx_project import SpdxProject
|
|
15
19
|
from continuous_delivery_scripts.utils.configuration import (
|
|
16
20
|
configuration,
|
|
17
21
|
ConfigurationVariable,
|
|
18
22
|
)
|
|
19
|
-
from continuous_delivery_scripts.utils.definitions import CommitType
|
|
23
|
+
from continuous_delivery_scripts.utils.definitions import CommitType, UNKNOWN
|
|
20
24
|
from continuous_delivery_scripts.utils.git_helpers import (
|
|
21
25
|
LocalProjectRepository,
|
|
22
26
|
GitWrapper,
|
|
@@ -25,9 +29,12 @@ from continuous_delivery_scripts.utils.language_specifics_base import (
|
|
|
25
29
|
BaseLanguage,
|
|
26
30
|
get_language_from_file_name,
|
|
27
31
|
)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
from continuous_delivery_scripts.utils.package_helpers import (
|
|
33
|
+
LicenceSource,
|
|
34
|
+
PackageMetadata,
|
|
35
|
+
ProjectMetadata,
|
|
36
|
+
ProjectMetadataFetcher,
|
|
37
|
+
)
|
|
31
38
|
|
|
32
39
|
logger = logging.getLogger(__name__)
|
|
33
40
|
|
|
@@ -37,6 +44,9 @@ ENVVAR_GORELEASER_GIT_TOKEN = "GITHUB_TOKEN"
|
|
|
37
44
|
ENVVAR_GORELEASER_CUSTOMISED_TAG = "GORELEASER_CURRENT_TAG"
|
|
38
45
|
ENVVAR_GO_MOD = "GO111MODULE"
|
|
39
46
|
GO_MOD_ON_VALUE = "on"
|
|
47
|
+
# go-licenses report --template receives Name, Version, LicenseURL and LicenseName for each library.
|
|
48
|
+
# https://github.com/google/go-licenses/blob/master/README.md#reports-with-custom-templates
|
|
49
|
+
GO_LICENSES_TEMPLATE = "{{range .}}{{.Name}}\t{{.Version}}\t{{.LicenseURL}}\t{{.LicenseName}}\n{{end}}"
|
|
40
50
|
|
|
41
51
|
|
|
42
52
|
def _generate_doc2go_command_list(output_directory: Path, module: str) -> List[str]:
|
|
@@ -81,24 +91,147 @@ def _install_goreleaser_command_list() -> List[str]:
|
|
|
81
91
|
return ["go", "install", "github.com/goreleaser/goreleaser/v2@latest"]
|
|
82
92
|
|
|
83
93
|
|
|
94
|
+
def _install_go_licenses_command_list() -> List[str]:
|
|
95
|
+
return ["go", "install", "github.com/google/go-licenses/v2@latest"]
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _installed_go_tool_path(tool_name: str, env: MutableMapping[str, str]) -> str:
|
|
99
|
+
"""Find a binary installed using go install, even when Go's bin directory is not on PATH."""
|
|
100
|
+
go_bin = check_output(["go", "env", "GOBIN"], env=env, encoding="utf8").strip()
|
|
101
|
+
if not go_bin:
|
|
102
|
+
go_path = check_output(["go", "env", "GOPATH"], env=env, encoding="utf8").strip()
|
|
103
|
+
go_bin = str(Path(go_path.split(os.pathsep)[0]) / "bin")
|
|
104
|
+
executable = Path(go_bin) / (f"{tool_name}.exe" if os.name == "nt" else tool_name)
|
|
105
|
+
if not executable.is_file():
|
|
106
|
+
raise FileNotFoundError(f"Could not find installed {tool_name} binary: {executable}")
|
|
107
|
+
return str(executable)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _candidate_go_module_directories(include_project_root: bool = False) -> List[Path]:
|
|
111
|
+
"""Share module selection between release tags and licence reporting."""
|
|
112
|
+
candidates = [SRC_DIR]
|
|
113
|
+
if include_project_root:
|
|
114
|
+
candidates.append(ROOT_DIR)
|
|
115
|
+
workspace_modules = _determine_go_work_module_directories()
|
|
116
|
+
candidates.extend(workspace_modules if workspace_modules else _determine_go_subproject_directories())
|
|
117
|
+
return list(dict.fromkeys(candidates))
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _go_licence_module_directories() -> List[Path]:
|
|
121
|
+
"""Find actual Go modules for dependency reporting."""
|
|
122
|
+
modules = [
|
|
123
|
+
path for path in _candidate_go_module_directories(include_project_root=True) if (path / "go.mod").is_file()
|
|
124
|
+
]
|
|
125
|
+
if not modules:
|
|
126
|
+
raise FileNotFoundError(f"No go.mod found in {SRC_DIR}, {ROOT_DIR} or their Go workspace modules.")
|
|
127
|
+
return modules
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _go_module_name(module_dir: Path, env: MutableMapping[str, str]) -> str:
|
|
131
|
+
"""Read the import path declared by a Go module."""
|
|
132
|
+
module = json.loads(check_output(["go", "list", "-m", "-json"], cwd=module_dir, env=env, encoding="utf8"))
|
|
133
|
+
return str(module["Path"])
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _parse_go_licences(output: str) -> List[PackageMetadata]:
|
|
137
|
+
"""Translate go-licenses template output into shared package metadata."""
|
|
138
|
+
packages = []
|
|
139
|
+
for row in csv.reader(io.StringIO(output), delimiter="\t"):
|
|
140
|
+
if len(row) != 4 or not row[0].strip():
|
|
141
|
+
raise ValueError(f"Unexpected go-licenses report row: {row}")
|
|
142
|
+
name, version, licence_url, licence = (item.strip() for item in row)
|
|
143
|
+
known_licence = bool(licence and licence.lower() != UNKNOWN)
|
|
144
|
+
evidence = [{"kind": "licence", "path": licence_url, "text": ""}] if licence_url.startswith("https://") else []
|
|
145
|
+
packages.append(
|
|
146
|
+
PackageMetadata.from_fields(
|
|
147
|
+
name=name,
|
|
148
|
+
version=version or UNKNOWN,
|
|
149
|
+
licence=licence if known_licence else UNKNOWN,
|
|
150
|
+
licence_source=LicenceSource.TOOL if known_licence else LicenceSource.UNKNOWN,
|
|
151
|
+
declared_licence=licence or UNKNOWN,
|
|
152
|
+
url=licence_url or UNKNOWN,
|
|
153
|
+
licence_evidence=evidence,
|
|
154
|
+
)
|
|
155
|
+
)
|
|
156
|
+
return packages
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class GoProjectMetadataFetcher(ProjectMetadataFetcher):
|
|
160
|
+
"""Retrieve Go dependency licences for the shared SPDX and compliance report."""
|
|
161
|
+
|
|
162
|
+
def __init__(self) -> None:
|
|
163
|
+
"""Initialise with the configured project name."""
|
|
164
|
+
super().__init__(str(configuration.get_value(ConfigurationVariable.PROJECT_NAME)))
|
|
165
|
+
|
|
166
|
+
def fetch_project_metadata(self) -> ProjectMetadata:
|
|
167
|
+
"""Collect module dependencies using go-licenses without replacing shared policy checks."""
|
|
168
|
+
module_directories = _go_licence_module_directories()
|
|
169
|
+
env = os.environ.copy()
|
|
170
|
+
env[ENVVAR_GO_MOD] = GO_MOD_ON_VALUE
|
|
171
|
+
executable = _ensure_go_tool_installed(
|
|
172
|
+
tool_name="go-licenses",
|
|
173
|
+
version_command=["go-licenses", "report", "--help"],
|
|
174
|
+
install_command=_install_go_licenses_command_list(),
|
|
175
|
+
env=env,
|
|
176
|
+
)
|
|
177
|
+
project = ProjectMetadata(self._package_name)
|
|
178
|
+
project.project_metadata = PackageMetadata.from_fields(
|
|
179
|
+
name=self._package_name,
|
|
180
|
+
licence=str(configuration.get_value(ConfigurationVariable.FILE_LICENCE_IDENTIFIER)),
|
|
181
|
+
licence_source=LicenceSource.CONFIGURATION,
|
|
182
|
+
)
|
|
183
|
+
dependencies: Dict[str, PackageMetadata] = {}
|
|
184
|
+
modules = [(module_dir, _go_module_name(module_dir, env)) for module_dir in module_directories]
|
|
185
|
+
with TemporaryDirectory() as temporary_dir:
|
|
186
|
+
template_path = Path(temporary_dir) / "go-licenses.tpl"
|
|
187
|
+
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
|
|
211
|
+
for dependency in dependencies.values():
|
|
212
|
+
project.add_dependency_metadata(dependency)
|
|
213
|
+
return project
|
|
214
|
+
|
|
215
|
+
|
|
84
216
|
def _ensure_go_tool_installed(
|
|
85
217
|
tool_name: str,
|
|
86
218
|
version_command: List[str],
|
|
87
219
|
install_command: List[str],
|
|
88
220
|
env: MutableMapping[str, str],
|
|
89
|
-
) ->
|
|
90
|
-
"""
|
|
221
|
+
) -> str:
|
|
222
|
+
"""Return a usable Go tool on PATH or install it into the Go binary directory."""
|
|
91
223
|
tool_path = shutil.which(tool_name)
|
|
92
224
|
if tool_path:
|
|
93
225
|
try:
|
|
94
226
|
check_output(version_command, env=env)
|
|
95
227
|
logger.info("Using %s from PATH: %s", tool_name, tool_path)
|
|
96
|
-
return
|
|
228
|
+
return tool_path
|
|
97
229
|
except Exception as exception:
|
|
98
230
|
logger.warning("Could not use %s from PATH: %s", tool_name, exception)
|
|
99
231
|
|
|
100
232
|
logger.info("Installing %s with go install.", tool_name)
|
|
101
233
|
check_call(install_command, env=env)
|
|
234
|
+
return _installed_go_tool_path(tool_name, env)
|
|
102
235
|
|
|
103
236
|
|
|
104
237
|
def _call_doc2go(output_directory: Path, module: str) -> None:
|
|
@@ -212,15 +345,9 @@ def _determine_go_module_tag(version: str) -> List[str]:
|
|
|
212
345
|
https://go.dev/ref/mod#workspaces, and
|
|
213
346
|
https://github.com/golang/go/wiki/Modules/a549b3e4b7ad6be6e7d11c37ef247bb2279c8146#faqs--multi-module-repositories.
|
|
214
347
|
"""
|
|
215
|
-
module_directories = [SRC_DIR]
|
|
216
|
-
go_work_module_directories = _determine_go_work_module_directories()
|
|
217
|
-
if go_work_module_directories:
|
|
218
|
-
module_directories.extend(go_work_module_directories)
|
|
219
|
-
else:
|
|
220
|
-
module_directories.extend(_determine_go_subproject_directories())
|
|
221
|
-
|
|
222
348
|
tags = [
|
|
223
|
-
_determine_go_module_tag_for_directory(module_directory, version)
|
|
349
|
+
_determine_go_module_tag_for_directory(module_directory, version)
|
|
350
|
+
for module_directory in _candidate_go_module_directories()
|
|
224
351
|
]
|
|
225
352
|
return list(dict.fromkeys([tag for tag in tags if tag]))
|
|
226
353
|
|
|
@@ -263,7 +390,7 @@ class Go(BaseLanguage):
|
|
|
263
390
|
|
|
264
391
|
def can_get_project_metadata(self) -> bool:
|
|
265
392
|
"""States whether project metadata can be retrieved."""
|
|
266
|
-
return
|
|
393
|
+
return True
|
|
267
394
|
|
|
268
395
|
def get_secret_registry_exclude_files(self) -> List[str]:
|
|
269
396
|
"""Gets additional detect-secrets exclude patterns for Go projects."""
|
|
@@ -274,10 +401,9 @@ class Go(BaseLanguage):
|
|
|
274
401
|
(r"^\.github[\\/]workflows[\\/].*"),
|
|
275
402
|
]
|
|
276
403
|
|
|
277
|
-
def get_current_spdx_project(self) -> Optional[
|
|
404
|
+
def get_current_spdx_project(self) -> Optional[SpdxProject]:
|
|
278
405
|
"""Gets current SPDX description."""
|
|
279
|
-
|
|
280
|
-
return None
|
|
406
|
+
return SpdxProject(GoProjectMetadataFetcher())
|
|
281
407
|
|
|
282
408
|
def should_clean_before_packaging(self) -> bool:
|
|
283
409
|
"""States whether the repository must be cleaned before packaging happens."""
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from typing import TYPE_CHECKING, List, Optional
|
|
9
|
+
from urllib.parse import urlsplit
|
|
9
10
|
|
|
10
11
|
from continuous_delivery_scripts.spdx_report.spdx_dependency import (
|
|
11
12
|
DependencySpdxDocumentRef,
|
|
@@ -23,7 +24,8 @@ from continuous_delivery_scripts.utils.configuration import (
|
|
|
23
24
|
ConfigurationVariable,
|
|
24
25
|
)
|
|
25
26
|
from continuous_delivery_scripts.utils.hash_helpers import generate_uuid_based_on_str
|
|
26
|
-
from continuous_delivery_scripts.utils.
|
|
27
|
+
from continuous_delivery_scripts.utils.package_helpers import PackageMetadata
|
|
28
|
+
from continuous_delivery_scripts.utils.third_party_licences import LICENSE_REF_PROPRIETARY
|
|
27
29
|
|
|
28
30
|
if TYPE_CHECKING:
|
|
29
31
|
from spdx.document import Document
|
|
@@ -230,7 +232,7 @@ class SpdxDocument:
|
|
|
230
232
|
the corresponding document
|
|
231
233
|
"""
|
|
232
234
|
from spdx.creationinfo import Person, Organization, Tool
|
|
233
|
-
from spdx.document import Document, License
|
|
235
|
+
from spdx.document import Document, ExtractedLicense, License
|
|
234
236
|
from spdx.review import Review
|
|
235
237
|
from spdx.version import Version
|
|
236
238
|
|
|
@@ -240,7 +242,7 @@ class SpdxDocument:
|
|
|
240
242
|
doc.namespace = determine_spdx_value(self.document_namespace)
|
|
241
243
|
doc.spdx_id = "SPDXRef-DOCUMENT"
|
|
242
244
|
doc.comment = determine_spdx_value(
|
|
243
|
-
"This document was created automatically using available
|
|
245
|
+
"This document was created automatically using available project and dependency information."
|
|
244
246
|
)
|
|
245
247
|
doc.data_license = License.from_identifier("CC0-1.0")
|
|
246
248
|
doc.creation_info.add_creator(Person(self.author, self.author_email))
|
|
@@ -262,7 +264,35 @@ class SpdxDocument:
|
|
|
262
264
|
# be described in a file and hence, all dependencies are described
|
|
263
265
|
# in separate files. Find out what to do with dependencies when new
|
|
264
266
|
# tools are released as it is not entirely clear in the specification
|
|
265
|
-
|
|
267
|
+
spdx_package = self.generate_spdx_package()
|
|
268
|
+
doc.package = spdx_package.generate_spdx_package()
|
|
269
|
+
if LICENSE_REF_PROPRIETARY in spdx_package.main_licence or LICENSE_REF_PROPRIETARY in spdx_package.licence:
|
|
270
|
+
proprietary_licence = ExtractedLicense(LICENSE_REF_PROPRIETARY)
|
|
271
|
+
proprietary_licence.full_name = "Proprietary licence"
|
|
272
|
+
proprietary_licence.text = "Proprietary licence terms are not included in this SPDX document."
|
|
273
|
+
proprietary_licence.comment = (
|
|
274
|
+
"This is a locally defined licence reference, not an SPDX License List identifier. "
|
|
275
|
+
"See https://spdx.github.io/spdx-spec/v2.3/other-licensing-information-detected/ "
|
|
276
|
+
"for the LicenseRef format; consult the rights holder for the licence terms."
|
|
277
|
+
)
|
|
278
|
+
if LICENSE_REF_PROPRIETARY in spdx_package.main_licence:
|
|
279
|
+
licence_urls = {
|
|
280
|
+
evidence.get("path", "")
|
|
281
|
+
for evidence in self._package_metadata.licence_evidence
|
|
282
|
+
if evidence.get("kind") == "licence"
|
|
283
|
+
}
|
|
284
|
+
for url in sorted(licence_urls):
|
|
285
|
+
try:
|
|
286
|
+
parsed_url = urlsplit(url)
|
|
287
|
+
except ValueError:
|
|
288
|
+
continue
|
|
289
|
+
if (
|
|
290
|
+
parsed_url.scheme in ("http", "https")
|
|
291
|
+
and parsed_url.netloc
|
|
292
|
+
and not any(c.isspace() for c in url)
|
|
293
|
+
):
|
|
294
|
+
proprietary_licence.add_xref(url)
|
|
295
|
+
doc.add_extr_lic(proprietary_licence)
|
|
266
296
|
|
|
267
297
|
for external_reference in self.external_refs:
|
|
268
298
|
doc.add_ext_document_reference(external_reference.generate_external_reference())
|
|
@@ -67,7 +67,7 @@ COPYRIGHT_PATTERN = r"Copyright.*$"
|
|
|
67
67
|
COPYRIGHT_REGEX_PATTERN = re.compile(COPYRIGHT_PATTERN, flags=re.MULTILINE | re.IGNORECASE)
|
|
68
68
|
# Specification of the identifier based on https://spdx.org/spdx-specification-21-web-version#h.twlc0ztnng3b
|
|
69
69
|
# and https://spdx.org/ids-how
|
|
70
|
-
SPDX_LICENCE_IDENTIFIER_PATTERN = r"SPDX-License-Identifier: ([\.\w+\-\(\)\
|
|
70
|
+
SPDX_LICENCE_IDENTIFIER_PATTERN = r"SPDX-License-Identifier: ([\.\w+\-\(\)\t ]+)[\*]?$"
|
|
71
71
|
SPDX_IDENTIFIER_REGEX_PATTERN = re.compile(SPDX_LICENCE_IDENTIFIER_PATTERN, re.MULTILINE)
|
|
72
72
|
THIRD_PARTY_CONFIG_NAMESPACE = "spdx"
|
|
73
73
|
PATHS_TO_EXCLUDE = [
|
|
@@ -77,6 +77,7 @@ PATHS_TO_EXCLUDE = [
|
|
|
77
77
|
"*.rdf",
|
|
78
78
|
"*.pyc",
|
|
79
79
|
"*.bin",
|
|
80
|
+
"*.exe",
|
|
80
81
|
"*.tar",
|
|
81
82
|
"*.zip",
|
|
82
83
|
"**/__pycache__/**",
|
|
@@ -6,18 +6,21 @@
|
|
|
6
6
|
|
|
7
7
|
from dataclasses import dataclass
|
|
8
8
|
from pathlib import Path
|
|
9
|
+
import re
|
|
9
10
|
from typing import TYPE_CHECKING, List, Optional
|
|
10
11
|
|
|
11
12
|
from license_expression import ExpressionError
|
|
12
13
|
|
|
13
14
|
from continuous_delivery_scripts.spdx_report.spdx_file import SpdxFile
|
|
15
|
+
from continuous_delivery_scripts.utils.hash_helpers import generate_uuid_based_on_str
|
|
14
16
|
from continuous_delivery_scripts.spdx_report.spdx_helpers import (
|
|
15
17
|
determine_spdx_value,
|
|
16
18
|
list_project_files_for_licensing,
|
|
17
19
|
)
|
|
18
20
|
from continuous_delivery_scripts.utils.definitions import UNKNOWN
|
|
19
|
-
from continuous_delivery_scripts.utils.
|
|
21
|
+
from continuous_delivery_scripts.utils.package_helpers import PackageMetadata
|
|
20
22
|
from continuous_delivery_scripts.utils.third_party_licences import (
|
|
23
|
+
LICENSE_REF_PROPRIETARY,
|
|
21
24
|
UNKNOWN_LICENCE,
|
|
22
25
|
cleanse_licence_expression,
|
|
23
26
|
is_licence_accepted,
|
|
@@ -30,7 +33,7 @@ if TYPE_CHECKING:
|
|
|
30
33
|
|
|
31
34
|
@dataclass(frozen=True, order=True)
|
|
32
35
|
class PackageInfo:
|
|
33
|
-
"""Definition of a
|
|
36
|
+
"""Definition of a project or dependency package.
|
|
34
37
|
|
|
35
38
|
Attributes:
|
|
36
39
|
metadata: metadata about an installed package.
|
|
@@ -90,7 +93,9 @@ class SpdxPackage:
|
|
|
90
93
|
Returns:
|
|
91
94
|
An ID
|
|
92
95
|
"""
|
|
93
|
-
|
|
96
|
+
if not self._is_dependency:
|
|
97
|
+
return self._package_info.uuid
|
|
98
|
+
return self.name if re.fullmatch(r"[A-Za-z0-9.-]+", self.name) else str(generate_uuid_based_on_str(self.name))
|
|
94
99
|
|
|
95
100
|
@property
|
|
96
101
|
def is_dependency(self) -> bool:
|
|
@@ -137,7 +142,14 @@ class SpdxPackage:
|
|
|
137
142
|
@property
|
|
138
143
|
def is_main_licence_accepted(self) -> bool:
|
|
139
144
|
"""States whether the main licence of the package is part of the accepted licence list."""
|
|
140
|
-
return bool(is_licence_accepted(self.main_licence))
|
|
145
|
+
return bool(is_licence_accepted(self.main_licence, self._project_licence_refs))
|
|
146
|
+
|
|
147
|
+
@property
|
|
148
|
+
def _project_licence_refs(self) -> List[str]:
|
|
149
|
+
"""Allow the project's own proprietary licence without permitting it for dependencies."""
|
|
150
|
+
if not self._is_dependency and LICENSE_REF_PROPRIETARY in self.main_licence:
|
|
151
|
+
return [LICENSE_REF_PROPRIETARY]
|
|
152
|
+
return []
|
|
141
153
|
|
|
142
154
|
@property
|
|
143
155
|
def licence(self) -> str:
|
|
@@ -158,7 +170,7 @@ class SpdxPackage:
|
|
|
158
170
|
@property
|
|
159
171
|
def is_licence_accepted(self) -> bool:
|
|
160
172
|
"""States whether the actual package's licence of the package is part of the accepted licence list."""
|
|
161
|
-
return bool(is_licence_accepted(self.licence))
|
|
173
|
+
return bool(is_licence_accepted(self.licence, self._project_licence_refs))
|
|
162
174
|
|
|
163
175
|
@property
|
|
164
176
|
def author(self) -> str:
|