Skip to content

Commit

Permalink
feat: add basic CLI based on typos options
Browse files Browse the repository at this point in the history
It now supports the following options:

Arguments:
  [PATH]...  Paths to check [default: .]

Options:
      --sort              Sort results
      --format <FORMAT>   Render style for messages [default: long] [possible values: long, json]
      --hidden            Search hidden files and directories
      --no-ignore         Don't respect ignore files
      --no-ignore-dot     Don't respect .ignore files
      --no-ignore-global  Don't respect global ignore files
      --no-ignore-parent  Don't respect ignore files in parent directories
      --no-ignore-vcs     Don't respect ignore files in vcs directories
  -h, --help              Print help
  -V, --version           Print version
  • Loading branch information
ronnychevalier committed Jul 16, 2024
1 parent 10056d6 commit c09b3f4
Show file tree
Hide file tree
Showing 4 changed files with 247 additions and 12 deletions.
120 changes: 120 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ lang-yaml = ["dep:tree-sitter-yaml"]

[dependencies]
anyhow = "1.0.86"
clap = { version = "4.5.9", features = ["derive"] }
ignore = "0.4.22"
miette = { version = "7.2.0", features = ["fancy"] }
thiserror = "1.0.61"
Expand Down Expand Up @@ -73,6 +74,9 @@ trailing_empty_array = "warn"
as_ptr_cast_mut = "warn"
lint_groups_priority = "allow"

[profile.dev]
opt-level = 1

[profile.release]
lto = true
strip = "symbols"
Expand Down
106 changes: 106 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use std::fs::Metadata;
use std::path::Path;
use std::path::PathBuf;

use ignore::{DirEntry, WalkBuilder};

#[derive(Copy, Clone, PartialEq, Eq, clap::ValueEnum, Default)]
pub enum Format {
#[default]
Long,
Json,
}

impl Format {
pub fn into_error_hook(self) -> miette::ErrorHook {
match self {
Self::Long => Box::new(|_| Box::new(miette::GraphicalReportHandler::new())),
Self::Json => Box::new(|_| Box::new(miette::JSONReportHandler::new())),
}
}
}

#[derive(clap::Parser)]
#[command(about, version)]
pub(crate) struct Args {
/// Paths to check
#[arg(default_value = ".")]
path: Vec<PathBuf>,

/// Sort results
#[arg(long)]
sort: bool,

/// Render style for messages
#[arg(long, value_enum, ignore_case = true, default_value("long"))]
format: Format,

#[command(flatten)]
walk: WalkArgs,
}

#[derive(clap::Args)]
struct WalkArgs {
/// Search hidden files and directories
#[arg(long)]
hidden: bool,

/// Don't respect ignore files
#[arg(long)]
no_ignore: bool,

/// Don't respect .ignore files
#[arg(long)]
no_ignore_dot: bool,

/// Don't respect global ignore files
#[arg(long)]
no_ignore_global: bool,

/// Don't respect ignore files in parent directories
#[arg(long)]
no_ignore_parent: bool,

/// Don't respect ignore files in vcs directories
#[arg(long)]
no_ignore_vcs: bool,
}

impl Args {
pub fn to_walk_builder(&self, path: &Path) -> WalkBuilder {
let mut walk = ignore::WalkBuilder::new(path);
walk.skip_stdout(true)
.git_global(
!(self.walk.no_ignore_global || self.walk.no_ignore_vcs || self.walk.no_ignore),
)
.git_ignore(!self.walk.no_ignore_vcs || self.walk.no_ignore)
.git_exclude(!self.walk.no_ignore_vcs || self.walk.no_ignore)
.hidden(self.walk.hidden)
.parents(!(self.walk.no_ignore_parent || self.walk.no_ignore))
.ignore(!(self.walk.no_ignore_dot || self.walk.no_ignore));
if self.sort {
walk.sort_by_file_name(|a, b| a.cmp(b));
}

walk
}

pub fn to_walk(&self) -> impl Iterator<Item = DirEntry> + '_ {
self.path.iter().flat_map(|path| {
self.to_walk_builder(path)
.build()
.filter_map(Result::ok)
.filter(|entry| {
entry
.metadata()
.as_ref()
.map(Metadata::is_file)
.unwrap_or(false)
})
})
}

pub fn format(&self) -> Format {
self.format
}
}
29 changes: 17 additions & 12 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs::Metadata;
use std::ops::Deref;
use std::sync::OnceLock;

use clap::Parser;

use tree_sitter::Language;

use orthotypos::lint::Linter;

mod cli;

struct Lazy<T> {
cell: OnceLock<T>,
init: fn() -> T,
Expand Down Expand Up @@ -57,16 +60,13 @@ static EXTENSION_LANGUAGE: Lazy<HashMap<&'static OsStr, Language>> = Lazy::new(|
});

fn main() -> anyhow::Result<()> {
for file in ignore::Walk::new(".")
.filter_map(Result::ok)
.filter(|entry| {
entry
.metadata()
.as_ref()
.map(Metadata::is_file)
.unwrap_or(false)
})
{
let args = crate::cli::Args::parse();

let report_handler = args.format().into_error_hook();
miette::set_hook(report_handler)?;

let mut typo_found = false;
for file in args.to_walk() {
let extension = file.path().extension().unwrap_or_default();
let Some(language) = EXTENSION_LANGUAGE.get(extension) else {
continue;
Expand All @@ -78,8 +78,13 @@ fn main() -> anyhow::Result<()> {
for typo in &linter {
let typo: miette::Report = typo.into();
eprintln!("{typo:?}");
typo_found = true;
}
}

Ok(())
if typo_found {
std::process::exit(1);
} else {
Ok(())
}
}

0 comments on commit c09b3f4

Please sign in to comment.