use std::path::Path;
use crate::exit::{EXIT_FAILURE, EXIT_OK, EXIT_USAGE};
use crate::export::{self, ExportError, ExportRefusal};
use crate::usage::EXPORT_USAGE;
use super::root::require_repo;
fn usage_error(message: &str) -> i32 {
eprintln!("devscout export: {message}\n{EXPORT_USAGE}");
EXIT_USAGE
}
fn parse_out(args: &[String]) -> Result<Option<String>, i32> {
let mut out: Option<String> = None;
let mut index = 0;
while index < args.len() {
let arg = args[index].as_str();
if arg != "--out" {
return Err(usage_error(&format!("unexpected argument `{arg}`")));
}
if out.is_some() {
return Err(usage_error("`--out` given more than once"));
}
let Some(value) = args.get(index + 1) else {
return Err(usage_error("`--out` needs a file"));
};
if value.starts_with('-') {
return Err(usage_error("`--out` needs a file"));
}
out = Some(value.clone());
index += 2;
}
Ok(out)
}
pub(crate) fn cmd_export(cwd: &Path, args: &[String]) -> i32 {
let out = match parse_out(args) {
Ok(out) => out,
Err(code) => return code,
};
let root = match require_repo(cwd) {
Ok(root) => root,
Err(message) => {
eprintln!("{}", ExportRefusal::NoIndex(message).line());
return EXIT_FAILURE;
}
};
match export::run(&root, cwd, out.as_deref().map(Path::new)) {
Ok(()) => EXIT_OK,
Err(ExportError::Refused(refusal)) => {
eprintln!("{}", refusal.line());
EXIT_FAILURE
}
Err(ExportError::Output(message)) => {
eprintln!("devscout export: {message}");
EXIT_FAILURE
}
Err(ExportError::Stdout) => EXIT_FAILURE,
}
}