mirror of
https://github.com/denoland/deno.git
synced 2025-01-09 07:39:15 -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::rules::PackageLintRule;
|
||||||
use super::ConfiguredRules;
|
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 struct CliLinterOptions {
|
||||||
pub configured_rules: ConfiguredRules,
|
pub configured_rules: ConfiguredRules,
|
||||||
pub fix: bool,
|
pub fix: bool,
|
||||||
|
@ -97,15 +109,12 @@ impl CliLinter {
|
||||||
file_path: &Path,
|
file_path: &Path,
|
||||||
source_code: String,
|
source_code: String,
|
||||||
ext: Option<&str>,
|
ext: Option<&str>,
|
||||||
) -> Result<(ParsedSource, Vec<LintDiagnostic>), AnyError> {
|
) -> Result<LintResult, AnyError> {
|
||||||
let specifier = specifier_from_file_path(file_path)?;
|
let specifier = specifier_from_file_path(file_path)?;
|
||||||
|
|
||||||
let metrics = minified_file::analyze_content(&source_code);
|
let metrics = minified_file::analyze_content(&source_code);
|
||||||
if metrics.is_likely_minified() {
|
if metrics.is_likely_minified() {
|
||||||
bail!(
|
Ok(LintResult::Skipped);
|
||||||
"{} appears to be a minified file, skipping linting",
|
|
||||||
specifier.as_str()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let media_type = if let Some(ext) = ext {
|
let media_type = if let Some(ext) = ext {
|
||||||
|
@ -119,7 +128,7 @@ impl CliLinter {
|
||||||
if self.fix {
|
if self.fix {
|
||||||
self.lint_file_and_fix(&specifier, media_type, source_code, file_path)
|
self.lint_file_and_fix(&specifier, media_type, source_code, file_path)
|
||||||
} else {
|
} else {
|
||||||
self
|
let (parsed_source, diagnostics) = self
|
||||||
.linter
|
.linter
|
||||||
.lint_file(LintFileOptions {
|
.lint_file(LintFileOptions {
|
||||||
specifier,
|
specifier,
|
||||||
|
@ -127,7 +136,11 @@ impl CliLinter {
|
||||||
source_code,
|
source_code,
|
||||||
config: self.deno_lint_config.clone(),
|
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,
|
media_type: MediaType,
|
||||||
source_code: String,
|
source_code: String,
|
||||||
file_path: &Path,
|
file_path: &Path,
|
||||||
) -> Result<(ParsedSource, Vec<LintDiagnostic>), deno_core::anyhow::Error> {
|
) -> Result<LintResult, deno_core::anyhow::Error> {
|
||||||
// initial lint
|
// initial lint
|
||||||
let (source, diagnostics) = self.linter.lint_file(LintFileOptions {
|
let (source, diagnostics) = self.linter.lint_file(LintFileOptions {
|
||||||
specifier: specifier.clone(),
|
specifier: specifier.clone(),
|
||||||
|
@ -194,7 +207,10 @@ impl CliLinter {
|
||||||
.context("Failed writing fix to file.")?;
|
.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).
|
//! [`deno_lint`](https://github.com/denoland/deno_lint).
|
||||||
|
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
use deno_ast::ParsedSource;
|
|
||||||
use deno_config::deno_json::LintRulesConfig;
|
use deno_config::deno_json::LintRulesConfig;
|
||||||
use deno_config::glob::FileCollector;
|
use deno_config::glob::FileCollector;
|
||||||
use deno_config::glob::FilePatterns;
|
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::LocalFutureExt;
|
||||||
use deno_core::unsync::future::SharedLocal;
|
use deno_core::unsync::future::SharedLocal;
|
||||||
use deno_graph::ModuleGraph;
|
use deno_graph::ModuleGraph;
|
||||||
use deno_lint::diagnostic::LintDiagnostic;
|
|
||||||
use deno_lint::linter::LintConfig;
|
use deno_lint::linter::LintConfig;
|
||||||
|
use linter::LintResult;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use reporters::create_reporter;
|
use reporters::create_reporter;
|
||||||
use reporters::LintReporter;
|
use reporters::LintReporter;
|
||||||
|
@ -371,14 +370,18 @@ impl WorkspaceLinter {
|
||||||
file_text,
|
file_text,
|
||||||
cli_options.ext_flag().as_deref(),
|
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 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
|
// update the incremental cache if there were no diagnostics
|
||||||
incremental_cache.update_file(
|
incremental_cache.update_file(
|
||||||
&file_path,
|
&file_path,
|
||||||
// ensure the returned text is used here as it may have been modified via --fix
|
// 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,
|
file_path: &Path,
|
||||||
configured_rules: ConfiguredRules,
|
configured_rules: ConfiguredRules,
|
||||||
deno_lint_config: LintConfig,
|
deno_lint_config: LintConfig,
|
||||||
) -> Result<(ParsedSource, Vec<LintDiagnostic>), AnyError> {
|
) -> Result<LintResult, AnyError> {
|
||||||
let mut source_code = String::new();
|
let mut source_code = String::new();
|
||||||
if stdin().read_to_string(&mut source_code).is_err() {
|
if stdin().read_to_string(&mut source_code).is_err() {
|
||||||
return Err(generic_error("Failed to read from stdin"));
|
return Err(generic_error("Failed to read from stdin"));
|
||||||
|
@ -515,19 +518,24 @@ fn lint_stdin(
|
||||||
|
|
||||||
fn handle_lint_result(
|
fn handle_lint_result(
|
||||||
file_path: &str,
|
file_path: &str,
|
||||||
result: Result<(ParsedSource, Vec<LintDiagnostic>), AnyError>,
|
result: Result<LintResult, AnyError>,
|
||||||
reporter_lock: Arc<Mutex<Box<dyn LintReporter + Send>>>,
|
reporter_lock: Arc<Mutex<Box<dyn LintReporter + Send>>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut reporter = reporter_lock.lock();
|
let mut reporter = reporter_lock.lock();
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok((source, mut file_diagnostics)) => {
|
Ok(lint_result) => {
|
||||||
if !source.diagnostics().is_empty() {
|
if let LintResult::Linted {
|
||||||
for parse_diagnostic in source.diagnostics() {
|
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);
|
log::warn!("{}: {}", colors::yellow("warn"), parse_diagnostic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_diagnostics.sort_by(|a, b| match a.specifier.cmp(&b.specifier) {
|
diagnostics.sort_by(|a, b| match a.specifier.cmp(&b.specifier) {
|
||||||
std::cmp::Ordering::Equal => {
|
std::cmp::Ordering::Equal => {
|
||||||
let a_start = a.range.as_ref().map(|r| r.range.start);
|
let a_start = a.range.as_ref().map(|r| r.range.start);
|
||||||
let b_start = b.range.as_ref().map(|r| r.range.start);
|
let b_start = b.range.as_ref().map(|r| r.range.start);
|
||||||
|
@ -538,10 +546,13 @@ fn handle_lint_result(
|
||||||
}
|
}
|
||||||
file_order => file_order,
|
file_order => file_order,
|
||||||
});
|
});
|
||||||
for d in &file_diagnostics {
|
for d in &diagnostics {
|
||||||
reporter.visit_diagnostic(d);
|
reporter.visit_diagnostic(d);
|
||||||
}
|
}
|
||||||
file_diagnostics.is_empty()
|
diagnostics.is_empty()
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
reporter.visit_error(file_path, &err);
|
reporter.visit_error(file_path, &err);
|
||||||
|
|
Loading…
Reference in a new issue