1use dev_prefix::*;
17use types::*;
18use logging;
19use user;
20use utils;
21use security;
22
23use clap::{ArgMatches, ErrorKind as ClEk};
24use ansi_term::Colour::Green;
25
26mod export;
27mod types;
28mod matches;
29mod ls;
30pub mod check;
31mod display;
32mod fmt;
33mod init;
34mod tutorial;
35mod update;
36#[cfg(feature = "beta")]
37mod plugin;
38
39mod server;
40
41#[cfg(test)]
42mod tests;
43
44pub fn get_loglevel(matches: &ArgMatches) -> (u8, bool) {
45 let verbosity = match matches.occurrences_of("verbose") {
46 v @ 0...3 => v,
47 _ => {
48 eprintln!("WARN: verbosity cannot be higher than 3, defaulting to 3");
50 3
51 }
52 } as u8;
53 let quiet = matches.is_present("quiet");
54 (verbosity, quiet)
55}
56
57#[cfg(feature = "beta")]
58fn run_beta<W>(_project: Option<&Project>, matches: &ArgMatches, w: &mut W) -> Result<u8>
60where
61 W: io::Write,
62{
63 if let Some(mat) = matches.subcommand_matches("plugin") {
64 info!("Calling plugin command");
65 let c = plugin::get_cmd(mat)?;
66 plugin::run_cmd(&c, w)
67 } else {
68 Err(ErrorKind::NothingDone.into())
69 }
70}
71
72#[cfg(not(feature = "beta"))]
73fn run_beta<W>(_: Option<&Project>, _: &ArgMatches, _: &mut W) -> Result<u8>
75where
76 W: io::Write,
77{
78 Err(ErrorKind::NothingDone.into())
79}
80
81pub fn cmd<W, I, T>(w: &mut W, args: I) -> Result<u8>
82where
83 I: IntoIterator<Item = T>,
84 T: Into<OsString> + clone::Clone,
85 W: io::Write,
86{
87 let matches = match matches::get_matches(args) {
88 Ok(m) => m,
89 Err(e) => match e.kind {
90 ClEk::HelpDisplayed | ClEk::VersionDisplayed => {
91 eprint!("{}", e);
92 return Ok(0);
93 }
94 _ => return Err(ErrorKind::CmdError(e.to_string()).into()),
95 },
96 };
97
98 let (v, q) = get_loglevel(&matches);
100 logging::init_logger(q, v, true).unwrap();
101
102 if let Some(up) = matches.subcommand_matches("update") {
104 info!("Calling the update command");
105 let cmd = update::get_cmd(up);
106 return Ok(update::run_cmd(&cmd).expect("update failed"));
107 }
108
109 let cwd = env::current_dir().unwrap();
110 let work_tree = match matches.value_of("work-tree") {
111 Some(w) => PathBuf::from(w),
112 None => cwd.to_path_buf(),
113 };
114 if !work_tree.is_dir() {
115 let msg = format!(
116 "ERROR: work-tree {} is not a directory",
117 work_tree.display()
118 );
119 return Err(ErrorKind::CmdError(msg).into());
120 }
121
122 if matches.subcommand_matches("init").is_some() {
124 info!("Calling the init command");
125 init::run_cmd(&work_tree)?;
126 return Ok(0);
127 }
128
129 if let Some(t) = matches.subcommand_matches("tutorial") {
131 info!("Calling the tutorial command");
132 let c = tutorial::get_cmd(t)?;
133 tutorial::run_cmd(&work_tree, c).unwrap();
134 return Ok(0);
135 }
136
137 if matches.subcommand_matches("plugin").is_some() {
140 return run_beta(None, &matches, w);
141 }
142
143 let repo = match utils::find_repo(&work_tree) {
145 Ok(r) => r,
146 Err(_) => {
147 let msg = "Could not find .art folder. Try running `art init`";
148 return Err(ErrorKind::CmdError(msg.to_string()).into());
149 }
150 };
151 debug!("Using repo dir {:?}", repo);
152
153 let project = user::load_repo(&repo)?;
154
155 security::validate(&repo, &project)?;
157
158 debug!("settings={:?}", project.settings);
159
160 if let Some(ls) = matches.subcommand_matches("ls") {
161 info!("Calling the ls command");
162 let cmd = ls::get_cmd(ls).unwrap();
163 ls::run_cmd(w, &work_tree, &cmd, &project)
164 } else if matches.subcommand_matches("check").is_some() {
165 info!("Calling the check command");
166 let cmd = check::Cmd {
167 color: types::COLOR_IF_POSSIBLE,
168 };
169 check::run_cmd(w, &work_tree, &project, &cmd)
170 } else if let Some(mat) = matches.subcommand_matches("fmt") {
171 info!("Calling the fmt command");
172 let c = fmt::get_cmd(mat)?;
173 fmt::run_cmd(w, &repo, &project, &c)
174 } else if let Some(mat) = matches.subcommand_matches("export") {
175 info!("Calling the export command");
176 let c = export::get_cmd(mat)?;
177 export::run_cmd(&cwd, &project, &c)
178 } else if let Some(mat) = matches.subcommand_matches("serve") {
179 let addr = server::get_cmd(mat);
180 server::run_cmd(project.clone(), &addr);
181 Ok(0)
182 } else if match run_beta(Some(&project), &matches, w) {
183 Ok(r) => return Ok(r),
184 Err(err) => match *err.kind() {
185 ErrorKind::NothingDone => false,
186 _ => return Err(err),
187 },
188 } {
189 unreachable!();
190 } else {
191 write!(
192 w,
193 "{} {}: use -h to show help",
194 Green.bold().paint("artifact"),
195 Green.paint(VERSION)
196 ).unwrap();
197 return Ok(0);
198 }
199}