aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart-spdx-licenses
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-04 14:41:59 +0900
committernsfisis <nsfisis@gmail.com>2026-05-04 15:43:56 +0900
commita24d6e2f148417b32188cd1e643439a2858f4eac (patch)
tree593bbb830c6d46a33a40465dbd16fda98082543d /crates/mozart-spdx-licenses
parentc59a923669c57adbf6e5eecce7feae59afcf0aac (diff)
downloadphp-mozart-a24d6e2f148417b32188cd1e643439a2858f4eac.tar.gz
php-mozart-a24d6e2f148417b32188cd1e643439a2858f4eac.tar.zst
php-mozart-a24d6e2f148417b32188cd1e643439a2858f4eac.zip
feat(validate): port ValidatingArrayLoader license checks
Mirror Composer's Package\Loader\ValidatingArrayLoader::load() license block: warn on non-string/wrong-shape values, validate the SPDX expression with proprietary→MIT substitution, and surface "extra spaces" diagnostics. Validity is gated on the manifest's `time` field (checked only for releases without a date or within the last 8 days), mirroring Composer's strtotime('-8days') window.
Diffstat (limited to 'crates/mozart-spdx-licenses')
-rw-r--r--crates/mozart-spdx-licenses/Cargo.toml3
-rw-r--r--crates/mozart-spdx-licenses/src/lib.rs29
2 files changed, 21 insertions, 11 deletions
diff --git a/crates/mozart-spdx-licenses/Cargo.toml b/crates/mozart-spdx-licenses/Cargo.toml
index 1500932..7361c93 100644
--- a/crates/mozart-spdx-licenses/Cargo.toml
+++ b/crates/mozart-spdx-licenses/Cargo.toml
@@ -3,9 +3,6 @@ name = "mozart-spdx-licenses"
version.workspace = true
edition.workspace = true
-[dependencies]
-indexmap.workspace = true
-
[build-dependencies]
serde.workspace = true
serde_json.workspace = true
diff --git a/crates/mozart-spdx-licenses/src/lib.rs b/crates/mozart-spdx-licenses/src/lib.rs
index 668270f..a551988 100644
--- a/crates/mozart-spdx-licenses/src/lib.rs
+++ b/crates/mozart-spdx-licenses/src/lib.rs
@@ -1,4 +1,4 @@
-use indexmap::IndexMap;
+use std::collections::HashMap;
use std::sync::LazyLock;
include!(concat!(env!("OUT_DIR"), "/spdx_data.rs"));
@@ -21,16 +21,16 @@ pub struct ExceptionInfo {
/// SPDX license database with expression validation.
pub struct SpdxLicenses {
- licenses: IndexMap<&'static str, LicenseInfo>,
- exceptions: IndexMap<&'static str, ExceptionInfo>,
- name_to_id: IndexMap<&'static str, &'static str>,
+ licenses: HashMap<&'static str, LicenseInfo>,
+ exceptions: HashMap<&'static str, ExceptionInfo>,
+ name_to_id: HashMap<&'static str, &'static str>,
}
impl SpdxLicenses {
/// Build the license database from generated data.
pub fn new() -> Self {
- let mut licenses = IndexMap::with_capacity(LICENSES.len());
- let mut name_to_id = IndexMap::with_capacity(LICENSES.len());
+ let mut licenses = HashMap::with_capacity(LICENSES.len());
+ let mut name_to_id = HashMap::with_capacity(LICENSES.len());
for &(lower, id, full_name, osi, deprecated) in LICENSES {
licenses.insert(
lower,
@@ -44,7 +44,7 @@ impl SpdxLicenses {
name_to_id.insert(full_name, id);
}
- let mut exceptions = IndexMap::with_capacity(EXCEPTIONS.len());
+ let mut exceptions = HashMap::with_capacity(EXCEPTIONS.len());
for &(lower, id, full_name) in EXCEPTIONS {
exceptions.insert(
lower,
@@ -95,7 +95,6 @@ impl SpdxLicenses {
/// exceptions, the `+` (or-later) operator, LicenseRef, and the special
/// values `NONE` and `NOASSERTION`.
pub fn validate(&self, license: &str) -> bool {
- let license = license.trim();
if license.is_empty() {
return false;
}
@@ -418,6 +417,20 @@ mod tests {
}
#[test]
+ fn no_edge_whitespace_allowed() {
+ // Composer's `^(NONE|NOASSERTION|...)$` (with `x` flag) admits no
+ // leading or trailing whitespace; mirror that.
+ let db = spdx();
+ assert!(db.validate("MIT"));
+ assert!(!db.validate(" MIT"));
+ assert!(!db.validate("MIT "));
+ assert!(!db.validate(" MIT "));
+ assert!(!db.validate("\tMIT"));
+ assert!(!db.validate("MIT\t"));
+ assert!(!db.validate("\nMIT"));
+ }
+
+ #[test]
fn validate_list() {
let db = spdx();
assert!(db.validate_list(&["MIT", "Apache-2.0"]));