From c4c9ee01f4ab27359ed823ef2c7f3ee6b9a32df5 Mon Sep 17 00:00:00 2001 From: dvvvvvv Date: Mon, 4 Nov 2019 23:07:54 +0900 Subject: add date formatting feature --- src/app.rs | 2 -- src/flags.rs | 4 +++- src/meta/date.rs | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/app.rs b/src/app.rs index 6f7ac19..6a13efa 100644 --- a/src/app.rs +++ b/src/app.rs @@ -134,8 +134,6 @@ pub fn build() -> App<'static, 'static> { .arg( Arg::with_name("date") .long("date") - .possible_value("date") - .possible_value("relative") .default_value("date") .multiple(true) .number_of_values(1) diff --git a/src/flags.rs b/src/flags.rs index 848b158..900fe58 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -248,10 +248,11 @@ impl<'a> From<&'a str> for SizeFlag { } } -#[derive(Clone, Debug, Copy, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum DateFlag { Date, Relative, + Formatted(String), } impl<'a> From<&'a str> for DateFlag { @@ -259,6 +260,7 @@ impl<'a> From<&'a str> for DateFlag { match time { "date" => DateFlag::Date, "relative" => DateFlag::Relative, + time if time.starts_with("+") => DateFlag::Formatted(time[1..].to_owned()), _ => panic!("invalid \"time\" flag: {}", time), } } diff --git a/src/meta/date.rs b/src/meta/date.rs index a909983..fcfb8c9 100644 --- a/src/meta/date.rs +++ b/src/meta/date.rs @@ -41,9 +41,10 @@ impl Date { } pub fn date_string(&self, flags: &Flags) -> String { - match flags.date { + match &flags.date { DateFlag::Date => self.0.ctime().to_string(), DateFlag::Relative => format!("{}", HumanTime::from(self.0 - time::now())), + DateFlag::Formatted(format) => self.0.to_local().strftime(&format).unwrap().to_string(), } } } -- cgit v1.2.3 From 698bc2ef3bd714144992f92e310a78d67e0e6048 Mon Sep 17 00:00:00 2001 From: dvvvvvv Date: Thu, 7 Nov 2019 11:59:20 +0900 Subject: add date formatting validation --- Cargo.toml | 1 + src/app.rs | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index ac9f36f..071ad1d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ path = "src/main.rs" [build-dependencies] clap = "2.33.*" version_check = "0.9.*" +time = "0.1.*" [dependencies] ansi_term = "0.12.*" diff --git a/src/app.rs b/src/app.rs index 6a13efa..4db93e7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,5 +1,6 @@ use clap::{App, Arg}; + pub fn build() -> App<'static, 'static> { App::new("lsd") .version(crate_version!()) @@ -134,6 +135,7 @@ pub fn build() -> App<'static, 'static> { .arg( Arg::with_name("date") .long("date") + .validator(validate_date_argument) .default_value("date") .multiple(true) .number_of_values(1) @@ -202,3 +204,16 @@ pub fn build() -> App<'static, 'static> { .help("Do not display files/directories with names matching the glob pattern(s)"), ) } + +fn validate_date_argument(arg: String) -> Result<(), String> { + use std::error::Error; + if arg.starts_with("+") { + time::now().strftime(&arg).map(drop).map_err(|err| err.description().to_string()) + } else if &arg == "date" { + Result::Ok(()) + } else if &arg == "relative" { + Result::Ok(()) + } else { + Result::Err("possible values: date, relative".to_owned()) + } +} -- cgit v1.2.3 From 50cf660567d2178f843df4f8ea7a3f2b9f60000e Mon Sep 17 00:00:00 2001 From: dvvvvvv Date: Fri, 8 Nov 2019 12:14:39 +0900 Subject: change test parse to validation function --- src/app.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/app.rs b/src/app.rs index 4db93e7..06d96e2 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,6 +1,5 @@ use clap::{App, Arg}; - pub fn build() -> App<'static, 'static> { App::new("lsd") .version(crate_version!()) @@ -208,7 +207,7 @@ pub fn build() -> App<'static, 'static> { fn validate_date_argument(arg: String) -> Result<(), String> { use std::error::Error; if arg.starts_with("+") { - time::now().strftime(&arg).map(drop).map_err(|err| err.description().to_string()) + validate_time_format(&arg).map_err(|err| err.description().to_string()) } else if &arg == "date" { Result::Ok(()) } else if &arg == "relative" { @@ -217,3 +216,26 @@ fn validate_date_argument(arg: String) -> Result<(), String> { Result::Err("possible values: date, relative".to_owned()) } } + +fn validate_time_format(formatter: &str) -> Result<(), time::ParseError> { + let mut chars = formatter.chars(); + loop { + match chars.next() { + Some('%') => match chars.next() { + Some('A') | Some('a') | Some('B') | Some('b') | Some('C') | Some('c') + | Some('D') | Some('d') | Some('e') | Some('F') | Some('f') | Some('G') + | Some('g') | Some('H') | Some('h') | Some('I') | Some('j') | Some('k') + | Some('l') | Some('M') | Some('m') | Some('n') | Some('P') | Some('p') + | Some('R') | Some('r') | Some('S') | Some('s') | Some('T') | Some('t') + | Some('U') | Some('u') | Some('V') | Some('v') | Some('W') | Some('w') + | Some('X') | Some('x') | Some('Y') | Some('y') | Some('Z') | Some('z') + | Some('+') | Some('%') => (), + Some(c) => return Err(time::ParseError::InvalidFormatSpecifier(c)), + None => return Err(time::ParseError::MissingFormatConverter), + }, + None => break, + _ => continue, + } + } + Ok(()) +} -- cgit v1.2.3 From e6ee773277c7ef50971537b3a59d5350f937cdb4 Mon Sep 17 00:00:00 2001 From: dvvvvvv Date: Sun, 10 Nov 2019 15:53:26 +0900 Subject: add date validation message --- src/app.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/app.rs b/src/app.rs index 06d96e2..f4ce318 100644 --- a/src/app.rs +++ b/src/app.rs @@ -138,7 +138,7 @@ pub fn build() -> App<'static, 'static> { .default_value("date") .multiple(true) .number_of_values(1) - .help("How to display date"), + .help("How to display date [possible values: date, relative, +date-time-format]"), ) .arg( Arg::with_name("timesort") @@ -213,7 +213,10 @@ fn validate_date_argument(arg: String) -> Result<(), String> { } else if &arg == "relative" { Result::Ok(()) } else { - Result::Err("possible values: date, relative".to_owned()) + Result::Err( + "possible values: date, relative, +date-time-format" + .to_owned() + ) } } -- cgit v1.2.3 From 58d44a6450951eeff7f3828f216957042aa9193b Mon Sep 17 00:00:00 2001 From: dvvvvvv Date: Sun, 10 Nov 2019 16:56:33 +0900 Subject: change string literal into char literal --- src/app.rs | 2 +- src/flags.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app.rs b/src/app.rs index f4ce318..291bebe 100644 --- a/src/app.rs +++ b/src/app.rs @@ -206,7 +206,7 @@ pub fn build() -> App<'static, 'static> { fn validate_date_argument(arg: String) -> Result<(), String> { use std::error::Error; - if arg.starts_with("+") { + if arg.starts_with('+') { validate_time_format(&arg).map_err(|err| err.description().to_string()) } else if &arg == "date" { Result::Ok(()) diff --git a/src/flags.rs b/src/flags.rs index 900fe58..d8e8c43 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -260,7 +260,7 @@ impl<'a> From<&'a str> for DateFlag { match time { "date" => DateFlag::Date, "relative" => DateFlag::Relative, - time if time.starts_with("+") => DateFlag::Formatted(time[1..].to_owned()), + time if time.starts_with('+') => DateFlag::Formatted(time[1..].to_owned()), _ => panic!("invalid \"time\" flag: {}", time), } } -- cgit v1.2.3 From f1fed05413f1756ff784363f6c4476d922378e69 Mon Sep 17 00:00:00 2001 From: dvvvvvv Date: Sun, 10 Nov 2019 17:36:50 +0900 Subject: squeeze if-branches in date validation method --- src/app.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/app.rs b/src/app.rs index 291bebe..3078aae 100644 --- a/src/app.rs +++ b/src/app.rs @@ -208,15 +208,10 @@ fn validate_date_argument(arg: String) -> Result<(), String> { use std::error::Error; if arg.starts_with('+') { validate_time_format(&arg).map_err(|err| err.description().to_string()) - } else if &arg == "date" { - Result::Ok(()) - } else if &arg == "relative" { + } else if &arg == "date" || &arg == "relative" { Result::Ok(()) } else { - Result::Err( - "possible values: date, relative, +date-time-format" - .to_owned() - ) + Result::Err("possible values: date, relative, +date-time-format".to_owned()) } } -- cgit v1.2.3 From 748a2722a2688b44d8d70d3f87899dccbf66f937 Mon Sep 17 00:00:00 2001 From: Qwerty-Space Date: Fri, 3 Jan 2020 21:44:23 +0000 Subject: Add nerd fonts, minor typo and positional changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Add nerd fonts to xresources • Move ls alias to "optional", as it is not required for lsd to function, so keeping it in "required" is misleading • you→your --- README.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 55974cf..a844b23 100644 --- a/README.md +++ b/README.md @@ -115,17 +115,24 @@ The [release page](https://github.com/Peltoche/lsd/releases) includes precompile ### Required -In order to use lsd instead of the default ls you need to add this to you shell -configuration file (~/.bashrc, ~/.zshrc, etc.) : +Enable nerd fonts for your terminal, URxvt for example: + +.Xresources +``` +URxvt*font: xft:Hack Nerd Font:style=Regular:size=11 +``` + +### Optional + + +In order to use lsd when entering the `ls` command, you need to add this to your shell +configuration file (~/.bashrc, ~/.zshrc, etc.): ```sh alias ls='lsd' ``` -### Optional - -Some examples of useful aliases. You can add this to you shell configuration -file (~/.bashrc, ~/.zshrc, etc.) just under the alias above : +Some further examples of useful aliases: ```sh alias l='ls -l' -- cgit v1.2.3 From 87e87d87cdf91d7e8a3f385b0a5beb96ddbd8824 Mon Sep 17 00:00:00 2001 From: Pierre Peltier Date: Wed, 11 Dec 2019 10:46:41 +0100 Subject: Do not panic if the pipes a closed before all the output is written --- src/core.rs | 10 +++++----- src/main.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ src/meta/mod.rs | 13 +++++++------ 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/core.rs b/src/core.rs index 60c73e7..6a120b3 100644 --- a/src/core.rs +++ b/src/core.rs @@ -3,7 +3,7 @@ use crate::display; use crate::flags::{Display, Flags, IconTheme, Layout, WhenFlag}; use crate::icon::{self, Icons}; use crate::meta::Meta; -use crate::sort; +use crate::{print_error, print_output, sort}; use std::fs; use std::path::PathBuf; @@ -84,14 +84,14 @@ impl Core { for path in paths { if let Err(err) = fs::canonicalize(&path) { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); continue; } let mut meta = match Meta::from_path(&path) { Ok(meta) => meta, Err(err) => { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); continue; } }; @@ -107,7 +107,7 @@ impl Core { meta_list.push(meta); } Err(err) => { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); continue; } }; @@ -140,6 +140,6 @@ impl Core { display::grid(&metas, &self.flags, &self.colors, &self.icons) }; - print!("{}", output); + print_output!("{}", output); } } diff --git a/src/main.rs b/src/main.rs index 87440b6..5251884 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,6 +38,49 @@ use crate::core::Core; use crate::flags::Flags; use std::path::PathBuf; +/// Macro used to avoid panicking when the lsd method is used with a pipe and +/// stderr close before our program. +#[macro_export] +macro_rules! print_error { + ($($arg:tt)*) => { + use std::io::Write; + + let stderr = std::io::stderr(); + + { + let mut handle = stderr.lock(); + // We can write on stderr, so we simply ignore the error and don't print + // and stop with success. + let res = handle.write_all(std::format!($($arg)*).as_bytes()); + if res.is_err() { + std::process::exit(0); + } + } + }; +} + +/// Macro used to avoid panicking when the lsd method is used with a pipe and +/// stdout close before our program. +#[macro_export] +macro_rules! print_output { + ($($arg:tt)*) => { + use std::io::Write; + + let stderr = std::io::stdout(); + + + { + let mut handle = stderr.lock(); + // We can write on stdout, so we simply ignore the error and don't print + // and stop with success. + let res = handle.write_all(std::format!($($arg)*).as_bytes()); + if res.is_err() { + std::process::exit(0); + } + } + }; +} + fn main() { let matches = app::build().get_matches_from(wild::args_os()); diff --git a/src/meta/mod.rs b/src/meta/mod.rs index 4f51191..69bc34f 100644 --- a/src/meta/mod.rs +++ b/src/meta/mod.rs @@ -20,6 +20,7 @@ pub use self::size::Size; pub use self::symlink::SymLink; pub use crate::flags::Display; pub use crate::icon::Icons; +use crate::print_error; use std::fs; use std::fs::read_link; @@ -65,7 +66,7 @@ impl Meta { let entries = match self.path.read_dir() { Ok(entries) => entries, Err(err) => { - eprintln!("cannot access '{}': {}", self.path.display(), err); + print_error!("cannot access '{}': {}", self.path.display(), err); return Ok(None); } }; @@ -112,7 +113,7 @@ impl Meta { let mut entry_meta = match Self::from_path(&path) { Ok(res) => res, Err(err) => { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); continue; } }; @@ -120,7 +121,7 @@ impl Meta { match entry_meta.recurse_into(depth - 1, display, ignore_globs) { Ok(content) => entry_meta.content = content, Err(err) => { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); continue; } }; @@ -158,7 +159,7 @@ impl Meta { let metadata = match metadata { Ok(meta) => meta, Err(err) => { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); return 0; } }; @@ -171,7 +172,7 @@ impl Meta { let entries = match path.read_dir() { Ok(entries) => entries, Err(err) => { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); return size; } }; @@ -179,7 +180,7 @@ impl Meta { let path = match entry { Ok(entry) => entry.path(), Err(err) => { - eprintln!("cannot access '{}': {}", path.display(), err); + print_error!("cannot access '{}': {}", path.display(), err); continue; } }; -- cgit v1.2.3 From 0ebb39d60cc498cf92c09e8b3fa46316873941b6 Mon Sep 17 00:00:00 2001 From: zwPapEr Date: Sat, 2 Nov 2019 15:42:42 +0800 Subject: impl showing inode by setting blocks working on https://github.com/Peltoche/lsd/issues/276 --- src/app.rs | 11 ++++++++++- src/display.rs | 3 +++ src/flags.rs | 2 ++ src/meta/inode.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/meta/mod.rs | 5 +++++ 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/meta/inode.rs diff --git a/src/app.rs b/src/app.rs index 3078aae..e97df00 100644 --- a/src/app.rs +++ b/src/app.rs @@ -178,7 +178,16 @@ pub fn build() -> App<'static, 'static> { .multiple(true) .number_of_values(1) .require_delimiter(true) - .possible_values(&["permission", "user", "group", "size", "date", "name"]) + .possible_values(&[ + "permission", + "user", + "group", + "size", + "date", + "name", + "inode", + ]) + .default_value("permission,user,group,size,date,name") .help("Specify the blocks that will be displayed and in what order"), ) .arg( diff --git a/src/display.rs b/src/display.rs index 93179d8..b3d8e5f 100644 --- a/src/display.rs +++ b/src/display.rs @@ -221,6 +221,9 @@ fn get_output<'a>( let mut strings: Vec = Vec::new(); for block in flags.blocks.iter() { match block { + Block::INode => { + strings.push(meta.inode.render(colors)); + } Block::Permission => { let s: &[ColoredString] = &[ meta.file_type.render(colors), diff --git a/src/flags.rs b/src/flags.rs index d8e8c43..6c6de7f 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -205,6 +205,7 @@ pub enum Block { SizeValue, Date, Name, + INode, } impl<'a> From<&'a str> for Block { fn from(block: &'a str) -> Self { @@ -217,6 +218,7 @@ impl<'a> From<&'a str> for Block { "size_value" => Block::SizeValue, "date" => Block::Date, "name" => Block::Name, + "inode" => Block::INode, _ => panic!("invalid \"time\" flag: {}", block), } } diff --git a/src/meta/inode.rs b/src/meta/inode.rs new file mode 100644 index 0000000..bf30273 --- /dev/null +++ b/src/meta/inode.rs @@ -0,0 +1,55 @@ +use crate::color::{ColoredString, Colors, Elem}; +use std::fs::Metadata; + +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +pub struct INode { + index: u64, +} + +impl<'a> From<&'a Metadata> for INode { + #[cfg(unix)] + fn from(meta: &Metadata) -> Self { + use std::os::unix::fs::MetadataExt; + + let index = meta.ino(); + + Self { index: index } + } + + #[cfg(windows)] + fn from(_: &Metadata) -> Self { + panic!("Cannot get inode on Windows") + } +} + +impl INode { + pub fn render(&self, colors: &Colors) -> ColoredString { + colors.colorize(self.index.to_string(), &Elem::SymLink) + } +} + +#[cfg(test)] +mod tests { + use super::INode; + use std::env; + use std::io; + use std::path::Path; + use std::process::{Command, ExitStatus}; + + #[cfg(unix)] + fn cross_platform_touch(path: &Path) -> io::Result { + Command::new("touch").arg(&path).status() + } + + #[test] + fn test_inode_no_zero() { + let mut file_path = env::temp_dir(); + file_path.push("inode.tmp"); + + let success = cross_platform_touch(&file_path).unwrap().success(); + assert!(success, "failed to exec touch"); + + let inode = INode::from(&file_path.metadata().unwrap()); + assert_ne!(inode.index, 0); + } +} diff --git a/src/meta/mod.rs b/src/meta/mod.rs index 69bc34f..2ecc472 100644 --- a/src/meta/mod.rs +++ b/src/meta/mod.rs @@ -1,6 +1,7 @@ mod date; mod filetype; mod indicator; +mod inode; mod name; mod owner; mod permissions; @@ -13,6 +14,7 @@ mod windows_utils; pub use self::date::Date; pub use self::filetype::FileType; pub use self::indicator::Indicator; +pub use self::inode::INode; pub use self::name::Name; pub use self::owner::Owner; pub use self::permissions::Permissions; @@ -40,6 +42,7 @@ pub struct Meta { pub size: Size, pub symlink: SymLink, pub indicator: Indicator, + pub inode: INode, pub content: Option>, } @@ -211,8 +214,10 @@ impl Meta { let file_type = FileType::new(&metadata, &permissions); let name = Name::new(&path, file_type); + let inode = INode::from(&metadata); Ok(Self { + inode, path: path.to_path_buf(), symlink: SymLink::from(path.as_path()), size: Size::from(&metadata), -- cgit v1.2.3 From da2e2081e3b242ad69ae41d2663e7b60e261a022 Mon Sep 17 00:00:00 2001 From: zwPapEr Date: Sat, 7 Dec 2019 11:22:00 +0800 Subject: test: :art: fix clippy style and tests, add an inode test inode: :hammer: only get inode on unix, return 0 for windows --- src/meta/inode.rs | 6 +++--- tests/integration.rs | 53 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/meta/inode.rs b/src/meta/inode.rs index bf30273..d40edf5 100644 --- a/src/meta/inode.rs +++ b/src/meta/inode.rs @@ -13,12 +13,12 @@ impl<'a> From<&'a Metadata> for INode { let index = meta.ino(); - Self { index: index } + Self { index } } #[cfg(windows)] fn from(_: &Metadata) -> Self { - panic!("Cannot get inode on Windows") + Self { index: 0 } } } @@ -29,6 +29,7 @@ impl INode { } #[cfg(test)] +#[cfg(unix)] mod tests { use super::INode; use std::env; @@ -36,7 +37,6 @@ mod tests { use std::path::Path; use std::process::{Command, ExitStatus}; - #[cfg(unix)] fn cross_platform_touch(path: &Path) -> io::Result { Command::new("touch").arg(&path).status() } diff --git a/tests/integration.rs b/tests/integration.rs index d61487f..96ac61e 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -19,13 +19,34 @@ fn test_list_empty_directory() { .stdout(predicate::eq("")); } +#[test] +fn test_list_almost_all_empty_directory() { + cmd() + .arg("--almost-all") + .arg(tempdir().path()) + .assert() + .stdout(predicate::eq("")); + + cmd() + .arg("-A") + .arg(tempdir().path()) + .assert() + .stdout(predicate::eq("")); +} + #[test] fn test_list_all_empty_directory() { cmd() .arg("--all") .arg(tempdir().path()) .assert() - .stdout(predicate::eq(".\n..\n")); + .stdout(predicate::str::is_match(".* \\.\n.* \\.\\.\n$").unwrap()); + + cmd() + .arg("-a") + .arg(tempdir().path()) + .assert() + .stdout(predicate::str::is_match(".* \\.\n.* \\.\\.\n$").unwrap()); } #[test] @@ -36,7 +57,19 @@ fn test_list_populated_directory() { cmd() .arg(dir.path()) .assert() - .stdout(predicate::eq("one\ntwo\n")); + .stdout(predicate::str::is_match(".* one\n.* two\n$").unwrap()); +} + +#[test] +fn test_list_almost_all_populated_directory() { + let dir = tempdir(); + dir.child("one").touch().unwrap(); + dir.child("two").touch().unwrap(); + cmd() + .arg("--almost-all") + .arg(dir.path()) + .assert() + .stdout(predicate::str::is_match(".* one\n.* two\n$").unwrap()); } #[test] @@ -48,7 +81,21 @@ fn test_list_all_populated_directory() { .arg("--all") .arg(dir.path()) .assert() - .stdout(predicate::eq(".\n..\none\ntwo\n")); + .stdout(predicate::str::is_match(".* \\.\n.* \\.\\.\n.* one\n.* two\n$").unwrap()); +} + +#[test] +#[cfg(unix)] +fn test_list_inode_populated_directory() { + let dir = tempdir(); + dir.child("one").touch().unwrap(); + dir.child("two").touch().unwrap(); + cmd() + .arg("--blocks") + .arg("inode,name") + .arg(dir.path()) + .assert() + .stdout(predicate::str::is_match("\\d+ one\n\\d+ two\n$").unwrap()); } fn cmd() -> Command { -- cgit v1.2.3 From 37a97353a1a7035d2a2f7de888bd7c97849a4a9d Mon Sep 17 00:00:00 2001 From: zwPapEr Date: Thu, 12 Dec 2019 12:17:02 +0800 Subject: inode: :hammer: using - for not supported windows inode --- src/app.rs | 1 - src/meta/inode.rs | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/app.rs b/src/app.rs index e97df00..92f75c5 100644 --- a/src/app.rs +++ b/src/app.rs @@ -187,7 +187,6 @@ pub fn build() -> App<'static, 'static> { "name", "inode", ]) - .default_value("permission,user,group,size,date,name") .help("Specify the blocks that will be displayed and in what order"), ) .arg( diff --git a/src/meta/inode.rs b/src/meta/inode.rs index d40edf5..930830c 100644 --- a/src/meta/inode.rs +++ b/src/meta/inode.rs @@ -4,6 +4,7 @@ use std::fs::Metadata; #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub struct INode { index: u64, + valide: bool, } impl<'a> From<&'a Metadata> for INode { @@ -13,17 +14,27 @@ impl<'a> From<&'a Metadata> for INode { let index = meta.ino(); - Self { index } + Self { + index: index, + valide: true, + } } #[cfg(windows)] fn from(_: &Metadata) -> Self { - Self { index: 0 } + Self { + index: 0, + valide: false, + } } } impl INode { pub fn render(&self, colors: &Colors) -> ColoredString { + if !self.valide { + return colors.colorize(String::from("-"), &Elem::SymLink); + } + colors.colorize(self.index.to_string(), &Elem::SymLink) } } -- cgit v1.2.3 From d9b68ccd10c13f5d08ed2d9444aabe4b3ad7607e Mon Sep 17 00:00:00 2001 From: zwPapEr Date: Thu, 12 Dec 2019 12:28:50 +0800 Subject: test: :hammer: fix test after delete default, add inode windows test --- src/meta/inode.rs | 2 +- tests/integration.rs | 30 +++++++++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/meta/inode.rs b/src/meta/inode.rs index 930830c..2d9e52b 100644 --- a/src/meta/inode.rs +++ b/src/meta/inode.rs @@ -15,7 +15,7 @@ impl<'a> From<&'a Metadata> for INode { let index = meta.ino(); Self { - index: index, + index, valide: true, } } diff --git a/tests/integration.rs b/tests/integration.rs index 96ac61e..c934f26 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -21,32 +21,34 @@ fn test_list_empty_directory() { #[test] fn test_list_almost_all_empty_directory() { + let matched = ""; cmd() .arg("--almost-all") .arg(tempdir().path()) .assert() - .stdout(predicate::eq("")); + .stdout(predicate::eq(matched)); cmd() .arg("-A") .arg(tempdir().path()) .assert() - .stdout(predicate::eq("")); + .stdout(predicate::eq(matched)); } #[test] fn test_list_all_empty_directory() { + let matched = "\\.\n\\.\\.\n$"; cmd() .arg("--all") .arg(tempdir().path()) .assert() - .stdout(predicate::str::is_match(".* \\.\n.* \\.\\.\n$").unwrap()); + .stdout(predicate::str::is_match(matched).unwrap()); cmd() .arg("-a") .arg(tempdir().path()) .assert() - .stdout(predicate::str::is_match(".* \\.\n.* \\.\\.\n$").unwrap()); + .stdout(predicate::str::is_match(matched).unwrap()); } #[test] @@ -57,7 +59,7 @@ fn test_list_populated_directory() { cmd() .arg(dir.path()) .assert() - .stdout(predicate::str::is_match(".* one\n.* two\n$").unwrap()); + .stdout(predicate::str::is_match("one\ntwo\n$").unwrap()); } #[test] @@ -69,7 +71,7 @@ fn test_list_almost_all_populated_directory() { .arg("--almost-all") .arg(dir.path()) .assert() - .stdout(predicate::str::is_match(".* one\n.* two\n$").unwrap()); + .stdout(predicate::str::is_match("one\ntwo\n$").unwrap()); } #[test] @@ -81,7 +83,7 @@ fn test_list_all_populated_directory() { .arg("--all") .arg(dir.path()) .assert() - .stdout(predicate::str::is_match(".* \\.\n.* \\.\\.\n.* one\n.* two\n$").unwrap()); + .stdout(predicate::str::is_match("\\.\n\\.\\.\none\ntwo\n$").unwrap()); } #[test] @@ -98,6 +100,20 @@ fn test_list_inode_populated_directory() { .stdout(predicate::str::is_match("\\d+ one\n\\d+ two\n$").unwrap()); } +#[test] +#[cfg(windows)] +fn test_list_inode_populated_directory() { + let dir = tempdir(); + dir.child("one").touch().unwrap(); + dir.child("two").touch().unwrap(); + cmd() + .arg("--blocks") + .arg("inode,name") + .arg(dir.path()) + .assert() + .stdout(predicate::str::is_match("- one\n\\- two\n$").unwrap()); +} + fn cmd() -> Command { Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap() } -- cgit v1.2.3 From 1af45a10e8f3e4aae18955c33e5ea66c3db22e58 Mon Sep 17 00:00:00 2001 From: zwPapEr Date: Sun, 15 Dec 2019 14:22:11 +0800 Subject: inode: :art: use option for inode, and two color for valid or not --- src/color.rs | 15 ++++++++++++++- src/display.rs | 4 +--- src/meta/inode.rs | 26 +++++++++++--------------- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/color.rs b/src/color.rs index b18a857..5823a67 100644 --- a/src/color.rs +++ b/src/color.rs @@ -42,6 +42,11 @@ pub enum Elem { FileLarge, FileMedium, FileSmall, + + /// INode + INode { + valid: bool, + } } impl Elem { @@ -151,13 +156,17 @@ impl Colors { } else { Some("di") } - } + }, Elem::SymLink => Some("ln"), Elem::Pipe => Some("pi"), Elem::Socket => Some("so"), Elem::BlockDevice => Some("bd"), Elem::CharDevice => Some("cd"), Elem::BrokenSymLink => Some("or"), + Elem::INode { valid } => match valid { + true => Some("so"), + false => Some("no"), + }, _ => None, }; @@ -233,6 +242,10 @@ impl Colors { m.insert(Elem::FileMedium, Colour::Fixed(216)); // LightSalmon1 m.insert(Elem::FileLarge, Colour::Fixed(172)); // Orange3 + // INode + m.insert(Elem::INode { valid: true }, Colour::Fixed(13)); // Pink + m.insert(Elem::INode { valid: false }, Colour::Fixed(245)); // Grey + m } } diff --git a/src/display.rs b/src/display.rs index b3d8e5f..6cde985 100644 --- a/src/display.rs +++ b/src/display.rs @@ -221,9 +221,7 @@ fn get_output<'a>( let mut strings: Vec = Vec::new(); for block in flags.blocks.iter() { match block { - Block::INode => { - strings.push(meta.inode.render(colors)); - } + Block::INode => strings.push(meta.inode.render(colors)), Block::Permission => { let s: &[ColoredString] = &[ meta.file_type.render(colors), diff --git a/src/meta/inode.rs b/src/meta/inode.rs index 2d9e52b..9bc67d9 100644 --- a/src/meta/inode.rs +++ b/src/meta/inode.rs @@ -3,8 +3,7 @@ use std::fs::Metadata; #[derive(Debug, PartialEq, Eq, Copy, Clone)] pub struct INode { - index: u64, - valide: bool, + index: Option, } impl<'a> From<&'a Metadata> for INode { @@ -14,28 +13,21 @@ impl<'a> From<&'a Metadata> for INode { let index = meta.ino(); - Self { - index, - valide: true, - } + Self { index: Some(index) } } #[cfg(windows)] fn from(_: &Metadata) -> Self { - Self { - index: 0, - valide: false, - } + Self { index: None } } } impl INode { pub fn render(&self, colors: &Colors) -> ColoredString { - if !self.valide { - return colors.colorize(String::from("-"), &Elem::SymLink); + match self.index { + Some(i) => colors.colorize(i.to_string(), &Elem::INode{ valid: true }), + None => colors.colorize(String::from("-"), &Elem::INode{ valid: false }), } - - colors.colorize(self.index.to_string(), &Elem::SymLink) } } @@ -61,6 +53,10 @@ mod tests { assert!(success, "failed to exec touch"); let inode = INode::from(&file_path.metadata().unwrap()); - assert_ne!(inode.index, 0); + + #[cfg(unix)] + assert!(inode.index.is_some()); + #[cfg(windows)] + assert!(inode.index.is_none()); } } -- cgit v1.2.3 From 11d10caf0fd4c9e8209fb41fac88121ac903d753 Mon Sep 17 00:00:00 2001 From: zwPapEr Date: Sun, 15 Dec 2019 14:59:18 +0800 Subject: args: :sparkles: add inode(i) args for showing inode,name --- src/app.rs | 8 ++++++++ src/color.rs | 4 ++-- src/flags.rs | 19 ++++++++++++------- src/meta/inode.rs | 4 ++-- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/app.rs b/src/app.rs index 92f75c5..d60568b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -210,6 +210,14 @@ pub fn build() -> App<'static, 'static> { .default_value("") .help("Do not display files/directories with names matching the glob pattern(s)"), ) + .arg( + Arg::with_name("inode") + .short("i") + .long("inode") + .multiple(true) + .conflicts_with("blocks") + .help("Display inode and file names"), + ) } fn validate_date_argument(arg: String) -> Result<(), String> { diff --git a/src/color.rs b/src/color.rs index 5823a67..943a1d0 100644 --- a/src/color.rs +++ b/src/color.rs @@ -46,7 +46,7 @@ pub enum Elem { /// INode INode { valid: bool, - } + }, } impl Elem { @@ -156,7 +156,7 @@ impl Colors { } else { Some("di") } - }, + } Elem::SymLink => Some("ln"), Elem::Pipe => Some("pi"), Elem::Socket => Some("so"), diff --git a/src/flags.rs b/src/flags.rs index 6c6de7f..003ee57 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -15,6 +15,7 @@ pub struct Flags { pub color: WhenFlag, pub icon: WhenFlag, pub icon_theme: IconTheme, + pub inode: bool, pub recursion_depth: usize, pub blocks: Vec, pub no_symlink: bool, @@ -32,6 +33,8 @@ impl Flags { let date_inputs: Vec<&str> = matches.values_of("date").unwrap().collect(); let dir_order_inputs: Vec<&str> = matches.values_of("group-dirs").unwrap().collect(); let ignore_globs_inputs: Vec<&str> = matches.values_of("ignore-glob").unwrap().collect(); + // inode set layout to oneline and blocks to inode,name + let inode = matches.is_present("inode"); let blocks_inputs: Vec<&str> = if let Some(blocks) = matches.values_of("blocks") { blocks.collect() } else { @@ -67,6 +70,7 @@ impl Flags { } else if matches.is_present("long") || matches.is_present("oneline") || blocks_inputs.len() > 1 + || inode { Layout::OneLine } else { @@ -94,19 +98,18 @@ impl Flags { None => usize::max_value(), }; - let blocks: Vec = if !blocks_inputs.is_empty() { - blocks_inputs.into_iter().map(Block::from).collect() - } else if matches.is_present("long") { - vec![ + let blocks: Vec = match () { + _ if inode => vec![Block::INode, Block::Name], + _ if !blocks_inputs.is_empty() => blocks_inputs.into_iter().map(Block::from).collect(), + _ if matches.is_present("long") => vec![ Block::Permission, Block::User, Block::Group, Block::Size, Block::Date, Block::Name, - ] - } else { - vec![Block::Name] + ], + _ => vec![Block::Name], }; let mut ignore_globs_builder = GlobSetBuilder::new(); @@ -168,6 +171,7 @@ impl Flags { }, no_symlink: matches.is_present("no-symlink"), total_size: matches.is_present("total-size"), + inode, }) } } @@ -192,6 +196,7 @@ impl Default for Flags { no_symlink: false, total_size: false, ignore_globs: GlobSet::empty(), + inode: false, } } } diff --git a/src/meta/inode.rs b/src/meta/inode.rs index 9bc67d9..6849947 100644 --- a/src/meta/inode.rs +++ b/src/meta/inode.rs @@ -25,8 +25,8 @@ impl<'a> From<&'a Metadata> for INode { impl INode { pub fn render(&self, colors: &Colors) -> ColoredString { match self.index { - Some(i) => colors.colorize(i.to_string(), &Elem::INode{ valid: true }), - None => colors.colorize(String::from("-"), &Elem::INode{ valid: false }), + Some(i) => colors.colorize(i.to_string(), &Elem::INode { valid: true }), + None => colors.colorize(String::from("-"), &Elem::INode { valid: false }), } } } -- cgit v1.2.3 From 74660f1d70267428b993eb2578e19b1a2d475325 Mon Sep 17 00:00:00 2001 From: zwPapEr Date: Sun, 15 Dec 2019 15:35:41 +0800 Subject: test: add inode args integration test --- tests/integration.rs | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/tests/integration.rs b/tests/integration.rs index c934f26..f662040 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -87,31 +87,45 @@ fn test_list_all_populated_directory() { } #[test] -#[cfg(unix)] fn test_list_inode_populated_directory() { let dir = tempdir(); dir.child("one").touch().unwrap(); dir.child("two").touch().unwrap(); + + #[cfg(unix)] + let matched = "\\d+ one\n\\d+ two\n$"; + #[cfg(windows)] + let matched = "- one\n\\- two\n$"; + cmd() - .arg("--blocks") - .arg("inode,name") + .arg("--inode") .arg(dir.path()) .assert() - .stdout(predicate::str::is_match("\\d+ one\n\\d+ two\n$").unwrap()); + .stdout(predicate::str::is_match(matched).unwrap()); + cmd() + .arg("-i") + .arg(dir.path()) + .assert() + .stdout(predicate::str::is_match(matched).unwrap()); } #[test] -#[cfg(windows)] -fn test_list_inode_populated_directory() { +fn test_list_block_inode_populated_directory() { let dir = tempdir(); dir.child("one").touch().unwrap(); dir.child("two").touch().unwrap(); + + #[cfg(unix)] + let matched = "\\d+ one\n\\d+ two\n$"; + #[cfg(windows)] + let matched = "- one\n\\- two\n$"; + cmd() .arg("--blocks") .arg("inode,name") .arg(dir.path()) .assert() - .stdout(predicate::str::is_match("- one\n\\- two\n$").unwrap()); + .stdout(predicate::str::is_match(matched).unwrap()); } fn cmd() -> Command { -- cgit v1.2.3 From 7ca7290e238ae534fb1e04aed165f9a77b8eb1ba Mon Sep 17 00:00:00 2001 From: zwPapEr Date: Sun, 22 Dec 2019 20:20:52 +0800 Subject: args/inode: :hammer: inode work with long --- src/app.rs | 3 +-- src/flags.rs | 8 ++++++-- tests/integration.rs | 6 ++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/app.rs b/src/app.rs index d60568b..4e282d6 100644 --- a/src/app.rs +++ b/src/app.rs @@ -215,8 +215,7 @@ pub fn build() -> App<'static, 'static> { .short("i") .long("inode") .multiple(true) - .conflicts_with("blocks") - .help("Display inode and file names"), + .help("Display inode(Linux only)"), ) } diff --git a/src/flags.rs b/src/flags.rs index 003ee57..8564dbe 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -98,8 +98,7 @@ impl Flags { None => usize::max_value(), }; - let blocks: Vec = match () { - _ if inode => vec![Block::INode, Block::Name], + let mut blocks: Vec = match () { _ if !blocks_inputs.is_empty() => blocks_inputs.into_iter().map(Block::from).collect(), _ if matches.is_present("long") => vec![ Block::Permission, @@ -112,6 +111,11 @@ impl Flags { _ => vec![Block::Name], }; + // Add inode as first column if with inode flag + if inode && !blocks.contains(&Block::INode) { + blocks.insert(0, Block::INode); + } + let mut ignore_globs_builder = GlobSetBuilder::new(); for pattern in ignore_globs_inputs { let glob = match Glob::new(pattern) { diff --git a/tests/integration.rs b/tests/integration.rs index f662040..05dfa95 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -128,6 +128,12 @@ fn test_list_block_inode_populated_directory() { .stdout(predicate::str::is_match(matched).unwrap()); } +#[test] +fn test_list_inode_with_long_ok() { + let dir = tempdir(); + cmd().arg("-i").arg("-l").arg(dir.path()).assert().success(); +} + fn cmd() -> Command { Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap() } -- cgit v1.2.3 From 4e50ea2b55393aad10d3f296325c57d47fb413d0 Mon Sep 17 00:00:00 2001 From: zwPapEr Date: Sat, 11 Jan 2020 10:18:41 +0800 Subject: inode: :art: update the inode help msg --- src/app.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.rs b/src/app.rs index 4e282d6..d67e713 100644 --- a/src/app.rs +++ b/src/app.rs @@ -215,7 +215,7 @@ pub fn build() -> App<'static, 'static> { .short("i") .long("inode") .multiple(true) - .help("Display inode(Linux only)"), + .help("Display the index number of each file"), ) } -- cgit v1.2.3 From d30f3750781d56eeefa93465df7419cbe4788d07 Mon Sep 17 00:00:00 2001 From: zwPapEr Date: Sat, 11 Jan 2020 16:15:46 +0800 Subject: revert the match to if else for blocks --- src/flags.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/flags.rs b/src/flags.rs index 8564dbe..1d3b860 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -98,17 +98,19 @@ impl Flags { None => usize::max_value(), }; - let mut blocks: Vec = match () { - _ if !blocks_inputs.is_empty() => blocks_inputs.into_iter().map(Block::from).collect(), - _ if matches.is_present("long") => vec![ + let mut blocks: Vec = if !blocks_inputs.is_empty() { + blocks_inputs.into_iter().map(Block::from).collect() + } else if matches.is_present("long") { + vec![ Block::Permission, Block::User, Block::Group, Block::Size, Block::Date, Block::Name, - ], - _ => vec![Block::Name], + ] + } else { + vec![Block::Name] }; // Add inode as first column if with inode flag -- cgit v1.2.3 From ad25edcd7e5d1490394082af99ae94c0e42635b1 Mon Sep 17 00:00:00 2001 From: jpda Date: Tue, 21 Jan 2020 08:52:09 -0500 Subject: added csharp, sln and razor icons --- src/icon.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/icon.rs b/src/icon.rs index dc6bdd6..43e71da 100644 --- a/src/icon.rs +++ b/src/icon.rs @@ -181,6 +181,10 @@ impl Icons { m.insert("conf", "\u{e615}"); // "" m.insert("cp", "\u{e61d}"); // "" m.insert("cpp", "\u{e61d}"); // "" + m.insert("cs", "\u{f81a}"); // "" + m.insert("cshtml", "\u{f1fa}"); // "" + m.insert("csproj", "\u{f81a}"); // "" + m.insert("csx", "\u{f81a}"); // "" m.insert("csh", "\u{f489}"); // "" m.insert("css", "\u{e749}"); // "" m.insert("csv", "\u{f1c3}"); // "" @@ -278,6 +282,7 @@ impl Icons { m.insert("r", "\u{f25d}"); // "" m.insert("rakefile", "\u{e21e}"); // "" m.insert("rar", "\u{f410}"); // "" + m.insert("razor", "\u{f1fa}"); // "" m.insert("rb", "\u{e21e}"); // "" m.insert("rdata", "\u{f25d}"); // "" m.insert("rdb", "\u{e76d}"); // "" @@ -299,6 +304,7 @@ impl Icons { m.insert("sh", "\u{f489}"); // "" m.insert("shell", "\u{f489}"); // "" m.insert("slim", "\u{e73b}"); // "" + m.insert("sln", "\u{e70c}"); // "" m.insert("sql", "\u{f1c0}"); // "" m.insert("sqlite3", "\u{e7c4}"); // "" m.insert("styl", "\u{e600}"); // "" -- cgit v1.2.3 From 645be4a668fad2d08e1017cdd0e995b3f808dd37 Mon Sep 17 00:00:00 2001 From: zwPapEr Date: Sun, 5 Apr 2020 18:27:01 +0800 Subject: delete fs canonicalize for show broken softlink without error fix https://github.com/Peltoche/lsd/issues/72 --- src/core.rs | 6 ------ src/main.rs | 4 ++++ tests/integration.rs | 23 +++++++++++++++++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/core.rs b/src/core.rs index 6a120b3..57f653d 100644 --- a/src/core.rs +++ b/src/core.rs @@ -4,7 +4,6 @@ use crate::flags::{Display, Flags, IconTheme, Layout, WhenFlag}; use crate::icon::{self, Icons}; use crate::meta::Meta; use crate::{print_error, print_output, sort}; -use std::fs; use std::path::PathBuf; #[cfg(not(target_os = "windows"))] @@ -83,11 +82,6 @@ impl Core { }; for path in paths { - if let Err(err) = fs::canonicalize(&path) { - print_error!("cannot access '{}': {}", path.display(), err); - continue; - } - let mut meta = match Meta::from_path(&path) { Ok(meta) => meta, Err(err) => { diff --git a/src/main.rs b/src/main.rs index 5251884..e1537ce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -84,6 +84,10 @@ macro_rules! print_output { fn main() { let matches = app::build().get_matches_from(wild::args_os()); + // input translate glob FILE without single quote into real names + // for example: + // * to all files matched + // '*' remain as '*' let inputs = matches .values_of("FILE") .expect("failed to retrieve cli value") diff --git a/tests/integration.rs b/tests/integration.rs index 05dfa95..8d38fc7 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -6,6 +6,9 @@ use assert_fs::prelude::*; use predicates::prelude::*; use std::process::Command; +#[cfg(unix)] +use std::os::unix::fs; + #[test] fn test_runs_okay() { cmd().assert().success(); @@ -134,6 +137,26 @@ fn test_list_inode_with_long_ok() { cmd().arg("-i").arg("-l").arg(dir.path()).assert().success(); } +#[cfg(unix)] +#[test] +fn test_list_broken_link_ok() { + let dir = tempdir(); + let broken_link = dir.path().join("broken-softlink"); + let matched = "No such file or directory"; + fs::symlink("not-existed-file", &broken_link).unwrap(); + + cmd() + .arg(&broken_link) + .assert() + .stderr(predicate::str::contains(matched).not()); + + cmd() + .arg("-l") + .arg(broken_link) + .assert() + .stderr(predicate::str::contains(matched).not()); +} + fn cmd() -> Command { Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap() } -- cgit v1.2.3 From a017a3d0549aa4673555b51603b7fa5c1e5d49a9 Mon Sep 17 00:00:00 2001 From: zwPapEr Date: Sun, 5 Apr 2020 21:51:23 +0800 Subject: fix err description deprecated --- build.rs | 2 +- src/app.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/build.rs b/build.rs index b7933a3..f5f04fd 100644 --- a/build.rs +++ b/build.rs @@ -27,7 +27,7 @@ fn main() { } } - let var = std::env::var_os("SHELL_COMPLETIONS_DIR").or(std::env::var_os("OUT_DIR")); + let var = std::env::var_os("SHELL_COMPLETIONS_DIR").or_else(|| std::env::var_os("OUT_DIR")); let outdir = match var { None => return, Some(outdir) => outdir, diff --git a/src/app.rs b/src/app.rs index d67e713..af906c8 100644 --- a/src/app.rs +++ b/src/app.rs @@ -220,9 +220,8 @@ pub fn build() -> App<'static, 'static> { } fn validate_date_argument(arg: String) -> Result<(), String> { - use std::error::Error; if arg.starts_with('+') { - validate_time_format(&arg).map_err(|err| err.description().to_string()) + validate_time_format(&arg).map_err(|err| err.to_string()) } else if &arg == "date" || &arg == "relative" { Result::Ok(()) } else { -- cgit v1.2.3 From 04129e8624ebfc516a921dc2b443d3ba0c302973 Mon Sep 17 00:00:00 2001 From: zwPapEr Date: Tue, 7 Apr 2020 13:49:57 +0800 Subject: *: :art: add newline to each print error --- src/core.rs | 4 ++-- src/meta/mod.rs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core.rs b/src/core.rs index 57f653d..16aaf8f 100644 --- a/src/core.rs +++ b/src/core.rs @@ -85,7 +85,7 @@ impl Core { let mut meta = match Meta::from_path(&path) { Ok(meta) => meta, Err(err) => { - print_error!("cannot access '{}': {}", path.display(), err); + print_error!("lsd: {}: {}\n", path.display(), err); continue; } }; @@ -101,7 +101,7 @@ impl Core { meta_list.push(meta); } Err(err) => { - print_error!("cannot access '{}': {}", path.display(), err); + print_error!("lsd: {}: {}\n", path.display(), err); continue; } }; diff --git a/src/meta/mod.rs b/src/meta/mod.rs index 2ecc472..b29a57a 100644 --- a/src/meta/mod.rs +++ b/src/meta/mod.rs @@ -69,7 +69,7 @@ impl Meta { let entries = match self.path.read_dir() { Ok(entries) => entries, Err(err) => { - print_error!("cannot access '{}': {}", self.path.display(), err); + print_error!("lsd: {}: {}\n", self.path.display(), err); return Ok(None); } }; @@ -116,7 +116,7 @@ impl Meta { let mut entry_meta = match Self::from_path(&path) { Ok(res) => res, Err(err) => { - print_error!("cannot access '{}': {}", path.display(), err); + print_error!("lsd: {}: {}\n", path.display(), err); continue; } }; @@ -124,7 +124,7 @@ impl Meta { match entry_meta.recurse_into(depth - 1, display, ignore_globs) { Ok(content) => entry_meta.content = content, Err(err) => { - print_error!("cannot access '{}': {}", path.display(), err); + print_error!("lsd: {}: {}\n", path.display(), err); continue; } }; @@ -162,7 +162,7 @@ impl Meta { let metadata = match metadata { Ok(meta) => meta, Err(err) => { - print_error!("cannot access '{}': {}", path.display(), err); + print_error!("lsd: {}: {}\n", path.display(), err); return 0; } }; @@ -175,7 +175,7 @@ impl Meta { let entries = match path.read_dir() { Ok(entries) => entries, Err(err) => { - print_error!("cannot access '{}': {}", path.display(), err); + print_error!("lsd: {}: {}\n", path.display(), err); return size; } }; @@ -183,7 +183,7 @@ impl Meta { let path = match entry { Ok(entry) => entry.path(), Err(err) => { - print_error!("cannot access '{}': {}", path.display(), err); + print_error!("lsd: {}: {}\n", path.display(), err); continue; } }; -- cgit v1.2.3 From 13ca1000c7a1d6fdb54e63988a57116abbfe5068 Mon Sep 17 00:00:00 2001 From: Pierre Peltier Date: Thu, 9 Apr 2020 11:05:15 +0200 Subject: Release 0.17.0 --- CHANGELOG.md | 27 ++++++++++++++++++++++++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfa7caa..a823eb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,29 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.17.0] - 2020-04-09 +### Added +- Add some icons for the special Unix file types from [xSetech](https://github.com/xSetech) +- Add some integration tests from [allenap](https://github.com/allenap) +- Add the flag `--ignore-glob` from [sumitsahrawat](https://github.com/sumitsahrawat) +- Add the elixir icon from [JiNova](https://github.com/JiNova) +- Add the NixOS/nix installation instructions from [06kellyjac](https://github.com/06kellyjac) +- Add the Elm icon from [optikfluffel](https://github.com/optikfluffel) +- Add the date formatting feature from [dvvvvvv](https://github.com/dvvvvvv) +- Add the `inode` block from [zwpaper](https://github.com/zwpaper) +- Add the `--inode` flag from [zwpaper](https://github.com/zwpaper) +- Add the csharp, sln and razor icons from [jpda](https://github.com/jpda) + +### Changed +- Move all the CI/CD from travis to github actions from [rivy](https://github.com/rivy) +- Allow the usage of several `--depth` arguments from [abazylewicz](https://github.com/abazylewicz) + +### Fixed +- Fix the GID permissions display from [xduugu](https://github.com/xduugu) +- Fix the panic if the pipe is closed before the output is written from [Peltoche](https://github.com/Peltoche) +- Fix the broken softlink display from [zwpaper](https://github.com/zwpaper) + ## [0.16.0] - 2019-08-02 ### Added - Add the flag `--blocks` from [meain](https://github.com/meain) @@ -225,7 +248,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Change the component alignement by using term_grid -[Unreleased]: https://github.com/Peltoche/lsd/compare/0.15.1...HEAD +[Unreleased]: https://github.com/Peltoche/lsd/compare/0.17.0...HEAD +[0.17.0]: https://github.com/Peltoche/lsd/compare/0.16.0...0.17.0 +[0.16.0]: https://github.com/Peltoche/lsd/compare/0.15.1...0.16.0 [0.15.1]: https://github.com/Peltoche/lsd/compare/0.15.0...0.15.1 [0.15.0]: https://github.com/Peltoche/lsd/compare/0.14.1...0.15.0 [0.14.0]: https://github.com/Peltoche/lsd/compare/0.13.1...0.14.0 diff --git a/Cargo.lock b/Cargo.lock index 62990be..fff95b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -262,7 +262,7 @@ dependencies = [ [[package]] name = "lsd" -version = "0.16.0" +version = "0.17.0" dependencies = [ "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "assert_cmd 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 071ad1d..2412c8f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ license = "Apache-2.0" name = "lsd" readme = "./README.md" repository = "https://github.com/Peltoche/lsd" -version = "0.16.0" +version = "0.17.0" edition = "2018" [[bin]] -- cgit v1.2.3 From 10d1bd941c1281ccdf9832c7ac840232ec7f05fa Mon Sep 17 00:00:00 2001 From: Pierre Peltier Date: Thu, 9 Apr 2020 11:07:24 +0200 Subject: (cargo-release) start next development iteration 0.17.1-pre --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 2412c8f..78f689a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ license = "Apache-2.0" name = "lsd" readme = "./README.md" repository = "https://github.com/Peltoche/lsd" -version = "0.17.0" +version = "0.17.1-pre" edition = "2018" [[bin]] -- cgit v1.2.3 From d366c169874e266b82a517249ae2479f3c7a0387 Mon Sep 17 00:00:00 2001 From: Pierre Peltier Date: Thu, 9 Apr 2020 11:13:27 +0200 Subject: Run cargo update --- Cargo.lock | 315 +++++++++++++++++++++++++++++++------------------------------ 1 file changed, 162 insertions(+), 153 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fff95b7..f1f64ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,10 +2,10 @@ # It is not intended for manual editing. [[package]] name = "aho-corasick" -version = "0.7.6" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -30,7 +30,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "escargot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "predicates 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "predicates 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "predicates-tree 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -41,7 +41,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "globwalk 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "predicates 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "predicates 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "predicates-tree 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -49,16 +49,17 @@ dependencies = [ [[package]] name = "atty" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "autocfg" -version = "0.1.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -68,18 +69,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bstr" -version = "0.2.8" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "c2-chacha" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -89,12 +82,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "chrono" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -103,7 +95,7 @@ name = "chrono-humanize" version = "0.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -112,28 +104,30 @@ version = "2.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-channel" -version = "0.3.9" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-utils" -version = "0.6.6" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -150,16 +144,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "float-cmp" -version = "0.4.0" +version = "0.6