Skip to content

Commit

Permalink
ls: Add options --summary and --long
Browse files Browse the repository at this point in the history
  • Loading branch information
aawsome committed Jul 17, 2023
1 parent 1232a06 commit 314567b
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 4 deletions.
3 changes: 2 additions & 1 deletion changelog/new.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ New features:
- fix: wait for password-command to successfully exit, allowing to input something into the command, and read password from stdout.
- repoinfo: Added new options --json, --only-files, --only-index
- Creation of new keys now enforces confirmation of entered key. This helps to prevent mistype of passwords during the initial entry
- Check: Add check if time is set for packs-to-delete
- Check: Add check if time is set for packs-to-delete
- ls: Options --long (-l) and --summary (-s) have been added.
106 changes: 103 additions & 3 deletions src/commands/ls.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
//! `ls` subcommand

use std::path::Path;

/// App-local prelude includes `app_reader()`/`app_writer()`/`app_config()`
/// accessors along with logging macros. Customize as you see fit.
use crate::{commands::open_repository, status_err, Application, RUSTIC_APP};

use abscissa_core::{Command, Runnable, Shutdown};
use anyhow::Result;

use rustic_core::TreeStreamerOptions;
use libc::{S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR};

Check failure on line 12 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Test (stable, windows-latest)

unresolved import `libc`
use rustic_core::{Node, NodeType, TreeStreamerOptions};

/// `ls` subcommand
#[derive(clap::Parser, Command, Debug)]
Expand All @@ -20,6 +23,14 @@ pub(crate) struct LsCmd {
#[clap(long)]
recursive: bool,

/// show summary
#[clap(long, short = 's')]
summary: bool,

/// show long listing
#[clap(long, short = 'l')]
long: bool,

#[clap(flatten)]
streamer_opts: TreeStreamerOptions,
}
Expand All @@ -33,6 +44,25 @@ impl Runnable for LsCmd {
}
}

#[derive(Default)]
struct Summary {
files: usize,
size: u64,
dirs: usize,
}

impl Summary {
fn update(&mut self, node: &Node) {
if node.is_dir() {
self.dirs += 1;
}
if node.is_file() {
self.files += 1;
self.size += node.meta.size;
}
}
}

impl LsCmd {
fn inner_run(&self) -> Result<()> {
let config = RUSTIC_APP.config();
Expand All @@ -42,13 +72,83 @@ impl LsCmd {
let node =
repo.node_from_snapshot_path(&self.snap, |sn| config.snapshot_filter.matches(sn))?;

// recursive if standard if we specify a snapshot without dirs. In other cases, use the parameter `recursive`
let recursive = !self.snap.contains(':') || self.recursive;

let mut summary = Summary::default();

for item in repo.ls(&node, &self.streamer_opts, recursive)? {
let (path, _) = item?;
println!("{path:?} ");
let (path, node) = item?;
summary.update(&node);
if self.long {
print_node(&node, &path);
} else {
println!("{path:?} ");
}
}

if self.summary {
println!(
"total: {} dirs, {} files, {} bytes",
summary.dirs, summary.files, summary.size
)

Check failure on line 94 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

consider adding a `;` to the last statement for consistent formatting

error: consider adding a `;` to the last statement for consistent formatting --> src/commands/ls.rs:91:13 | 91 | / println!( 92 | | "total: {} dirs, {} files, {} bytes", 93 | | summary.dirs, summary.files, summary.size 94 | | ) | |_____________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned = note: `-D clippy::semicolon-if-nothing-returned` implied by `-D warnings` help: add a `;` here | 91 ~ println!( 92 + "total: {} dirs, {} files, {} bytes", 93 + summary.dirs, summary.files, summary.size 94 + ); |

Check failure on line 94 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

consider adding a `;` to the last statement for consistent formatting

error: consider adding a `;` to the last statement for consistent formatting --> src/commands/ls.rs:91:13 | 91 | / println!( 92 | | "total: {} dirs, {} files, {} bytes", 93 | | summary.dirs, summary.files, summary.size 94 | | ) | |_____________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned = note: `-D clippy::semicolon-if-nothing-returned` implied by `-D warnings` help: add a `;` here | 91 ~ println!( 92 + "total: {} dirs, {} files, {} bytes", 93 + summary.dirs, summary.files, summary.size 94 + ); |
}

Ok(())
}
}

// print node in format similar to unix `ls`
fn print_node(node: &Node, path: &Path) {
println!(
"{:>1}{:>9} {:>8} {:>8} {:>9} {:>12} {path:?} {}",
match node.node_type {
NodeType::Dir => 'd',
NodeType::Symlink { .. } => 'l',
NodeType::Chardev { .. } => 'c',
NodeType::Dev { .. } => 'b',
NodeType::Fifo { .. } => 'p',
NodeType::Socket => 's',
_ => '-',
},
node.meta
.mode
.map(|m| parse_permissions(m))

Check failure on line 116 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

redundant closure

error: redundant closure --> src/commands/ls.rs:116:18 | 116 | .map(|m| parse_permissions(m)) | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `parse_permissions` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure = note: `-D clippy::redundant-closure` implied by `-D warnings`

Check failure on line 116 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

redundant closure

error: redundant closure --> src/commands/ls.rs:116:18 | 116 | .map(|m| parse_permissions(m)) | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `parse_permissions` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure = note: `-D clippy::redundant-closure` implied by `-D warnings`
.unwrap_or("?????????".to_string()),

Check failure on line 117 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

use of `unwrap_or` followed by a function call

error: use of `unwrap_or` followed by a function call --> src/commands/ls.rs:117:14 | 117 | .unwrap_or("?????????".to_string()), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "?????????".to_string())` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call = note: `-D clippy::or-fun-call` implied by `-D warnings`

Check failure on line 117 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

use of `unwrap_or` followed by a function call

error: use of `unwrap_or` followed by a function call --> src/commands/ls.rs:117:14 | 117 | .unwrap_or("?????????".to_string()), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "?????????".to_string())` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call = note: `-D clippy::or-fun-call` implied by `-D warnings`
node.meta.user.clone().unwrap_or("?".to_string()),

Check failure on line 118 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

use of `unwrap_or` followed by a function call

error: use of `unwrap_or` followed by a function call --> src/commands/ls.rs:118:32 | 118 | node.meta.user.clone().unwrap_or("?".to_string()), | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "?".to_string())` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call

Check failure on line 118 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

use of `unwrap_or` followed by a function call

error: use of `unwrap_or` followed by a function call --> src/commands/ls.rs:118:32 | 118 | node.meta.user.clone().unwrap_or("?".to_string()), | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "?".to_string())` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call
node.meta.group.clone().unwrap_or("?".to_string()),

Check failure on line 119 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

use of `unwrap_or` followed by a function call

error: use of `unwrap_or` followed by a function call --> src/commands/ls.rs:119:33 | 119 | node.meta.group.clone().unwrap_or("?".to_string()), | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "?".to_string())` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call

Check failure on line 119 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

use of `unwrap_or` followed by a function call

error: use of `unwrap_or` followed by a function call --> src/commands/ls.rs:119:33 | 119 | node.meta.group.clone().unwrap_or("?".to_string()), | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "?".to_string())` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call
node.meta.size,
node.meta
.mtime
.map(|t| t.format("%_d %b %H:%M").to_string())
.unwrap_or("?".to_string()),

