From 4e1b55ec80592956a0fbe5683668af729527c321 Mon Sep 17 00:00:00 2001 From: Fabian Wickborn Date: Wed, 18 Sep 2019 19:48:12 +0200 Subject: [PATCH] Enable Windows builds Fixes #32. --- .travis.yml | 3 +++ Cargo.lock | 2 ++ Cargo.toml | 1 + README.md | 14 ++++++++++++++ src/lib.rs | 2 +- src/main.rs | 2 +- src/walk.rs | 21 ++++++++++----------- src/walk/unix.rs | 17 +++++++++++++++++ src/walk/windows.rs | 16 ++++++++++++++++ 9 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 src/walk/unix.rs create mode 100644 src/walk/windows.rs diff --git a/.travis.yml b/.travis.yml index 0e08879..146ec3f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,9 @@ matrix: - os: osx rust: stable env: TARGET=x86_64-apple-darwin + - os: windows + rust: stable + env: TARGET=x86_64-pc-windows-msvc # Minimum Rust supported channel. - os: linux rust: 1.29.0 diff --git a/Cargo.lock b/Cargo.lock index a9534fc..2e0a93f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "ansi_term" version = "0.11.0" diff --git a/Cargo.toml b/Cargo.toml index fa17741..59f20a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ name = "diskus" readme = "README.md" repository = "https://github.com/sharkdp/diskus" version = "0.5.0" +edition = "2018" [dependencies] num_cpus = "1.0" diff --git a/README.md b/README.md index 65ed19e..3d1d986 100644 --- a/README.md +++ b/README.md @@ -125,3 +125,17 @@ Licensed under either of * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. + + +## Windows caveats + + Since even the Windows-internal tools such as (but not limited to) + - Powershell, + - Explorer, + - dir, + + are not respecting hardlinks or junction points when determining the + size of a directory, it has been decided that diskus will count + any such entries multiple times. too. See + https://github.com/sharkdp/diskus/issues/32#issuecomment-532817905 for + an example of this behaviour. diff --git a/src/lib.rs b/src/lib.rs index b0cf55e..47e726e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,4 +19,4 @@ extern crate rayon; pub mod walk; -pub use walk::Walk; +pub use crate::walk::Walk; diff --git a/src/main.rs b/src/main.rs index 9dc48d2..30ba5b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ use std::path::PathBuf; use clap::{App, AppSettings, Arg}; use humansize::{file_size_opts, FileSize}; -use walk::Walk; +use crate::walk::Walk; fn print_result(size: u64) { println!( diff --git a/src/walk.rs b/src/walk.rs index 0125713..5078359 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -1,6 +1,5 @@ use std::collections::HashSet; use std::fs; -use std::os::unix::fs::MetadataExt; use std::path::PathBuf; use std::thread; @@ -9,8 +8,15 @@ use crossbeam_channel as channel; use rayon; use rayon::prelude::*; -#[derive(Eq, PartialEq, Hash)] -struct UniqueID(u64, u64); +#[cfg(target_os = "windows")] +mod windows; +#[cfg(target_os = "windows")] +pub use self::windows::*; + +#[cfg(not(target_os = "windows"))] +mod unix; +#[cfg(not(target_os = "windows"))] +pub use self::unix::*; enum Message { SizeEntry(Option, u64), @@ -21,14 +27,7 @@ enum Message { fn walk(tx: channel::Sender, entries: &[PathBuf]) { entries.into_par_iter().for_each_with(tx, |tx_ref, entry| { if let Ok(metadata) = entry.symlink_metadata() { - // If the entry has more than one hard link, generate - // a unique ID consisting of device and inode in order - // not to count this entry twice. - let unique_id = if metadata.is_file() && metadata.nlink() > 1 { - Some(UniqueID(metadata.dev(), metadata.ino())) - } else { - None - }; + let unique_id = generate_unique_id(&metadata); let size = metadata.len(); diff --git a/src/walk/unix.rs b/src/walk/unix.rs new file mode 100644 index 0000000..16770a9 --- /dev/null +++ b/src/walk/unix.rs @@ -0,0 +1,17 @@ +use std::os::unix::fs::MetadataExt; + + +#[derive(Eq, PartialEq, Hash)] +pub struct UniqueID(u64, u64); + + +fn generate_unique_id(metadata: &std::fs::Metadata) -> Option { + // If the entry has more than one hard link, generate + // a unique ID consisting of device and inode in order + // not to count this entry twice. + if metadata.is_file() && metadata.nlink() > 1 { + Some(UniqueID(metadata.dev(), metadata.ino())) + } else { + None + } +} \ No newline at end of file diff --git a/src/walk/windows.rs b/src/walk/windows.rs new file mode 100644 index 0000000..08a40f2 --- /dev/null +++ b/src/walk/windows.rs @@ -0,0 +1,16 @@ +#[derive(Eq, PartialEq, Hash)] +pub struct UniqueID(String); + +pub fn generate_unique_id(_metadata: &std::fs::Metadata) -> Option { + // Since even the Windows-internal tools such as (but not limited to) + // - Powershell, + // - Explorer, + // - dir, + // are not respecting hardlinks or junction points when determining the + // size of a directory [1], it has been decided that diskus will count + // any such entries multiple times. too. + // + // Footnotes: + // [1] https://github.com/sharkdp/diskus/issues/32#issuecomment-532817905 + None +}