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:
parent
4b695e2db0
commit
4d5f9028fd
2 changed files with 61 additions and 34 deletions
|
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue