diff options
Diffstat (limited to 'cli/tools')
-rw-r--r-- | cli/tools/registry/diagnostics.rs | 22 | ||||
-rw-r--r-- | cli/tools/registry/mod.rs | 68 |
2 files changed, 89 insertions, 1 deletions
diff --git a/cli/tools/registry/diagnostics.rs b/cli/tools/registry/diagnostics.rs index 34f08b666..54b281194 100644 --- a/cli/tools/registry/diagnostics.rs +++ b/cli/tools/registry/diagnostics.rs @@ -119,6 +119,10 @@ pub enum PublishDiagnostic { range: SourceRange, }, SyntaxError(ParseDiagnostic), + MissingLicense { + /// This only exists because diagnostics require a location. + expected_path: PathBuf, + }, } impl PublishDiagnostic { @@ -168,6 +172,8 @@ impl Diagnostic for PublishDiagnostic { MissingConstraint { .. } => DiagnosticLevel::Error, BannedTripleSlashDirectives { .. } => DiagnosticLevel::Error, SyntaxError { .. } => DiagnosticLevel::Error, + // todo(#24676): make this an error in Deno 1.46 + MissingLicense { .. } => DiagnosticLevel::Warning, } } @@ -187,6 +193,7 @@ impl Diagnostic for PublishDiagnostic { Cow::Borrowed("banned-triple-slash-directives") } SyntaxError { .. } => Cow::Borrowed("syntax-error"), + MissingLicense { .. } => Cow::Borrowed("missing-license"), } } @@ -208,6 +215,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"), } } @@ -275,6 +283,9 @@ impl Diagnostic for PublishDiagnostic { text_info: Cow::Borrowed(text_info), }, SyntaxError(diagnostic) => diagnostic.location(), + MissingLicense { expected_path } => DiagnosticLocation::Path { + path: expected_path.clone(), + }, } } @@ -355,6 +366,7 @@ impl Diagnostic for PublishDiagnostic { }], }), SyntaxError(diagnostic) => diagnostic.snippet(), + MissingLicense { .. } => None, } } @@ -388,6 +400,9 @@ impl Diagnostic for PublishDiagnostic { Cow::Borrowed("remove the triple slash directive"), ), SyntaxError(diagnostic) => diagnostic.hint(), + MissingLicense { .. } => Some( + Cow::Borrowed("add a LICENSE file to the package and ensure it is not ignored from being published"), + ), } } @@ -424,7 +439,8 @@ impl Diagnostic for PublishDiagnostic { | UnsupportedJsxTsx { .. } | ExcludedModule { .. } | MissingConstraint { .. } - | BannedTripleSlashDirectives { .. } => None, + | BannedTripleSlashDirectives { .. } + | MissingLicense { .. } => None, } } @@ -474,6 +490,7 @@ impl Diagnostic for PublishDiagnostic { Cow::Borrowed("or set their 'lib' compiler option appropriately"), ]), SyntaxError(diagnostic) => diagnostic.info(), + MissingLicense { .. } => Cow::Borrowed(&[]), } } @@ -507,6 +524,9 @@ impl Diagnostic for PublishDiagnostic { "https://jsr.io/go/banned-triple-slash-directives", )), SyntaxError(diagnostic) => diagnostic.docs_url(), + MissingLicense { .. } => { + Some(Cow::Borrowed("https://jsr.io/go/missing-license")) + } } } } diff --git a/cli/tools/registry/mod.rs b/cli/tools/registry/mod.rs index 2e781ccee..1c4e1bea7 100644 --- a/cli/tools/registry/mod.rs +++ b/cli/tools/registry/mod.rs @@ -462,6 +462,13 @@ impl PublishPreparer { &publish_paths, &diagnostics_collector, ); + + if !has_license_file(publish_paths.iter().map(|p| &p.specifier)) { + diagnostics_collector.push(PublishDiagnostic::MissingLicense { + expected_path: root_dir.join("LICENSE"), + }); + } + tar::create_gzipped_tarball( &publish_paths, LazyGraphSourceParser::new(&source_cache, &graph), @@ -1187,6 +1194,36 @@ async fn check_if_git_repo_dirty(cwd: &Path) -> Option<String> { } } +fn has_license_file<'a>( + mut specifiers: impl Iterator<Item = &'a ModuleSpecifier>, +) -> bool { + let allowed_license_files = { + let files = HashSet::from([ + "license", + "license.md", + "license.txt", + "licence", + "licence.md", + "licence.txt", + ]); + if cfg!(debug_assertions) { + for file in &files { + assert_eq!(*file, file.to_lowercase()); + } + } + files + }; + specifiers.any(|specifier| { + specifier + .path() + .rsplit_once('/') + .map(|(_, file)| { + allowed_license_files.contains(file.to_lowercase().as_str()) + }) + .unwrap_or(false) + }) +} + #[allow(clippy::print_stderr)] fn ring_bell() { // ASCII code for the bell character. @@ -1195,6 +1232,10 @@ fn ring_bell() { #[cfg(test)] mod tests { + use deno_ast::ModuleSpecifier; + + use crate::tools::registry::has_license_file; + use super::tar::PublishableTarball; use super::tar::PublishableTarballFile; use super::verify_version_manifest; @@ -1296,4 +1337,31 @@ mod tests { assert!(verify_version_manifest(meta_bytes, &package).is_err()); } + + #[test] + fn test_has_license_files() { + fn has_license_file_str(expected: &[&str]) -> bool { + let specifiers = expected + .iter() + .map(|s| ModuleSpecifier::parse(s).unwrap()) + .collect::<Vec<_>>(); + has_license_file(specifiers.iter()) + } + + assert!(has_license_file_str(&["file:///LICENSE"])); + assert!(has_license_file_str(&["file:///license"])); + assert!(has_license_file_str(&["file:///LICENSE.txt"])); + assert!(has_license_file_str(&["file:///LICENSE.md"])); + assert!(has_license_file_str(&["file:///LICENCE"])); + assert!(has_license_file_str(&["file:///LICENCE.txt"])); + assert!(has_license_file_str(&["file:///LICENCE.md"])); + assert!(has_license_file_str(&[ + "file:///other", + "file:///test/LICENCE.md" + ]),); + assert!(!has_license_file_str(&[ + "file:///other", + "file:///test/tLICENSE" + ]),); + } } |