1extern crate clap;
3extern crate colored;
5extern crate git2;
7extern crate hostname;
9#[macro_use]
11extern crate serde_json;
12
13use clap::{App,Arg,ArgGroup,ArgMatches,SubCommand};
14
15use std::path;
16use std::env;
17use std::process;
18use std::ffi;
19
20pub use self::error::Error;
22pub use self::result::Result;
23
24pub mod error;
26pub mod result;
27
28mod config;
30mod destroy;
31mod home;
32mod init;
33mod link;
34mod unlink;
35
36pub fn run(matches : &ArgMatches) -> Result<()> {
37 match matches.subcommand() {
38 ("config", Some(sub_matches)) => config::run(&sub_matches),
39 ("destroy", Some(sub_matches)) => destroy::run(&sub_matches),
40 ("home", Some(sub_matches)) => home::run(&sub_matches),
41 ("init", Some(sub_matches)) => init::run(&sub_matches),
42 ("link", Some(sub_matches)) => link::run(&sub_matches),
43 ("unlink", Some(sub_matches)) => unlink::run(&sub_matches),
44 _ => Ok(())
45 }
46}
47
48pub fn app<'a, 'b>() -> App<'a, 'b> {
49 App::new("Ellipsis")
50 .author("Andrew Lee <andrewtl@stanford.edu>")
51 .about("Manages your dotfiles")
52 .subcommand(SubCommand::with_name("config")
53 .about("Manages the configuation file")
54 .arg(Arg::with_name("edit")
55 .long("edit")
56 .short("e")
57 .help("Open the config file for editing")))
58 .subcommand(SubCommand::with_name("destroy")
59 .about("Destroy the current installation")
60 .arg(Arg::with_name("force")
61 .long("force")
62 .short("f")
63 .help("Force the deletion of the given files. Without this option,
64 this command will not modify the filesystem."))
65 .arg(Arg::with_name("dry-run")
66 .long("dry-run")
67 .short("n")
68 .help("Don't actually do anything, just show what would happen"))
69 .group(ArgGroup::with_name("effect")
70 .args(&["force", "dry-run"])
71 .required(true)))
72 .subcommand(SubCommand::with_name("home")
73 .about("Print the ellipsis home directory"))
74 .subcommand(SubCommand::with_name("init")
75 .about("Init the repository")
76 .arg(Arg::with_name("URI")
77 .index(1)
78 .required(true)
79 .help("The repository to fetch")))
80 .subcommand(SubCommand::with_name("link")
81 .about("Properly symlink files"))
82 .subcommand(SubCommand::with_name("unlink")
83 .about("Delete symlinks"))
84}
85
86pub fn home_dir() -> Option<path::PathBuf> {
88 if let Ok(str) = env::var("XDG_DATA_HOME") {
89 Some(path::PathBuf::from(str).join("ellipsis"))
90 } else {
91
92 if let Some(myhome) = env::home_dir() {
93 Some(myhome.join(".ellipsis"))
94 } else {
95 None
96 }
97 }
98}
99
100pub fn config_file() -> Option<path::PathBuf> {
102 if let Some(home) = home_dir() {
103 if let Some(hname) = hostname::get_hostname() {
104 Some(home.join(format!("{}.dot.json", hname)))
105 } else {
106 None
107 }
108 } else {
109 None
110 }
111}
112
113pub fn editor<P: AsRef<ffi::OsStr>>(path : P) -> Result<()> {
114 process::Command::new(
115 env::var("EDITOR").unwrap_or(String::from("vi")))
116 .arg(path)
117 .status()?;
118 Ok(())
119}
120
121
122#[cfg(test)]
123mod test;