mirror of
https://github.com/XAMPPRocky/tokei
synced 2024-08-27 19:29:27 +00:00
Make --no-ignore imply all other --no-ignore- flags (#588)
* Make --no-ignore imply all other --no-ignore- flags And add --no-ignore-dot to only disable .ignore files, matching ripgrep. Fixes #585. * Cosmetic code updates for consistency * Update CLI help text in README * Update src/utils/fs.rs Co-authored-by: Liwen Guo <lg@livven.me> Co-authored-by: XAMPPRocky <4464295+XAMPPRocky@users.noreply.github.com>
This commit is contained in:
parent
82429f5c32
commit
a6fa401dc4
13
README.md
13
README.md
|
@ -229,9 +229,12 @@ FLAGS:
|
|||
-h, --help Prints help information
|
||||
--hidden Count hidden files.
|
||||
-l, --languages Prints out supported languages and their extensions.
|
||||
--no-ignore Don't respect ignore files.
|
||||
--no-ignore-parent Don't respect ignore files in parent directories.
|
||||
--no-ignore-vcs Don't respect VCS ignore files.
|
||||
--no-ignore Don't respect ignore files (.gitignore, .ignore, etc.). This implies --no-ignore-parent,
|
||||
--no-ignore-dot, and --no-ignore-vcs.
|
||||
--no-ignore-dot Don't respect .ignore and .tokeignore files, including those in parent directories.
|
||||
--no-ignore-parent Don't respect ignore files (.gitignore, .ignore, etc.) in parent directories.
|
||||
--no-ignore-vcs Don't respect VCS ignore files (.gitignore, .hgignore, etc.), including those in parent
|
||||
directories.
|
||||
-V, --version Prints version information
|
||||
-v, --verbose Set log output level:
|
||||
1: to show unknown file extensions,
|
||||
|
@ -240,7 +243,7 @@ FLAGS:
|
|||
|
||||
OPTIONS:
|
||||
-c, --columns <columns> Sets a strict column width of the output, only available for terminal output.
|
||||
-e, --exclude <exclude>... Ignore all files & directories containing the word.
|
||||
-e, --exclude <exclude>... Ignore all files & directories matching the pattern.
|
||||
-i, --input <file_input> Gives statistics from a previous tokei run. Can be given a file path, or "stdin" to
|
||||
read from stdin.
|
||||
-o, --output <output> Outputs Tokei in a specific format. Compile with additional features for more format
|
||||
|
@ -249,7 +252,7 @@ OPTIONS:
|
|||
-t, --type <types> Filters output by language type, seperated by a comma. i.e. -t=Rust,Markdown
|
||||
|
||||
ARGS:
|
||||
<input>... The input file(s)/directory(ies) to be counted.
|
||||
<input>... The path(s) to the file or directory to be counted.
|
||||
```
|
||||
|
||||
## Badges
|
||||
|
|
22
src/cli.rs
22
src/cli.rs
|
@ -14,6 +14,7 @@ pub struct Cli<'a> {
|
|||
pub hidden: bool,
|
||||
pub no_ignore: bool,
|
||||
pub no_ignore_parent: bool,
|
||||
pub no_ignore_dot: bool,
|
||||
pub no_ignore_vcs: bool,
|
||||
pub output: Option<Format>,
|
||||
pub print_languages: bool,
|
||||
|
@ -57,11 +58,17 @@ impl<'a> Cli<'a> {
|
|||
conflicts_with[input]
|
||||
"Prints out supported languages and their extensions.")
|
||||
(@arg no_ignore: --("no-ignore")
|
||||
"Don't respect ignore files.")
|
||||
"Don't respect ignore files (.gitignore, .ignore, etc.). This implies \
|
||||
--no-ignore-parent, --no-ignore-dot, and --no-ignore-vcs.")
|
||||
(@arg no_ignore_parent: --("no-ignore-parent")
|
||||
"Don't respect ignore files in parent directories.")
|
||||
"Don't respect ignore files (.gitignore, .ignore, etc.) in parent \
|
||||
directories.")
|
||||
(@arg no_ignore_dot: --("no-ignore-dot")
|
||||
"Don't respect .ignore and .tokeignore files, including those in \
|
||||
parent directories.")
|
||||
(@arg no_ignore_vcs: --("no-ignore-vcs")
|
||||
"Don't respect VCS (.gitignore, .hgignore, etc) ignore files.")
|
||||
"Don't respect VCS ignore files (.gitignore, .hgignore, etc.), including \
|
||||
those in parent directories.")
|
||||
(@arg output: -o --output
|
||||
// `all` is used so to fail later with a better error
|
||||
possible_values(Format::all())
|
||||
|
@ -95,6 +102,7 @@ impl<'a> Cli<'a> {
|
|||
let hidden = matches.is_present("hidden");
|
||||
let no_ignore = matches.is_present("no_ignore");
|
||||
let no_ignore_parent = matches.is_present("no_ignore_parent");
|
||||
let no_ignore_dot = matches.is_present("no_ignore_dot");
|
||||
let no_ignore_vcs = matches.is_present("no_ignore_vcs");
|
||||
let print_languages = matches.is_present("languages");
|
||||
let verbose = matches.occurrences_of("verbose");
|
||||
|
@ -135,6 +143,7 @@ impl<'a> Cli<'a> {
|
|||
matches,
|
||||
no_ignore,
|
||||
no_ignore_parent,
|
||||
no_ignore_dot,
|
||||
no_ignore_vcs,
|
||||
output,
|
||||
print_languages,
|
||||
|
@ -181,6 +190,7 @@ impl<'a> Cli<'a> {
|
|||
/// #### Shared options
|
||||
/// * `no_ignore`
|
||||
/// * `no_ignore_parent`
|
||||
/// * `no_ignore_dot`
|
||||
/// * `no_ignore_vcs`
|
||||
/// * `types`
|
||||
pub fn override_config(&mut self, mut config: Config) -> Config {
|
||||
|
@ -202,6 +212,12 @@ impl<'a> Cli<'a> {
|
|||
config.no_ignore_parent
|
||||
};
|
||||
|
||||
config.no_ignore_dot = if self.no_ignore_dot {
|
||||
Some(true)
|
||||
} else {
|
||||
config.no_ignore_dot
|
||||
};
|
||||
|
||||
config.no_ignore_vcs = if self.no_ignore_vcs {
|
||||
Some(true)
|
||||
} else {
|
||||
|
|
|
@ -23,11 +23,17 @@ pub struct Config {
|
|||
pub columns: Option<usize>,
|
||||
/// Count hidden files and directories. *Default:* `false`.
|
||||
pub hidden: Option<bool>,
|
||||
/// Don't respect ignore files. *Default:* `false`.
|
||||
/// Don't respect ignore files (.gitignore, .ignore, etc.). This implies --no-ignore-parent,
|
||||
/// --no-ignore-dot, and --no-ignore-vcs. *Default:* `false`.
|
||||
pub no_ignore: Option<bool>,
|
||||
/// Don't respect ignore files in parent directories. *Default:* `false`.
|
||||
/// Don't respect ignore files (.gitignore, .ignore, etc.) in parent directories.
|
||||
/// *Default:* `false`.
|
||||
pub no_ignore_parent: Option<bool>,
|
||||
/// Don't respect VCS ignore files. *Default:* `false`.
|
||||
/// Don't respect .ignore and .tokeignore files, including those in parent directories.
|
||||
/// *Default:* `false`.
|
||||
pub no_ignore_dot: Option<bool>,
|
||||
/// Don't respect VCS ignore files (.gitignore, .hgignore, etc.), including those in
|
||||
/// parent directories. *Default:* `false`.
|
||||
pub no_ignore_vcs: Option<bool>,
|
||||
/// Whether to treat doc strings in languages as comments. *Default:*
|
||||
/// `false`.
|
||||
|
@ -107,6 +113,9 @@ impl Config {
|
|||
no_ignore_parent: current_dir
|
||||
.no_ignore_parent
|
||||
.or(home_dir.no_ignore_parent.or(conf_dir.no_ignore_parent)),
|
||||
no_ignore_dot: current_dir
|
||||
.no_ignore_dot
|
||||
.or(home_dir.no_ignore_dot.or(conf_dir.no_ignore_dot)),
|
||||
no_ignore_vcs: current_dir
|
||||
.no_ignore_vcs
|
||||
.or(home_dir.no_ignore_vcs.or(conf_dir.no_ignore_vcs)),
|
||||
|
|
163
src/utils/fs.rs
163
src/utils/fs.rs
|
@ -37,22 +37,23 @@ pub fn get_all_files<A: AsRef<Path>>(
|
|||
walker.overrides(overrides.build().expect("Excludes provided were invalid"));
|
||||
}
|
||||
|
||||
// Flip the booleans as ignore's semantics are the opposite of our options.
|
||||
let no_ignore_vcs = config.no_ignore_vcs.map(|b| !b).unwrap_or(true);
|
||||
let ignore = config.no_ignore.map(|b| !b).unwrap_or(true);
|
||||
let ignore_dot = ignore && config.no_ignore_dot.map(|b| !b).unwrap_or(true);
|
||||
let ignore_vcs = ignore && config.no_ignore_vcs.map(|b| !b).unwrap_or(true);
|
||||
|
||||
// Custom ignore files always work even if the `ignore` option is false,
|
||||
// so we only add if that option is not present.
|
||||
if !config.no_ignore.unwrap_or(false) {
|
||||
if ignore_dot {
|
||||
walker.add_custom_ignore_filename(IGNORE_FILE);
|
||||
}
|
||||
|
||||
walker
|
||||
.git_exclude(no_ignore_vcs)
|
||||
.git_global(no_ignore_vcs)
|
||||
.git_ignore(no_ignore_vcs)
|
||||
.git_exclude(ignore_vcs)
|
||||
.git_global(ignore_vcs)
|
||||
.git_ignore(ignore_vcs)
|
||||
.hidden(config.hidden.map(|b| !b).unwrap_or(true))
|
||||
.ignore(config.no_ignore.map(|b| !b).unwrap_or(true))
|
||||
.parents(config.no_ignore_parent.map(|b| !b).unwrap_or(true));
|
||||
.ignore(ignore_dot)
|
||||
.parents(ignore && config.no_ignore_parent.map(|b| !b).unwrap_or(true));
|
||||
|
||||
walker.build_parallel().run(move || {
|
||||
let tx = tx.clone();
|
||||
|
@ -182,13 +183,11 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn no_ignore() {
|
||||
fn no_ignore_implies_dot() {
|
||||
let dir = TempDir::new().expect("Couldn't create temp dir.");
|
||||
let mut config = Config::default();
|
||||
let mut languages = Languages::new();
|
||||
|
||||
//git2::Repository::init(dir.path()).expect("Couldn't create git repo.");
|
||||
|
||||
fs::write(dir.path().join(".ignore"), IGNORE_PATTERN).unwrap();
|
||||
fs::write(dir.path().join(FILE_NAME), FILE_CONTENTS).unwrap();
|
||||
|
||||
|
@ -213,9 +212,41 @@ mod tests {
|
|||
assert!(languages.get(LANGUAGE).is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_ignore_implies_vcs_gitignore() {
|
||||
let dir = TempDir::new().expect("Couldn't create temp dir.");
|
||||
let mut config = Config::default();
|
||||
let mut languages = Languages::new();
|
||||
|
||||
git2::Repository::init(dir.path()).expect("Couldn't create git repo.");
|
||||
|
||||
fs::write(dir.path().join(".gitignore"), IGNORE_PATTERN).unwrap();
|
||||
fs::write(dir.path().join(FILE_NAME), FILE_CONTENTS).unwrap();
|
||||
|
||||
super::get_all_files(
|
||||
&[dir.path().to_str().unwrap()],
|
||||
&[],
|
||||
&mut languages,
|
||||
&config,
|
||||
);
|
||||
|
||||
assert!(languages.get(LANGUAGE).is_none());
|
||||
|
||||
config.no_ignore = Some(true);
|
||||
|
||||
super::get_all_files(
|
||||
&[dir.path().to_str().unwrap()],
|
||||
&[],
|
||||
&mut languages,
|
||||
&config,
|
||||
);
|
||||
|
||||
assert!(languages.get(LANGUAGE).is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_ignore_parent() {
|
||||
let parent_dir = TempDir::new().expect("Couldn't create temp dir");
|
||||
let parent_dir = TempDir::new().expect("Couldn't create temp dir.");
|
||||
let child_dir = parent_dir.path().join("child/");
|
||||
let mut config = Config::default();
|
||||
let mut languages = Languages::new();
|
||||
|
@ -233,7 +264,7 @@ mod tests {
|
|||
&config,
|
||||
);
|
||||
|
||||
assert_eq!(None, languages.get(&LanguageType::Rust));
|
||||
assert!(languages.get(LANGUAGE).is_none());
|
||||
|
||||
config.no_ignore_parent = Some(true);
|
||||
|
||||
|
@ -244,7 +275,90 @@ mod tests {
|
|||
&config,
|
||||
);
|
||||
|
||||
assert!(languages.get(&LanguageType::Rust).is_some());
|
||||
assert!(languages.get(LANGUAGE).is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_ignore_dot() {
|
||||
let dir = TempDir::new().expect("Couldn't create temp dir.");
|
||||
let mut config = Config::default();
|
||||
let mut languages = Languages::new();
|
||||
|
||||
fs::write(dir.path().join(".ignore"), IGNORE_PATTERN).unwrap();
|
||||
fs::write(dir.path().join(FILE_NAME), FILE_CONTENTS).unwrap();
|
||||
|
||||
super::get_all_files(
|
||||
&[dir.path().to_str().unwrap()],
|
||||
&[],
|
||||
&mut languages,
|
||||
&config,
|
||||
);
|
||||
|
||||
assert!(languages.get(LANGUAGE).is_none());
|
||||
|
||||
config.no_ignore_dot = Some(true);
|
||||
|
||||
super::get_all_files(
|
||||
&[dir.path().to_str().unwrap()],
|
||||
&[],
|
||||
&mut languages,
|
||||
&config,
|
||||
);
|
||||
|
||||
assert!(languages.get(LANGUAGE).is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_ignore_dot_still_vcs_gitignore() {
|
||||
let dir = TempDir::new().expect("Couldn't create temp dir.");
|
||||
let mut config = Config::default();
|
||||
let mut languages = Languages::new();
|
||||
|
||||
git2::Repository::init(dir.path()).expect("Couldn't create git repo.");
|
||||
|
||||
fs::write(dir.path().join(".gitignore"), IGNORE_PATTERN).unwrap();
|
||||
fs::write(dir.path().join(FILE_NAME), FILE_CONTENTS).unwrap();
|
||||
|
||||
config.no_ignore_dot = Some(true);
|
||||
|
||||
super::get_all_files(
|
||||
&[dir.path().to_str().unwrap()],
|
||||
&[],
|
||||
&mut languages,
|
||||
&config,
|
||||
);
|
||||
|
||||
assert!(languages.get(LANGUAGE).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_ignore_dot_includes_custom_ignore() {
|
||||
let dir = TempDir::new().expect("Couldn't create temp dir.");
|
||||
let mut config = Config::default();
|
||||
let mut languages = Languages::new();
|
||||
|
||||
fs::write(dir.path().join(IGNORE_FILE), IGNORE_PATTERN).unwrap();
|
||||
fs::write(dir.path().join(FILE_NAME), FILE_CONTENTS).unwrap();
|
||||
|
||||
super::get_all_files(
|
||||
&[dir.path().to_str().unwrap()],
|
||||
&[],
|
||||
&mut languages,
|
||||
&config,
|
||||
);
|
||||
|
||||
assert!(languages.get(LANGUAGE).is_none());
|
||||
|
||||
config.no_ignore_dot = Some(true);
|
||||
|
||||
super::get_all_files(
|
||||
&[dir.path().to_str().unwrap()],
|
||||
&[],
|
||||
&mut languages,
|
||||
&config,
|
||||
);
|
||||
|
||||
assert!(languages.get(LANGUAGE).is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -279,6 +393,27 @@ mod tests {
|
|||
assert!(languages.get(LANGUAGE).is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_ignore_vcs_gitignore_still_dot() {
|
||||
let dir = TempDir::new().expect("Couldn't create temp dir.");
|
||||
let mut config = Config::default();
|
||||
let mut languages = Languages::new();
|
||||
|
||||
fs::write(dir.path().join(".ignore"), IGNORE_PATTERN).unwrap();
|
||||
fs::write(dir.path().join(FILE_NAME), FILE_CONTENTS).unwrap();
|
||||
|
||||
config.no_ignore_vcs = Some(true);
|
||||
|
||||
super::get_all_files(
|
||||
&[dir.path().to_str().unwrap()],
|
||||
&[],
|
||||
&mut languages,
|
||||
&config,
|
||||
);
|
||||
|
||||
assert!(languages.get(LANGUAGE).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_ignore_vcs_gitexclude() {
|
||||
let dir = TempDir::new().expect("Couldn't create temp dir.");
|
||||
|
|
Loading…
Reference in a new issue