refactor: one helper each for the repeated blocks
This commit is contained in:
@@ -13,47 +13,59 @@ use self::store::{Leads, Repo, ignored, leads, resolve, symlink_metadata_opt, tr
|
||||
use crate::cli::link as cli;
|
||||
use crate::ctx::Ctx;
|
||||
use crate::fsops::suffixed;
|
||||
use crate::output::{line, note, warning};
|
||||
use crate::output::{line, note, plural, warning};
|
||||
|
||||
const BACKUP_SUFFIX: &str = ".ahab-bak";
|
||||
// where the link waits while the payload comes back out of the store
|
||||
const RESTORING_SUFFIX: &str = ".ahab-restoring";
|
||||
|
||||
// move untracked paths out of the repo and symlink them back
|
||||
pub fn add(ctx: &Ctx, args: &cli::Add) -> Result<()> {
|
||||
let (paths, force) = (args.paths.as_slice(), args.force);
|
||||
let repo = Repo::discover(ctx, args.store.root())?;
|
||||
let report = Report::new(&repo);
|
||||
|
||||
if let [path] = paths {
|
||||
return link_one(ctx, &repo, path, force, &report);
|
||||
// one path's failure is its own; several are counted, so a run over a list says
|
||||
// what happened to each and then how the run as a whole went. a single path has
|
||||
// nothing to count, so its error is simply the command's
|
||||
fn each(paths: &[PathBuf], mut act: impl FnMut(&Path) -> Result<()>) -> Result<()> {
|
||||
if let [only] = paths {
|
||||
return act(only);
|
||||
}
|
||||
|
||||
let mut failed = 0;
|
||||
for path in paths {
|
||||
if let Err(e) = link_one(ctx, &repo, path, force, &report) {
|
||||
if let Err(e) = act(path) {
|
||||
warning!("{e:#}");
|
||||
failed += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if failed > 0 {
|
||||
return Err(anyhow!("{failed} of {} paths failed", paths.len()));
|
||||
match failed {
|
||||
0 => Ok(()),
|
||||
failed => Err(anyhow!("{failed} of {} paths failed", paths.len())),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// move untracked paths out of the repo and symlink them back
|
||||
pub fn add(ctx: &Ctx, args: &cli::Add) -> Result<()> {
|
||||
let repo = Repo::discover(ctx, args.store.root())?;
|
||||
let report = Report::new(&repo);
|
||||
|
||||
each(&args.paths, |path| {
|
||||
link_one(ctx, &repo, path, args.force, &report)
|
||||
})
|
||||
}
|
||||
|
||||
// move paths in the store back into the repo, the inverse of add
|
||||
pub fn restore(ctx: &Ctx, args: &cli::Restore) -> Result<()> {
|
||||
let (paths, all) = (args.paths.as_slice(), args.all);
|
||||
let repo = Repo::discover(ctx, args.store.root())?;
|
||||
let report = Report::new(&repo);
|
||||
|
||||
// clap requires one or the other and refuses both, so only the two real
|
||||
// cases are left here
|
||||
let stored = match all {
|
||||
let stored = match args.all {
|
||||
true => stored_paths(&repo, &repo.store)?,
|
||||
false => paths.iter().cloned().map(|p| (p, Stored::Linked)).collect(),
|
||||
false => args
|
||||
.paths
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|path| (path, Stored::Linked))
|
||||
.collect(),
|
||||
};
|
||||
|
||||
// only a linked path can be moved back; the store can hold orphans too
|
||||
@@ -70,7 +82,7 @@ pub fn restore(ctx: &Ctx, args: &cli::Restore) -> Result<()> {
|
||||
n => note!(
|
||||
ctx,
|
||||
"nothing to restore: {n} path{} in the store {} not linked, see `ahab link list`",
|
||||
if n == 1 { "" } else { "s" },
|
||||
plural(n),
|
||||
if n == 1 { "is" } else { "are" }
|
||||
),
|
||||
}
|
||||
@@ -82,26 +94,11 @@ pub fn restore(ctx: &Ctx, args: &cli::Restore) -> Result<()> {
|
||||
note!(
|
||||
ctx,
|
||||
"leaving {skipped} path{} that the store holds but nothing links to",
|
||||
if skipped == 1 { "" } else { "s" }
|
||||
plural(skipped)
|
||||
);
|
||||
}
|
||||
|
||||
if let [path] = linked.as_slice() {
|
||||
return restore_one(ctx, &repo, path, &report);
|
||||
}
|
||||
|
||||
let mut failed = 0;
|
||||
for path in &linked {
|
||||
if let Err(e) = restore_one(ctx, &repo, path, &report) {
|
||||
warning!("{e:#}");
|
||||
failed += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if failed > 0 {
|
||||
return Err(anyhow!("{failed} of {} paths failed", linked.len()));
|
||||
}
|
||||
Ok(())
|
||||
each(&linked, |path| restore_one(ctx, &repo, path, &report))
|
||||
}
|
||||
|
||||
fn restore_one(ctx: &Ctx, repo: &Repo, path: &Path, report: &Report) -> Result<()> {
|
||||
@@ -247,12 +244,18 @@ pub fn list(ctx: &Ctx, args: &cli::List) -> Result<()> {
|
||||
Stored::Taken => "shadowed",
|
||||
};
|
||||
|
||||
line!("\t{:<11}{}", format!("{verb}:"), rel.display());
|
||||
entry(verb, rel);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// one line of what the store did with a path, in the column width `status`
|
||||
// prints too: the two used to set it separately and had to be kept in step
|
||||
fn entry(verb: &str, path: &Path) {
|
||||
line!("\t{:<11}{}", format!("{verb}:"), path.display());
|
||||
}
|
||||
|
||||
struct Report {
|
||||
store: PathBuf,
|
||||
named: Cell<bool>,
|
||||
@@ -272,7 +275,7 @@ impl Report {
|
||||
line!("store: {}", self.store.display());
|
||||
}
|
||||
|
||||
line!("\t{:<11}{}", format!("{verb}:"), path.display());
|
||||
entry(verb, path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user