From 639cee562e927207207612332681d2c14f76be06 Mon Sep 17 00:00:00 2001 From: "David E. Wheeler" Date: Thu, 18 Jul 2024 15:39:34 -0400 Subject: [PATCH] Add purl --- schema/v2/purl.schema.json | 15 +++++++++++ tests/v2_schema_test.rs | 54 ++++++++++++++++++++++++++++++++++---- 2 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 schema/v2/purl.schema.json diff --git a/schema/v2/purl.schema.json b/schema/v2/purl.schema.json new file mode 100644 index 0000000..1e64975 --- /dev/null +++ b/schema/v2/purl.schema.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://pgxn.org/meta/v2/purl.schema.json", + "title": "Path", + "description": "A *purl* is specifies a valid package in the format defined by the [purl spec](https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst). All known [purl Types](https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst) **MAY** be used, as well as `pgxn` for PGXN packages and `postgres` for PostgreSQL core [contrib](https://www.postgresql.org/docs/current/contrib.html) or development packages. Versions appearing after a `@` are valid but ignored.", + "type": "string", + "format": "uri", + "pattern": "^pkg:[a-zA-Z.+-][a-zA-Z0-9.+-]+/[^@?#]+(?:@[^?#]+)?(?:\\?[^#]+)?(?:#\\S+)?$", + "examples": [ + "pkg:pgxn/pgtap", + "pkg:postgres/pg_regress", + "pkg:generic/python3", + "pkg:pypi/pyarrow@11.0.0" + ] +} diff --git a/tests/v2_schema_test.rs b/tests/v2_schema_test.rs index 99668e3..7059725 100644 --- a/tests/v2_schema_test.rs +++ b/tests/v2_schema_test.rs @@ -196,8 +196,8 @@ fn test_v2_license() -> Result<(), Box> { let id = id_for(SCHEMA_VERSION, "license"); let idx = compiler.compile(&id, &mut schemas)?; - // Test valid relative paths. - for valid_path in [ + // Test valid relative licenses. + for valid_license in [ json!("MIT"), json!("PostgreSQL"), json!("Apache-2.0 OR MIT"), @@ -214,12 +214,12 @@ fn test_v2_license() -> Result<(), Box> { json!("LicenseRef-MIT-Style-1"), json!("DocumentRef-spdx-tool-1.2:LicenseRef-MIT-Style-2"), ] { - if let Err(e) = schemas.validate(&valid_path, idx) { - panic!("path pattern {} failed: {e}", valid_path); + if let Err(e) = schemas.validate(&valid_license, idx) { + panic!("path pattern {} failed: {e}", valid_license); } } - // Test invalid paths. + // Test invalid licenses. for invalid_license in [ json!(""), json!(null), @@ -236,3 +236,47 @@ fn test_v2_license() -> Result<(), Box> { } Ok(()) } + +#[test] +fn test_v2_purl() -> Result<(), Box> { + // Load the schemas and compile the semver schema. + let mut compiler = new_compiler("schema/v2")?; + let mut schemas = Schemas::new(); + let id = id_for(SCHEMA_VERSION, "purl"); + let idx = compiler.compile(&id, &mut schemas)?; + + // Test valid relative purls. + for valid_purl in [ + json!("pkg:pgxn/pgtap"), + json!("pkg:postgres/pg_regress"), + json!("pkg:generic/python3"), + json!("pkg:pypi/pyarrow@11.0.0"), + json!("pkg:type/namespace/name"), + json!("pkg:type/namespace/name@version"), + json!("pkg:type/namespace/name@version?qualifiers"), + json!("pkg:type/namespace/name@version?qualifiers#subpath"), + ] { + if let Err(e) = schemas.validate(&valid_purl, idx) { + panic!("path pattern {} failed: {e}", valid_purl); + } + } + + // Test invalid purls. + for invalid_purl in [ + json!("http://example.com"), + json!("https://example.com"), + json!("mailto:hi@example.com"), + json!(null), + json!("0"), + json!(0), + json!("\n\t"), + json!("()"), + json!("AND"), + json!("OR"), + ] { + if schemas.validate(&invalid_purl, idx).is_ok() { + panic!("{} unexpectedly passed!", invalid_purl) + } + } + Ok(()) +}