continuous-delivery-scripts 3.5.1__tar.gz → 4.0.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.
Files changed (71) hide show
  1. {continuous_delivery_scripts-3.5.1/continuous_delivery_scripts.egg-info → continuous_delivery_scripts-4.0.0}/PKG-INFO +7 -6
  2. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/_version.py +5 -5
  3. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/assert_news.py +13 -5
  4. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/news_file.py +4 -1
  5. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/third_party_licences.py +137 -11
  6. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0/continuous_delivery_scripts.egg-info}/PKG-INFO +7 -6
  7. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts.egg-info/requires.txt +2 -2
  8. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/setup.py +6 -5
  9. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/LICENSE +0 -0
  10. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/MANIFEST.in +0 -0
  11. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/README.md +0 -0
  12. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/__init__.py +0 -0
  13. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/create_news_file.py +0 -0
  14. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/detect_secrets.py +0 -0
  15. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/generate_docs.py +0 -0
  16. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/generate_news.py +0 -0
  17. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/get_config.py +0 -0
  18. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/get_version.py +0 -0
  19. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/language_specifics.py +0 -0
  20. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/license_files.py +0 -0
  21. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/plugins/BASIC.MD +0 -0
  22. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/plugins/CI.MD +0 -0
  23. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/plugins/GITHUB_ACTIONS.MD +0 -0
  24. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/plugins/GOLAND.MD +0 -0
  25. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/plugins/NOOP.MD +0 -0
  26. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/plugins/PYTHON.MD +0 -0
  27. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/plugins/__init__.py +0 -0
  28. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/plugins/basic.py +0 -0
  29. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/plugins/ci.py +0 -0
  30. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/plugins/docker.py +0 -0
  31. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/plugins/github_actions.py +0 -0
  32. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/plugins/golang.py +0 -0
  33. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/plugins/noop.py +0 -0
  34. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/plugins/python.py +0 -0
  35. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/report_third_party_ip.py +0 -0
  36. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/spdx_report/__init__.py +0 -0
  37. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/spdx_report/spdx_dependency.py +0 -0
  38. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/spdx_report/spdx_document.py +0 -0
  39. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/spdx_report/spdx_file.py +0 -0
  40. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/spdx_report/spdx_helpers.py +0 -0
  41. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/spdx_report/spdx_package.py +0 -0
  42. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/spdx_report/spdx_project.py +0 -0
  43. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/spdx_report/spdx_summary.py +0 -0
  44. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/spdx_report/templates/third_party_IP_report.csv.jinja2 +0 -0
  45. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/spdx_report/templates/third_party_IP_report.html.jinja2 +0 -0
  46. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/spdx_report/templates/third_party_IP_report.txt.jinja2 +0 -0
  47. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/tag_and_release.py +0 -0
  48. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/update_secrets_registry.py +0 -0
  49. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/__init__.py +0 -0
  50. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/aws_helpers.py +0 -0
  51. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/configuration.py +0 -0
  52. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/definitions.py +0 -0
  53. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/filesystem_helpers.py +0 -0
  54. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/git_helpers.py +0 -0
  55. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/hash_helpers.py +0 -0
  56. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/language_specifics_base.py +0 -0
  57. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/logging.py +0 -0
  58. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/noop/__init__.py +0 -0
  59. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/noop/package_helpers.py +0 -0
  60. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/package_helpers.py +0 -0
  61. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/python/__init__.py +0 -0
  62. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/python/package_helpers.py +0 -0
  63. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/python/python_helpers.py +0 -0
  64. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/string_helpers.py +0 -0
  65. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts/utils/versioning.py +0 -0
  66. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts.egg-info/SOURCES.txt +0 -0
  67. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts.egg-info/dependency_links.txt +0 -0
  68. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts.egg-info/entry_points.txt +0 -0
  69. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/continuous_delivery_scripts.egg-info/top_level.txt +0 -0
  70. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/pyproject.toml +0 -0
  71. {continuous_delivery_scripts-3.5.1 → continuous_delivery_scripts-4.0.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: continuous-delivery-scripts
3
- Version: 3.5.1
3
+ Version: 4.0.0
4
4
  Summary: Continuous Delivery scripts to increase automation
5
5
  Home-page: https://github.com/ARMmbed/continuous-delivery-scripts
6
6
  Author: CMSIS team
@@ -11,19 +11,20 @@ Classifier: Intended Audience :: Developers
11
11
  Classifier: License :: OSI Approved :: Apache Software License
12
12
  Classifier: Programming Language :: Python
13
13
  Classifier: Programming Language :: Python :: 3 :: Only
14
- Classifier: Programming Language :: Python :: 3.8
15
- Classifier: Programming Language :: Python :: 3.9
16
14
  Classifier: Programming Language :: Python :: 3.10
17
15
  Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
18
19
  Classifier: Topic :: Software Development :: Build Tools
19
- Requires-Python: >=3.8,<4
20
+ Requires-Python: >=3.10,<4
20
21
  Description-Content-Type: text/markdown
21
22
  License-File: LICENSE
22
23
  Requires-Dist: setuptools
23
24
  Requires-Dist: gitpython
24
25
  Requires-Dist: towncrier==22.12.0
25
26
  Requires-Dist: pyautoversion~=1.2.0
26
- Requires-Dist: pdoc3==0.10.0
27
+ Requires-Dist: pdoc3==0.11.6
27
28
  Requires-Dist: toml
28
29
  Requires-Dist: semver~=2.13.0
29
30
  Requires-Dist: python-dotenv
@@ -32,7 +33,7 @@ Requires-Dist: boto3
32
33
  Requires-Dist: detect-secrets[gibberish]==1.5.0
33
34
  Requires-Dist: packaging
34
35
  Requires-Dist: licenseheaders<0.8.9
35
- Requires-Dist: spdx-tools==0.6.1
36
+ Requires-Dist: spdx-tools==0.8.5
36
37
  Requires-Dist: license-expression
37
38
  Requires-Dist: wcmatch
38
39
  Requires-Dist: jellyfish
@@ -11,8 +11,8 @@ References
11
11
  This file is autogenerated, do not modify by hand.
12
12
  """
13
13
 
14
- __version__ = "3.5.1"
15
- COMMIT = "5f0dc45967d1e56a6e03168c0c9b54cc7aaa98c7"
16
- MAJOR = 3
17
- MINOR = 5
18
- PATCH = 1
14
+ __version__ = "4.0.0"
15
+ COMMIT = "88537b61214eccbd719674df43ddf40d985ecd92"
16
+ MAJOR = 4
17
+ MINOR = 0
18
+ PATCH = 0
@@ -21,6 +21,10 @@ logger = logging.getLogger(__name__)
21
21
  NEWS_FILE_NAME_REGEX = r"^[0-9]+.(misc|doc|removal|bugfix|feature|major)$"
22
22
 
23
23
 
24
+ class MissingNewsFileError(FileNotFoundError):
25
+ """The branch contains no added news file."""
26
+
27
+
24
28
  class NewsFileValidator:
25
29
  """Verifies individual news files."""
26
30
 
@@ -77,10 +81,11 @@ def find_news_files(git: GitWrapper, root_dir: str, news_dir: str) -> List[str]:
77
81
  # If no news files were added, then we check for addition on the branch.
78
82
  # Relies on the fact GitWrapper returns paths that are always relative
79
83
  # to the project root.
80
- added_news_files = [file_path for file_path in files_changed if file_path.startswith(news_dir)]
84
+ news_prefix = news_dir.replace("\\", "/").rstrip("/") + "/"
85
+ added_news_files = [file_path for file_path in files_changed if file_path.startswith(news_prefix)]
81
86
  if len(added_news_files) == 0:
82
87
  files_changed = git.list_files_added_on_current_branch()
83
- added_news_files = [file_path for file_path in files_changed if file_path.startswith(news_dir)]
88
+ added_news_files = [file_path for file_path in files_changed if file_path.startswith(news_prefix)]
84
89
  return [str(pathlib.Path(root_dir, file_path)) for file_path in added_news_files]
85
90
 
86
91
 
@@ -94,7 +99,7 @@ def validate_news_files(git: GitWrapper, root_dir: str, news_dir: str) -> None:
94
99
  """
95
100
  added_news_files = find_news_files(git=git, news_dir=news_dir, root_dir=root_dir)
96
101
  if not added_news_files:
97
- raise FileNotFoundError(f"PR must contain a news file in {news_dir}. See README.md.")
102
+ raise MissingNewsFileError(f"PR must contain a news file in {news_dir}. See README.md.")
98
103
  for absolute_file_path in added_news_files:
99
104
  validate_news_file(absolute_file_path)
100
105
 
@@ -164,8 +169,8 @@ def main() -> None:
164
169
  absolute_news_dir = configuration.get_value(ConfigurationVariable.NEWS_DIR)
165
170
  news_dir = str(pathlib.Path(absolute_news_dir).relative_to(root_dir))
166
171
  try:
167
- validate_news_files(git=git, news_dir=news_dir, root_dir=root_dir)
168
- except Exception as e:
172
+ validate_news_files(git=git, news_dir=news_dir, root_dir=str(git.root))
173
+ except MissingNewsFileError as e:
169
174
  log_exception(logger, e)
170
175
  try:
171
176
  news_file = generate_news_file(git, git.get_corresponding_path(pathlib.Path(news_dir)))
@@ -173,6 +178,9 @@ def main() -> None:
173
178
  except Exception as e2:
174
179
  log_exception(logger, e2)
175
180
  sys.exit(1)
181
+ except Exception as e:
182
+ log_exception(logger, e)
183
+ sys.exit(1)
176
184
 
177
185
 
178
186
  if __name__ == "__main__":
@@ -7,6 +7,7 @@
7
7
  import enum
8
8
  import pathlib
9
9
  import logging
10
+ import time
10
11
  from datetime import datetime
11
12
  from typing import Any, Optional
12
13
 
@@ -57,4 +58,6 @@ def _write_file(file_path: pathlib.Path, text: str) -> None:
57
58
 
58
59
  def determine_basic_new_news_file_name() -> str:
59
60
  """Returns a new news file name."""
60
- return datetime.now().strftime("%Y%m%d%H%M%S")
61
+ now_ns = time.time_ns()
62
+ seconds, nanoseconds = divmod(now_ns, 1_000_000_000)
63
+ return f"{datetime.fromtimestamp(seconds):%Y%m%d%H%M%S}{nanoseconds:09d}"
@@ -9,9 +9,9 @@ import re
9
9
  import json
10
10
  from dataclasses import dataclass
11
11
  from importlib.util import find_spec
12
- from license_expression import Licensing, LicenseExpression, OR
12
+ from license_expression import Licensing, LicenseExpression, OR, get_spdx_licensing
13
13
  from pathlib import Path
14
- from typing import Iterable, cast, Optional, Iterator, List, Pattern, Any
14
+ from typing import Dict, Iterable, cast, Optional, Iterator, List, Pattern, Any, Tuple
15
15
 
16
16
  from continuous_delivery_scripts.utils.configuration import (
17
17
  ConfigurationVariable,
@@ -57,10 +57,101 @@ LICENCE_NON_ACCEPTED_CHARACTERS = r"[^\w\s\.\:\-()]"
57
57
  def _get_spdx_licenses_path() -> Path:
58
58
  spec = find_spec("spdx")
59
59
  if not spec or not spec.origin:
60
- raise ModuleNotFoundError("No module named 'spdx'")
60
+ raise FileNotFoundError("Could not find SPDX licenses.json")
61
61
  return Path(spec.origin).resolve().parent.joinpath("licenses.json")
62
62
 
63
63
 
64
+ FALLBACK_LICENCE_DATA = {
65
+ "0BSD": {
66
+ "reference_number": "319",
67
+ "name": "BSD Zero Clause License",
68
+ },
69
+ "Apache-2.0": {
70
+ "reference_number": "26",
71
+ "name": "Apache License 2.0",
72
+ },
73
+ "GPL-3.0-only": {
74
+ "name": "GNU General Public License v3.0 only",
75
+ },
76
+ "MPL-2.0": {
77
+ "name": "Mozilla Public License 2.0",
78
+ },
79
+ "MIT": {
80
+ "name": "MIT License",
81
+ },
82
+ "PSF-2.0": {
83
+ "name": "Python Software Foundation License 2.0",
84
+ },
85
+ "Python-2.0": {
86
+ "name": "Python License 2.0",
87
+ },
88
+ }
89
+
90
+
91
+ FALLBACK_LICENCE_ALIASES = {
92
+ "0BSD": ["BSD", "BSD License", "BSD Zero Clause License"],
93
+ "Apache-2.0": [
94
+ "Apache",
95
+ "Apache 2",
96
+ "Apache 2.0",
97
+ "Apache License 2",
98
+ "Apache License 2.0",
99
+ "Apache License Version 2",
100
+ "Apache License Version 2.0",
101
+ "Apache License, Version 2",
102
+ "Apache License, Version 2.0",
103
+ "Apache Licence 2",
104
+ "Apache Licence 2.0",
105
+ "Apache Licence Version 2",
106
+ "Apache Licence Version 2.0",
107
+ "Apache Licence, Version 2",
108
+ "Apache Licence, Version 2.0",
109
+ "Apache Software License",
110
+ ],
111
+ "GPL-3.0-only": ["GPL 3", "GPL 3.0", "GPL-3.0", "GPL-3", "GNU GPL 3"],
112
+ "MIT": ["MIT License"],
113
+ "PSF-2.0": ["Python Software Foundation License 2.0"],
114
+ "Python-2.0": ["Python Software Foundation License"],
115
+ }
116
+
117
+
118
+ def _build_fallback_licence(identifier: str, is_deprecated: bool = False) -> Licence:
119
+ metadata = FALLBACK_LICENCE_DATA.get(identifier, {})
120
+ return Licence(
121
+ reference_number=str(metadata.get("reference_number", "")),
122
+ identifier=identifier,
123
+ name=str(metadata.get("name", identifier)),
124
+ is_deprecated=is_deprecated,
125
+ is_osi_approved=bool(metadata.get("is_osi_approved", True)),
126
+ url=f"http://spdx.org/licenses/{identifier}.json",
127
+ reference=f"./{identifier}.html",
128
+ )
129
+
130
+
131
+ def _iter_fallback_licences() -> Iterable[Tuple[Licence, Iterable[str]]]:
132
+ spdx_licensing = get_spdx_licensing()
133
+ seen = set()
134
+ for symbol in spdx_licensing.known_symbols.values():
135
+ identifier = getattr(symbol, "key", None)
136
+ if not identifier or identifier in seen:
137
+ continue
138
+ if identifier.startswith("LicenseRef-") or getattr(symbol, "is_exception", False):
139
+ continue
140
+ seen.add(identifier)
141
+ aliases = list(getattr(symbol, "aliases", ())) + FALLBACK_LICENCE_ALIASES.get(identifier, [])
142
+ yield _build_fallback_licence(identifier, is_deprecated=bool(getattr(symbol, "is_deprecated", False))), aliases
143
+
144
+
145
+ def _normalise_licence_text(text: str) -> str:
146
+ normalised_text = text.strip().lower()
147
+ normalised_text = re.sub(r"osi\s?approved[:]*", "", normalised_text)
148
+ normalised_text = re.sub(r"licen[cs]e", " ", normalised_text)
149
+ normalised_text = re.sub(r"version", " ", normalised_text)
150
+ normalised_text = re.sub(r"[^\w\s]", " ", normalised_text)
151
+ normalised_text = re.sub(r"\s+", " ", normalised_text)
152
+ return normalised_text.strip()
153
+
154
+
64
155
  def _parse_licence_expression(licensing: Licensing, licence_expression: str) -> LicenseExpression:
65
156
  # Removing any unwanted characters so that the expression follows the laws:
66
157
  # > the valid characters are: letters and numbers, underscore, dot, colon or hyphen signs and spaces
@@ -92,11 +183,17 @@ def iter_licenses(licence_info: dict) -> Iterable[Licence]:
92
183
  def _handle_special_licence_entries(cleansed_descriptor: str) -> str:
93
184
  if cleansed_descriptor in ["Python Software Foundation License"]:
94
185
  return "Python"
186
+ if re.fullmatch(r"Python(?:[\w\s\-\.]*)", cleansed_descriptor, re.IGNORECASE):
187
+ return "Python-2.0"
95
188
  if cleansed_descriptor in ["Apache Software License", "Apache", "apache"]:
96
189
  return "Apache-2.0"
97
190
  if cleansed_descriptor in ["LGPL", "UNKNOWN", "Dual License"]:
98
191
  # It is not possible to find which is the actual licence to consider.
99
192
  return UNKNOWN_LICENCE.identifier
193
+ if re.fullmatch(r"Apache(?:\s+(?:Software\s+)?)?(?:Licen[cs]e)?(?:,?\s+Version)?\s*2(?:\.0)?", cleansed_descriptor):
194
+ return "Apache-2.0"
195
+ if re.fullmatch(r"GPL\s*3(?:\.0)?", cleansed_descriptor, re.IGNORECASE):
196
+ return "GPL-3.0-only"
100
197
  return cleansed_descriptor
101
198
 
102
199
 
@@ -122,18 +219,32 @@ class OpenSourceLicences:
122
219
  self._licence_store: Optional[dict] = None
123
220
  self._licence_list: Optional[list] = None
124
221
 
222
+ def _store_licence(self, licence: Licence, aliases: Iterable[str] = ()) -> None:
223
+ if not self._licence_store or self._licence_list is None:
224
+ return
225
+ entries = [licence.identifier, licence.name, *aliases]
226
+ for entry in entries:
227
+ if not entry:
228
+ continue
229
+ self._licence_store[entry] = licence
230
+ self._licence_list.append(entry)
231
+
125
232
  def load(self) -> None:
126
233
  """Loads licence data from internal Json file."""
127
234
  if self._licence_list and self._licence_store:
128
235
  return
129
236
  self._licence_store = {UNKNOWN_LICENCE.identifier: UNKNOWN_LICENCE}
130
237
  self._licence_list = [UNKNOWN_LICENCE.identifier]
131
- with open(_get_spdx_licenses_path(), "r", encoding="utf8") as f:
132
- for licence in iter_licenses(json.load(f)):
133
- self._licence_store[licence.identifier] = licence
134
- self._licence_list.append(licence.identifier)
135
- self._licence_store[licence.name] = licence
136
- self._licence_list.append(licence.name)
238
+ try:
239
+ with open(_get_spdx_licenses_path(), "r", encoding="utf8") as f:
240
+ for licence in iter_licenses(json.load(f)):
241
+ self._store_licence(licence)
242
+ return
243
+ except (FileNotFoundError, ModuleNotFoundError):
244
+ pass
245
+
246
+ for licence, aliases in _iter_fallback_licences():
247
+ self._store_licence(licence, aliases)
137
248
 
138
249
  def get_licences_from_pattern(self, licence_descriptor_pattern: Pattern) -> Optional[List[Licence]]:
139
250
  """Determines all the licences following a certain pattern."""
@@ -153,8 +264,23 @@ class OpenSourceLicences:
153
264
  if not self._licence_store or not self._licence_list or not licence_descriptor:
154
265
  return None
155
266
  cleansed_descriptor = cleanse_licence_descriptor(licence_descriptor)
156
- likelihood, licence = determine_similar_string_from_list(cleansed_descriptor, self._licence_list)
157
- return self._licence_store.get(licence) if likelihood > LICENCE_LIKELIHOOD_THRESHOLD else None
267
+ exact_match = self._licence_store.get(cleansed_descriptor)
268
+ if exact_match:
269
+ return cast(Licence, exact_match)
270
+
271
+ normalised_map: Dict[str, Licence] = {}
272
+ for name in self._licence_list:
273
+ licence = cast(Licence, self._licence_store.get(name))
274
+ if licence:
275
+ normalised_map[_normalise_licence_text(name)] = licence
276
+
277
+ normalised_descriptor = _normalise_licence_text(cleansed_descriptor)
278
+ normalised_exact_match = normalised_map.get(normalised_descriptor)
279
+ if normalised_exact_match:
280
+ return normalised_exact_match
281
+
282
+ likelihood, matched_key = determine_similar_string_from_list(normalised_descriptor, normalised_map.keys())
283
+ return normalised_map.get(matched_key) if likelihood > LICENCE_LIKELIHOOD_THRESHOLD else None
158
284
 
159
285
 
160
286
  OPENSOURCE_LICENCES = OpenSourceLicences()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: continuous-delivery-scripts
3
- Version: 3.5.1
3
+ Version: 4.0.0
4
4
  Summary: Continuous Delivery scripts to increase automation
5
5
  Home-page: https://github.com/ARMmbed/continuous-delivery-scripts
6
6
  Author: CMSIS team
@@ -11,19 +11,20 @@ Classifier: Intended Audience :: Developers
11
11
  Classifier: License :: OSI Approved :: Apache Software License
12
12
  Classifier: Programming Language :: Python
13
13
  Classifier: Programming Language :: Python :: 3 :: Only
14
- Classifier: Programming Language :: Python :: 3.8
15
- Classifier: Programming Language :: Python :: 3.9
16
14
  Classifier: Programming Language :: Python :: 3.10
17
15
  Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
18
19
  Classifier: Topic :: Software Development :: Build Tools
19
- Requires-Python: >=3.8,<4
20
+ Requires-Python: >=3.10,<4
20
21
  Description-Content-Type: text/markdown
21
22
  License-File: LICENSE
22
23
  Requires-Dist: setuptools
23
24
  Requires-Dist: gitpython
24
25
  Requires-Dist: towncrier==22.12.0
25
26
  Requires-Dist: pyautoversion~=1.2.0
26
- Requires-Dist: pdoc3==0.10.0
27
+ Requires-Dist: pdoc3==0.11.6
27
28
  Requires-Dist: toml
28
29
  Requires-Dist: semver~=2.13.0
29
30
  Requires-Dist: python-dotenv
@@ -32,7 +33,7 @@ Requires-Dist: boto3
32
33
  Requires-Dist: detect-secrets[gibberish]==1.5.0
33
34
  Requires-Dist: packaging
34
35
  Requires-Dist: licenseheaders<0.8.9
35
- Requires-Dist: spdx-tools==0.6.1
36
+ Requires-Dist: spdx-tools==0.8.5
36
37
  Requires-Dist: license-expression
37
38
  Requires-Dist: wcmatch
38
39
  Requires-Dist: jellyfish
@@ -2,7 +2,7 @@ setuptools
2
2
  gitpython
3
3
  towncrier==22.12.0
4
4
  pyautoversion~=1.2.0
5
- pdoc3==0.10.0
5
+ pdoc3==0.11.6
6
6
  toml
7
7
  semver~=2.13.0
8
8
  python-dotenv
@@ -11,7 +11,7 @@ boto3
11
11
  detect-secrets[gibberish]==1.5.0
12
12
  packaging
13
13
  licenseheaders<0.8.9
14
- spdx-tools==0.6.1
14
+ spdx-tools==0.8.5
15
15
  license-expression
16
16
  wcmatch
17
17
  jellyfish
@@ -30,10 +30,11 @@ setup(
30
30
  "License :: OSI Approved :: Apache Software License",
31
31
  "Programming Language :: Python",
32
32
  "Programming Language :: Python :: 3 :: Only",
33
- "Programming Language :: Python :: 3.8",
34
- "Programming Language :: Python :: 3.9",
35
33
  "Programming Language :: Python :: 3.10",
36
34
  "Programming Language :: Python :: 3.11",
35
+ "Programming Language :: Python :: 3.12",
36
+ "Programming Language :: Python :: 3.13",
37
+ "Programming Language :: Python :: 3.14",
37
38
  "Topic :: Software Development :: Build Tools",
38
39
  ],
39
40
  description="Continuous Delivery scripts to increase automation",
@@ -61,7 +62,7 @@ setup(
61
62
  "towncrier==22.12.0",
62
63
  "pyautoversion~=1.2.0",
63
64
  # FIXME change when https://github.com/pdoc3/pdoc/issues/299 is fixed
64
- "pdoc3==0.10.0",
65
+ "pdoc3==0.11.6",
65
66
  "toml",
66
67
  "semver~=2.13.0",
67
68
  "python-dotenv",
@@ -70,7 +71,7 @@ setup(
70
71
  "detect-secrets[gibberish]==1.5.0",
71
72
  "packaging",
72
73
  "licenseheaders<0.8.9",
73
- "spdx-tools==0.6.1",
74
+ "spdx-tools==0.8.5",
74
75
  "license-expression",
75
76
  "wcmatch",
76
77
  "jellyfish",
@@ -82,7 +83,7 @@ setup(
82
83
  long_description=long_description,
83
84
  name=PROJECT_SLUG,
84
85
  packages=[SOURCE_DIR],
85
- python_requires=">=3.8,<4",
86
+ python_requires=">=3.10,<4",
86
87
  url=f"https://github.com/ARMmbed/{PROJECT_SLUG}",
87
88
  version=__version__,
88
89
  )