Check failure on line 124 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

use of `unwrap_or` followed by a function call

error: use of `unwrap_or` followed by a function call --> src/commands/ls.rs:124:14 | 124 | .unwrap_or("?".to_string()), | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "?".to_string())` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call

Check failure on line 124 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

use of `unwrap_or` followed by a function call

error: use of `unwrap_or` followed by a function call --> src/commands/ls.rs:124:14 | 124 | .unwrap_or("?".to_string()), | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "?".to_string())` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call
if let NodeType::Symlink { linktarget } = &node.node_type {
["->", linktarget].join(" ")
} else {
"".to_string()

Check failure on line 128 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

empty String is being created manually

error: empty String is being created manually --> src/commands/ls.rs:128:13 | 128 | "".to_string() | ^^^^^^^^^^^^^^ help: consider using: `String::new()` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_string_new = note: `-D clippy::manual-string-new` implied by `-D warnings`

Check failure on line 128 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

empty String is being created manually

error: empty String is being created manually --> src/commands/ls.rs:128:13 | 128 | "".to_string() | ^^^^^^^^^^^^^^ help: consider using: `String::new()` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_string_new = note: `-D clippy::manual-string-new` implied by `-D warnings`
}
);
}

// helper fn to put permissions in readable format
fn parse_permissions(mode: u32) -> String {
let user = triplet(mode, S_IRUSR, S_IWUSR, S_IXUSR);

Check failure on line 135 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Publishing x86_64-apple-darwin

arguments to this function are incorrect

Check failure on line 135 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Publishing aarch64-apple-darwin

arguments to this function are incorrect
let group = triplet(mode, S_IRGRP, S_IWGRP, S_IXGRP);

Check failure on line 136 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Publishing x86_64-apple-darwin

arguments to this function are incorrect

Check failure on line 136 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Publishing aarch64-apple-darwin

arguments to this function are incorrect
let other = triplet(mode, S_IROTH, S_IWOTH, S_IXOTH);

Check failure on line 137 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Publishing x86_64-apple-darwin

arguments to this function are incorrect

Check failure on line 137 in src/commands/ls.rs

View workflow job for this annotation

GitHub Actions / Publishing aarch64-apple-darwin

arguments to this function are incorrect
[user, group, other].join("")
}

// helper fn to put permissions in readable format
fn triplet(mode: u32, read: u32, write: u32, execute: u32) -> String {
match (mode & read, mode & write, mode & execute) {
(0, 0, 0) => "---",
(_, 0, 0) => "r--",
(0, _, 0) => "-w-",
(0, 0, _) => "--x",
(_, 0, _) => "r-x",
(_, _, 0) => "rw-",
(0, _, _) => "-wx",
(_, _, _) => "rwx",
}
.to_string()
}

0 comments on commit 314567b

Please sign in to comment.