253 lines
10 KiB
Markdown
253 lines
10 KiB
Markdown
<div align="center">
|
|
|
|
# fif
|
|
|
|
![A screenshot demonstrating fif's ability to detect the correct file extensions for a few files.
|
|
](https://gitlab.com/Lynnesbian/fif/-/raw/master/doc/screenshot.png)
|
|
|
|
[![Version](https://img.shields.io/crates/v/fif.svg?logo=rust&style=flat-square)
|
|
](https://crates.io/crates/fif)
|
|
[![Minimum Supported Rust Version](https://img.shields.io/badge/msrv-1.57.0-orange?logo=rust&style=flat-square)
|
|
](https://gitlab.com/Lynnesbian/fif/-/blob/master/README.md#version-policy)
|
|
[![License](https://img.shields.io/crates/l/fif.svg?style=flat-square)
|
|
](https://gitlab.com/Lynnesbian/fif/-/blob/master/LICENSE)
|
|
[![Build status](https://img.shields.io/gitlab/pipeline/Lynnesbian/fif/master?logo=gitlab&style=flat-square)
|
|
](https://gitlab.com/Lynnesbian/fif/-/pipelines/latest)
|
|
[![Unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg?style=flat-square)
|
|
](https://github.com/rust-secure-code/safety-dance/)
|
|
[![Dependency versions](https://deps.rs/repo/gitlab/lynnesbian/fif/status.svg)
|
|
](https://deps.rs/repo/gitlab/lynnesbian/fif)
|
|
[![REUSE status](https://api.reuse.software/badge/gitlab.com/Lynnesbian/fif/)
|
|
](https://api.reuse.software/info/gitlab.com/Lynnesbian/fif/)
|
|
|
|
*A command-line tool for detecting and optionally correcting files with incorrect extensions.*
|
|
</div>
|
|
|
|
fif recursively scans the given directory and outputs a shell script to fix the name of any files with incorrect
|
|
extensions. By default, fif will scan all non-hidden files in the given directory, and will ignore symlinks.
|
|
|
|
As fif prints a shell script to stdout rather than acting on the files directly, you may wish to redirect its output to
|
|
a file, e.g. `fif ~/Documents > output.sh`. You can also pipe the output directly into your shell, e.g.
|
|
`fif ~/Documents | bash`, although this is not recommended - you should look over fif's output and verify for yourself
|
|
that it won't do anything that will give you a headache before running it.
|
|
|
|
## 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 the `install` command, or use a tool like [cargo-update
|
|
](https://github.com/nabijaczleweli/cargo-update), which can update crates installed via `cargo install`.
|
|
|
|
On macOS, `fif` can be installed through [MacPorts](https://www.macports.org):
|
|
```bash
|
|
sudo port selfupdate
|
|
sudo port install fif
|
|
```
|
|
|
|
### 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 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, but it supports far
|
|
fewer file types than `xdg-mime` does, thanks to the excellent Shared MIME Info library.
|
|
|
|
You can override the default backend for your system at compile time like so:
|
|
|
|
```bash
|
|
# xdg-mime
|
|
cargo install fif --locked --features=xdg-mime-backend
|
|
# infer
|
|
cargo install fif --locked --features=infer-backend
|
|
```
|
|
|
|
It is also possible to get a more minimal build by installing without default features:
|
|
```bash
|
|
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.
|
|
|
|
### The basics
|
|
The simplest way to use fif looks like this:
|
|
|
|
```bash
|
|
fif ~/Downloads
|
|
```
|
|
|
|
This command will scan all non-hidden files in your `~/Downloads` directory.
|
|
|
|
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
|
|
```
|
|
|
|
Both `-e` and `-E` have equivalent `-x` and `-X` flags that exclude the given extensions rather than including them:
|
|
```bash
|
|
# 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
|
|
By default, fif will output a bash script (or PowerShell script on Windows) that can be used to fix all the files it
|
|
found with incorrect file extensions.
|
|
|
|
You might find it useful to output this script to a file (rather than to stdout):
|
|
|
|
```bash
|
|
fif ~/Documents > output.sh
|
|
```
|
|
|
|
You can also manually specify an output format to use:
|
|
|
|
```bash
|
|
fif -O powershell ~/Documents > output.ps1
|
|
```
|
|
|
|
#### The `--fix` flag
|
|
|
|
If, however, you'd rather have fif fix the misnamed files itself, rather than relying on a shell script, you can use
|
|
the `--fix` flag:
|
|
|
|
```bash
|
|
# rename any misnamed .jpg files in the user's pictures directory
|
|
fif ~/Pictures --fix -e jpg
|
|
# fix any misnamed files found in the user's downloads
|
|
fif ~/Downloads --fix
|
|
```
|
|
|
|
By default, fif will avoid taking any potentially destructive actions (renaming a file to a name that already exists).
|
|
This behaviour can be disabled with the `--overwrite` flag, which will instead prompt you to overwrite the existing
|
|
file. fif will also prompt you to retry on errors.
|
|
|
|
For more information on how the `--fix` flag works, and how it behaves in conjunction with the `--overwrite` flag
|
|
and `--prompt` parameter, see [the corresponding wiki page](https://gitlab.com/Lynnesbian/fif/-/wikis/Fix).
|
|
|
|
### Logging
|
|
By default, fif will log any info, warnings, and errors encountered during execution. This can be changed with the `-v`
|
|
flag:
|
|
```bash
|
|
# also log debug info
|
|
fif -v ~/Downloads
|
|
# ...and trace info
|
|
fif -vv ~/Downloads
|
|
```
|
|
|
|
You can also reduce the level of logging with the `-q` flag:
|
|
```bash
|
|
# don't show info
|
|
fif -q ~/Downloads
|
|
# ...or warnings
|
|
fif -qq ~/Downloads
|
|
# ...or even errors!
|
|
fif -qqq ~/Downloads
|
|
```
|
|
|
|
The verbosity of the logging can also be modified by setting the environment variable `FIF_LOG` or `RUST_LOG` to `off`,
|
|
`trace`, `debug`, `info`, `warn`, or `error`. Values set by `FIF_LOG` override `RUST_LOG`, and both override the `-v`
|
|
and `-q` flags.
|
|
|
|
For example:
|
|
|
|
```bash
|
|
# show all levels except trace
|
|
FIF_LOG=debug fif ~/Downloads
|
|
# only show errors
|
|
FIF_LOG=error fif ~/Downloads
|
|
```
|
|
|
|
The five logging levels are used as follows:
|
|
| Level | Description | Example |
|
|
|-|-|-|
|
|
| error | Errors that cause fif to stop running | fif was unable to open the provided directory |
|
|
| warn | Warnings that don't cause fif to stop running | fif was unable to determine the MIME type of a given file |
|
|
| 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/
|
|
|
|
|
|
## Version policy
|
|
fif adheres to the [semantic versioning](https://semver.org/) principles. While fif remains at version 0.x, the version
|
|
number will be updated as follows:
|
|
- The MAJOR version will be bumped to 1 when I believe fif to be "feature complete".
|
|
- The MINOR version will be bumped whenever I add a fairly important feature to fif (in the past, this has been bumped
|
|
when adding the ability to exclude extensions, and when fif gained the ability to output a bash script rather than a
|
|
list of invalid filenames). The MINOR version will also be bumped when increasing the MSRV.
|
|
- The PATCH version will be bumped in all other cases, including minor feature additions (in the past, this has occurred
|
|
when adding features such as more output formats and the "ignore unknown extensions" flag).
|
|
|
|
If/when fif hits version 1.0, these rules will likely remain the same as they are now.
|
|
|
|
## Code style
|
|
fif is formatted with `rustfmt` using a nightly toolchain, specifically with the command `cargo +nightly fmt`. Tabs are
|
|
used for indentation, and are assumed to be two spaces wide. Lines are 120 characters wide. Braces are placed on the
|
|
same line (["OTBS"](https://en.wikipedia.org/wiki/Indentation_style#Variant:_1TBS_(OTBS)) format), except in the case of
|
|
`where` clauses in generic parameters.
|
|
|
|
For more detailed information on the formatting rules used by this project, see the configured options in
|
|
[`rustfmt.toml`](https://gitlab.com/Lynnesbian/fif/-/blob/master/rustfmt.toml).
|
|
|
|
## Additional credits
|
|
Some of the code for correctly handling files with multiple valid extensions (particularly in the case of the
|
|
Portable Executable format) comes from [Czkawka](https://github.com/qarmin/czkawka)
|
|
|
|
## License
|
|
Copyright (C) 2021 Lynnesbian
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|