Compare commits
5 commits
c3b5dbea35
...
2d5d41b162
Author | SHA1 | Date | |
---|---|---|---|
2d5d41b162 | |||
04574e5932 | |||
ca5773c167 | |||
a50350a15e | |||
8341c4aaf7 |
11 changed files with 154 additions and 45 deletions
|
@ -1,13 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="CPP_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="Python" name="Python facet">
|
||||
<configuration sdkName="Python 3.9" />
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/imgs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/old" />
|
||||
|
|
19
.idea/runConfigurations/Coverage.xml
Normal file
19
.idea/runConfigurations/Coverage.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Coverage" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||
<option name="command" value="test" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<option name="channel" value="NIGHTLY" />
|
||||
<option name="requiredFeatures" value="true" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="emulateTerminal" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<envs>
|
||||
<env name="RUST_LOG" value="debug" />
|
||||
</envs>
|
||||
<option name="isRedirectInput" value="false" />
|
||||
<option name="redirectInputPath" value="" />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
19
.idea/runConfigurations/Run.xml
Normal file
19
.idea/runConfigurations/Run.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Run" type="CargoCommandRunConfiguration" factoryName="Cargo Command" nameIsGenerated="true">
|
||||
<option name="command" value="run -- imgs" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="requiredFeatures" value="true" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="emulateTerminal" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<envs>
|
||||
<env name="RUST_LOG" value="debug" />
|
||||
</envs>
|
||||
<option name="isRedirectInput" value="false" />
|
||||
<option name="redirectInputPath" value="" />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
19
.idea/runConfigurations/Test.xml
Normal file
19
.idea/runConfigurations/Test.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Test" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||
<option name="command" value="test" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="requiredFeatures" value="true" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="emulateTerminal" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<envs>
|
||||
<env name="RUST_LOG" value="debug" />
|
||||
</envs>
|
||||
<option name="isRedirectInput" value="false" />
|
||||
<option name="redirectInputPath" value="" />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
19
.idea/runConfigurations/Test__infer_.xml
Normal file
19
.idea/runConfigurations/Test__infer_.xml
Normal file
|
@ -0,0 +1,19 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Test (infer)" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||
<option name="command" value="test --features=infer-backend" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="requiredFeatures" value="true" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="emulateTerminal" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<envs>
|
||||
<env name="RUST_LOG" value="debug" />
|
||||
</envs>
|
||||
<option name="isRedirectInput" value="false" />
|
||||
<option name="redirectInputPath" value="" />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
|
@ -7,6 +7,7 @@ Dates are given in YYYY-MM-DD format.
|
|||
- Added JSON output support via `-o json`
|
||||
#### Other
|
||||
- `videos` is now an alias for `video`
|
||||
- More extensive README documentation
|
||||
|
||||
### v0.3.0 (2021-04-28)
|
||||
#### Features
|
||||
|
@ -71,7 +72,7 @@ Dates are given in YYYY-MM-DD format.
|
|||
(files without extensions are still skipped unless the -S flag is used)
|
||||
#### Bugfixes
|
||||
- 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 first
|
||||
[here](https://github.com/bodil/smartstring/blob/v0.2.6/src/config.rs#L101-L103) for why that was a problem in the first
|
||||
place)
|
||||
- Fixed broken tests for the [`infer`] backend
|
||||
#### Other
|
||||
|
|
10
Cargo.toml
10
Cargo.toml
|
@ -20,8 +20,8 @@ maintenance = { status = "experimental" }
|
|||
[features]
|
||||
default = ["multi-threaded", "json"]
|
||||
multi-threaded = ["rayon"]
|
||||
infer-backend = []
|
||||
xdg-mime-backend = []
|
||||
infer-backend = ["infer"]
|
||||
xdg-mime-backend = ["xdg-mime"]
|
||||
json = ["serde", "serde_json"]
|
||||
|
||||
[dependencies]
|
||||
|
@ -30,7 +30,6 @@ log = "0.4.14"
|
|||
mime_guess = { package = "new_mime_guess", version = "2.1.0" }
|
||||
snailquote = "0.3.0"
|
||||
once_cell = "1.7.2"
|
||||
infer = "0.4.0"
|
||||
rayon = { version = "1.5.0", optional = true }
|
||||
exitcode = "1.1.2"
|
||||
cfg-if = "1.0.0"
|
||||
|
@ -38,8 +37,13 @@ itertools = "0.10.0"
|
|||
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||
serde_json = { version = "1.0", optional = true }
|
||||
|
||||
[target.'cfg(not(unix))'.dependencies]
|
||||
xdg-mime = { version = "0.3.3", optional = true }
|
||||
infer = "0.4.0"
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
xdg-mime = "0.3.3"
|
||||
infer = { version = "0.4.0", optional = true}
|
||||
|
||||
[target.'cfg(not(all(target_endian = "big", target_pointer_width = "32")))'.dependencies]
|
||||
smartstring = "0.2.6"
|
||||
|
|
83
README.md
83
README.md
|
@ -27,41 +27,58 @@ a file, e.g. `fif ~/Documents > output.sh`. You can also pipe the output directl
|
|||
`fif ~/Documents | bash`, although this is not recommended - you should look over fif's output and verify for yourself
|
||||
that it's not doing anything that will give you a headache before running it.
|
||||
|
||||
## Installation
|
||||
### Cargo
|
||||
## Features
|
||||
- :white_check_mark: Cross platform
|
||||
- :white_check_mark: Multi-threaded
|
||||
- :white_check_mark: Configurable
|
||||
|
||||
## Building
|
||||
fif can be built, installed, and tested with [Cargo], as with most rust programs:
|
||||
```bash
|
||||
git clone https://gitlab.com/Lynnesbian/fif/
|
||||
cd fif
|
||||
# run tests (optional)
|
||||
cargo test --locked
|
||||
# build fif with its default feature set
|
||||
cargo build --locked --release
|
||||
```
|
||||
The `--locked` flag ensures that Cargo uses the dependency versions specified in [the lock
|
||||
file](https://gitlab.com/Lynnesbian/fif/-/blob/master/Cargo.lock), and the `--release` flag builds fif with release
|
||||
optimisations enabled -- this takes longer, but produces a much faster binary.
|
||||
|
||||
### Installing
|
||||
```bash
|
||||
# install the fif crate (to ~/.cargo/bin or %USERPROFILE%\.cargo\bin by default)
|
||||
cargo install --locked fif
|
||||
```
|
||||
|
||||
To update, simply re-run this command, or use a tool like [cargo-update
|
||||
](https://github.com/nabijaczleweli/cargo-update).
|
||||
To update, simply re-run the `install` command, or use a tool like [cargo-update
|
||||
](https://github.com/nabijaczleweli/cargo-update), which can update crates installed via `cargo install`.
|
||||
|
||||
#### Other backends
|
||||
`fif` supports using [`infer`](https://crates.io/crates/infer) or [`xdg-mime`](https://crates.io/crates/xdg-mime) as its
|
||||
backend for looking up file types. By default, xdg-mime will be used on
|
||||
[*nix systems](https://en.wikipedia.org/wiki/Unix-like) (Linux, macOS, *BSD, etc.), and infer on all other systems.
|
||||
### Cargo Features
|
||||
fif supports using [`infer`] or [`xdg-mime`] as its backend for looking up file types. By default, xdg-mime will be
|
||||
used on [*nix systems](https://en.wikipedia.org/wiki/Unix-like) (Linux, macOS, *BSD, etc.), and infer on all other
|
||||
systems.
|
||||
|
||||
`xdg-mime` should work on any *nix system with [libmagic/file(1)](https://www.darwinsys.com/file/) installed, although
|
||||
I've only tested it on Linux and FreeBSD. `infer` should work on any system.
|
||||
`xdg-mime` should work on any *nix system with the [Shared MIME Info] library installed (consult your package
|
||||
manager), although I've only tested it on Linux and FreeBSD. `infer` should work on any system.
|
||||
|
||||
You can override the default backend for your system at compile time like so:
|
||||
|
||||
```bash
|
||||
# xdg-mime
|
||||
cargo install fif --features=xdg-mime-backend
|
||||
cargo install fif --locked --features=xdg-mime-backend
|
||||
# infer
|
||||
cargo install fif --features=infer-backend
|
||||
cargo install fif --locked --features=infer-backend
|
||||
```
|
||||
|
||||
Of the supported backends, `xdg-mime` by far supports the most file types, as it uses the excellent [Shared MIME
|
||||
Info](https://gitlab.freedesktop.org/xdg/shared-mime-info/) database, whereas `infer` uses its own baked-in database.
|
||||
However, `infer` is also faster to load, if only by a few dozen milliseconds, and has no external dependencies.
|
||||
|
||||
#### Multithreading
|
||||
It is also possible to disable multithreading by installing without default features:
|
||||
It is also possible to get a more minimal build by installing without default features:
|
||||
```bash
|
||||
cargo install fif --no-default-features
|
||||
cargo install fif --locked --no-default-features
|
||||
```
|
||||
This will disable some non-essential but nice to have features, like multi-threading support.
|
||||
|
||||
For more info on fif's compile-time features, see [the wiki](https://gitlab.com/Lynnesbian/fif/-/wikis/Cargo-Features).
|
||||
|
||||
## Usage
|
||||
See `fif --help` for more.
|
||||
|
@ -75,16 +92,25 @@ fif ~/Downloads
|
|||
|
||||
This command will scan all non-hidden files in your `~/Downloads` directory.
|
||||
|
||||
You can also manually specify a set of extensions to use:
|
||||
The `-e` and `-E` flags can be used to specify individual extensions and sets of extensions to scan, respectively:
|
||||
|
||||
```bash
|
||||
# only scan files with the extensions .jpeg, .jpg, .zip, and .docx
|
||||
fif -e jpeg,jpg,zip,docx ~/Documents
|
||||
# only scan files with "image extensions" - .jpg, .png, .gif, .webp...
|
||||
fif -E images ~/Pictures
|
||||
# scan .zip files, videos, and audio
|
||||
fif -e zip -E videos,audio ~/Downloads
|
||||
```
|
||||
|
||||
Or a set of extensions - for example, to scan files with image extensions (jpg, png, gif, bmp...):
|
||||
|
||||
Both `-e` and `-E` have equivalent `-x` and `-X` flags that exclude the given extensions rather than including them:
|
||||
```bash
|
||||
fif -E images ~/Pictures
|
||||
# scan everything except filenames ending in .zip
|
||||
fif -x zip ~/Downloads
|
||||
# scan all files with image extensions, but not .jpg and .jpeg files
|
||||
fif -x jpg,jpeg -E images ~/Pictures
|
||||
# scan everything except text and system files
|
||||
fif -X text,system ~/.local/share
|
||||
```
|
||||
|
||||
### Output
|
||||
|
@ -94,7 +120,7 @@ found with incorrect file extensions.
|
|||
You might find it useful to output this script to a file (rather than to stdout):
|
||||
|
||||
```bash
|
||||
fif -E images ~/Pictures > output.sh
|
||||
fif ~/Documents > output.sh
|
||||
```
|
||||
|
||||
You can also manually specify an output format to use:
|
||||
|
@ -143,3 +169,12 @@ The five logging levels are used as follows:
|
|||
| info | Information pertaining to fif's status | The provided directory was scanned without issue, and no files are in need of renaming |
|
||||
| debug | Debug information - usually not important to end users | The list of extensions fif will consider |
|
||||
| trace | Trace info - usually not important to end users | "Found 15 items to check", "Scan successful", etc. |
|
||||
|
||||
For a more comprehensive explanation of all of fif's parameters and how to use them, run `fif --help` (or `fif -h` for
|
||||
a more concise overview).
|
||||
|
||||
<!-- links -->
|
||||
[Cargo]: https://doc.rust-lang.org/cargo/
|
||||
[`xdg-mime`]: https://crates.io/crates/xdg-mime
|
||||
[`infer`]: https://crates.io/crates/infer
|
||||
[Shared MIME Info]: https://gitlab.freedesktop.org/xdg/shared-mime-info/
|
|
@ -76,7 +76,7 @@ fn main() {
|
|||
trace!("Initialise mimetype database");
|
||||
init_db();
|
||||
|
||||
debug!("Iterating directory: {:?}", args.dirs);
|
||||
debug!("Iterating directory: {:?}", args.dir);
|
||||
|
||||
let extensions = args.extensions();
|
||||
let excludes = args.excluded_extensions();
|
||||
|
@ -89,12 +89,7 @@ fn main() {
|
|||
debug!("Checking files regardless of extensions");
|
||||
}
|
||||
|
||||
let entries = scan_directory(
|
||||
&args.dirs,
|
||||
extensions.as_ref(),
|
||||
excludes.as_ref(),
|
||||
&args.get_scan_opts(),
|
||||
);
|
||||
let entries = scan_directory(&args.dir, extensions.as_ref(), excludes.as_ref(), &args.get_scan_opts());
|
||||
|
||||
if entries.is_none() {
|
||||
// no need to log anything for fatal errors - fif will already have printed something obvious like
|
||||
|
|
|
@ -115,9 +115,8 @@ pub struct Parameters {
|
|||
pub quiet: u8,
|
||||
|
||||
/// The directory to process.
|
||||
// TODO: right now this can only take a single directory - should this be improved?
|
||||
#[clap(name = "DIR", default_value = ".", parse(from_os_str))]
|
||||
pub dirs: PathBuf,
|
||||
pub dir: PathBuf,
|
||||
}
|
||||
|
||||
fn lowercase_exts(exts: &str) -> Result<(), String> {
|
||||
|
|
|
@ -70,7 +70,9 @@ fn recommend_ext() {
|
|||
assert!(mime_extension_lookup(IMAGE_JPEG.essence_str().into())
|
||||
.unwrap()
|
||||
.contains(&String::from("jpg")));
|
||||
assert!(mime_extension_lookup(IMAGE_PNG.essence_str().into()).unwrap().contains(&String::from("png")));
|
||||
assert!(mime_extension_lookup(IMAGE_PNG.essence_str().into())
|
||||
.unwrap()
|
||||
.contains(&String::from("png")));
|
||||
assert!(mime_extension_lookup(APPLICATION_PDF.essence_str().into())
|
||||
.unwrap()
|
||||
.contains(&String::from("pdf")));
|
||||
|
@ -116,7 +118,7 @@ fn simple_directory() {
|
|||
follow_symlinks: false,
|
||||
};
|
||||
|
||||
let entries = scan_directory(&dir.path().to_path_buf(), None, None, &scan_opts).expect("Directory scan failed.");
|
||||
let entries = scan_directory(dir.path(), None, None, &scan_opts).expect("Directory scan failed.");
|
||||
|
||||
assert_eq!(entries.len(), files.len());
|
||||
|
||||
|
@ -210,7 +212,7 @@ fn argument_parsing() {
|
|||
fn positional_args() {
|
||||
for flag in &["-x", "-e", "-X", "-E"] {
|
||||
assert_eq!(
|
||||
Parameters::parse_from(vec!["fif", flag, "images", "directory"]).dirs,
|
||||
Parameters::parse_from(vec!["fif", flag, "images", "directory"]).dir,
|
||||
PathBuf::from("directory")
|
||||
)
|
||||
}
|
||||
|
@ -363,6 +365,7 @@ fn outputs_move_commands() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "json")]
|
||||
/// Ensure JSON output is valid.
|
||||
fn test_json() {
|
||||
use crate::formats::Json;
|
||||
|
|
Loading…
Reference in a new issue