Compare commits
6 commits
a941040948
...
8cdd0a8fc1
Author | SHA1 | Date | |
---|---|---|---|
8cdd0a8fc1 | |||
59c87a3729 | |||
863954b2a2 | |||
44a0351884 | |||
2f1151805f | |||
011b9eee99 |
9 changed files with 60 additions and 47 deletions
|
@ -1,6 +1,7 @@
|
||||||
<component name="InspectionProjectProfileManager">
|
<component name="InspectionProjectProfileManager">
|
||||||
<profile version="1.0">
|
<profile version="1.0">
|
||||||
<option name="myName" value="Project Default" />
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="DuplicatedCode" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="RegExpRepeatedSpace" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
<inspection_tool class="RegExpRepeatedSpace" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
||||||
</profile>
|
</profile>
|
||||||
</component>
|
</component>
|
3
.kateproject
Normal file
3
.kateproject
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"index": true
|
||||||
|
}
|
|
@ -2,6 +2,11 @@
|
||||||
Dates are given in YYYY-MM-DD format.
|
Dates are given in YYYY-MM-DD format.
|
||||||
|
|
||||||
## v0.3
|
## v0.3
|
||||||
|
### v0.3.4 (2021-mm-dd)
|
||||||
|
#### Other
|
||||||
|
- Refactored `formats.rs`
|
||||||
|
- More accurate dependency versions in `Cargo.toml` to ensure that the MSRV stays supported
|
||||||
|
|
||||||
### v0.3.3 (2021-07-07)
|
### v0.3.3 (2021-07-07)
|
||||||
#### Features
|
#### Features
|
||||||
- Added `--canonical-paths` flag for outputting canonical paths in output - for example,
|
- Added `--canonical-paths` flag for outputting canonical paths in output - for example,
|
||||||
|
@ -91,7 +96,7 @@ 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.7/src/config.rs#L102-L104) for why that was a problem in the
|
||||||
first place)
|
first place)
|
||||||
- Fixed broken tests for the [`infer`] backend
|
- Fixed broken tests for the [`infer`] backend
|
||||||
#### Other
|
#### Other
|
||||||
|
|
22
Cargo.lock
generated
22
Cargo.lock
generated
|
@ -1,7 +1,5 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
|
@ -310,9 +308,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.97"
|
version = "0.2.98"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
|
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
|
@ -346,9 +344,9 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "new_mime_guess"
|
name = "new_mime_guess"
|
||||||
version = "2.1.0"
|
version = "2.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e714f72c691c7d2b344ec8dd57d7f52b59651f46b9de477fb68363f097d694ae"
|
checksum = "991337b97f81dff759c3edabb0bc01ceac92bff6f54852853824bbe1acd969f7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"mime",
|
"mime",
|
||||||
"unicase",
|
"unicase",
|
||||||
|
@ -419,9 +417,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.27"
|
version = "1.0.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
@ -571,9 +569,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.64"
|
version = "1.0.66"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
@ -607,9 +605,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.73"
|
version = "1.0.74"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
|
checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
18
Cargo.toml
18
Cargo.toml
|
@ -27,7 +27,7 @@ json = ["serde", "serde_json"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
walkdir = "2.3.2"
|
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.1" }
|
||||||
snailquote = "0.3.0"
|
snailquote = "0.3.0"
|
||||||
once_cell = "1.8.0"
|
once_cell = "1.8.0"
|
||||||
rayon = { version = "1.5.0", optional = true }
|
rayon = { version = "1.5.0", optional = true }
|
||||||
|
@ -46,7 +46,17 @@ xdg-mime = "0.3.3"
|
||||||
infer = { version = "0.5.0", optional = true }
|
infer = { version = "0.5.0", optional = true }
|
||||||
|
|
||||||
[target.'cfg(not(all(target_endian = "big", target_pointer_width = "32")))'.dependencies]
|
[target.'cfg(not(all(target_endian = "big", target_pointer_width = "32")))'.dependencies]
|
||||||
smartstring = "0.2.6"
|
# the seemingly weird target constraint here is due to this:
|
||||||
|
# https://github.com/bodil/smartstring/blob/v0.2.7/src/config.rs#L102-L104
|
||||||
|
# essentially, smartstring is intentionally blocked from compiling on 32-bit big endian archs, so our dependency on it
|
||||||
|
# needs to be too. otherwise, fif won't work on platforms like powerpc, even though this dependency is the only
|
||||||
|
# blocker -- fif runs just fine on powerpc without smartstring. or at least, just fine under qemu user-mode powerpc ~u0
|
||||||
|
|
||||||
|
# additionally, smartstring 0.2.8 requires rust >=1.46 (due to https://github.com/rust-lang/rust/issues/49146), and
|
||||||
|
# 0.2.3 doesn't impl Display on its SmartString type.
|
||||||
|
# so, we need at least 0.2.4 so we can println! strings, and at most 0.2.7 until we bump the MSRV to at least 1.46.
|
||||||
|
# see https://github.com/bodil/smartstring/blob/master/CHANGELOG.md
|
||||||
|
smartstring = "<= 0.2.7, >= 0.2.4"
|
||||||
|
|
||||||
[dependencies.clap]
|
[dependencies.clap]
|
||||||
version = "3.0.0-beta.2"
|
version = "3.0.0-beta.2"
|
||||||
|
@ -69,10 +79,6 @@ rand = "0.8.3"
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = "thin"
|
lto = "thin"
|
||||||
|
|
||||||
# perform some simple optimisations when testing
|
|
||||||
[profile.test]
|
|
||||||
opt-level = 1
|
|
||||||
|
|
||||||
# optimise dependencies, even when producing debug and test builds
|
# optimise dependencies, even when producing debug and test builds
|
||||||
[profile.dev.package."*"]
|
[profile.dev.package."*"]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
|
@ -122,23 +122,14 @@ fn smart_write<W: Write>(f: &mut W, writeables: &[Writable]) -> io::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this might need a restructure.
|
pub trait FormatSteps {
|
||||||
// it would be nice if i didn't have to write a case for every OutputFormat variant that looked like
|
|
||||||
// OutputFormat::PowerShell => PowerShell::new().write_all(...)
|
|
||||||
// also, JSON's implementation differs vastly from PowerShell and Shell's implementations. Maybe they shouldn't be
|
|
||||||
// treated as implementing the same trait, since in that case, the format trait is more of a concept rather than an
|
|
||||||
// actual definition of behaviour.
|
|
||||||
// structuring code is *hard*
|
|
||||||
pub trait Format {
|
|
||||||
fn new() -> Self;
|
|
||||||
fn rename<W: Write>(&self, _f: &mut W, _from: &Path, _to: &Path) -> io::Result<()> { unreachable!() }
|
fn rename<W: Write>(&self, _f: &mut W, _from: &Path, _to: &Path) -> io::Result<()> { unreachable!() }
|
||||||
fn no_known_extension<W: Write>(&self, _f: &mut W, _path: &Path) -> io::Result<()> { unreachable!() }
|
fn no_known_extension<W: Write>(&self, _f: &mut W, _path: &Path) -> io::Result<()> { unreachable!() }
|
||||||
fn unreadable<W: Write>(&self, _f: &mut W, _path: &Path) -> io::Result<()> { unreachable!() }
|
fn unreadable<W: Write>(&self, _f: &mut W, _path: &Path) -> io::Result<()> { unreachable!() }
|
||||||
fn unknown_type<W: Write>(&self, _f: &mut W, _path: &Path) -> io::Result<()> { unreachable!() }
|
fn unknown_type<W: Write>(&self, _f: &mut W, _path: &Path) -> io::Result<()> { unreachable!() }
|
||||||
fn header<W: Write>(&self, _f: &mut W, _entries: &Entries) -> io::Result<()> { unreachable!() }
|
fn header<W: Write>(&self, _f: &mut W, _entries: &Entries) -> io::Result<()> { unreachable!() }
|
||||||
fn footer<W: Write>(&self, _f: &mut W, _entries: &Entries) -> io::Result<()> { unreachable!() }
|
fn footer<W: Write>(&self, _f: &mut W, _entries: &Entries) -> io::Result<()> { unreachable!() }
|
||||||
|
fn write_steps<W: Write>(&self, f: &mut W, entries: &Entries) -> io::Result<()> {
|
||||||
fn write_all<W: Write>(&self, f: &mut W, entries: &Entries) -> io::Result<()> {
|
|
||||||
// TODO: clean this up - it's kinda messy
|
// TODO: clean this up - it's kinda messy
|
||||||
self.header(f, entries)?;
|
self.header(f, entries)?;
|
||||||
|
|
||||||
|
@ -185,12 +176,18 @@ pub trait Format {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Format {
|
||||||
|
fn write_all<W: Write>(&self, f: &mut W, entries: &Entries) -> io::Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
/// Bourne-Shell compatible script.
|
/// Bourne-Shell compatible script.
|
||||||
pub struct Shell {}
|
pub struct Shell;
|
||||||
|
|
||||||
impl Format for Shell {
|
impl Format for Shell {
|
||||||
fn new() -> Self { Self {} }
|
fn write_all<W: Write>(&self, f: &mut W, entries: &Entries) -> io::Result<()> { self.write_steps(f, entries) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatSteps for Shell {
|
||||||
fn rename<W: Write>(&self, f: &mut W, from: &Path, to: &Path) -> io::Result<()> {
|
fn rename<W: Write>(&self, f: &mut W, from: &Path, to: &Path) -> io::Result<()> {
|
||||||
smart_write(f, writablesln!("mv -v -i -- ", from, Space, to))
|
smart_write(f, writablesln!("mv -v -i -- ", from, Space, to))
|
||||||
}
|
}
|
||||||
|
@ -238,11 +235,13 @@ impl Format for Shell {
|
||||||
// PowerShell is a noun, not a type
|
// PowerShell is a noun, not a type
|
||||||
#[allow(clippy::doc_markdown)]
|
#[allow(clippy::doc_markdown)]
|
||||||
/// PowerShell script.
|
/// PowerShell script.
|
||||||
pub struct PowerShell {}
|
pub struct PowerShell;
|
||||||
|
|
||||||
impl Format for PowerShell {
|
impl Format for PowerShell {
|
||||||
fn new() -> Self { Self {} }
|
fn write_all<W: Write>(&self, f: &mut W, entries: &Entries) -> io::Result<()> { self.write_steps(f, entries) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatSteps for PowerShell {
|
||||||
fn rename<W: Write>(&self, f: &mut W, from: &Path, to: &Path) -> io::Result<()> {
|
fn rename<W: Write>(&self, f: &mut W, from: &Path, to: &Path) -> io::Result<()> {
|
||||||
// unfortunately there doesn't seem to be an equivalent of sh's `mv -i` -- passing the '-Confirm' flag will prompt
|
// unfortunately there doesn't seem to be an equivalent of sh's `mv -i` -- passing the '-Confirm' flag will prompt
|
||||||
// the user to confirm every single rename, and using Move-Item -Force will always overwrite without prompting.
|
// the user to confirm every single rename, and using Move-Item -Force will always overwrite without prompting.
|
||||||
|
@ -303,7 +302,10 @@ impl Format for PowerShell {
|
||||||
|
|
||||||
pub struct Text;
|
pub struct Text;
|
||||||
impl Format for Text {
|
impl Format for Text {
|
||||||
fn new() -> Self { Self {} }
|
fn write_all<W: Write>(&self, f: &mut W, entries: &Entries) -> io::Result<()> { self.write_steps(f, entries) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatSteps for Text {
|
||||||
fn rename<W: Write>(&self, f: &mut W, from: &Path, to: &Path) -> io::Result<()> {
|
fn rename<W: Write>(&self, f: &mut W, from: &Path, to: &Path) -> io::Result<()> {
|
||||||
smart_write(f, writablesln![from, " should be renamed to ", to])
|
smart_write(f, writablesln![from, " should be renamed to ", to])
|
||||||
}
|
}
|
||||||
|
@ -337,8 +339,6 @@ pub struct Json;
|
||||||
|
|
||||||
#[cfg(feature = "json")]
|
#[cfg(feature = "json")]
|
||||||
impl Format for Json {
|
impl Format for Json {
|
||||||
fn new() -> Self { Self {} }
|
|
||||||
|
|
||||||
fn write_all<W: Write>(&self, f: &mut W, entries: &Entries) -> io::Result<()> {
|
fn write_all<W: Write>(&self, f: &mut W, entries: &Entries) -> io::Result<()> {
|
||||||
#[derive(serde::Serialize)]
|
#[derive(serde::Serialize)]
|
||||||
struct SerdeEntries<'a> {
|
struct SerdeEntries<'a> {
|
||||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -30,7 +30,7 @@ use walkdir::{DirEntry, WalkDir};
|
||||||
|
|
||||||
use crate::findings::Findings;
|
use crate::findings::Findings;
|
||||||
use crate::findings::ScanError;
|
use crate::findings::ScanError;
|
||||||
use crate::formats::{Format, PowerShell, Shell};
|
use crate::formats::Format;
|
||||||
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 crate::utils::{clap_long_version, os_name};
|
||||||
|
@ -142,17 +142,17 @@ fn main() {
|
||||||
|
|
||||||
if results.is_empty() {
|
if results.is_empty() {
|
||||||
info!("All files have valid extensions!");
|
info!("All files have valid extensions!");
|
||||||
exit(0);
|
exit(exitcode::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut buffered_stdout = BufWriter::new(stdout());
|
let mut buffered_stdout = BufWriter::new(stdout());
|
||||||
|
|
||||||
let result = match args.output_format {
|
let result = match args.output_format {
|
||||||
OutputFormat::Sh => Shell::new().write_all(&mut buffered_stdout, &results),
|
OutputFormat::Sh => formats::Shell.write_all(&mut buffered_stdout, &results),
|
||||||
OutputFormat::PowerShell => PowerShell::new().write_all(&mut buffered_stdout, &results),
|
OutputFormat::PowerShell => formats::PowerShell.write_all(&mut buffered_stdout, &results),
|
||||||
#[cfg(feature = "json")]
|
#[cfg(feature = "json")]
|
||||||
OutputFormat::Json => formats::Json::new().write_all(&mut buffered_stdout, &results),
|
OutputFormat::Json => formats::Json.write_all(&mut buffered_stdout, &results),
|
||||||
OutputFormat::Text => formats::Text::new().write_all(&mut buffered_stdout, &results),
|
OutputFormat::Text => formats::Text.write_all(&mut buffered_stdout, &results),
|
||||||
};
|
};
|
||||||
|
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
|
|
|
@ -352,8 +352,8 @@ fn outputs_move_commands() {
|
||||||
let mut contents = std::string::String::new();
|
let mut contents = std::string::String::new();
|
||||||
|
|
||||||
match *format {
|
match *format {
|
||||||
"Shell" => Shell::new().write_all(&mut cursor, &entries),
|
"Shell" => Shell.write_all(&mut cursor, &entries),
|
||||||
"PowerShell" => PowerShell::new().write_all(&mut cursor, &entries),
|
"PowerShell" => PowerShell.write_all(&mut cursor, &entries),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
.expect("Failed to write to cursor");
|
.expect("Failed to write to cursor");
|
||||||
|
@ -389,7 +389,7 @@ fn test_json() {
|
||||||
let mut cursor = std::io::Cursor::new(Vec::new());
|
let mut cursor = std::io::Cursor::new(Vec::new());
|
||||||
let mut contents = std::string::String::new();
|
let mut contents = std::string::String::new();
|
||||||
|
|
||||||
Json::new()
|
Json
|
||||||
.write_all(&mut cursor, &entries)
|
.write_all(&mut cursor, &entries)
|
||||||
.expect("Failed to write to cursor");
|
.expect("Failed to write to cursor");
|
||||||
|
|
||||||
|
|
2
test.py
2
test.py
|
@ -5,7 +5,7 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
def test_archs():
|
def test_archs():
|
||||||
archs = ["aarch64", "powerpc"]
|
archs = ["aarch64", "powerpc", "riscv64gc"]
|
||||||
upto = 1
|
upto = 1
|
||||||
target = len(archs)
|
target = len(archs)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue