use rslint_cli::ExplanationRunner;
use std::path::PathBuf;
use structopt::{clap::arg_enum, StructOpt};
const DEV_FLAGS_HELP: &str = "
Developer flags that are used by RSLint developers to debug RSLint.
-Z help -- Shows this message
-Z tokenize -- Tokenizes the input files and dumps the tokens
-Z dumpast -- Parses the input files and prints the parsed AST
Run with 'rslint -Z <FLAG> <FILES>'.";
#[derive(Debug, StructOpt)]
#[structopt(
name = "rslint",
about = "An extremely fast and configurable JavaScript linter"
)]
pub(crate) struct Options {
#[structopt(short, long)]
verbose: bool,
#[structopt(default_value = "./")]
files: Vec<String>,
#[structopt(subcommand)]
cmd: Option<SubCommand>,
#[structopt(short, long)]
fix: bool,
#[structopt(short = "D", long)]
dirty: bool,
#[structopt(long)]
no_global_config: bool,
#[structopt(long)]
no_ignore: bool,
#[structopt(long)]
use_gitignore: bool,
#[structopt(long)]
ignore_file: Option<PathBuf>,
#[structopt(long)]
max_threads: Option<usize>,
#[structopt(short = "F", long)]
formatter: Option<String>,
#[structopt(name = "FLAG", short = "Z")]
dev_flag: Option<DevFlag>,
}
arg_enum! {
#[derive(Debug, PartialEq, Eq)]
enum DevFlag {
Help,
Tokenize,
DumpAst,
}
}
#[derive(Debug, StructOpt, PartialEq, Eq)]
pub(crate) enum SubCommand {
Explain { rules: Vec<String> },
Rules,
Infer { files: Vec<String> },
}
fn main() {
#[cfg(not(debug_assertions))]
std::panic::set_hook(Box::new(rslint_cli::panic_hook));
let opt = Options::from_args();
execute(opt);
}
fn execute(opt: Options) {
match (opt.dev_flag, opt.cmd) {
(Some(DevFlag::Help), _) => println!("{}", DEV_FLAGS_HELP),
(Some(DevFlag::Tokenize), _) => rslint_cli::tokenize(opt.files),
(Some(DevFlag::DumpAst), _) => rslint_cli::dump_ast(opt.files),
(_, Some(SubCommand::Explain { rules })) => ExplanationRunner::new(rules).print(),
(_, Some(SubCommand::Rules)) => rslint_cli::show_all_rules(),
(_, Some(SubCommand::Infer { files })) => rslint_cli::infer(files),
(_, None) => rslint_cli::run(
opt.files,
opt.verbose,
opt.fix,
opt.dirty,
opt.formatter,
opt.no_global_config,
opt.max_threads.unwrap_or_else(num_cpus::get),
opt.no_ignore,
opt.ignore_file,
opt.use_gitignore,
),
}
}