Merge pull request #43 from bootandy/no_color

Add flag for No color, refactor tests
This commit is contained in:
andy boot
2019-12-08 23:50:58 +00:00
committed by GitHub
5 changed files with 142 additions and 176 deletions
Generated
+1 -1
View File
@@ -187,7 +187,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "du-dust" name = "du-dust"
version = "0.4.1" version = "0.4.2"
dependencies = [ dependencies = [
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+1 -1
View File
@@ -1,7 +1,7 @@
[package] [package]
name = "du-dust" name = "du-dust"
description = "A more intuitive version of du" description = "A more intuitive version of du"
version = "0.4.1" version = "0.4.2"
authors = ["bootandy <bootandy@gmail.com>", "nebkor <code@ardent.nebcorp.com>"] authors = ["bootandy <bootandy@gmail.com>", "nebkor <code@ardent.nebcorp.com>"]
edition = "2018" edition = "2018"
+22 -10
View File
@@ -9,6 +9,7 @@ static UNITS: [char; 4] = ['T', 'G', 'M', 'K'];
pub struct DisplayData { pub struct DisplayData {
pub short_paths: bool, pub short_paths: bool,
pub is_reversed: bool, pub is_reversed: bool,
pub colors_on: bool,
} }
impl DisplayData { impl DisplayData {
@@ -72,13 +73,20 @@ impl DisplayData {
} }
} }
pub fn draw_it(permissions: bool, use_full_path: bool, is_reversed: bool, root_node: Node) { pub fn draw_it(
permissions: bool,
use_full_path: bool,
is_reversed: bool,
no_colors: bool,
root_node: Node,
) {
if !permissions { if !permissions {
eprintln!("Did not have permissions for all directories"); eprintln!("Did not have permissions for all directories");
} }
let display_data = DisplayData { let display_data = DisplayData {
short_paths: !use_full_path, short_paths: !use_full_path,
is_reversed, is_reversed,
colors_on: !no_colors,
}; };
for c in display_data.get_children_from_node(root_node) { for c in display_data.get_children_from_node(root_node) {
@@ -88,8 +96,6 @@ pub fn draw_it(permissions: bool, use_full_path: bool, is_reversed: bool, root_n
} }
fn display_node(node: Node, is_biggest: bool, indent: &str, display_data: &DisplayData) { fn display_node(node: Node, is_biggest: bool, indent: &str, display_data: &DisplayData) {
let short = display_data.short_paths;
let mut num_siblings = node.children.len() as u64; let mut num_siblings = node.children.len() as u64;
let max_sibling = num_siblings; let max_sibling = num_siblings;
let new_indent = clean_indentation_string(indent); let new_indent = clean_indentation_string(indent);
@@ -97,7 +103,7 @@ fn display_node(node: Node, is_biggest: bool, indent: &str, display_data: &Displ
let size = node.size; let size = node.size;
if !display_data.is_reversed { if !display_data.is_reversed {
print_this_node(&*name, size, is_biggest, short, indent); print_this_node(&*name, size, is_biggest, display_data, indent);
} }
for c in display_data.get_children_from_node(node) { for c in display_data.get_children_from_node(node) {
@@ -109,7 +115,7 @@ fn display_node(node: Node, is_biggest: bool, indent: &str, display_data: &Displ
} }
if display_data.is_reversed { if display_data.is_reversed {
print_this_node(&*name, size, is_biggest, short, indent); print_this_node(&*name, size, is_biggest, display_data, indent);
} }
} }
@@ -130,23 +136,29 @@ fn clean_indentation_string(s: &str) -> String {
is is
} }
fn print_this_node(name: &str, size: u64, is_biggest: bool, short_paths: bool, indentation: &str) { fn print_this_node(
name: &str,
size: u64,
is_biggest: bool,
display_data: &DisplayData,
indentation: &str,
) {
let pretty_size = format!("{:>5}", human_readable_number(size),); let pretty_size = format!("{:>5}", human_readable_number(size),);
println!( println!(
"{}", "{}",
format_string(name, is_biggest, short_paths, &*pretty_size, indentation) format_string(name, is_biggest, display_data, &*pretty_size, indentation)
) )
} }
pub fn format_string( pub fn format_string(
dir_name: &str, dir_name: &str,
is_biggest: bool, is_biggest: bool,
short_paths: bool, display_data: &DisplayData,
size: &str, size: &str,
indentation: &str, indentation: &str,
) -> String { ) -> String {
let printable_name = { let printable_name = {
if short_paths { if display_data.short_paths {
dir_name.split('/').last().unwrap_or(dir_name) dir_name.split('/').last().unwrap_or(dir_name)
} else { } else {
dir_name dir_name
@@ -154,7 +166,7 @@ pub fn format_string(
}; };
format!( format!(
"{} {} {}", "{} {} {}",
if is_biggest { if is_biggest && display_data.colors_on {
Fixed(196).paint(size) Fixed(196).paint(size)
} else { } else {
Style::new().paint(size) Style::new().paint(size)
+8 -2
View File
@@ -57,6 +57,12 @@ fn main() {
.long("reverse") .long("reverse")
.help("If applied tree will be printed upside down (biggest lowest)"), .help("If applied tree will be printed upside down (biggest lowest)"),
) )
.arg(
Arg::with_name("no_colors")
.short("c")
.long("no_colors")
.help("If applied no colors will be printed (normally largest directories are marked in red"),
)
.arg(Arg::with_name("inputs").multiple(true)) .arg(Arg::with_name("inputs").multiple(true))
.get_matches(); .get_matches();
@@ -95,7 +101,6 @@ fn main() {
} }
let use_apparent_size = options.is_present("display_apparent_size"); let use_apparent_size = options.is_present("display_apparent_size");
let use_full_path = options.is_present("display_full_paths");
let simplified_dirs = simplify_dir_names(target_dirs); let simplified_dirs = simplify_dir_names(target_dirs);
let (permissions, nodes) = get_dir_tree(&simplified_dirs, use_apparent_size, threads); let (permissions, nodes) = get_dir_tree(&simplified_dirs, use_apparent_size, threads);
@@ -110,8 +115,9 @@ fn main() {
draw_it( draw_it(
permissions, permissions,
use_full_path, options.is_present("display_full_paths"),
options.is_present("reverse"), options.is_present("reverse"),
options.is_present("no_colors"),
tree, tree,
); );
} }
+109 -161
View File
@@ -1,4 +1,5 @@
use super::*; use super::*;
use crate::display::DisplayData;
use display::format_string; use display::format_string;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
@@ -37,67 +38,83 @@ pub fn test_main_multi_arg() {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
fn main_output(short_paths: bool) -> String { fn main_output(short_paths: bool) -> String {
let d = DisplayData {
short_paths,
is_reversed: false,
colors_on: true,
};
format!( format!(
"{} "{}
{} {}
{} {}
{}", {}",
format_string("src/test_dir", true, short_paths, " 4.0K", "─┬"), format_string("src/test_dir", true, &d, " 4.0K", "─┬"),
format_string("src/test_dir/many", true, short_paths, " 4.0K", " └─┬",), format_string("src/test_dir/many", true, &d, " 4.0K", " └─┬",),
format_string( format_string("src/test_dir/many/hello_file", true, &d, " 4.0K", " ├──",),
"src/test_dir/many/hello_file", format_string("src/test_dir/many/a_file", false, &d, " 0B", " └──",),
true,
short_paths,
" 4.0K",
" ├──",
),
format_string(
"src/test_dir/many/a_file",
false,
short_paths,
" 0B",
" └──",
),
) )
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
fn main_output(short_paths: bool) -> String { fn main_output(short_paths: bool) -> String {
let d = DisplayData {
short_paths,
is_reversed: false,
colors_on: true,
};
format!( format!(
"{} "{}
{} {}
{} {}
{}", {}",
format_string("src/test_dir", true, short_paths, " 12K", "─┬"), format_string("src/test_dir", true, &d, " 12K", "─┬"),
format_string("src/test_dir/many", true, short_paths, " 8.0K", " └─┬",), format_string("src/test_dir/many", true, &d, " 8.0K", " └─┬",),
format_string( format_string("src/test_dir/many/hello_file", true, &d, " 4.0K", " ├──",),
"src/test_dir/many/hello_file", format_string("src/test_dir/many/a_file", false, &d, " 0B", " └──",),
true,
short_paths,
" 4.0K",
" ├──",
),
format_string(
"src/test_dir/many/a_file",
false,
short_paths,
" 0B",
" └──",
),
) )
} }
#[test]
pub fn test_no_color_flag() {
assert_cli::Assert::main_binary()
.with_args(&["-c", "src/test_dir/"])
.stdout()
.is(no_color_flag_output())
.unwrap();
}
#[cfg(target_os = "macos")]
fn no_color_flag_output() -> String {
"
4.0K ─┬ test_dir
4.0K └─┬ many
4.0K ├── hello_file
0B └── a_file
"
.to_string()
}
#[cfg(target_os = "linux")]
fn no_color_flag_output() -> String {
"
12K ─┬ test_dir
8.0K └─┬ many
4.0K ├── hello_file
0B └── a_file
"
.to_string()
}
#[test] #[test]
pub fn test_apparent_size() { pub fn test_apparent_size() {
let d = DisplayData {
short_paths: true,
is_reversed: false,
colors_on: true,
};
let r = format!( let r = format!(
"{}", "{}",
format_string( format_string("src/test_dir/many/hello_file", true, &d, " 6B", " ├──",),
"src/test_dir/many/hello_file",
true,
true,
" 6B",
" ├──",
),
); );
assert_cli::Assert::main_binary() assert_cli::Assert::main_binary()
@@ -161,41 +178,21 @@ pub fn test_soft_sym_link() {
.output(); .output();
assert!(c.is_ok()); assert!(c.is_ok());
let r = soft_sym_link_output(dir_s, file_path_s, link_name_s); let a = format!(" ─┬ {}", dir_s);
let b = format!(" ├── {}", file_path_s);
let c = format!(" └── {}", link_name_s);
// We cannot guarantee which version will appear first.
// TODO: Consider adding predictable iteration order (sort file entries by name?)
assert_cli::Assert::main_binary() assert_cli::Assert::main_binary()
.with_args(&[dir_s]) .with_args(&["-p", &dir_s])
.stdout() .stdout()
.contains(r) .contains(a)
.stdout()
.contains(b)
.stdout()
.contains(c)
.unwrap(); .unwrap();
} }
#[cfg(target_os = "macos")]
fn soft_sym_link_output(dir: &str, file_path: &str, link_name: &str) -> String {
format!(
"{}
{}
{}",
format_string(dir, true, true, " 8.0K", "─┬"),
format_string(file_path, true, true, " 4.0K", " ├──",),
format_string(link_name, false, true, " 4.0K", " └──",),
)
}
#[cfg(target_os = "linux")]
fn soft_sym_link_output(dir: &str, file_path: &str, link_name: &str) -> String {
format!(
"{}
{}
{}",
format_string(dir, true, true, " 8.0K", "─┬"),
format_string(file_path, true, true, " 4.0K", " ├──",),
format_string(link_name, false, true, " 0B", " └──",),
)
}
// Hard links are ignored as the inode is the same as the file // Hard links are ignored as the inode is the same as the file
#[test] #[test]
pub fn test_hard_sym_link() { pub fn test_hard_sym_link() {
@@ -212,61 +209,32 @@ pub fn test_hard_sym_link() {
.output(); .output();
assert!(c.is_ok()); assert!(c.is_ok());
let (r, r2) = hard_link_output(dir_s, file_path_s, link_name_s); let a = format!(" ─┬ {}", dir_s);
let b = format!(" └── {}", link_name_s);
let b2 = format!(" └── {}", file_path_s);
// Because this is a hard link the file and hard link look identical. Therefore // Because this is a hard link the file and hard link look identical. Therefore
// we cannot guarantee which version will appear first. // we cannot guarantee which version will appear first.
// TODO: Consider adding predictable iteration order (sort file entries by name?)
let result = panic::catch_unwind(|| { let result = panic::catch_unwind(|| {
assert_cli::Assert::main_binary() assert_cli::Assert::main_binary()
.with_args(&[dir_s]) .with_args(&["-p", dir_s])
.stdout() .stdout()
.contains(r) .contains(a.clone())
.stdout()
.contains(b)
.unwrap(); .unwrap();
}); });
if result.is_err() { if result.is_err() {
assert_cli::Assert::main_binary() assert_cli::Assert::main_binary()
.with_args(&[dir_s]) .with_args(&["-p", dir_s])
.stdout() .stdout()
.contains(r2) .contains(a)
.stdout()
.contains(b2)
.unwrap(); .unwrap();
} }
} }
#[cfg(target_os = "macos")]
fn hard_link_output(dir_s: &str, file_path_s: &str, link_name_s: &str) -> (String, String) {
let r = format!(
"{}
{}",
format_string(dir_s, true, true, " 4.0K", "─┬"),
format_string(file_path_s, true, true, " 4.0K", " └──")
);
let r2 = format!(
"{}
{}",
format_string(dir_s, true, true, " 4.0K", "─┬"),
format_string(link_name_s, true, true, " 4.0K", " └──")
);
(r, r2)
}
#[cfg(target_os = "linux")]
fn hard_link_output(dir_s: &str, file_path_s: &str, link_name_s: &str) -> (String, String) {
let r = format!(
"{}
{}",
format_string(dir_s, true, true, " 8.0K", "─┬"),
format_string(file_path_s, true, true, " 4.0K", " └──")
);
let r2 = format!(
"{}
{}",
format_string(dir_s, true, true, " 8.0K", "─┬"),
format_string(link_name_s, true, true, " 4.0K", " └──")
);
(r, r2)
}
// Check we don't recurse down an infinite symlink tree // Check we don't recurse down an infinite symlink tree
#[test] #[test]
pub fn test_recursive_sym_link() { pub fn test_recursive_sym_link() {
@@ -283,70 +251,50 @@ pub fn test_recursive_sym_link() {
.output(); .output();
assert!(c.is_ok()); assert!(c.is_ok());
assert_cli::Assert::main_binary() let a = format!(" ─┬ {}", dir_s);
.with_args(&[dir_s]) let b = format!(" └── {}", link_name_s);
.stdout()
.contains(recursive_sym_link_output(dir_s, link_name_s))
.unwrap();
}
#[cfg(target_os = "macos")]
fn recursive_sym_link_output(dir: &str, link_name: &str) -> String {
format!(
"{}
{}",
format_string(dir, true, true, " 4.0K", "─┬"),
format_string(link_name, true, true, " 4.0K", " └──",),
)
}
#[cfg(target_os = "linux")]
fn recursive_sym_link_output(dir: &str, link_name: &str) -> String {
format!(
"{}
{}",
format_string(dir, true, true, " 4.0K", "─┬"),
format_string(link_name, true, true, " 0B", " └──",),
)
}
// Check against directories and files whos names are substrings of each other
#[test]
#[cfg(target_os = "macos")]
pub fn test_substring_of_names() {
assert_cli::Assert::main_binary() assert_cli::Assert::main_binary()
.with_args(&["src/test_dir2"]) .with_args(&["-p", dir_s])
.stdout() .stdout()
.contains(" ─┬ test_dir2") .contains(a)
.stdout() .stdout()
.contains(" ├─┬ dir") .contains(b)
.stdout()
.contains(" │ └── hello")
.stdout()
.contains(" ├── dir_name_clash")
.stdout()
.contains(" └─┬ dir_substring")
.stdout()
.contains(" └── hello")
.unwrap(); .unwrap();
} }
// Check against directories and files whos names are substrings of each other // Check against directories and files whos names are substrings of each other
#[test] #[test]
#[cfg(target_os = "linux")]
pub fn test_substring_of_names() { pub fn test_substring_of_names() {
assert_cli::Assert::main_binary() assert_cli::Assert::main_binary()
.with_args(&["src/test_dir2"]) .with_args(&["-c", "src/test_dir2"])
.stdout() .stdout()
.contains(" ─┬ test_dir2") .is(no_substring_of_names_output())
.stdout()
.contains(" ├─┬ dir")
.stdout()
.contains(" │ └── hello")
.stdout()
.contains(" ├─┬ dir_substring")
.stdout()
.contains(" │ └── hello")
.stdout()
.contains(" └── dir_name_clash")
.unwrap(); .unwrap();
} }
#[cfg(target_os = "linux")]
fn no_substring_of_names_output() -> String {
"
24K ─┬ test_dir2
8.0K ├─┬ dir
4.0K │ └── hello
8.0K ├─┬ dir_substring
4.0K │ └── hello
4.0K └── dir_name_clash
"
.into()
}
#[cfg(target_os = "macos")]
fn no_substring_of_names_output() -> String {
"
12K ─┬ test_dir2
4.0K ├─┬ dir
4.0K │ └── hello
4.0K ├── dir_name_clash
4.0K └─┬ dir_substring
4.0K └── hello
"
.into()
}