Skip to content

Commit

Permalink
Use structopt instead of clap
Browse files Browse the repository at this point in the history
  • Loading branch information
Kampfkarren committed Nov 5, 2019
1 parent de0380a commit fce8dae
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 61 deletions.
2 changes: 1 addition & 1 deletion selene/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ authors = ["Kampfkarren <[email protected]>"]
edition = "2018"

[dependencies]
clap = "2"
codespan = "0.4"
codespan-reporting = "0.4"
full_moon = "0.4.0-rc.11"
glob = "0.3"
selene-lib = { path = "../selene-lib" }
num_cpus = "1.10"
structopt = "0.3"
termcolor = "1.0"
threadpool = "1.7"
toml = "0.5"
Expand Down
71 changes: 11 additions & 60 deletions selene/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ use std::{
},
};

use clap::{App, Arg};
use codespan_reporting::{diagnostic::Severity as CodespanSeverity, term::DisplayStyle};
use full_moon::ast::owned::Owned;
use selene_lib::{rules::Severity, standard_library::StandardLibrary, *};
use structopt::StructOpt;
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
use threadpool::ThreadPool;

mod opts;

macro_rules! error {
($fmt:expr) => {
error(fmt::format(format_args!($fmt))).unwrap();
Expand Down Expand Up @@ -121,9 +123,9 @@ fn read_file(checker: &Checker<toml::value::Value>, filename: &Path) {
&mut stdout,
&codespan_reporting::term::Config {
display_style: if QUIET.load(Ordering::Relaxed) {
DisplayStyle::Rich
} else {
DisplayStyle::Short
} else {
DisplayStyle::Rich
},
..Default::default()
},
Expand All @@ -135,52 +137,11 @@ fn read_file(checker: &Checker<toml::value::Value>, filename: &Path) {
}

fn main() {
let num_cpus = num_cpus::get().to_string();

let matches = App::new(env!("CARGO_PKG_NAME"))
.version(env!("CARGO_PKG_VERSION"))
.author("Kampfkarren")
.arg(
Arg::with_name("pattern")
.long("pattern")
.help("A glob to match files with to check")
.default_value("**/*.lua"),
)
.arg(
// .default is not used here since if the user explicitly specifies the config file
// we want it to error if it doesn't exist
Arg::with_name("config")
.long("config")
.help(
"A toml file to configure the behavior of selene [default: selene.toml]",
)
.takes_value(true),
)
.arg(
Arg::with_name("num-threads")
.long("num-threads")
.help(
"Number of threads to run on, default to the numbers of logical cores on your system"
)
.default_value(&num_cpus)
)
.arg(
Arg::with_name("quiet")
.short("q")
.help("Display only the necessary information")
)
.arg(
Arg::with_name("files")
.index(1)
.min_values(1)
.multiple(true)
.required(true),
)
.get_matches();
let matches = opts::Options::from_args();

QUIET.store(!matches.is_present("quiet"), Ordering::Relaxed);
QUIET.store(matches.quiet, Ordering::Relaxed);

let config: CheckerConfig<toml::value::Value> = match matches.value_of("config") {
let config: CheckerConfig<toml::value::Value> = match matches.config {
Some(config_file) => {
let config_contents = match fs::read_to_string(config_file) {
Ok(contents) => contents,
Expand Down Expand Up @@ -244,19 +205,9 @@ fn main() {
}
});

let num_threads: usize = match &matches.value_of("num-threads").unwrap().parse() {
Ok(num_threads) => *num_threads,
Err(error) => {
error!("Couldn't parse num-threads: {}", error);
return;
}
};

let pattern = matches.value_of("pattern").unwrap();

let pool = ThreadPool::new(num_threads);
let pool = ThreadPool::new(matches.num_threads);

for filename in matches.values_of_os("files").unwrap() {
for filename in &matches.files {
match fs::metadata(filename) {
Ok(metadata) => {
if metadata.is_file() {
Expand All @@ -266,7 +217,7 @@ fn main() {
pool.execute(move || read_file(&checker, Path::new(&filename)));
} else if metadata.is_dir() {
let glob =
match glob::glob(&format!("{}/{}", filename.to_string_lossy(), pattern)) {
match glob::glob(&format!("{}/{}", filename.to_string_lossy(), matches.pattern)) {
Ok(glob) => glob,
Err(error) => {
error!("Invalid glob pattern: {}", error);
Expand Down
34 changes: 34 additions & 0 deletions selene/src/opts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use std::ffi::OsString;

use structopt::StructOpt;

#[derive(StructOpt)]
#[structopt(rename_all = "kebab-case")]
pub struct Options {
/// A glob to match files with to check
#[structopt(long, default_value = "**/*.lua")]
pub pattern: String,

/// A toml file to configure the behavior of selene [default: selene.toml]
// .default is not used here since if the user explicitly specifies the config file
// we want it to error if it doesn't exist
#[structopt(long)]
pub config: Option<String>,

/// Number of threads to run on, default to the numbers of logical cores on your system
#[structopt(long, default_value = get_num_cpus())]
pub num_threads: usize,

/// Display only the necessary information
#[structopt(long, short)]
pub quiet: bool,

#[structopt(parse(from_os_str), min_values(1), index(1), required(true))]
pub files: Vec<OsString>,
}

// We can't just do default_value = num_cpus::get().to_string().as_str(),
// since that won't extend the lifetime for long enough.
fn get_num_cpus() -> &'static str {
Box::leak(num_cpus::get().to_string().into_boxed_str())
}

0 comments on commit fce8dae

Please sign in to comment.