build.rs/src/cli.rs

87 lines
2.9 KiB
Rust
Raw Normal View History

2020-11-25 22:59:39 +00:00
use std::path::PathBuf;
use structopt::StructOpt;
2022-01-06 17:08:51 +00:00
use structopt::clap::ErrorKind as ClapError;
2021-01-04 15:25:47 +00:00
// To get effective user id (EUID) so that setuid works
use users::{get_effective_uid,get_user_by_uid};
// For home directory
use users::os::unix::UserExt;
2020-05-01 10:48:22 +00:00
2022-01-06 17:08:51 +00:00
use crate::log;
use crate::log::Context;
2020-05-01 10:48:22 +00:00
#[derive(Debug, StructOpt)]
2020-11-25 22:59:39 +00:00
#[structopt(
2020-12-01 17:19:12 +00:00
name = "forgebuild",
2020-11-25 22:59:39 +00:00
about = "Update your repositories and trigger tasks"
)]
2020-05-01 10:48:22 +00:00
pub struct Cli {
#[structopt(short = "f", long = "force")]
2020-05-01 11:19:33 +00:00
pub force: bool,
2020-05-01 10:48:22 +00:00
#[structopt(short = "b", long = "basedir")]
pub basedir: Option<String>,
2022-01-12 18:20:10 +00:00
#[structopt(long = "inbox")]
pub inbox: bool,
#[structopt(long = "inbox-folder")]
pub inboxdir: Option<String>,
2020-05-01 10:48:22 +00:00
//#[structopt(def)]
2020-05-01 11:19:33 +00:00
pub tasks: Vec<String>,
2020-05-01 10:48:22 +00:00
}
impl Cli {
2022-01-06 17:08:51 +00:00
/// Builds the command-line from passed arguments
/// Returns the Cli instance alongside a PathBuf of the basedir
pub fn build() -> (Self, PathBuf) {
// We create a dedicated context so we don't have to pass it as argument
let mut context = Context::new();
// We don't want to use structopt's error handler for unknown argument as we have our own
// error message for that case (unknown_arg). So we use from_iter_safe() not from_args()
match Cli::from_iter_safe(std::env::args()) {
Ok(cmd) => {
// Parsing was successful, but we'd like to ensure requested basedir exists
match cmd.basedir().canonicalize() {
Ok(p) => {
(cmd, p)
},
Err(_) => {
// Missing basedir
context.insert("$i18n_basedir".to_string(), cmd.basedir().to_str().unwrap().to_string());
log::error("missing_basedir", &context);
std::process::exit(1);
}
}
},
Err(e) => {
match &e.kind {
ClapError::UnknownArgument => {
context.insert("$i18n_arg".to_string(), e.info.unwrap().first().unwrap().to_string());
log::error("unknown_arg", &context);
std::process::exit(1);
},
_ => e.exit()
}
}
}
}
2020-11-28 10:50:56 +00:00
/// Returns a PathBuf to the basedir. If it's a relative link,
/// it's not expanded here! Panics if no basedir is provided and $HOME isn't defined
pub fn basedir(&self) -> PathBuf {
if let Some(basedir) = &self.basedir {
// Returns an error when the path doesn't exist
2020-11-25 22:59:39 +00:00
PathBuf::from(basedir)
} else {
2021-01-04 15:25:47 +00:00
let owner = get_effective_uid();
let mut home_path = get_user_by_uid(owner).expect("Failed owner profile")
.home_dir().to_path_buf();
home_path.push(".forgebuild");
home_path
}
}
}