1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-06 22:35:51 -05:00

add lint result

This commit is contained in:
Bartek Iwańczuk 2024-11-14 12:56:45 +01:00
parent 4b695e2db0
commit 4d5f9028fd
No known key found for this signature in database
GPG key ID: 0C6BCDDC3B3AD750
2 changed files with 61 additions and 34 deletions

View file

@ -25,6 +25,18 @@ use super::rules::FileOrPackageLintRule;
use super::rules::PackageLintRule;
use super::ConfiguredRules;
pub enum LintResult {
/// File was linted and optionally produced diagnostics
Linted {
parsed_source: ParsedSource,
diagnostics: Vec<LintDiagnostic>,
},
/// File was not parsed and linted because, eg. it might have
/// been a minified file.
#[allow(unused)]
Skipped,
}
pub struct CliLinterOptions {
pub configured_rules: ConfiguredRules,
pub fix: bool,
@ -97,15 +109,12 @@ impl CliLinter {
file_path: &Path,
source_code: String,
ext: Option<&str>,
) -> Result<(ParsedSource, Vec<LintDiagnostic>), AnyError> {
) -> Result<LintResult, AnyError> {
let specifier = specifier_from_file_path(file_path)?;
let metrics = minified_file::analyze_content(&source_code);
if metrics.is_likely_minified() {
bail!(
"{} appears to be a minified file, skipping linting",
specifier.as_str()
);
Ok(LintResult::Skipped);
}
let media_type = if let Some(ext) = ext {
@ -119,7 +128,7 @@ impl CliLinter {
if self.fix {
self.lint_file_and_fix(&specifier, media_type, source_code, file_path)
} else {
self
let (parsed_source, diagnostics) = self
.linter
.lint_file(LintFileOptions {
specifier,
@ -127,7 +136,11 @@ impl CliLinter {
source_code,
config: self.deno_lint_config.clone(),
})
.map_err(AnyError::from)
.map_err(AnyError::from)?;
Ok(LintResult::Linted {
parsed_source,
diagnostics,
})
}
}
@ -137,7 +150,7 @@ impl CliLinter {
media_type: MediaType,
source_code: String,
file_path: &Path,
) -> Result<(ParsedSource, Vec<LintDiagnostic>), deno_core::anyhow::Error> {
) -> Result<LintResult, deno_core::anyhow::Error> {
// initial lint
let (source, diagnostics) = self.linter.lint_file(LintFileOptions {
specifier: specifier.clone(),
@ -194,7 +207,10 @@ impl CliLinter {
.context("Failed writing fix to file.")?;
}
Ok((source, diagnostics))
Ok(LintResult::Linted {
parsed_source: source,
diagnostics,
})
}
}

View file

@ -4,7 +4,6 @@
//! [`deno_lint`](https://github.com/denoland/deno_lint).
use deno_ast::ModuleSpecifier;
use deno_ast::ParsedSource;
use deno_config::deno_json::LintRulesConfig;
use deno_config::glob::FileCollector;
use deno_config::glob::FilePatterns;
@ -19,8 +18,8 @@ use deno_core::serde_json;
use deno_core::unsync::future::LocalFutureExt;
use deno_core::unsync::future::SharedLocal;
use deno_graph::ModuleGraph;
use deno_lint::diagnostic::LintDiagnostic;
use deno_lint::linter::LintConfig;
use linter::LintResult;
use log::debug;
use reporters::create_reporter;
use reporters::LintReporter;
@ -371,14 +370,18 @@ impl WorkspaceLinter {
file_text,
cli_options.ext_flag().as_deref(),
);
if let Ok((file_source, file_diagnostics)) = &r {
if let Ok(LintResult::Linted {
parsed_source,
diagnostics,
}) = &r
{
if let Some(incremental_cache) = &maybe_incremental_cache {
if file_diagnostics.is_empty() {
if diagnostics.is_empty() {
// update the incremental cache if there were no diagnostics
incremental_cache.update_file(
&file_path,
// ensure the returned text is used here as it may have been modified via --fix
file_source.text(),
parsed_source.text(),
)
}
}
@ -496,7 +499,7 @@ fn lint_stdin(
file_path: &Path,
configured_rules: ConfiguredRules,
deno_lint_config: LintConfig,
) -> Result<(ParsedSource, Vec<LintDiagnostic>), AnyError> {
) -> Result<LintResult, AnyError> {
let mut source_code = String::new();
if stdin().read_to_string(&mut source_code).is_err() {
return Err(generic_error("Failed to read from stdin"));
@ -515,33 +518,41 @@ fn lint_stdin(
fn handle_lint_result(
file_path: &str,
result: Result<(ParsedSource, Vec<LintDiagnostic>), AnyError>,
result: Result<LintResult, AnyError>,
reporter_lock: Arc<Mutex<Box<dyn LintReporter + Send>>>,
) -> bool {
let mut reporter = reporter_lock.lock();
match result {
Ok((source, mut file_diagnostics)) => {
if !source.diagnostics().is_empty() {
for parse_diagnostic in source.diagnostics() {
log::warn!("{}: {}", colors::yellow("warn"), parse_diagnostic);
}
}
file_diagnostics.sort_by(|a, b| match a.specifier.cmp(&b.specifier) {
std::cmp::Ordering::Equal => {
let a_start = a.range.as_ref().map(|r| r.range.start);
let b_start = b.range.as_ref().map(|r| r.range.start);
match a_start.cmp(&b_start) {
std::cmp::Ordering::Equal => a.details.code.cmp(&b.details.code),
other => other,
Ok(lint_result) => {
if let LintResult::Linted {
parsed_source,
mut diagnostics,
} = lint_result
{
if !parsed_source.diagnostics().is_empty() {
for parse_diagnostic in parsed_source.diagnostics() {
log::warn!("{}: {}", colors::yellow("warn"), parse_diagnostic);
}
}
file_order => file_order,
});
for d in &file_diagnostics {
reporter.visit_diagnostic(d);
diagnostics.sort_by(|a, b| match a.specifier.cmp(&b.specifier) {
std::cmp::Ordering::Equal => {
let a_start = a.range.as_ref().map(|r| r.range.start);
let b_start = b.range.as_ref().map(|r| r.range.start);
match a_start.cmp(&b_start) {
std::cmp::Ordering::Equal => a.details.code.cmp(&b.details.code),
other => other,
}
}
file_order => file_order,
});
for d in &diagnostics {
reporter.visit_diagnostic(d);
}
diagnostics.is_empty()
} else {
true
}
file_diagnostics.is_empty()
}
Err(err) => {
reporter.visit_error(file_path, &err);