Skip to content

Commit 46dd46f

Browse files
author
Andika Demas Riyandi
authored
Merge pull request #25 from numtide/basile/ignore
Use ignore for better control over globbing
2 parents e76e621 + c4ba6ca commit 46dd46f

File tree

6 files changed

+157
-40
lines changed

6 files changed

+157
-40
lines changed

Cargo.lock

+101
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ edition = "2018"
99
[dependencies]
1010
anyhow = "1.0"
1111
console = "0.13"
12+
either = "1.6.1"
1213
env_logger = { version = "0.8", default-features = false }
1314
filetime = "0.2"
1415
glob = "0.3"
1516
hex = "0.4"
17+
ignore = "0.4.17"
1618
log = "0.4"
1719
rayon = "1.5.0"
1820
serde = { version = "1.0", features = ["derive"] }

examples/monorepo/prjfmt.toml

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
# fmt is the universal code formatter - https://github.com/numtide/fmt
22
[formatters.ormolu]
33
files = "*.hs" # / "*.hs" / "Makefile" mandatory
4-
#includes = [ "haskell/" ] # "haskell-frontend/*.hs" treat it like whitelist, and haskell-frontend will be ignored. only if `includes` exists.
5-
#excludes = [] # blacklisted folder/files.
4+
excludes = [ "haskell/" ] # blacklisted folder/files.
65
command = "ormolu"
76
args = [
87
"--ghc-opt", "-XBangPatterns",
@@ -17,4 +16,4 @@ files = [ "*.rs" ]
1716
includes = [ "rust/" ]
1817
excludes = []
1918
command = "cargo"
20-
args = [ "fmt", "--" ]
19+
args = [ "fmt", "--" ]

overlay.nix

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ final: prev:
55
pname = "prjfmt";
66
version = "0.0.1";
77
src = ./.;
8-
cargoSha256 = "sha256-98M9OPWil9bKknam8ys4dNP6/iZObW0RrAC7PxiHxYI=";
8+
cargoSha256 = "sha256:0bsxwl5bhjg8d4mdyk2mx7g5744b790nhdlyg393vwjmnbnyy1k2";
99
doCheck = false;
1010
nativeBuildInputs = [ ];
1111
buildInputs = [ ];

src/formatters/tool.rs

+51-30
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@ use crate::formatters::manifest::{read_prjfmt_manifest, RootManifest};
44
use crate::{emoji, CLOG};
55
use anyhow::{anyhow, Error, Result};
66
use filetime::FileTime;
7-
use glob;
87
use rayon::prelude::*;
98
use serde::{Deserialize, Serialize};
109
use std::cmp::Ordering;
1110
use std::collections::{BTreeMap, BTreeSet};
1211
use std::fs::{metadata, read_to_string};
13-
use std::iter::Iterator;
12+
use std::iter::{IntoIterator, Iterator};
1413
use std::path::PathBuf;
1514
use xshell::cmd;
1615

@@ -113,38 +112,48 @@ pub fn run_prjfmt(cwd: PathBuf, cache_dir: PathBuf) -> anyhow::Result<()> {
113112
pub fn glob_to_path(
114113
cwd: &PathBuf,
115114
extensions: &FileExtensions,
116-
_includes: &Option<Vec<String>>,
117-
_excludes: &Option<Vec<String>>,
115+
includes: &Option<Vec<String>>,
116+
excludes: &Option<Vec<String>>,
118117
) -> anyhow::Result<Vec<PathBuf>> {
119-
let dir = cwd.to_str().unwrap_or("");
120-
121-
let glob_ext = |extension| -> anyhow::Result<_> {
122-
let pat = format!("{}/**/{}", dir, extension);
123-
let globs = glob::glob(&pat).map_err(|err| {
124-
anyhow::anyhow!(
125-
"{} Error at position: {} due to {}",
126-
emoji::ERROR,
127-
err.pos,
128-
err.msg
129-
)
130-
})?;
131-
132-
Ok(globs.map(|glob_res| Ok(glob_res?)))
133-
};
118+
use ignore::{overrides::OverrideBuilder, WalkBuilder};
134119

135-
match extensions {
136-
FileExtensions::SingleFile(sfile) => glob_ext(sfile)?.collect(),
137-
FileExtensions::MultipleFile(strs) => {
138-
strs.iter()
139-
.map(glob_ext)
140-
.try_fold(Vec::new(), |mut v, globs| {
141-
for glob in globs? {
142-
v.push(glob?)
143-
}
144-
Ok(v)
145-
})
120+
let mut overrides_builder = OverrideBuilder::new(cwd);
121+
122+
if let Some(includes) = includes {
123+
for include in includes {
124+
// Remove trailing `/` as we add one explicitly in the override
125+
let include = include.trim_end_matches('/');
126+
for extension in extensions.into_iter() {
127+
overrides_builder.add(&format!("{}/**/{}", include, extension))?;
128+
}
129+
}
130+
} else {
131+
for extension in extensions.into_iter() {
132+
overrides_builder.add(&extension)?;
146133
}
147134
}
135+
136+
if let Some(excludes) = excludes {
137+
for exclude in excludes {
138+
overrides_builder.add(&format!("!{}", exclude))?;
139+
}
140+
}
141+
142+
let overrides = overrides_builder.build()?;
143+
144+
Ok(WalkBuilder::new(cwd)
145+
.overrides(overrides)
146+
.build()
147+
.filter_map(|e| {
148+
e.ok().and_then(|e| {
149+
match e.file_type() {
150+
// Skip directory entries
151+
Some(t) if t.is_dir() => None,
152+
_ => Some(e.into_path()),
153+
}
154+
})
155+
})
156+
.collect())
148157
}
149158

150159
/// Convert each PathBuf into FileMeta
@@ -246,6 +255,18 @@ pub enum FileExtensions {
246255
MultipleFile(Vec<String>),
247256
}
248257

258+
impl<'a> IntoIterator for &'a FileExtensions {
259+
type Item = &'a String;
260+
type IntoIter = either::Either<std::iter::Once<&'a String>, std::slice::Iter<'a, String>>;
261+
262+
fn into_iter(self) -> Self::IntoIter {
263+
match self {
264+
FileExtensions::SingleFile(glob) => either::Either::Left(std::iter::once(glob)),
265+
FileExtensions::MultipleFile(globs) => either::Either::Right(globs.iter()),
266+
}
267+
}
268+
}
269+
249270
#[derive(Debug, Deserialize, Serialize, Clone)]
250271
/// Each context of the formatter config
251272
pub struct CmdContext {

src/main.rs

-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
#![allow(clippy::redundant_closure, clippy::redundant_pattern_matching)]
22

3-
extern crate anyhow;
4-
extern crate env_logger;
5-
extern crate log;
6-
extern crate prjfmt;
7-
extern crate structopt;
8-
93
use prjfmt::{run_cli, Cli, CLOG};
104
use structopt::StructOpt;
115

0 commit comments

Comments
 (0)