Compare commits
No commits in common. "02f377cbb2363673152c69bc1e73d02ca94ff045" and "df9c033b3820f49e7467c15ab1dcff592016c9b6" have entirely different histories.
02f377cbb2
...
df9c033b38
13 changed files with 61 additions and 149 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -9,4 +9,3 @@ fif_*
|
||||||
cargo-timing*.html
|
cargo-timing*.html
|
||||||
todo.txt
|
todo.txt
|
||||||
/pkg/*
|
/pkg/*
|
||||||
/out
|
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
<excludeFolder url="file://$MODULE_DIR$/awful" />
|
<excludeFolder url="file://$MODULE_DIR$/awful" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/.mypy_cache" />
|
<excludeFolder url="file://$MODULE_DIR$/.mypy_cache" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/pkg" />
|
<excludeFolder url="file://$MODULE_DIR$/pkg" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/out" />
|
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
|
26
CHANGELOG.md
26
CHANGELOG.md
|
@ -2,17 +2,7 @@
|
||||||
Dates are given in YYYY-MM-DD format.
|
Dates are given in YYYY-MM-DD format.
|
||||||
|
|
||||||
## v0.3
|
## v0.3
|
||||||
### v0.3.2 (2021-06-14)
|
### v0.3.1 (2021-07-06)
|
||||||
#### Bugfixes
|
|
||||||
- Fixed PowerShell output regression introduced in v0.2.13, whoops
|
|
||||||
#### Other
|
|
||||||
- Nicer version output: `fif -V` reports "fif v0.3.2" (instead of just "fif 0.3.2" without the "v"), and `fif --version`
|
|
||||||
reports `fif v0.3.2 (XDG-Mime backend)`, or whatever backend you're using
|
|
||||||
- fif's trace output now includes its version, backend, operating system, and architecture
|
|
||||||
- Block compilation if both the `xdg-mime-backend` and `infer-backend`
|
|
||||||
[features](https://gitlab.com/Lynnesbian/fif/-/wikis/Cargo-Features) are enabled
|
|
||||||
|
|
||||||
### v0.3.1 (2021-06-07)
|
|
||||||
#### Features
|
#### Features
|
||||||
- Added JSON output support via `-o json`
|
- Added JSON output support via `-o json`
|
||||||
- Added plaintext output support via `-o text`
|
- Added plaintext output support via `-o text`
|
||||||
|
@ -60,7 +50,7 @@ Dates are given in YYYY-MM-DD format.
|
||||||
- Added .rpa (Ren'Py archive) support to infer backend
|
- Added .rpa (Ren'Py archive) support to infer backend
|
||||||
- [`xdg-mime`] no longer uses git version
|
- [`xdg-mime`] no longer uses git version
|
||||||
- Output `\r\n` on Windows
|
- Output `\r\n` on Windows
|
||||||
- Use a macro to generate `Writable` arrays, making the code a little cleaner and nicer to write
|
- Use a macro to generate `Writable` arrays, making the code a little bit cleaner and nicer to write
|
||||||
|
|
||||||
### v0.2.12 (2021-04-14)
|
### v0.2.12 (2021-04-14)
|
||||||
#### Features
|
#### Features
|
||||||
|
@ -83,13 +73,13 @@ Dates are given in YYYY-MM-DD format.
|
||||||
(files without extensions are still skipped unless the -S flag is used)
|
(files without extensions are still skipped unless the -S flag is used)
|
||||||
#### Bugfixes
|
#### Bugfixes
|
||||||
- Fixed compilation on big endian 32-bit architectures (see
|
- Fixed compilation on big endian 32-bit architectures (see
|
||||||
[here](https://github.com/bodil/smartstring/blob/v0.2.6/src/config.rs#L101-L103) for why that was a problem in the
|
[here](https://github.com/bodil/smartstring/blob/v0.2.6/src/config.rs#L101-L103) for why that was a problem in the first
|
||||||
first place)
|
place)
|
||||||
- Fixed broken tests for the [`infer`] backend
|
- Fixed broken tests for the [`infer`] backend
|
||||||
#### Other
|
#### Other
|
||||||
- Better mime type detection:
|
- Better mime type detection:
|
||||||
- Consider "some/x-thing" and "some/thing" to be identical
|
- Consider "some/x-thing" and "some/thing" to be identical
|
||||||
- Use a patched version of mime_guess (which took a while to make 0u0;) with many more extension/type mappings
|
- Use a patched version of mime_guess (which took a while to make 0u0;) with many more extension<->type mappings
|
||||||
|
|
||||||
### v0.2.10 (2021-03-26)
|
### v0.2.10 (2021-03-26)
|
||||||
- PowerShell support!
|
- PowerShell support!
|
||||||
|
@ -119,7 +109,7 @@ Dates are given in YYYY-MM-DD format.
|
||||||
### v0.2.6 (2021-02-28)
|
### v0.2.6 (2021-02-28)
|
||||||
- Added tests!
|
- Added tests!
|
||||||
- Default to [`xdg-mime`] on all Unixy platforms, not just Linux - this also includes the various *BSDs (I've tested
|
- Default to [`xdg-mime`] on all Unixy platforms, not just Linux - this also includes the various *BSDs (I've tested
|
||||||
FreeBSD), macOS (haven't tested, but I have a very old MacBook running Leopard that has `file` preinstalled, so it
|
FreeBSD), macOS (haven't tested, but I have a very old MacBook running Leopard that has file preinstalled, so it
|
||||||
*should* work fine), Redox OS (haven't tested), etc.
|
*should* work fine), Redox OS (haven't tested), etc.
|
||||||
|
|
||||||
### v0.2.5 (2021-02-27)
|
### v0.2.5 (2021-02-27)
|
||||||
|
@ -153,7 +143,7 @@ Dates are given in YYYY-MM-DD format.
|
||||||
#### Features
|
#### Features
|
||||||
- Added extension sets -- you can now use, for example, `-E images` to check files with known image extensions
|
- Added extension sets -- you can now use, for example, `-E images` to check files with known image extensions
|
||||||
- Shell script output now uses `printf` instead of `echo`
|
- Shell script output now uses `printf` instead of `echo`
|
||||||
- Added [`infer`] backend, configurable with [Cargo features](https://gitlab.com/Lynnesbian/fif/-/wikis/Cargo-Features)
|
- Added [`infer`] backend
|
||||||
#### Bugfixes
|
#### Bugfixes
|
||||||
- Fixed broken singlethreaded support
|
- Fixed broken singlethreaded support
|
||||||
#### Other
|
#### Other
|
||||||
|
@ -176,7 +166,7 @@ Dates are given in YYYY-MM-DD format.
|
||||||
### v0.1.0 (2021-02-04)
|
### v0.1.0 (2021-02-04)
|
||||||
Initial commit!
|
Initial commit!
|
||||||
- Only one backend - [`xdg-mime`]
|
- Only one backend - [`xdg-mime`]
|
||||||
- No output formats - just prints a list of files to be renamed
|
- Prints files directly rather than outputting a script
|
||||||
- Only supported flags are `-e` (specify extensions) and `-s` (scan hidden files)
|
- Only supported flags are `-e` (specify extensions) and `-s` (scan hidden files)
|
||||||
|
|
||||||
<!-- links -->
|
<!-- links -->
|
||||||
|
|
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -183,7 +183,7 @@ checksum = "de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fif"
|
name = "fif"
|
||||||
version = "0.3.2"
|
version = "0.3.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cached",
|
"cached",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
@ -369,9 +369,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.8.0"
|
version = "1.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_str_bytes"
|
name = "os_str_bytes"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "fif"
|
name = "fif"
|
||||||
description = "A command-line tool for detecting and optionally correcting files with incorrect extensions."
|
description = "A command-line tool for detecting and optionally correcting files with incorrect extensions."
|
||||||
version = "0.3.2"
|
version = "0.3.1"
|
||||||
authors = ["Lynnesbian <lynne@bune.city>"]
|
authors = ["Lynnesbian <lynne@bune.city>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
|
@ -29,7 +29,7 @@ walkdir = "2.3.2"
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
mime_guess = { package = "new_mime_guess", version = "2.1.0" }
|
mime_guess = { package = "new_mime_guess", version = "2.1.0" }
|
||||||
snailquote = "0.3.0"
|
snailquote = "0.3.0"
|
||||||
once_cell = "1.8.0"
|
once_cell = "1.7.2"
|
||||||
rayon = { version = "1.5.0", optional = true }
|
rayon = { version = "1.5.0", optional = true }
|
||||||
exitcode = "1.1.2"
|
exitcode = "1.1.2"
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
|
|
10
build.rs
10
build.rs
|
@ -1,10 +0,0 @@
|
||||||
#[allow(unreachable_code, clippy::pedantic)]
|
|
||||||
fn main() -> Result<(), String> {
|
|
||||||
#[cfg(all(feature = "infer-backend", feature = "xdg-mime-backend"))]
|
|
||||||
// fail build if the user has set both the infer and xdg-mime backends
|
|
||||||
return Err(String::from(
|
|
||||||
"fif cannot be compiled with multiple backends set - please enable only one, or use the default.",
|
|
||||||
));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
38
clippy.sh
38
clippy.sh
|
@ -2,36 +2,30 @@
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
_extra=""
|
_extra=""
|
||||||
_ver="+stable"
|
|
||||||
if [ "$1" == "ci" ]; then
|
if [ "$1" == "ci" ]; then
|
||||||
# deny on warnings when running in CI
|
# deny on warnings when running in CI
|
||||||
_extra="-Dwarnings"
|
_extra="-Dwarnings"
|
||||||
elif [ "$1" == "nightly" ]; then
|
|
||||||
_ver="+nightly"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# allow find to fail
|
# allow find to fail
|
||||||
find . -name '*.rs' -exec touch "{}" \; || true
|
find . -name '*.rs' -exec touch "{}" \; || true
|
||||||
|
|
||||||
_backends=( "xdg-mime-backend" "infer-backend" )
|
cargo clippy --all-features --tests -- \
|
||||||
|
-W clippy::nursery \
|
||||||
for backend in "${_backends[@]}"; do
|
-W clippy::perf \
|
||||||
cargo $_ver clippy --tests --features="$backend" -- \
|
-W clippy::pedantic \
|
||||||
-W clippy::nursery \
|
-W clippy::complexity \
|
||||||
-W clippy::perf \
|
-W clippy::cargo \
|
||||||
-W clippy::pedantic \
|
-W clippy::float_cmp_const \
|
||||||
-W clippy::complexity \
|
-W clippy::lossy_float_literal \
|
||||||
-W clippy::cargo \
|
-W clippy::multiple_inherent_impl \
|
||||||
-W clippy::float_cmp_const \
|
-W clippy::string_to_string \
|
||||||
-W clippy::lossy_float_literal \
|
-W clippy::wrong_pub_self_convention \
|
||||||
-W clippy::multiple_inherent_impl \
|
-A clippy::unused_io_amount \
|
||||||
-W clippy::string_to_string \
|
-A clippy::redundant_closure_for_method_calls \
|
||||||
-A clippy::unused_io_amount \
|
-A clippy::shadow_unrelated \
|
||||||
-A clippy::redundant_closure_for_method_calls \
|
-A clippy::option_if_let_else \
|
||||||
-A clippy::shadow_unrelated \
|
"$_extra"
|
||||||
-A clippy::option_if_let_else \
|
|
||||||
"$_extra"
|
|
||||||
done
|
|
||||||
|
|
||||||
# ALLOWS:
|
# ALLOWS:
|
||||||
# unused_io_amount: there are two places where i want to read up to X bytes and i'm fine with getting less than that
|
# unused_io_amount: there are two places where i want to read up to X bytes and i'm fine with getting less than that
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
# avoid-breaking-exported-api = false # only available on nightly for now
|
|
||||||
cognitive-complexity-threshold = 15
|
|
|
@ -10,8 +10,7 @@ use cfg_if::cfg_if;
|
||||||
use snailquote::escape;
|
use snailquote::escape;
|
||||||
|
|
||||||
use crate::findings::ScanError;
|
use crate::findings::ScanError;
|
||||||
use crate::utils::clap_long_version;
|
use crate::{Findings, BACKEND};
|
||||||
use crate::Findings;
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
/// A macro for creating an array of `Writable`s without needing to pepper your code with `into()`s.
|
/// A macro for creating an array of `Writable`s without needing to pepper your code with `into()`s.
|
||||||
|
@ -50,6 +49,9 @@ macro_rules! writablesln {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The current version of fif, as defined in Cargo.toml.
|
||||||
|
const VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
type Entries<'a> = [Result<Findings<'a>, ScanError<'a>>];
|
type Entries<'a> = [Result<Findings<'a>, ScanError<'a>>];
|
||||||
|
|
||||||
|
@ -74,7 +76,7 @@ impl<'a> From<&'a OsStr> for Writable<'a> {
|
||||||
fn from(p: &'a OsStr) -> Writable<'a> { Writable::Path(p.as_ref()) }
|
fn from(p: &'a OsStr) -> Writable<'a> { Writable::Path(p.as_ref()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generated_by() -> String { format!("Generated by fif {}", clap_long_version()) }
|
fn generated_by() -> String { format!("Generated by fif {} ({} backend)", VERSION.unwrap_or("???"), BACKEND) }
|
||||||
|
|
||||||
fn smart_write<W: Write>(f: &mut W, writeables: &[Writable]) -> io::Result<()> {
|
fn smart_write<W: Write>(f: &mut W, writeables: &[Writable]) -> io::Result<()> {
|
||||||
// ehhhh
|
// ehhhh
|
||||||
|
@ -84,9 +86,9 @@ fn smart_write<W: Write>(f: &mut W, writeables: &[Writable]) -> io::Result<()> {
|
||||||
Writable::Newline => {
|
Writable::Newline => {
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
if #[cfg(windows)] {
|
if #[cfg(windows)] {
|
||||||
write!(f, "\r\n")?;
|
write!(f, "\r\n")?
|
||||||
} else {
|
} else {
|
||||||
writeln!(f,)?;
|
writeln!(f,)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,9 +100,9 @@ fn smart_write<W: Write>(f: &mut W, writeables: &[Writable]) -> io::Result<()> {
|
||||||
// the escaped string is the same as the input - this will occur for inputs like "file.txt" which don't
|
// the escaped string is the same as the input - this will occur for inputs like "file.txt" which don't
|
||||||
// need to be escaped. however, it's Best Practice™ to escape such strings anyway, so we prefix/suffix the
|
// need to be escaped. however, it's Best Practice™ to escape such strings anyway, so we prefix/suffix the
|
||||||
// escaped string with single quotes.
|
// escaped string with single quotes.
|
||||||
write!(f, "'{}'", escaped)?;
|
write!(f, "'{}'", escaped)?
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{}", escaped)?;
|
write!(f, "{}", escaped)?
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
write!(f, "'")?;
|
write!(f, "'")?;
|
||||||
|
@ -114,7 +116,7 @@ fn smart_write<W: Write>(f: &mut W, writeables: &[Writable]) -> io::Result<()> {
|
||||||
f.write_all(&*path.as_os_str().as_bytes())?;
|
f.write_all(&*path.as_os_str().as_bytes())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write!(f, "'")?;
|
write!(f, "'")?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,9 +171,9 @@ pub trait Format {
|
||||||
|
|
||||||
for finding in findings {
|
for finding in findings {
|
||||||
if let Some(ext) = finding.recommended_extension() {
|
if let Some(ext) = finding.recommended_extension() {
|
||||||
self.rename(f, finding.file, &finding.file.with_extension(ext.as_str()))?;
|
self.rename(f, finding.file, &finding.file.with_extension(ext.as_str()))?
|
||||||
} else {
|
} else {
|
||||||
self.no_known_extension(f, finding.file)?;
|
self.no_known_extension(f, finding.file)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +242,7 @@ impl Format for PowerShell {
|
||||||
fn no_known_extension<W: Write>(&self, f: &mut W, path: &Path) -> io::Result<()> {
|
fn no_known_extension<W: Write>(&self, f: &mut W, path: &Path) -> io::Result<()> {
|
||||||
smart_write(
|
smart_write(
|
||||||
f,
|
f,
|
||||||
writablesln![
|
writables![
|
||||||
"Write-Output @'",
|
"Write-Output @'",
|
||||||
Newline,
|
Newline,
|
||||||
"No known extension for ",
|
"No known extension for ",
|
||||||
|
@ -254,7 +256,7 @@ impl Format for PowerShell {
|
||||||
fn unreadable<W: Write>(&self, f: &mut W, path: &Path) -> io::Result<()> {
|
fn unreadable<W: Write>(&self, f: &mut W, path: &Path) -> io::Result<()> {
|
||||||
smart_write(
|
smart_write(
|
||||||
f,
|
f,
|
||||||
writablesln!["Write-Output @'", Newline, "Failed to read ", path, Newline, "'@"],
|
writables!["Write-Output @'", Newline, "Failed to read ", path, Newline, "'@"],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
src/main.rs
15
src/main.rs
|
@ -34,7 +34,6 @@ use crate::findings::ScanError;
|
||||||
use crate::formats::{Format, PowerShell, Shell};
|
use crate::formats::{Format, PowerShell, Shell};
|
||||||
use crate::mime_db::MimeDb;
|
use crate::mime_db::MimeDb;
|
||||||
use crate::parameters::{OutputFormat, ScanOpts};
|
use crate::parameters::{OutputFormat, ScanOpts};
|
||||||
use crate::utils::{clap_long_version, os_name};
|
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
mod findings;
|
mod findings;
|
||||||
|
@ -46,20 +45,22 @@ pub(crate) mod string_type;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
mod utils;
|
|
||||||
|
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
if #[cfg(any(all(unix, feature = "infer-backend"), all(not(unix), not(feature = "xdg-mime-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].
|
/// A [OnceCell] holding an instance of [mime_db::MimeDb].
|
||||||
static MIMEDB: OnceCell<mime_db::InferDb> = OnceCell::new();
|
static MIMEDB: OnceCell<mime_db::InferDb> = OnceCell::new();
|
||||||
|
/// The backend being used; either "Infer" or "XDG-Mime".
|
||||||
|
const BACKEND: &str = "Infer";
|
||||||
} else {
|
} else {
|
||||||
/// A [OnceCell] holding an instance of [mime_db::MimeDb].
|
/// A [OnceCell] holding an instance of [mime_db::MimeDb].
|
||||||
static MIMEDB: OnceCell<mime_db::XdgDb> = OnceCell::new();
|
static MIMEDB: OnceCell<mime_db::XdgDb> = OnceCell::new();
|
||||||
|
/// The backend being used; either "Infer" or "XDG-Mime".
|
||||||
|
const BACKEND: &str = "XDG-Mime";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[allow(clippy::cognitive_complexity)]
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: parameters::Parameters = parameters::Parameters::parse();
|
let args: parameters::Parameters = parameters::Parameters::parse();
|
||||||
|
|
||||||
|
@ -72,12 +73,6 @@ fn main() {
|
||||||
// .target(env_logger::Target::Stdout) // log to stdout rather than stderr
|
// .target(env_logger::Target::Stdout) // log to stdout rather than stderr
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
trace!(
|
|
||||||
"fif {}, running on {} {}",
|
|
||||||
clap_long_version(),
|
|
||||||
std::env::consts::ARCH,
|
|
||||||
os_name()
|
|
||||||
);
|
|
||||||
trace!("Initialise mimetype database");
|
trace!("Initialise mimetype database");
|
||||||
init_db();
|
init_db();
|
||||||
|
|
||||||
|
@ -131,7 +126,7 @@ fn main() {
|
||||||
r.file,
|
r.file,
|
||||||
r.mime,
|
r.mime,
|
||||||
r.recommended_extension().unwrap_or_else(|| "???".into())
|
r.recommended_extension().unwrap_or_else(|| "???".into())
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
Err(f) => warn!("{}", f),
|
Err(f) => warn!("{}", f),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
//! [Clap] struct used to parse command line arguments.
|
//! [Clap] struct used to parse command line arguments.
|
||||||
|
|
||||||
use crate::string_type::String as StringType;
|
use crate::string_type::String as StringType;
|
||||||
use crate::utils::{clap_long_version, clap_version};
|
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
use clap::{AppSettings, Clap};
|
use clap::{AppSettings, Clap};
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
@ -34,8 +33,7 @@ pub enum OutputFormat {
|
||||||
|
|
||||||
#[derive(Clap, Debug)]
|
#[derive(Clap, Debug)]
|
||||||
#[clap(
|
#[clap(
|
||||||
version = clap_version(),
|
version = option_env!("CARGO_PKG_VERSION").unwrap_or("???"),
|
||||||
long_version = clap_long_version(),
|
|
||||||
author = option_env!("CARGO_PKG_AUTHORS").unwrap_or("Lynnesbian"),
|
author = option_env!("CARGO_PKG_AUTHORS").unwrap_or("Lynnesbian"),
|
||||||
about = option_env!("CARGO_PKG_DESCRIPTION").unwrap_or("File Info Fixer"),
|
about = option_env!("CARGO_PKG_DESCRIPTION").unwrap_or("File Info Fixer"),
|
||||||
before_help = "Copyright © 2021 Lynnesbian under the GPL3 (or later) License.",
|
before_help = "Copyright © 2021 Lynnesbian under the GPL3 (or later) License.",
|
||||||
|
|
|
@ -49,7 +49,7 @@ fn get_ext() {
|
||||||
ext_checks.insert(Path::new(".hidden"), None);
|
ext_checks.insert(Path::new(".hidden"), None);
|
||||||
|
|
||||||
for (path, ext) in ext_checks {
|
for (path, ext) in ext_checks {
|
||||||
assert_eq!(extension_from_path(path), ext);
|
assert_eq!(extension_from_path(path), ext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ fn argument_parsing() {
|
||||||
follow_symlinks: true,
|
follow_symlinks: true,
|
||||||
},
|
},
|
||||||
"ScanOpts are incorrect"
|
"ScanOpts are incorrect"
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -214,7 +214,7 @@ fn positional_args() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Parameters::parse_from(vec!["fif", flag, "images", "directory"]).dir,
|
Parameters::parse_from(vec!["fif", flag, "images", "directory"]).dir,
|
||||||
PathBuf::from("directory")
|
PathBuf::from("directory")
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,12 +272,12 @@ fn exclude_set_overrides_include_set() {
|
||||||
.iter()
|
.iter()
|
||||||
.chain(ExtensionSet::Video.extensions().iter())
|
.chain(ExtensionSet::Video.extensions().iter())
|
||||||
{
|
{
|
||||||
assert!(extensions.contains(&ext), "Extensions should contain {}!", ext);
|
assert!(extensions.contains(&ext), "Extensions should contain {}!", ext)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure all of images' extensions are excluded
|
// ensure all of images' extensions are excluded
|
||||||
for ext in ExtensionSet::Images.extensions() {
|
for ext in ExtensionSet::Images.extensions() {
|
||||||
assert!(!extensions.contains(&ext), "Extensions should not contain {}!", ext);
|
assert!(!extensions.contains(&ext), "Extensions should not contain {}!", ext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ fn identify_random_bytes() {
|
||||||
for (mime, count) in &results {
|
for (mime, count) in &results {
|
||||||
println!("{}:\t{} counts", mime, count);
|
println!("{}:\t{} counts", mime, count);
|
||||||
}
|
}
|
||||||
println!("No type found:\t{} counts", 500 - results.values().sum::<i32>());
|
println!("No type found:\t{} counts", 500 - results.values().sum::<i32>())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -360,7 +360,7 @@ fn outputs_move_commands() {
|
||||||
"{} output doesn't contain move command!\n===\n{}",
|
"{} output doesn't contain move command!\n===\n{}",
|
||||||
format,
|
format,
|
||||||
contents
|
contents
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +394,7 @@ fn test_json() {
|
||||||
contents.contains(IMAGE_JPEG.essence_str()),
|
contents.contains(IMAGE_JPEG.essence_str()),
|
||||||
"JSON output doesn't contain move command!\n===\n{}",
|
"JSON output doesn't contain move command!\n===\n{}",
|
||||||
contents
|
contents
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -412,7 +412,7 @@ fn media_contains_audio_video_images() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Parameters::parse_from(&["fif", "-E", "media"]).extensions(),
|
Parameters::parse_from(&["fif", "-E", "media"]).extensions(),
|
||||||
Parameters::parse_from(&["fif", "-E", "audio,video,images"]).extensions()
|
Parameters::parse_from(&["fif", "-E", "audio,video,images"]).extensions()
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -429,7 +429,7 @@ fn writables_is_correct() {
|
||||||
Writable::Space
|
Writable::Space
|
||||||
],
|
],
|
||||||
writables!["henlo", (Path::new("henlo")), Newline, Space]
|
writables!["henlo", (Path::new("henlo")), Newline, Space]
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -452,6 +452,6 @@ fn verbosity() {
|
||||||
expected_results.insert("-vvvvvvvv", "trace");
|
expected_results.insert("-vvvvvvvv", "trace");
|
||||||
|
|
||||||
for (flags, level) in expected_results {
|
for (flags, level) in expected_results {
|
||||||
assert_eq!(Parameters::parse_from(&["fif", flags]).default_verbosity(), level);
|
assert_eq!(Parameters::parse_from(&["fif", flags]).default_verbosity(), level)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
53
src/utils.rs
53
src/utils.rs
|
@ -1,53 +0,0 @@
|
||||||
use cfg_if::cfg_if;
|
|
||||||
use once_cell::sync::OnceCell;
|
|
||||||
|
|
||||||
/// The current version of fif, as defined in Cargo.toml.
|
|
||||||
pub const VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION");
|
|
||||||
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(any(all(unix, feature = "infer-backend"), all(not(unix), not(feature = "xdg-mime-backend"))))] {
|
|
||||||
/// The backend being used; either "Infer" or "XDG-Mime".
|
|
||||||
pub const BACKEND: &str = "Infer";
|
|
||||||
} else {
|
|
||||||
/// The backend being used; either "Infer" or "XDG-Mime".
|
|
||||||
pub const BACKEND: &str = "XDG-Mime";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// the version and long_version given to clap need to be a &str, but we want to use format!, which returns a String.
|
|
||||||
// we can't just do something like `version = format!(...).as_str()`, because clap needs to know that the version will
|
|
||||||
// live for a given lifetime, which we need to satisfy by making our String static. of course, you can't use format!
|
|
||||||
// statically, so we need to use a OnceCell or similar to get around this.
|
|
||||||
static CLAP_VERSION: OnceCell<String> = OnceCell::new();
|
|
||||||
static CLAP_LONG_VERSION: OnceCell<String> = OnceCell::new();
|
|
||||||
|
|
||||||
/// Sets [`CLAP_VERSION`] to be the version defined in Cargo.toml, prefixed with a v (e.g. "v0.3.1"), then returns it as
|
|
||||||
/// a String.
|
|
||||||
pub fn clap_version() -> &'static str { CLAP_VERSION.get_or_init(|| format!("v{}", VERSION.unwrap_or("???"))) }
|
|
||||||
|
|
||||||
/// Sets [`CLAP_LONG_VERSION`] to be similar to [`CLAP_VERSION`], followed by the chosen backend in parentheses (e.g.
|
|
||||||
/// "v0.3.1 (XDG-Mime backend)"), then returns it as a String.
|
|
||||||
pub fn clap_long_version() -> &'static str {
|
|
||||||
CLAP_LONG_VERSION.get_or_init(|| format!("v{} ({} backend)", VERSION.unwrap_or("???"), BACKEND))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the name of the target operating system, like "Windows" or "macOS". Won't account for things like Wine or
|
|
||||||
/// Linuxulator.
|
|
||||||
#[allow(clippy::option_map_unit_fn)]
|
|
||||||
pub fn os_name() -> String {
|
|
||||||
use std::env::consts::OS;
|
|
||||||
match OS {
|
|
||||||
"ios" => "iOS".into(),
|
|
||||||
"macos" => "macOS".into(),
|
|
||||||
"freebsd" => "FreeBSD".into(),
|
|
||||||
"openbsd" => "OpenBSD".into(),
|
|
||||||
"netbsd" => "NetBSD".into(),
|
|
||||||
"vxworks" => "VxWorks".into(),
|
|
||||||
_ => {
|
|
||||||
// generic case: return consts::OS with the first letter in uppercase ("linux" -> "Linux")
|
|
||||||
let mut os_upper = String::from(OS);
|
|
||||||
os_upper.get_mut(0..1).map(|first| first.make_ascii_uppercase());
|
|
||||||
os_upper
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue