feat(cli): exit codes

chore: remove foo.js

chore: review comments

chore: shut clippy up

chore: ran cargo fmt

chore: unnecessary return
This commit is contained in:
thepassle 2023-02-25 16:09:24 +01:00 committed by Boshen
parent 4f36f7d2ef
commit eaeafa0a82
4 changed files with 75 additions and 15 deletions

1
Cargo.lock generated
View file

@ -826,6 +826,7 @@ dependencies = [
"mimalloc",
"oxc_allocator",
"oxc_ast",
"oxc_diagnostics",
"oxc_linter",
"oxc_parser",
"oxc_semantic",

View file

@ -16,6 +16,7 @@ jemallocator = { workspace = true }
mimalloc = { workspace = true }
[dependencies]
oxc_diagnostics = { path = "../oxc_diagnostics" }
oxc_allocator = { path = "../oxc_allocator" }
oxc_ast = { path = "../oxc_ast" }
oxc_parser = { path = "../oxc_parser" }

View file

@ -1,11 +1,12 @@
mod command;
mod walk;
use std::{fs, path::Path, rc::Rc};
use std::{fs, path::Path, path::PathBuf, rc::Rc};
pub use command::Command;
use oxc_allocator::Allocator;
use oxc_ast::SourceType;
use oxc_diagnostics::miette::Report;
use oxc_linter::Linter;
use oxc_parser::Parser;
use oxc_semantic::SemanticBuilder;
@ -14,16 +15,31 @@ use walk::Walk;
pub struct Cli;
#[derive(Debug)]
pub struct LintResult {
pub path: PathBuf,
pub diagnostics: Vec<Report>,
}
impl Cli {
pub fn lint<P: AsRef<Path>>(path: P) {
pub fn lint<P: AsRef<Path>>(path: P) -> Option<Vec<LintResult>> {
let paths = Walk::new(path).iter().collect::<Vec<_>>();
paths.par_iter().for_each(|path| {
Self::lint_path(path);
});
println!("Checked {} files", paths.len());
if paths.is_empty() {
return None;
}
let result: Vec<LintResult> = paths
.par_iter()
.map(|path| {
let diagnostics = Self::lint_path(path);
LintResult { path: path.to_path_buf(), diagnostics }
})
.collect();
Some(result)
}
fn lint_path(path: &Path) {
fn lint_path(path: &Path) -> Vec<Report> {
let source_text = fs::read_to_string(path).expect("{name} not found");
let allocator = Allocator::default();
let source_type = SourceType::from_path(path).expect("incorrect {path:?}");
@ -36,9 +52,9 @@ impl Cli {
ret.errors
};
for diagnostic in diagnostics {
let diagnostic = diagnostic.with_source_code(source_text.clone());
println!("{diagnostic:?}");
}
diagnostics
.into_iter()
.map(|diagnostic| diagnostic.with_source_code(source_text.clone()))
.collect()
}
}

View file

@ -9,15 +9,57 @@ static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc;
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
use std::path::PathBuf;
use std::process::{ExitCode, Termination};
use oxc_cli::{Cli, Command};
use oxc_cli::{Cli, Command, LintResult};
fn main() {
#[derive(Debug)]
pub enum CliRunResult {
None,
PathNotFound { path: PathBuf },
LintResult(Vec<LintResult>),
}
impl Termination for CliRunResult {
fn report(self) -> ExitCode {
match self {
Self::None => ExitCode::from(0),
Self::PathNotFound { path } => {
println!("Path {} does not exist.", path.to_string_lossy());
ExitCode::from(1)
}
Self::LintResult(results) => {
println!("Checked {} files.", results.len());
let has_errors = results.iter().any(|result| !result.diagnostics.is_empty());
if has_errors {
for LintResult { path, diagnostics } in results {
println!("File: {path:?}");
for diagnostic in diagnostics {
println!("{diagnostic:?}");
}
}
return ExitCode::from(1);
}
ExitCode::from(0)
}
}
}
}
fn main() -> CliRunResult {
match Command::new().build().get_matches().subcommand() {
Some(("lint", matches)) => {
let path = matches.get_one::<PathBuf>("path").unwrap();
Cli::lint(path);
if path.canonicalize().is_err() {
return CliRunResult::PathNotFound { path: path.clone() };
}
let result = Cli::lint(path);
CliRunResult::LintResult(result.unwrap())
}
_ => unreachable!(),
_ => CliRunResult::None,
}
}