use clap::{Arg, ArgMatches, SubCommand};
use commands::{default_explain, BasicOptions, StaticSubcommand};
use error::Error;
use meta::{Meta, Repository};
pub fn invocation() -> StaticSubcommand {
return SubCommand::with_name("remote")
.about("View and modify saved remote repositories.")
.subcommand(default_subcommand())
.subcommand(delete_subcommand())
.subcommand(list_subcommand())
.subcommand(set_subcommand());
}
pub fn list_subcommand() -> StaticSubcommand {
SubCommand::with_name("list").about("List all saved repositories.")
}
pub fn set_subcommand() -> StaticSubcommand {
SubCommand::with_name("set")
.about("Add or update a remote.")
.arg(
Arg::with_name("name")
.help("Short name to identify this repository.")
.required(true),
)
.arg(
Arg::with_name("remote")
.help("URL to the remote repository.")
.required(true),
)
.arg(
Arg::with_name("port")
.short("p")
.long("port")
.help("Port of the remote ssh server.")
.takes_value(true)
.validator(|val| {
let x: Result<u16, _> = val.parse();
match x {
Ok(_) => Ok(()),
Err(_) => Err(val),
}
}),
)
}
pub fn default_subcommand() -> StaticSubcommand {
SubCommand::with_name("default")
.about("Set default remote for push and pull.")
.arg(
Arg::with_name("name")
.help("Name of the default repository.")
.required(true),
)
.arg(
Arg::with_name("push")
.help("Only set the push repository (and other types set by flags)")
.long("push"),
)
.arg(
Arg::with_name("pull")
.help("Only set the pull repository (and other types set by flags)")
.long("pull"),
)
}
pub fn delete_subcommand() -> StaticSubcommand {
SubCommand::with_name("delete")
.about("Delete a remote.")
.arg(
Arg::with_name("name")
.help("Name of the repository to delete.")
.required(true),
)
}
pub fn run(arg_matches: &ArgMatches) -> Result<(), Error> {
let opts = BasicOptions::from_args(arg_matches)?;
match arg_matches.subcommand() {
("list", _) => run_list(&opts),
("set", Some(sub_args)) => run_set(&opts, sub_args),
("delete", Some(sub_args)) => run_delete(&opts, sub_args),
("default", Some(sub_args)) => run_default(&opts, sub_args),
_ => Ok(()),
}
}
pub fn run_default(opts: &BasicOptions, args: &ArgMatches) -> Result<(), Error> {
let name = args.value_of("name").unwrap(); let arg_pull = args.is_present("pull");
let arg_push = args.is_present("push");
let mut meta = Meta::load(&opts.repo_root).unwrap_or(Meta::new());
if !meta.remote.contains_key(name) {
println!("{} is not a named remote repository.", name);
println!("You can add a remote with pijul remote set, or list current remotes with pijul remote list");
return Err(Error::MissingRemoteRepository);
}
let (set_push, set_pull) = match (arg_pull, arg_push) {
(false, false) => (true, true),
_ => (arg_pull, arg_push),
};
if set_push {
meta.push = Some(name.to_string());
}
if set_pull {
meta.pull = Some(name.to_string());
}
meta.save(&opts.repo_root)?;
Ok(())
}
pub fn run_list(opts: &BasicOptions) -> Result<(), Error> {
let meta = Meta::load(&opts.repo_root).unwrap_or(Meta::new());
for (name, remote) in meta.remote.iter() {
println!("{} => {}", name, remote);
}
Ok(())
}
pub fn run_set(opts: &BasicOptions, args: &ArgMatches) -> Result<(), Error> {
let name = args.value_of("name").unwrap(); let remote = args.value_of("remote").unwrap(); let mut meta = Meta::load(&opts.repo_root).unwrap_or(Meta::new());
let repo: Repository = Repository {
address: remote.to_string(),
port: args.value_of("port").map(|x| x.parse().unwrap()),
};
meta.remote.insert(name.to_string(), repo);
meta.save(&opts.repo_root)?;
Ok(())
}
pub fn run_delete(opts: &BasicOptions, args: &ArgMatches) -> Result<(), Error> {
let name = args.value_of("name").unwrap(); let mut meta = Meta::load(&opts.repo_root).unwrap_or(Meta::new());
meta.remote.remove(name);
if meta
.push
.as_ref()
.map(|push| push == &name)
.unwrap_or(false)
{
meta.push = None;
}
if meta
.pull
.as_ref()
.map(|pull| pull == &name)
.unwrap_or(false)
{
meta.pull = None;
}
meta.save(&opts.repo_root)?;
Ok(())
}
pub fn explain(res: Result<(), Error>) {
default_explain(res)
}