diff --git a/schema/v2/dependencies.schema.json b/schema/v2/dependencies.schema.json index 09abbff..f87d983 100644 --- a/schema/v2/dependencies.schema.json +++ b/schema/v2/dependencies.schema.json @@ -5,14 +5,7 @@ "description": "*Dependencies* identify dependencies required to configure, build, test, install, and run the package provided by the distribution. These include not only PGXN packages, but also external libraries, system dependencies, and versions of PostgreSQL --- as well as any OS and architectures.", "type": "object", "properties": { - "platforms": { - "description": "A list of one or more strings that identify OSes and architectures supported by the package provided by the distribution. If this property is not present, consumers **SHOULD** assume that the package supports any platform that PostgreSQL supports. This property is typically needed only when the package depends on platform-specific features.", - "type": "array", - "minItems": 1, - "items": { - "$ref": "platform.schema.json" - } - }, + "platforms": { "$ref": "platforms.schema.json" }, "postgres": { "$ref": "postgres.schema.json" }, "pipeline": { "$ref": "pipeline.schema.json" }, "packages": { "$ref": "packages.schema.json" }, diff --git a/schema/v2/platform.schema.json b/schema/v2/platform.schema.json deleted file mode 100644 index 9083222..0000000 --- a/schema/v2/platform.schema.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://pgxn.org/meta/v2/platform.schema.json", - "title": "Platform", - "description": "A *Platform* identifies a computing platform as a one to three dash-delimited substrings: An OS name, the OS version, and the architecture: `$os-$version-$architecture`.\n\nIf the string contains no dash, it represents only the OS. If it contains a single dash, the first value represents the OS and second value is a version if it starts with an integer followed by a dot and the architecture if it does not start with a digit.", - "type": "string", - "pattern": "^(?:(any)|([a-zA-Z][a-zA-Z0-9]+)(?:-(?:0|[1-9]\\d*)[.][^\\s-]+[^-\\s]*)?(?:-([a-zA-Z0-9]+))?)$", - "$comment": "https://regex101.com/r/vJv9cK", - "examples": [ - "any", - "linux", - "gnulinux", - "musllinux", - "linux-amd64", - "gnulinux-amd64", - "musllinux-1.2", - "musllinux-1.2-arm64", - "darwin", - "darwin-arm64", - "darwin-23.5.0", - "darwin-23.5.0-arm64" - ] -} diff --git a/schema/v2/platforms.schema.json b/schema/v2/platforms.schema.json new file mode 100644 index 0000000..c3cb065 --- /dev/null +++ b/schema/v2/platforms.schema.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://pgxn.org/meta/v2/platforms.schema.json", + "title": "Platforms", + "description": "*Platforms* identify the OSes and architectures supported by the package provided by the distribution. If this property is not present, consumers **SHOULD** assume that the package supports any platform that PostgreSQL supports. This property is typically needed only when the package depends on platform-specific features.", + "type": "array", + "minItems": 1, + "items": { + "description": "A *Platform* identifies a computing platform as a one to three dash-delimited substrings: An OS name, the OS version, and the architecture: `$os-$version-$architecture`.\n\nIf the string contains no dash, it represents only the OS. If it contains a single dash, the first value represents the OS and second value is a version if it starts with an integer followed by a dot and the architecture if it does not start with a digit.", + "type": "string", + "pattern": "^(?:(any)|([a-zA-Z][a-zA-Z0-9]+)(?:-(?:0|[1-9]\\d*)[.][^\\s-]+[^-\\s]*)?(?:-([a-zA-Z0-9]+))?)$", + "$comment": "https://regex101.com/r/vJv9cK" + }, + "examples": [ + ["any"], + ["linux", "darwin", "windows"], + ["gnulinux", "musllinux"], + ["gnulinux-amd64", "musllinux-amd64"], + ["musllinux-1.2"], + ["musllinux-1.2-arm64"], + ["darwin-arm64"], + ["darwin-23.5.0"], + ["darwin-23.5.0-arm64"] + ] +} diff --git a/tests/v2_schema_test.rs b/tests/v2_schema_test.rs index 6ad95cd..0a644d1 100644 --- a/tests/v2_schema_test.rs +++ b/tests/v2_schema_test.rs @@ -66,21 +66,21 @@ fn test_v2_path() -> Result<(), Box> { let id = id_for(SCHEMA_VERSION, "path"); let idx = compiler.compile(&id, &mut schemas)?; - // Test valid relative paths. - for valid_path in [ + // Test valid paths. + for valid in [ json!("README.txt"), json!(".git"), json!("src/pair.c"), json!(".github/workflows/"), json!("this\\\\and\\\\that.txt"), ] { - if let Err(e) = schemas.validate(&valid_path, idx) { - panic!("path {} failed: {e}", valid_path); + if let Err(e) = schemas.validate(&valid, idx) { + panic!("path {} failed: {e}", valid); } } // Test invalid paths. - for invalid_path in [ + for invalid in [ json!("\\foo.md"), json!("this\\and\\that.txt"), json!("/absolute/path"), @@ -92,8 +92,8 @@ fn test_v2_path() -> Result<(), Box> { json!(""), json!("C:\\foo"), ] { - if schemas.validate(&invalid_path, idx).is_ok() { - panic!("{} unexpectedly passed!", invalid_path) + if schemas.validate(&invalid, idx).is_ok() { + panic!("{} unexpectedly passed!", invalid) } } Ok(()) @@ -108,7 +108,7 @@ fn test_v2_glob() -> Result<(), Box> { let idx = compiler.compile(&id, &mut schemas)?; // Test valid globs. - for valid_path in [ + for valid in [ json!("README.txt"), json!("/.git"), json!("/src/pair.c"), @@ -120,20 +120,20 @@ fn test_v2_glob() -> Result<(), Box> { json!("[a-z]*.txt"), json!("this\\\\and\\\\that.txt"), ] { - if let Err(e) = schemas.validate(&valid_path, idx) { - panic!("path pattern {} failed: {e}", valid_path); + if let Err(e) = schemas.validate(&valid, idx) { + panic!("glob {} failed: {e}", valid); } } // Test invalid globs. - for invalid_path in [ + for invalid in [ json!("this\\and\\that.txt"), json!(null), json!(""), json!("C:\\foo"), ] { - if schemas.validate(&invalid_path, idx).is_ok() { - panic!("{} unexpectedly passed!", invalid_path) + if schemas.validate(&invalid, idx).is_ok() { + panic!("{} unexpectedly passed!", invalid) } } @@ -237,7 +237,7 @@ fn test_v2_license() -> Result<(), Box> { json!("DocumentRef-spdx-tool-1.2:LicenseRef-MIT-Style-2"), ] { if let Err(e) = schemas.validate(&valid_license, idx) { - panic!("path pattern {} failed: {e}", valid_license); + panic!("license {} failed: {e}", valid_license); } } @@ -279,7 +279,7 @@ fn test_v2_purl() -> Result<(), Box> { json!("pkg:type/namespace/name@version?qualifiers#subpath"), ] { if let Err(e) = schemas.validate(&valid_purl, idx) { - panic!("path pattern {} failed: {e}", valid_purl); + panic!("purl {} failed: {e}", valid_purl); } } @@ -304,14 +304,14 @@ fn test_v2_purl() -> Result<(), Box> { } #[test] -fn test_v2_platform() -> Result<(), Box> { +fn test_v2_platforms() -> 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, "platform"); + let id = id_for(SCHEMA_VERSION, "platforms"); let idx = compiler.compile(&id, &mut schemas)?; - // Test valid relative platforms. + // Test valid platforms. for os in [ "any", "aix", @@ -330,9 +330,9 @@ fn test_v2_platform() -> Result<(), Box> { "wasip1", "windows", ] { - let platform = json!(os); + let platform = json!([os]); if let Err(e) = schemas.validate(&platform, idx) { - panic!("path pattern {} failed: {e}", platform); + panic!("platform {} failed: {e}", platform); } let architectures = [ @@ -341,9 +341,9 @@ fn test_v2_platform() -> Result<(), Box> { ]; for arch in architectures { - let platform = json!(format!("{os}-{arch}")); + let platform = json!([format!("{os}-{arch}")]); if let Err(e) = schemas.validate(&platform, idx) { - panic!("path pattern {} failed: {e}", platform); + panic!("platform pattern {} failed: {e}", platform); } } @@ -356,34 +356,54 @@ fn test_v2_platform() -> Result<(), Box> { if version.contains('-') { continue; } - let platform = json!(format!("{os}-{version}")); + let platform = json!([format!("{os}-{version}")]); if let Err(e) = schemas.validate(&platform, idx) { - panic!("path pattern {} failed: {e}", platform); + panic!("platform pattern {} failed: {e}", platform); } for arch in architectures { - let platform = json!(format!("{os}-{version}-{arch}")); + let platform = json!([format!("{os}-{version}-{arch}")]); if let Err(e) = schemas.validate(&platform, idx) { - panic!("path pattern {} failed: {e}", platform); + panic!("platform pattern {} failed: {e}", platform); } } } } + // Test valid platform lists. + for valid in [ + ("two", json!(["darwin", "linux"])), + ("three", json!(["darwin", "linux", "windows"])), + ("versions", json!(["musllinux-2.5", "gnulinux-3.3"])), + ( + "architectures", + json!(["musllinux-amd64", "gnulinux-amd64"]), + ), + ("full", json!(["musllinux-2.5-amd64", "gnulinux-3.3-amd64"])), + ] { + if let Err(e) = schemas.validate(&valid.1, idx) { + panic!("platform {} failed: {e}", valid.0); + } + } + // Test invalid platforms. - for invalid_platform in [ - json!("darwin amd64"), - json!("linux/amd64"), - json!("x86_64"), - json!("darwin_23.5.0_arm64"), - json!(null), - json!("0"), - json!(0), - json!("\n\t"), - json!("()"), + for invalid in [ + json!(["darwin amd64"]), + json!(["linux/amd64"]), + json!(["x86_64"]), + json!(["darwin_23.5.0_arm64"]), + json!([null]), + json!(["0"]), + json!([0]), + json!({}), + json!(true), + json!(42), + json!(["\n\t"]), + json!(["()"]), + json!(["darwin", "x86_64"]), ] { - if schemas.validate(&invalid_platform, idx).is_ok() { - panic!("{} unexpectedly passed!", invalid_platform) + if schemas.validate(&invalid, idx).is_ok() { + panic!("{} unexpectedly passed!", invalid) } } Ok(()) @@ -1740,7 +1760,7 @@ fn test_v2_pipeline() -> Result<(), Box> { json!("cargo"), ] { if let Err(e) = schemas.validate(&valid, idx) { - panic!("path {} failed: {e}", valid); + panic!("pipeline {} failed: {e}", valid); } }