just/src/main.rs

108 lines
2.6 KiB
Rust
Raw Normal View History

2016-09-27 22:49:17 -07:00
#[macro_use]
extern crate brev;
2016-06-16 17:13:43 -07:00
2016-09-27 22:49:17 -07:00
#[derive(PartialEq, Clone, Copy)]
enum Make {
GNU, // GNU Make installed as `gmake`
GNUStealthy, // GNU Make installed as `make`
Other, // Another make installed as `make`
2016-06-16 17:13:43 -07:00
}
2016-09-27 22:49:17 -07:00
impl Make {
fn command(self) -> &'static str {
if self == Make::GNU {
"gmake"
} else {
"make"
}
2016-06-16 17:13:43 -07:00
}
2016-09-27 22:49:17 -07:00
fn gnu(self) -> bool {
self != Make::Other
2016-06-16 17:13:43 -07:00
}
}
2016-09-27 22:49:17 -07:00
fn status(command: &mut std::process::Command) -> std::io::Result<std::process::ExitStatus> {
command
.stdin(std::process::Stdio::null())
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.status()
2016-06-16 17:13:43 -07:00
}
2016-09-27 22:49:17 -07:00
fn which_make() -> Option<Make> {
// check `gmake`
let result = status(std::process::Command::new("gmake").arg("-v"));
if let Ok(exit_status) = result {
if exit_status.success() {
return Some(Make::GNU);
}
2016-06-16 17:13:43 -07:00
}
2016-09-27 22:49:17 -07:00
// check `make`. pass gmake specific flags to see if it's actually gmake
let result = status(std::process::Command::new("make").arg("-v").arg("--always-make"));
if let Ok(exit_status) = result {
return if exit_status.success() {
Some(Make::GNUStealthy)
} else {
Some(Make::Other)
};
2016-06-16 17:13:43 -07:00
}
2016-09-27 22:49:17 -07:00
return None;
2016-06-16 17:13:43 -07:00
}
fn main() {
2016-09-27 22:49:17 -07:00
let make = match which_make() {
None => die!("Could not execute `make` or `gmake`."),
Some(make) => make,
};
2016-06-16 17:13:43 -07:00
loop {
2016-09-27 22:49:17 -07:00
match std::fs::metadata("justfile") {
Ok(metadata) => if metadata.is_file() { break; },
Err(error) => die!("Error fetching justfile metadata: {}", error),
2016-06-16 17:13:43 -07:00
}
2016-09-27 22:49:17 -07:00
match std::env::current_dir() {
Ok(pathbuf) => if pathbuf.as_os_str() == "/" { die!("No justfile found"); },
Err(error) => die!("Error getting current dir: {}", error),
2016-06-16 17:13:43 -07:00
}
2016-09-27 22:49:17 -07:00
if let Err(error) = std::env::set_current_dir("..") {
die!("Error changing directory: {}", error);
}
}
2016-06-16 17:13:43 -07:00
let recipes: Vec<String> = std::env::args().skip(1).take_while(|arg| arg != "--").collect();
let arguments: Vec<String> = std::env::args().skip(1 + recipes.len() + 1).collect();
2016-09-27 22:49:17 -07:00
for (i, argument) in arguments.into_iter().enumerate() {
std::env::set_var(format!("ARG{}", i), argument);
}
2016-06-16 17:13:43 -07:00
2016-09-27 22:49:17 -07:00
let mut command = std::process::Command::new(make.command());
command.arg("MAKEFLAGS=");
if make.gnu() {
command.arg("--always-make").arg("--no-print-directory");
}
command.arg("-f").arg("justfile");
for recipe in recipes {
command.arg(recipe);
}
match command.status() {
Err(error) => die!("Failed to execute `{:?}`: {}", command, error),
Ok(exit_status) => match exit_status.code() {
Some(code) => std::process::exit(code),
None => std::process::exit(-1),
}
}
2016-06-16 17:13:43 -07:00
}