added -X
for excluding sets of extensions. -X
is to -E
as -x
is to -e
.
This commit is contained in:
parent
b3ce5d3d46
commit
22f1f280d7
3 changed files with 67 additions and 19 deletions
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -4,10 +4,11 @@ Dates are given in YYYY-MM-DD format.
|
|||
## v0.2
|
||||
### v0.2.14 (2021-xx-yy)
|
||||
#### Features
|
||||
- Added `-x`/`--exclude` flag for excluding file extensions (overrides `-e` or `-E`)
|
||||
|
||||
- Added `-x`/`--exclude` flag for excluding file extensions (overrides `-e` or `-E` - `-E images -x jpg` scans all image
|
||||
files, except ".jpg" files)
|
||||
- Added `-X`/`--exclude-set` flag for excluding sets of files (like `-E`)
|
||||
#### Other
|
||||
- Publish my fork of ['mime_guess'] as ['new_mime_guess'], allowing it to be used properly with
|
||||
- Published my fork of ['mime_guess'] as ['new_mime_guess'], allowing it to be used properly with
|
||||
[crates.io](https://crates.io)
|
||||
|
||||
### v0.2.13 (2021-04-26)
|
||||
|
@ -152,5 +153,5 @@ Initial commit!
|
|||
[`clap`]: https://crates.io/crates/clap
|
||||
[`infer`]: https://crates.io/crates/infer
|
||||
[`mime_guess`]: https://crates.io/crates/mime_guess
|
||||
[`new_mime_guess`]: https://crates.io/crates/mime_guess
|
||||
[`snailquote`]: https://crates.io/crates/snailquote
|
||||
[`new_mime_guess`]: https://crates.io/crates/new_mime_guess
|
||||
[`snailquote`]: https://crates.io/crates/snailquote
|
||||
|
|
|
@ -55,7 +55,9 @@ pub struct Parameters {
|
|||
#[clap(short = 'x', long, use_delimiter = true, require_delimiter = true)]
|
||||
pub exclude: Option<Vec<StringType>>,
|
||||
|
||||
// TODO: -X/--exclude-set - allows you to exclude all extensions in a set, e.g. "-X documents"
|
||||
/// Exclude files using a preset list of extensions.
|
||||
#[clap(short = 'X', long, arg_enum)]
|
||||
pub exclude_set: Option<ExtensionSet>,
|
||||
|
||||
/// Don't skip hidden files and directories.
|
||||
/// Even if this flag is not present, fif will still recurse into a hidden root directory - for example, `fif
|
||||
|
@ -133,10 +135,26 @@ impl Parameters {
|
|||
}
|
||||
|
||||
pub fn excluded_extensions(&self) -> Option<Vec<&str>> {
|
||||
self
|
||||
.exclude
|
||||
.as_ref()
|
||||
.map(|exclude| exclude.iter().map(|ext| ext.as_str()).collect())
|
||||
// start with an empty vec
|
||||
let mut excluded = vec![];
|
||||
if let Some(exclude) = self.exclude.as_ref() {
|
||||
// add extensions excluded by `-x`
|
||||
excluded.append(&mut exclude.iter().map(|ext| ext.as_str()).collect());
|
||||
}
|
||||
|
||||
if let Some(exclude_set) = &self.exclude_set {
|
||||
// add extensions excluded by `-X`
|
||||
excluded.append(&mut exclude_set.extensions());
|
||||
}
|
||||
|
||||
if excluded.is_empty() {
|
||||
// no extensions to exclude - return none
|
||||
None
|
||||
} else {
|
||||
// excluded doesn't sound like a word anymore
|
||||
// tongue twister: enter X-options' excellent extension exclusion
|
||||
Some(excluded)
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn get_scan_opts(&self) -> ScanOpts {
|
||||
|
|
|
@ -7,10 +7,13 @@ use crate::{extension_from_path, scan_directory, scan_from_walkdir};
|
|||
|
||||
use mime_guess::mime::{APPLICATION_OCTET_STREAM, APPLICATION_PDF, IMAGE_JPEG, IMAGE_PNG};
|
||||
use mime_guess::Mime;
|
||||
use crate::parameters::Parameters;
|
||||
use clap::Clap;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsStr;
|
||||
use std::path::Path;
|
||||
use crate::parameters::ExtensionSet;
|
||||
|
||||
const JPEG_BYTES: &[u8] = b"\xFF\xD8\xFF";
|
||||
const PNG_BYTES: &[u8] = b"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A";
|
||||
|
@ -167,8 +170,7 @@ fn simple_directory() {
|
|||
#[test]
|
||||
/// Ensure that command line argument parsing works correctly - flags are interpreted, booleans are set, and so on.
|
||||
fn argument_parsing() {
|
||||
use crate::parameters::{Parameters, ScanOpts};
|
||||
use clap::Clap;
|
||||
use crate::parameters::ScanOpts;
|
||||
|
||||
// pass `-f`, which enables following symlinks, and `-E images`, which scans files with image extensions
|
||||
let args: Parameters = Parameters::parse_from(vec!["fif", "-f", "-E", "images"]);
|
||||
|
@ -204,11 +206,8 @@ fn argument_parsing() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
/// Ensure exclude overrides `-e` and `-E`.
|
||||
/// Ensure the `exclude` flag (`-x`) overrides `-e` and `-E`.
|
||||
fn exclude_overrides() {
|
||||
use crate::parameters::Parameters;
|
||||
use clap::Clap;
|
||||
|
||||
// pass `-E images`, which includes many image extensions, and `-x jpg,png`, which should remove "jpg" and "png" from
|
||||
// the extensions list
|
||||
let args: Parameters = Parameters::parse_from(vec!["fif", "-x", "jpg,png", "-E", "images"]);
|
||||
|
@ -232,12 +231,42 @@ fn exclude_overrides() {
|
|||
assert!(extensions.contains(&"jkl"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// Ensure the `exclude_set` flag (`-X`) overrides `-e`.
|
||||
fn exclude_set_overrides_includes() {
|
||||
// pass `-e jpg,flac` and `-X images` -- which should produce the equivalent of `-e flag`
|
||||
let args: Parameters = Parameters::parse_from(vec!["fif", "-e", "jpg,flac", "-X", "images"]);
|
||||
let extensions = args.extensions();
|
||||
assert!(extensions.is_some(), "Extensions should be set!");
|
||||
let mut extensions = extensions.unwrap().into_iter();
|
||||
|
||||
assert_eq!(extensions.next(), Some("flac"), "Extensions should contain flac!");
|
||||
assert_eq!(extensions.next(), None, "Too many extensions!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// Ensure the `exclude_set` flag (`-X`) overrides `-E`.
|
||||
fn exclude_set_overrides_include_set() {
|
||||
// pass `-E media` and `-X images` -- which should produce the equivalent of `-E audio,videos`
|
||||
let args: Parameters = Parameters::parse_from(vec!["fif", "-E", "media", "-X", "images"]);
|
||||
let extensions = args.extensions();
|
||||
assert!(extensions.is_some(), "Extensions should be set!");
|
||||
let extensions = extensions.unwrap();
|
||||
|
||||
// ensure all of audio and video's extensions are here
|
||||
for &ext in ExtensionSet::Audio.extensions().iter().chain(ExtensionSet::Videos.extensions().iter()) {
|
||||
assert!(extensions.contains(&ext), "Extensions should contain {}!", ext)
|
||||
}
|
||||
|
||||
// ensure all of images' extensions are excluded
|
||||
for ext in ExtensionSet::Images.extensions() {
|
||||
assert!(!extensions.contains(&ext), "Extensions should not contain {}!", ext)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// Ensure that badly formed command line arguments are rejected.
|
||||
fn rejects_bad_args() {
|
||||
use crate::parameters::Parameters;
|
||||
|
||||
use clap::Clap;
|
||||
let tests = [
|
||||
// Non-existent flags:
|
||||
vec!["fif", "-abcdefghijklmnopqrstuvwxyz"],
|
||||
|
|
Loading…
Reference in a new issue