use anyhow::{bail, Result};
use clap::Parser;
use console::Style;
use std::io::IsTerminal;
use std::path::PathBuf;
use crate::cfg::Config;
use crate::cli::{color, draw_boxed};
use crate::cmd::Command;
use crate::ssh::SshSession;
#[derive(Parser, Debug)]
pub struct Check {
#[clap()]
files: Vec<PathBuf>,
#[clap(long, short)]
details: bool,
#[clap(long, short)]
filenames: bool,
#[clap(long, short = 'D')]
no_details: bool,
#[clap(short, long = "url-only")]
url_only: bool,
#[clap(long, short = 't')]
with_time: bool,
#[clap(long, short = 's')]
with_size: bool,
}
impl Command for Check {
fn run(&self, session: &SshSession, config: &Config) -> Result<()> {
let show_details = (self.details || config.details) && !self.no_details;
let found = session
.list_files()?
.by_hash(
self.files.iter().map(|pb| pb.to_string_lossy()),
session.host.prefix_length,
false,
)?
.with_stats(show_details || self.with_time || self.with_size)?;
if self.url_only {
for (_, file, _) in found.iter() {
println!("{}", session.host.get_url(&format!("{}", file.display()))?);
}
} else if !config.is_silent() {
let content = found.format_files(
Some(&session.host),
self.filenames,
show_details || self.with_size,
show_details || self.with_time,
)?;
if std::io::stdout().is_terminal() {
draw_boxed(
format!(
"{} remote files:",
Style::new().bold().green().bright().apply_to("Found")
),
content.iter().map(|s| s.as_ref()),
&color::frame,
)?;
} else {
for line in content {
println!("{}", line);
}
}
}
if found.iter().count() == self.files.len() {
Ok(())
} else {
bail!(
"# of file expected/found differs: {}/{}",
self.files.len(),
found.iter().count()
);
}
}
}