Remove the init command.
parent
63085593c4
commit
7debe754d1
|
@ -1,4 +1,7 @@
|
|||
---
|
||||
user:
|
||||
name: jrpotter
|
||||
email: jrpotter@github.io
|
||||
local: $HOME/.homesync
|
||||
remote:
|
||||
name: origin
|
||||
|
|
106
src/config.rs
106
src/config.rs
|
@ -2,13 +2,7 @@ use super::{path, path::ResPathBuf};
|
|||
use paris::formatter::colorize_string;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use simplelog::{info, paris};
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
env::VarError,
|
||||
error, fmt, fs, io,
|
||||
io::Write,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use std::{collections::BTreeMap, env::VarError, error, fmt, fs, io, io::Write, path::PathBuf};
|
||||
use url::{ParseError, Url};
|
||||
|
||||
// ========================================
|
||||
|
@ -77,6 +71,12 @@ impl error::Error for Error {}
|
|||
// Config
|
||||
// ========================================
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct User {
|
||||
pub name: String,
|
||||
pub email: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Package {
|
||||
pub configs: Vec<PathBuf>,
|
||||
|
@ -91,6 +91,7 @@ pub struct Remote {
|
|||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Config {
|
||||
pub user: User,
|
||||
pub local: PathBuf,
|
||||
pub remote: Remote,
|
||||
pub packages: BTreeMap<String, Package>,
|
||||
|
@ -164,97 +165,6 @@ pub fn reload(pc: &PathConfig) -> Result<PathConfig> {
|
|||
load(&vec![pc.homesync_yml.clone()])
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Creation
|
||||
// ========================================
|
||||
|
||||
fn prompt_default(prompt: &str, default: String) -> Result<String> {
|
||||
print!("{}", prompt);
|
||||
io::stdout().flush()?;
|
||||
let mut value = String::new();
|
||||
io::stdin().read_line(&mut value)?;
|
||||
let trimmed = value.trim();
|
||||
if trimmed.is_empty() {
|
||||
Ok(default)
|
||||
} else {
|
||||
Ok(trimmed.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
fn prompt_local(path: Option<&Path>) -> Result<PathBuf> {
|
||||
let default = path.map_or("$HOME/.homesync".to_owned(), |p| p.display().to_string());
|
||||
let value = prompt_default(
|
||||
&format!(
|
||||
"Local git repository <{}> (enter to continue): ",
|
||||
colorize_string(format!("<yellow>{}</>", &default)),
|
||||
),
|
||||
default,
|
||||
)?;
|
||||
Ok(PathBuf::from(value))
|
||||
}
|
||||
|
||||
fn prompt_remote(remote: Option<&Remote>) -> Result<Remote> {
|
||||
let default_name = remote.map_or("origin".to_owned(), |r| r.name.to_owned());
|
||||
let remote_name = prompt_default(
|
||||
&format!(
|
||||
"Remote git name <{}> (enter to continue): ",
|
||||
colorize_string(format!("<yellow>{}</>", &default_name))
|
||||
),
|
||||
default_name,
|
||||
)?;
|
||||
|
||||
let default_branch = remote.map_or("origin".to_owned(), |r| r.branch.to_owned());
|
||||
let remote_branch = prompt_default(
|
||||
&format!(
|
||||
"Remote git branch <{}> (enter to continue): ",
|
||||
colorize_string(format!("<yellow>{}</>", &default_branch))
|
||||
),
|
||||
default_branch,
|
||||
)?;
|
||||
|
||||
let default_url = remote.map_or("https://github.com/owner/repo.git".to_owned(), |r| {
|
||||
r.url.to_string()
|
||||
});
|
||||
let remote_url = prompt_default(
|
||||
&format!(
|
||||
"Remote git url <{}> (enter to continue): ",
|
||||
colorize_string(format!("<yellow>{}</>", &default_url))
|
||||
),
|
||||
default_url,
|
||||
)?;
|
||||
|
||||
Ok(Remote {
|
||||
name: remote_name,
|
||||
branch: remote_branch,
|
||||
url: Url::parse(&remote_url)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn write(path: &ResPathBuf, loaded: Option<Config>) -> Result<PathConfig> {
|
||||
println!(
|
||||
"Generating config at {}...\n",
|
||||
colorize_string(format!("<green>{}</>", path.unresolved().display())),
|
||||
);
|
||||
let local = prompt_local(match &loaded {
|
||||
Some(c) => Some(c.local.as_ref()),
|
||||
None => None,
|
||||
})?;
|
||||
let remote = prompt_remote(match &loaded {
|
||||
Some(c) => Some(&c.remote),
|
||||
None => None,
|
||||
})?;
|
||||
let generated = PathConfig {
|
||||
homesync_yml: path.clone(),
|
||||
config: Config {
|
||||
local,
|
||||
remote,
|
||||
packages: loaded.map_or(BTreeMap::new(), |c| c.packages),
|
||||
},
|
||||
};
|
||||
generated.write()?;
|
||||
Ok(generated)
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Listing
|
||||
// ========================================
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::{config::PathConfig, path};
|
||||
use git2::{IndexAddOption, ObjectType, Remote, Repository, Signature, StashFlags};
|
||||
use git2::{IndexAddOption, ObjectType, Remote, Repository, Signature};
|
||||
use path::ResPathBuf;
|
||||
use simplelog::{info, paris};
|
||||
use std::{
|
||||
|
|
32
src/lib.rs
32
src/lib.rs
|
@ -4,8 +4,7 @@ pub mod git;
|
|||
pub mod path;
|
||||
|
||||
use config::PathConfig;
|
||||
use path::ResPathBuf;
|
||||
use std::{error::Error, io};
|
||||
use std::error::Error;
|
||||
|
||||
type Result = std::result::Result<(), Box<dyn Error>>;
|
||||
|
||||
|
@ -21,35 +20,6 @@ pub fn run_daemon(config: PathConfig, freq_secs: u64) -> Result {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_init(candidates: Vec<ResPathBuf>) -> Result {
|
||||
debug_assert!(!candidates.is_empty(), "Empty candidates found in `init`.");
|
||||
if candidates.is_empty() {
|
||||
Err(config::Error::IOError(io::Error::new(
|
||||
io::ErrorKind::NotFound,
|
||||
"No suitable config file found.",
|
||||
)))?;
|
||||
}
|
||||
let config = match config::load(&candidates) {
|
||||
// Check if we already have a local config somewhere. If so, reprompt
|
||||
// the same configuration options and override the values present in the
|
||||
// current YAML file.
|
||||
Ok(loaded) => config::write(&loaded.homesync_yml, Some(loaded.config))?,
|
||||
// Otherwise create a new config file at the given location. We always
|
||||
// assume we want to write to the first file in our priority list. If
|
||||
// not, the user should specify which config they want to write using
|
||||
// the `-c` flag.
|
||||
// TODO(jrpotter): Verify I have permission to write at specified path.
|
||||
// Make directories if necessary.
|
||||
Err(config::Error::MissingConfig) if !candidates.is_empty() => {
|
||||
config::write(&candidates[0], None)?
|
||||
}
|
||||
Err(e) => Err(e)?,
|
||||
};
|
||||
git::init(&config)?;
|
||||
println!("\nFinished initialization.");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn run_list(config: PathConfig) -> Result {
|
||||
config::list_packages(config);
|
||||
Ok(())
|
||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -60,7 +60,6 @@ fn main() {
|
|||
.default_value("5"),
|
||||
),
|
||||
)
|
||||
.subcommand(App::new("init").about("Initialize the homesync local repository"))
|
||||
.subcommand(App::new("list").about("See which packages homesync manages"))
|
||||
.subcommand(App::new("push").about("Push changes from local to remote"))
|
||||
.get_matches();
|
||||
|
@ -72,16 +71,8 @@ fn main() {
|
|||
|
||||
fn dispatch(matches: clap::ArgMatches) -> Result<(), Box<dyn Error>> {
|
||||
let candidates = find_candidates(&matches)?;
|
||||
match matches.subcommand() {
|
||||
Some(("init", _)) => Ok(homesync::run_init(candidates)?),
|
||||
// All subcommands beside `init` require a config. If we invoke any of
|
||||
// these, immediately attempt to load our config. Note once a config is
|
||||
// loaded, this same config is used throughout the lifetime of the
|
||||
// process. We avoid introducing the ability to "change" which config is
|
||||
// used, even if one of higher priority is eventually defined.
|
||||
subcommand => {
|
||||
let config = homesync::config::load(&candidates)?;
|
||||
match subcommand {
|
||||
match matches.subcommand() {
|
||||
Some(("apply", _)) => Ok(homesync::run_apply(config)?),
|
||||
Some(("daemon", matches)) => {
|
||||
let freq_secs: u64 = match matches.value_of("frequency") {
|
||||
|
@ -100,8 +91,6 @@ fn dispatch(matches: clap::ArgMatches) -> Result<(), Box<dyn Error>> {
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_candidates(matches: &clap::ArgMatches) -> Result<Vec<ResPathBuf>, io::Error> {
|
||||
let candidates = match matches.value_of("config") {
|
||||
|
|
Loading…
Reference in New Issue