diff --git a/HISTORY.rst b/HISTORY.rst index 4b9179b7..31a3fedf 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -24,11 +24,12 @@ PlatformIO Core 5 * `pio pkg uninstall `_ - uninstall the project dependencies or custom packages * `pio pkg update `__ - update the project dependencies or custom packages + - Added support for multi-licensed packages in `library.json `__ using SPDX Expressions (`issue #4037 `_) - Automatically install dependencies of the local (private) libraries (`issue #2910 `_) - Added support for dependencies declared in a "tool" type package - - Ignore files according to the patterns declared in ".gitignore" when using `pio package pack `__ command (`issue #4188 `_) + - Ignore files according to the patterns declared in ".gitignore" when using the `pio package pack `__ command (`issue #4188 `_) - Dropped automatic updates of global libraries and development platforms (`issue #4179 `_) - - Dropped support for "pythonPackages" field in "platform.json" manifest in favor of `Extra Python Dependencies `__ + - Dropped support for the "pythonPackages" field in "platform.json" manifest in favor of `Extra Python Dependencies `__ * **Static Code Analysis** @@ -38,7 +39,7 @@ PlatformIO Core 5 * **Miscellaneous** * Improved PIO Remote setup on credit-card sized computers (Raspberry Pi, BeagleBon, etc) (`issue #3865 `_) -* Better handling of the failed tests using `Unit Testing `__ solution +* Better handling of the failed tests using the `Unit Testing `__ solution. 5.2.5 (2022-02-10) ~~~~~~~~~~~~~~~~~~ diff --git a/docs b/docs index b953caef..1e6df4bb 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit b953caefb78f6b6a09b944c13162426aa34a18cb +Subproject commit 1e6df4bb839b370b1951abf3e26b7712c78f91c5 diff --git a/platformio/package/manifest/schema.py b/platformio/package/manifest/schema.py index cf2353de..e0a87475 100644 --- a/platformio/package/manifest/schema.py +++ b/platformio/package/manifest/schema.py @@ -15,6 +15,7 @@ # pylint: disable=too-many-ancestors import json +import re import marshmallow import requests @@ -254,9 +255,18 @@ class ManifestSchema(BaseSchema): spdx = self.load_spdx_licenses() except requests.exceptions.RequestException: raise ValidationError("Could not load SPDX licenses for validation") - for item in spdx.get("licenses", []): - if item.get("licenseId") == value: - return True + known_ids = set(item.get("licenseId") for item in spdx.get("licenses", [])) + if value in known_ids: + return True + # parse license expression + # https://spdx.github.io/spdx-spec/SPDX-license-expressions/ + package_ids = [ + item.strip() + for item in re.sub(r"(\s+(?:OR|AND|WITH)\s+|[\(\)])", " ", value).split(" ") + if item.strip() + ] + if known_ids >= set(package_ids): + return True raise ValidationError( "Invalid SPDX license identifier. See valid identifiers at " "https://spdx.org/licenses/" diff --git a/tests/package/test_manifest.py b/tests/package/test_manifest.py index 0fc76f1a..3e97c83e 100644 --- a/tests/package/test_manifest.py +++ b/tests/package/test_manifest.py @@ -426,6 +426,25 @@ def test_library_json_schema(): }, ) + # test multiple licenses + contents = """ +{ + "name": "MultiLicense", + "version": "1.0.0", + "license": "MIT AND (LGPL-2.1-or-later OR BSD-3-Clause)" +} +""" + raw_data = parser.LibraryJsonManifestParser(contents).as_dict() + data = ManifestSchema().load_manifest(raw_data) + assert not jsondiff.diff( + data, + { + "name": "MultiLicense", + "version": "1.0.0", + "license": "MIT AND (LGPL-2.1-or-later OR BSD-3-Clause)", + }, + ) + def test_library_properties_schema(): contents = """