use crate::helpers::check_repo_migration_needed;
use async_trait::async_trait;
use clap::{Arg, ArgMatches, Command};
use liboxen::error::OxenError;
use liboxen::model::LocalRepository;
use liboxen::opts::RestoreOpts;
use liboxen::{repositories, util};
use std::collections::HashSet;
use std::path::PathBuf;
use crate::cmd::RunCmd;
pub const NAME: &str = "restore";
pub struct RestoreCmd;
pub fn restore_args() -> Command {
Command::new(NAME)
.about("Restore specified paths in the working tree with some contents from a restore source.")
.arg(
Arg::new("paths")
.required(true)
.action(clap::ArgAction::Append),
)
.arg_required_else_help(true)
.arg(
Arg::new("source")
.long("source")
.help("Restores a specific revision of the file. Can supply commit id or branch name")
.action(clap::ArgAction::Set)
.requires("paths"),
)
.arg(
Arg::new("staged")
.long("staged")
.help("Restore content in staging area. By default, if --staged is given, the contents are restored from HEAD. Use --source to restore from a different commit.")
.action(clap::ArgAction::SetTrue)
.requires("paths"),
)
}
#[async_trait]
impl RunCmd for RestoreCmd {
fn name(&self) -> &str {
NAME
}
fn args(&self) -> Command {
restore_args()
}
async fn run(&self, args: &ArgMatches) -> Result<(), OxenError> {
let repository = LocalRepository::from_current_dir()?;
check_repo_migration_needed(&repository)?;
let paths: Vec<PathBuf> = args
.get_many::<String>("paths")
.expect("Must supply paths")
.map(|p| -> Result<PathBuf, OxenError> {
let current_dir = std::env::current_dir()?;
let joined_path = current_dir.join(p);
util::fs::canonicalize(&joined_path).or_else(|_| Ok(joined_path))
})
.collect::<Result<Vec<PathBuf>, OxenError>>()?;
let paths: HashSet<PathBuf> = HashSet::from_iter(paths.iter().cloned());
let opts = if let Some(source) = args.get_one::<String>("source") {
RestoreOpts {
paths,
staged: args.get_flag("staged"),
is_remote: false,
source_ref: Some(String::from(source)),
}
} else {
RestoreOpts {
paths,
staged: args.get_flag("staged"),
is_remote: false,
source_ref: None,
}
};
repositories::restore::restore(&repository, opts).await?;
Ok(())
}
}