summaryrefslogtreecommitdiff
path: root/cli/tools/registry/diagnostics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tools/registry/diagnostics.rs')
-rw-r--r--cli/tools/registry/diagnostics.rs108
1 files changed, 82 insertions, 26 deletions
diff --git a/cli/tools/registry/diagnostics.rs b/cli/tools/registry/diagnostics.rs
index 31f815767..49f8de045 100644
--- a/cli/tools/registry/diagnostics.rs
+++ b/cli/tools/registry/diagnostics.rs
@@ -20,6 +20,7 @@ use deno_ast::SourceTextInfo;
use deno_core::anyhow::anyhow;
use deno_core::error::AnyError;
use deno_graph::FastCheckDiagnostic;
+use deno_semver::Version;
use lsp_types::Url;
use super::unfurl::SpecifierUnfurlerDiagnostic;
@@ -107,6 +108,13 @@ pub enum PublishDiagnostic {
ExcludedModule {
specifier: Url,
},
+ MissingConstraint {
+ specifier: Url,
+ specifier_text: String,
+ resolved_version: Option<Version>,
+ text_info: SourceTextInfo,
+ referrer: deno_graph::Range,
+ },
}
impl PublishDiagnostic {
@@ -153,6 +161,7 @@ impl Diagnostic for PublishDiagnostic {
InvalidExternalImport { .. } => DiagnosticLevel::Error,
UnsupportedJsxTsx { .. } => DiagnosticLevel::Warning,
ExcludedModule { .. } => DiagnosticLevel::Error,
+ MissingConstraint { .. } => DiagnosticLevel::Error,
}
}
@@ -167,6 +176,7 @@ impl Diagnostic for PublishDiagnostic {
InvalidExternalImport { .. } => Cow::Borrowed("invalid-external-import"),
UnsupportedJsxTsx { .. } => Cow::Borrowed("unsupported-jsx-tsx"),
ExcludedModule { .. } => Cow::Borrowed("excluded-module"),
+ MissingConstraint { .. } => Cow::Borrowed("missing-constraint"),
}
}
@@ -185,10 +195,25 @@ impl Diagnostic for PublishDiagnostic {
InvalidExternalImport { kind, .. } => Cow::Owned(format!("invalid import to a {kind} specifier")),
UnsupportedJsxTsx { .. } => Cow::Borrowed("JSX and TSX files are currently not supported"),
ExcludedModule { .. } => Cow::Borrowed("module in package's module graph was excluded from publishing"),
+ MissingConstraint { specifier, .. } => Cow::Owned(format!("specifier '{}' is missing a version constraint", specifier)),
}
}
fn location(&self) -> DiagnosticLocation {
+ fn from_referrer_range<'a>(
+ referrer: &'a deno_graph::Range,
+ text_info: &'a SourceTextInfo,
+ ) -> DiagnosticLocation<'a> {
+ DiagnosticLocation::ModulePosition {
+ specifier: Cow::Borrowed(&referrer.specifier),
+ text_info: Cow::Borrowed(text_info),
+ source_pos: DiagnosticSourcePos::LineAndCol {
+ line: referrer.start.line,
+ column: referrer.start.character,
+ },
+ }
+ }
+
use PublishDiagnostic::*;
match &self {
FastCheck(diagnostic) => diagnostic.location(),
@@ -216,24 +241,49 @@ impl Diagnostic for PublishDiagnostic {
referrer,
text_info,
..
- } => DiagnosticLocation::ModulePosition {
- specifier: Cow::Borrowed(&referrer.specifier),
- text_info: Cow::Borrowed(text_info),
- source_pos: DiagnosticSourcePos::LineAndCol {
- line: referrer.start.line,
- column: referrer.start.character,
- },
- },
+ } => from_referrer_range(referrer, text_info),
UnsupportedJsxTsx { specifier } => DiagnosticLocation::Module {
specifier: Cow::Borrowed(specifier),
},
ExcludedModule { specifier } => DiagnosticLocation::Module {
specifier: Cow::Borrowed(specifier),
},
+ MissingConstraint {
+ referrer,
+ text_info,
+ ..
+ } => from_referrer_range(referrer, text_info),
}
}
fn snippet(&self) -> Option<DiagnosticSnippet<'_>> {
+ fn from_range<'a>(
+ text_info: &'a SourceTextInfo,
+ referrer: &'a deno_graph::Range,
+ ) -> Option<DiagnosticSnippet<'a>> {
+ if referrer.start.line == 0 && referrer.start.character == 0 {
+ return None; // no range, probably a jsxImportSource import
+ }
+
+ Some(DiagnosticSnippet {
+ source: Cow::Borrowed(text_info),
+ highlight: DiagnosticSnippetHighlight {
+ style: DiagnosticSnippetHighlightStyle::Error,
+ range: DiagnosticSourceRange {
+ start: DiagnosticSourcePos::LineAndCol {
+ line: referrer.start.line,
+ column: referrer.start.character,
+ },
+ end: DiagnosticSourcePos::LineAndCol {
+ line: referrer.end.line,
+ column: referrer.end.character,
+ },
+ },
+ description: Some("the specifier".into()),
+ },
+ })
+ }
+
use PublishDiagnostic::*;
match &self {
FastCheck(diagnostic) => diagnostic.snippet(),
@@ -261,25 +311,14 @@ impl Diagnostic for PublishDiagnostic {
referrer,
text_info,
..
- } => Some(DiagnosticSnippet {
- source: Cow::Borrowed(text_info),
- highlight: DiagnosticSnippetHighlight {
- style: DiagnosticSnippetHighlightStyle::Error,
- range: DiagnosticSourceRange {
- start: DiagnosticSourcePos::LineAndCol {
- line: referrer.start.line,
- column: referrer.start.character,
- },
- end: DiagnosticSourcePos::LineAndCol {
- line: referrer.end.line,
- column: referrer.end.character,
- },
- },
- description: Some("the specifier".into()),
- },
- }),
+ } => from_range(text_info, referrer),
UnsupportedJsxTsx { .. } => None,
ExcludedModule { .. } => None,
+ MissingConstraint {
+ referrer,
+ text_info,
+ ..
+ } => from_range(text_info, referrer),
}
}
@@ -302,6 +341,13 @@ impl Diagnostic for PublishDiagnostic {
ExcludedModule { .. } => Some(
Cow::Borrowed("remove the module from 'exclude' and/or 'publish.exclude' in the config file or use 'publish.exclude' with a negative glob to unexclude from gitignore"),
),
+ MissingConstraint { specifier_text, .. } => {
+ Some(Cow::Borrowed(if specifier_text.starts_with("jsr:") || specifier_text.starts_with("npm:") {
+ "specify a version constraint for the specifier"
+ } else {
+ "specify a version constraint for the specifier in the import map"
+ }))
+ },
}
}
@@ -366,7 +412,14 @@ impl Diagnostic for PublishDiagnostic {
]),
ExcludedModule { .. } => Cow::Owned(vec![
Cow::Borrowed("excluded modules referenced via a package export will error at runtime due to not existing in the package"),
- ])
+ ]),
+ MissingConstraint { resolved_version, .. } => Cow::Owned(vec![
+ Cow::Owned(format!(
+ "the specifier resolved to version {} today, but will resolve to a different",
+ resolved_version.as_ref().map(|v| v.to_string()).unwrap_or_else(|| "<unresolved>".to_string())),
+ ),
+ Cow::Borrowed("major version if one is published in the future and potentially break"),
+ ]),
}
}
@@ -393,6 +446,9 @@ impl Diagnostic for PublishDiagnostic {
ExcludedModule { .. } => {
Some(Cow::Borrowed("https://jsr.io/go/excluded-module"))
}
+ MissingConstraint { .. } => {
+ Some(Cow::Borrowed("https://jsr.io/go/missing-constraint"))
+ }
}
}
}