diff --git a/Cargo.lock b/Cargo.lock index f5ace65510..4f4477a9f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1360,9 +1360,9 @@ dependencies = [ [[package]] name = "deno_config" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1f3c577bf7fdbb449cb99c2560309364c71cc3dcc7af94387ef8810b089173" +checksum = "4bc5aa53d1c3a3d0b9fd218e3f30f1080312f811b60e1866b88ec9f665447c4e" dependencies = [ "anyhow", "deno_package_json", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index e53979298f..9b65d0c81b 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -65,7 +65,7 @@ winres.workspace = true [dependencies] deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] } deno_cache_dir = { workspace = true } -deno_config = { version = "=0.28.0", features = ["workspace", "sync"] } +deno_config = { version = "=0.29.0", features = ["workspace", "sync"] } deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] } deno_doc = { version = "0.146.0", features = ["html", "syntect"] } deno_emit = "=0.44.0" diff --git a/cli/schemas/config-file.v1.json b/cli/schemas/config-file.v1.json index 96a95ca162..edbb6f6d11 100644 --- a/cli/schemas/config-file.v1.json +++ b/cli/schemas/config-file.v1.json @@ -546,6 +546,10 @@ } } }, + "license": { + "description": "The SPDX license identifier if this is a JSR package. Specify this or add a license file to the package.", + "type": ["string"] + }, "lock": { "description": "Whether to use a lock file or the path to use for the lock file. Can be overridden by CLI arguments.", "type": ["string", "boolean"], diff --git a/cli/tools/init/mod.rs b/cli/tools/init/mod.rs index 6d442198ee..b9ae803c73 100644 --- a/cli/tools/init/mod.rs +++ b/cli/tools/init/mod.rs @@ -138,6 +138,7 @@ Deno.test(function addTest() { "tasks": { "dev": "deno test --watch mod.ts" }, + "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@1" }, diff --git a/cli/tools/registry/diagnostics.rs b/cli/tools/registry/diagnostics.rs index e1c6e4e655..69434f1ea8 100644 --- a/cli/tools/registry/diagnostics.rs +++ b/cli/tools/registry/diagnostics.rs @@ -120,8 +120,7 @@ pub enum PublishDiagnostic { }, SyntaxError(ParseDiagnostic), MissingLicense { - /// This only exists because diagnostics require a location. - expected_path: PathBuf, + config_specifier: Url, }, } @@ -214,7 +213,7 @@ impl Diagnostic for PublishDiagnostic { MissingConstraint { specifier, .. } => Cow::Owned(format!("specifier '{}' is missing a version constraint", specifier)), BannedTripleSlashDirectives { .. } => Cow::Borrowed("triple slash directives that modify globals are not allowed"), SyntaxError(diagnostic) => diagnostic.message(), - MissingLicense { .. } => Cow::Borrowed("missing license file"), + MissingLicense { .. } => Cow::Borrowed("missing license field or file"), } } @@ -282,8 +281,8 @@ impl Diagnostic for PublishDiagnostic { text_info: Cow::Borrowed(text_info), }, SyntaxError(diagnostic) => diagnostic.location(), - MissingLicense { expected_path } => DiagnosticLocation::Path { - path: expected_path.clone(), + MissingLicense { config_specifier } => DiagnosticLocation::Module { + specifier: Cow::Borrowed(config_specifier), }, } } @@ -400,7 +399,7 @@ impl Diagnostic for PublishDiagnostic { ), SyntaxError(diagnostic) => diagnostic.hint(), MissingLicense { .. } => Some( - Cow::Borrowed("add a LICENSE file to the package and ensure it is not ignored from being published"), + Cow::Borrowed("add a \"license\" field. Alternatively, add a LICENSE file to the package and ensure it is not ignored from being published"), ), } } diff --git a/cli/tools/registry/mod.rs b/cli/tools/registry/mod.rs index 34e803c732..d6e06fb58a 100644 --- a/cli/tools/registry/mod.rs +++ b/cli/tools/registry/mod.rs @@ -449,6 +449,8 @@ impl PublishPreparer { let cli_options = self.cli_options.clone(); let source_cache = self.source_cache.clone(); let config_path = config_path.clone(); + let config_url = deno_json.specifier.clone(); + let has_license_field = package.license.is_some(); move || { let root_specifier = ModuleSpecifier::from_directory_path(&root_dir).unwrap(); @@ -467,7 +469,9 @@ impl PublishPreparer { &diagnostics_collector, ); - if !has_license_file(publish_paths.iter().map(|p| &p.specifier)) { + if !has_license_field + && !has_license_file(publish_paths.iter().map(|p| &p.specifier)) + { if let Some(license_path) = resolve_license_file(&root_dir, cli_options.workspace()) { @@ -483,7 +487,7 @@ impl PublishPreparer { }); } else { diagnostics_collector.push(PublishDiagnostic::MissingLicense { - expected_path: root_dir.join("LICENSE"), + config_specifier: config_url, }); } } diff --git a/tests/specs/publish/javascript_decl_file/LICENSE b/tests/specs/publish/javascript_decl_file/LICENSE deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/specs/publish/javascript_decl_file/deno.json b/tests/specs/publish/javascript_decl_file/deno.json index e5dbfa8d32..66368bf002 100644 --- a/tests/specs/publish/javascript_decl_file/deno.json +++ b/tests/specs/publish/javascript_decl_file/deno.json @@ -3,5 +3,6 @@ "version": "1.0.0", "exports": { ".": "./mod.js" - } + }, + "license": "MIT" } diff --git a/tests/specs/publish/missing_license/mod.out b/tests/specs/publish/missing_license/mod.out index d3e183662a..f5fbb9b7e3 100644 --- a/tests/specs/publish/missing_license/mod.out +++ b/tests/specs/publish/missing_license/mod.out @@ -1,9 +1,9 @@ Check file:///[WILDLINE]/missing_license/mod.ts Checking for slow types in the public API... Check file:///[WILDLINE]/missing_license/mod.ts -error[missing-license]: missing license file - --> [WILDLINE]LICENSE - = hint: add a LICENSE file to the package and ensure it is not ignored from being published +error[missing-license]: missing license field or file + --> [WILDLINE]deno.json + = hint: add a "license" field. Alternatively, add a LICENSE file to the package and ensure it is not ignored from being published docs: https://jsr.io/go/missing-license