new option for scanning extensionless files, nicer #[cfg]s, -s no longer skips hidden root dir...
This commit is contained in:
parent
4412161193
commit
8a152d4118
6 changed files with 47 additions and 18 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -168,7 +168,7 @@ checksum = "de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193"
|
|||
|
||||
[[package]]
|
||||
name = "fif"
|
||||
version = "0.2.7"
|
||||
version = "0.2.8"
|
||||
dependencies = [
|
||||
"cached",
|
||||
"cfg-if",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "fif"
|
||||
description = "A command-line tool for detecting and optionally correcting files with incorrect extensions."
|
||||
version = "0.2.7"
|
||||
version = "0.2.8"
|
||||
authors = ["Lynnesbian <lynne@bune.city>"]
|
||||
edition = "2018"
|
||||
license = "GPL-3.0-or-later"
|
||||
|
@ -35,7 +35,7 @@ rayon = { version = "1.5.0", optional = true }
|
|||
exitcode = "1.1.2"
|
||||
cfg-if = "1.0.0"
|
||||
|
||||
[target.'cfg(any(unix, target_os="redox"))'.dependencies]
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
xdg-mime = "0.3"
|
||||
|
||||
[patch.crates-io]
|
||||
|
|
30
src/main.rs
30
src/main.rs
|
@ -29,7 +29,7 @@ use walkdir::{DirEntry, WalkDir};
|
|||
use crate::findings::Findings;
|
||||
use crate::formats::{Format, Script};
|
||||
use crate::mime_db::MimeDb;
|
||||
use crate::parameters::OutputFormat;
|
||||
use crate::parameters::{OutputFormat, ScanOpts};
|
||||
use crate::scan_error::ScanError;
|
||||
use env_logger::Env;
|
||||
use std::process::exit;
|
||||
|
@ -46,7 +46,7 @@ mod scan_error;
|
|||
mod tests;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(all(not(unix), not(feature = "xdg-mime-backend")), all(unix, feature = "infer-backend")))] {
|
||||
if #[cfg(any(all(unix, feature = "infer-backend"), all(not(unix), not(feature = "xdg-mime-backend"))))] {
|
||||
/// A [OnceCell] holding an instance of [mime_db::MimeDb].
|
||||
static MIMEDB: OnceCell<mime_db::InferDb> = OnceCell::new();
|
||||
/// The backend being used; either "Infer" or "XDG-Mime".
|
||||
|
@ -80,7 +80,7 @@ fn main() {
|
|||
|
||||
debug!("Checking files with extensions: {:?}", extensions);
|
||||
|
||||
let entries = scan_directory(&args.dirs, &extensions, args.scan_hidden);
|
||||
let entries = scan_directory(&args.dirs, &extensions, &args.get_scan_opts());
|
||||
|
||||
if entries.is_none() {
|
||||
// no need to log anything for fatal errors - fif will already have printed something obvious like
|
||||
|
@ -161,9 +161,15 @@ cfg_if! {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if a file matches the given criteria.
|
||||
fn wanted_file(scan_hidden: bool, exts: &[&str], entry: &DirEntry) -> bool {
|
||||
if !scan_hidden && is_hidden(entry) {
|
||||
/// Returns `true` if a file matches the given criteria. This means checking whether the file's extension appears in
|
||||
/// `exts`, potentially skipping over hidden files, and so on.
|
||||
fn wanted_file(entry: &DirEntry, exts: &[&str], scan_opts: &ScanOpts) -> bool {
|
||||
if entry.depth() == 0 {
|
||||
// the root directory should always be scanned.
|
||||
return true;
|
||||
}
|
||||
|
||||
if !scan_opts.hidden && is_hidden(entry) {
|
||||
// skip hidden files and directories. this check is performed first because it's very lightweight.
|
||||
return false;
|
||||
}
|
||||
|
@ -175,9 +181,10 @@ fn wanted_file(scan_hidden: bool, exts: &[&str], entry: &DirEntry) -> bool {
|
|||
|
||||
let ext = extension_from_path(entry.path());
|
||||
|
||||
if ext.is_none() {
|
||||
if ext.is_none() && !scan_opts.extensionless {
|
||||
// don't scan files without extensions.
|
||||
return false;
|
||||
} // don't scan files without extensions. TODO - this should be configurable
|
||||
}
|
||||
|
||||
exts.contains(&ext.unwrap().to_lowercase().as_str())
|
||||
}
|
||||
|
@ -186,6 +193,7 @@ fn wanted_file(scan_hidden: bool, exts: &[&str], entry: &DirEntry) -> bool {
|
|||
///
|
||||
/// The extension is currently [converted to a lossy string](std::ffi::OsStr::to_string_lossy), although it will
|
||||
/// (eventually) in future return an OsStr instead.
|
||||
// TODO: ↑
|
||||
fn extension_from_path(path: &Path) -> Option<String> {
|
||||
path.extension(). // Get the path's extension
|
||||
map(|e| String::from(e.to_string_lossy())) // Convert from OsStr to String
|
||||
|
@ -258,11 +266,11 @@ fn scan_from_walkdir(entries: &[DirEntry]) -> Vec<Result<Findings, ScanError>> {
|
|||
|
||||
/// Scans a given directory with [WalkDir], filters with [wanted_file], checks for errors, and returns a vector of
|
||||
/// [DirEntry]s.
|
||||
fn scan_directory(dirs: &PathBuf, exts: &Vec<&str>, scan_hidden: bool) -> Option<Vec<DirEntry>> {
|
||||
fn scan_directory(dirs: &PathBuf, exts: &Vec<&str>, scan_opts: &ScanOpts) -> Option<Vec<DirEntry>> {
|
||||
let stepper = WalkDir::new(dirs).into_iter();
|
||||
let mut probably_fatal_error = false;
|
||||
let entries: Vec<DirEntry> = stepper
|
||||
.filter_entry(|e| wanted_file(scan_hidden, exts, e)) // filter out unwanted files
|
||||
.filter_entry(|e| wanted_file(e, exts, scan_opts)) // filter out unwanted files
|
||||
.filter_map(|e| {
|
||||
if let Err(err) = &e {
|
||||
debug!("uh oh spaghettio!! {:#?}", e);
|
||||
|
@ -299,7 +307,7 @@ fn scan_directory(dirs: &PathBuf, exts: &Vec<&str>, scan_hidden: bool) -> Option
|
|||
/// Initialises [MIMEDB] with a value dependent on the current backend.
|
||||
fn init_db() {
|
||||
cfg_if! {
|
||||
if #[cfg(any(all(not(unix), not(feature = "xdg-mime-backend")), all(unix, feature = "infer-backend")))] {
|
||||
if #[cfg(any(all(unix, feature = "infer-backend"), all(not(unix), not(feature = "xdg-mime-backend"))))] {
|
||||
MIMEDB
|
||||
.set(mime_db::InferDb::init())
|
||||
.or(Err("Failed to initialise Infer backend!"))
|
||||
|
|
|
@ -9,7 +9,7 @@ pub trait MimeDb {
|
|||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(all(not(target_os = "linux"), not(feature = "xdg-mime-backend")), all(target_os = "linux", feature = "infer-backend")))] {
|
||||
if #[cfg(any(all(unix, feature = "infer-backend"), all(not(unix), not(feature = "xdg-mime-backend"))))] {
|
||||
use std::str::FromStr;
|
||||
|
||||
pub struct InferDb {
|
||||
|
|
|
@ -47,6 +47,10 @@ pub struct Parameters {
|
|||
#[clap(short, long)]
|
||||
pub scan_hidden: bool,
|
||||
|
||||
/// Scan files without extensions
|
||||
#[clap(short = 'S', long)]
|
||||
pub scan_extensionless: bool,
|
||||
|
||||
/// Output format to use
|
||||
#[clap(short, long, default_value = "script", arg_enum)]
|
||||
pub output_format: OutputFormat,
|
||||
|
@ -57,6 +61,14 @@ pub struct Parameters {
|
|||
pub dirs: PathBuf,
|
||||
}
|
||||
|
||||
/// Further options relating to scanning.
|
||||
pub struct ScanOpts {
|
||||
/// Whether hidden files and directories should be scanned.
|
||||
pub hidden: bool,
|
||||
/// Whether files without extensions should be scanned.
|
||||
pub extensionless: bool
|
||||
}
|
||||
|
||||
impl Parameters {
|
||||
pub fn extensions(&self) -> Vec<&str> {
|
||||
if let Some(exts) = &self.exts {
|
||||
|
@ -70,4 +82,8 @@ impl Parameters {
|
|||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_scan_opts(&self) -> ScanOpts {
|
||||
ScanOpts { hidden: self.scan_hidden, extensionless: self.scan_extensionless }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::inspectors::mime_extension_lookup;
|
|||
use crate::mime_db::*;
|
||||
use crate::{extension_from_path, init_db, scan_directory, scan_from_walkdir};
|
||||
|
||||
use crate::parameters::Parameters;
|
||||
use crate::parameters::{Parameters, ScanOpts};
|
||||
use cfg_if::cfg_if;
|
||||
use mime_guess::mime::{APPLICATION_OCTET_STREAM, APPLICATION_PDF, IMAGE_JPEG, IMAGE_PNG};
|
||||
use mime_guess::Mime;
|
||||
|
@ -16,7 +16,7 @@ const PDF_BYTES: &[u8] = b"%PDF-";
|
|||
const ZIP_BYTES: &[u8] = b"PK\x03\x04";
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(all(not(target_os = "linux"), not(feature = "xdg-mime-backend")), all(target_os = "linux", feature = "infer-backend")))] {
|
||||
if #[cfg(any(all(unix, feature = "infer-backend"), all(not(unix), not(feature = "xdg-mime-backend"))))] {
|
||||
fn get_mime_db() -> InferDb {
|
||||
InferDb::init()
|
||||
}
|
||||
|
@ -95,10 +95,15 @@ fn simple_directory() {
|
|||
drop(file);
|
||||
}
|
||||
|
||||
let scan_opts = ScanOpts{
|
||||
hidden: true,
|
||||
extensionless: false
|
||||
};
|
||||
|
||||
let entries = scan_directory(
|
||||
&dir.path().to_path_buf(),
|
||||
&vec!["jpg", "jpeg", "png", "pdf", "zip"],
|
||||
true,
|
||||
&scan_opts,
|
||||
)
|
||||
.expect("Directory scan failed.");
|
||||
|
||||
|
|
Loading…
Reference in a new issue