use ansi_term::Colour::{Cyan, Green, Purple, Yellow};
use clap::{crate_authors, crate_description, crate_name, crate_version, AppSettings, Parser};
use std::{env, path::PathBuf, process::exit};
use crate::commands::init::init;
use self::{
app::App,
help::{build_build_help_message, build_run_help_message},
};
pub mod app;
mod help;
#[derive(Debug, Parser)]
pub enum Command {
Run,
Build,
}
#[derive(Debug, Parser)]
#[clap(
name = crate_name!(),
version = crate_version!(),
about = crate_description!(),
author = crate_authors!(),
global_setting = AppSettings::ArgRequiredElseHelp
)]
pub struct CLI {
#[clap(subcommand)]
pub subcommand: Command,
}
impl CLI {
pub fn handle_failure() {
match rustc_version::version_meta().unwrap().channel {
rustc_version::Channel::Nightly => {
}
_ => {
println!(
"{} You are not using a {} compiler. Run {}.",
Yellow.paint("=>"),
Purple.paint("`nightly`"),
Cyan.paint("`rustup default nightly`"),
);
}
}
let cargo_home_path = std::env::var("CARGO_HOME");
let mut cargo_path = dirs::home_dir().unwrap().join(".cargo").join("bin");
if let Ok(cargo_home) = cargo_home_path {
cargo_path = PathBuf::from(cargo_home).join("bin");
}
let mut sccache_path = cargo_path.join("sccache");
if cfg!(windows) {
sccache_path = cargo_path.join("sccache.exe");
}
if !sccache_path.exists() {
println!(
"{} You have not installed {}. Run {}.",
Yellow.paint("=>"),
Purple.paint("`sccache`"),
Cyan.paint("`cargo install sccache`"),
);
}
if cfg!(unix) {
let lld_path = std::path::Path::new("/usr/bin/lld");
if !lld_path.exists() {
println!(
"{} You have not installed {}. Run {}.",
Yellow.paint("=>"),
Purple.paint("`lld`"),
Cyan.paint("`sudo apt install lld`"),
);
}
let clang_path = std::path::Path::new("/usr/bin/clang");
if !clang_path.exists() {
println!(
"{} You have not installed {}. Run {}.",
Yellow.paint("=>"),
Purple.paint("`clang`"),
Cyan.paint("`sudo apt install clang`"),
);
}
} else if cfg!(macos) {
let zld_path = std::path::Path::new("/usr/bin/zld");
if !zld_path.exists() {
println!(
"{} You have not installed {}. Run {}.",
Yellow.paint("=>"),
Purple.paint("`zld`"),
Cyan.paint("`brew install zld`"),
);
}
}
exit(1);
}
pub fn display_help(cmd: &str) {
let mut help_menu = format!(
r#"{} {}
Dimension <team@dimension.dev>
The blazing fast build tool for Rust.
{}:
fleet <SUBCOMMAND>
{}:
-h, --help Print help information
-v, --version Print version information
-up, --update-path Update paths in .cargo/config.toml
{}:
build Build a Fleet project
run Run a Fleet project"#,
Green.paint("fleet"),
env!("CARGO_PKG_VERSION"),
Yellow.paint("USAGE"),
Yellow.paint("OPTIONS"),
Yellow.paint("SUBCOMMANDS"),
);
if cmd == "run" {
help_menu = build_run_help_message()
} else if cmd == "build" {
help_menu = build_build_help_message()
}
println!("{}", help_menu)
}
pub fn run() {
let args = std::env::args().collect::<Vec<String>>();
let app = App::new();
if args.len() <= 1 {
CLI::display_help("help");
} else {
let cmd = &args[1];
if args.contains(&String::from("--help")) || args.contains(&String::from("-h")) {
CLI::display_help(cmd);
std::process::exit(1)
}
const VERSION: &str = env!("CARGO_PKG_VERSION");
if args.contains(&String::from("--version")) || args.contains(&String::from("-v")) {
println!("{}", VERSION);
std::process::exit(1)
}
if args.contains(&String::from("--update-path")) || args.contains(&String::from("-up"))
{
init(app);
std::process::exit(1)
}
match cmd.as_str() {
"run" => {
init(app);
let args: Vec<String> = args.iter().skip(2).map(|s| s.to_string()).collect();
let status = std::process::Command::new("cargo")
.arg("run")
.args(args)
.status()
.unwrap();
if !status.success() {
CLI::handle_failure();
}
}
"build" => {
init(app);
let args: Vec<String> = args.iter().skip(2).map(|s| s.to_string()).collect();
let status = std::process::Command::new("cargo")
.arg("build")
.args(args)
.status()
.unwrap();
if !status.success() {
CLI::handle_failure();
}
}
_ => {}
}
}
}
}