Skip to content

Commit c23718e

Browse files
committed
Add mandatory license field to patch metadata
1 parent 6536717 commit c23718e

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_patch_metadata.py

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,28 @@
3636
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3737
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3838
# SOFTWARE.
39-
from pathlib import Path
39+
import re
4040

4141
import sys
42+
from pathlib import Path
43+
44+
# Approved license identifiers in SPDX "short identifier" format
45+
ALLOWED_LICENSES = {
46+
'MIT', # https://spdx.org/licenses/MIT.html
47+
'BSD-3-Clause', # https://spdx.org/licenses/BSD-3-Clause.html
48+
'BSD-2-Clause', # https://spdx.org/licenses/BSD-2-Clause.html
49+
'Apache-2.0', # https://spdx.org/licenses/Apache-2.0.html
50+
'MPL-2.0', # https://spdx.org/licenses/MPL-2.0.html
51+
'LGPL-2.0-or-later', # https://spdx.org/licenses/LGPL-2.0-or-later.html
52+
'LGPL-3.0-or-later', # https://spdx.org/licenses/LGPL-3.0-or-later.html
53+
'PSF-2.0', # https://spdx.org/licenses/PSF-2.0.html
54+
}
55+
ALLOWED_WITH_CLAUSES = {
56+
'openssl-exception',
57+
}
4258

4359
SECTIONS = frozenset({'rules', 'add-sources'})
44-
RULE_KEYS = frozenset({'version', 'patch', 'subdir', 'dist-type', 'install-priority', 'ignore-rule-on-llvm'})
60+
RULE_KEYS = frozenset({'version', 'patch', 'license', 'subdir', 'dist-type', 'install-priority', 'ignore-rule-on-llvm'})
4561

4662
if sys.implementation.name == 'graalpy':
4763
import ensurepip
@@ -67,6 +83,17 @@ def validate_metadata(package_dir, metadata):
6783
patch_path = package_dir / patch
6884
assert patch_path.is_file(), f"Patch file does not exists: {patch_path}"
6985
patches.add(patch_path)
86+
license = rule.get('license')
87+
assert license, f"'license' not specified for patch {patch}"
88+
license = re.sub(r'[()]', ' ', license)
89+
for part in re.split(f'AND|OR', license):
90+
part = part.strip()
91+
if ' WITH ' in part:
92+
part, exception = re.split(r'\s+WITH\s+', part, 1)
93+
assert exception in ALLOWED_WITH_CLAUSES, \
94+
f"License WITH clause {exception} not in allowed list of clauses: {', '.join(ALLOWED_WITH_CLAUSES)}"
95+
assert part in ALLOWED_LICENSES, \
96+
f"License {part} not in allowed list of licenses: {', '.join(ALLOWED_LICENSES)}"
7097
if install_priority := rule.get('install-priority'):
7198
assert isinstance(install_priority, int), "'rules.install_priority' must be an int"
7299
if dist_type := rule.get('dist-type'):
@@ -87,11 +114,17 @@ def validate_metadata(package_dir, metadata):
87114

88115

89116
def test_patch_metadata():
117+
errors = []
90118
for package_dir in patch_dir.iterdir():
91119
if package_dir.is_dir():
92-
if (metadata_path := package_dir / 'metadata.toml').is_file():
93-
with open(metadata_path, 'rb') as f:
94-
metadata = tomli.load(f)
95-
validate_metadata(package_dir, metadata)
96-
else:
97-
assert False, f"Patch directory without metadata: {package_dir}"
120+
try:
121+
if (metadata_path := package_dir / 'metadata.toml').is_file():
122+
with open(metadata_path, 'rb') as f:
123+
metadata = tomli.load(f)
124+
validate_metadata(package_dir, metadata)
125+
else:
126+
assert False, f"Patch directory without metadata: {package_dir}"
127+
except Exception as e:
128+
errors.append(f"\t{package_dir.name}: {e}")
129+
if errors:
130+
raise AssertionError("Patch metadata validation failed:\n" + '\n'.join(errors))

graalpython/lib-graalpython/patches/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ Configuration files are named `metadata.toml` and can contain the following:
1111
[[rules]]
1212
# Optional. Relative path to a patch file. May be omitted when the entry just specifies `install-priority`
1313
patch = 'foo-1.0.0.patch'
14+
# Required if 'patch' is specified. SPDX license expression for the package (allows parentheses, 'AND', 'OR', 'WITH').
15+
# Allowed licenses are enumerated in test_patch_metadata.py
16+
license = 'MIT'
1417
# Optional. Version specifier according to https://peps.python.org/pep-0440/#version-specifiers. If omitted, it will
1518
# match any version
1619
version = '== 1.0.0'
@@ -33,4 +36,5 @@ install-priority = 1
3336
# The next entry will apply to all other artifacts of foo
3437
[[patches]]
3538
patch = 'foo.patch'
39+
license = 'MIT'
3640
```

0 commit comments

Comments
 (0)