use builder_cpp::{
bin_flags,
utils::log::{log, LogLevel},
};
use clap::{Parser, Subcommand};
use directories::ProjectDirs;
use builder_cpp::global_config::GlobalConfig;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
#[arg(short, long)]
build: bool,
#[arg(short, long)]
clean: bool,
#[arg(short, long)]
run: bool,
#[command(subcommand)]
commands: Option<Commands>,
#[arg(num_args(0..), last = true)]
bin_args: Vec<String>,
#[arg(long)]
gen_cc: bool,
#[arg(long)]
gen_vsc: bool,
#[arg(long)]
clean_packages: bool,
#[arg(long)]
update_packages: bool,
#[arg(long)]
restore_packages: bool,
}
#[derive(Subcommand, Debug)]
enum Commands {
Init {
name: String,
#[clap(long, action)]
c: bool,
#[clap(long, action)]
cpp: bool,
},
Config {
#[clap(verbatim_doc_comment)]
parameter: String,
#[clap(verbatim_doc_comment)]
value: String,
},
}
fn main() {
let project_dirs = ProjectDirs::from("com", "Dr42Apps", "builder-cpp").unwrap();
let config_dir = project_dirs.config_dir();
if !config_dir.exists() {
std::fs::create_dir_all(config_dir).unwrap();
}
let config = config_dir.join("config.toml");
if !config.exists() {
std::fs::write(
&config,
r#"
default_compiler = "gcc"
default_language = "cpp"
license = "NONE"
"#,
)
.unwrap();
}
let global_config = GlobalConfig::from_file(&config);
let args = Args::parse();
if args.commands.is_some() {
match args.commands {
Some(Commands::Init { name, c, cpp }) => {
if c && cpp {
log(LogLevel::Error, "Only one of --c or --cpp can be specified");
std::process::exit(1);
}
if !c && !cpp {
bin_flags::init_project(name, None, global_config);
std::process::exit(0);
}
if c {
bin_flags::init_project(name, Some(true), global_config);
} else {
bin_flags::init_project(name, Some(false), global_config);
}
}
Some(Commands::Config { parameter, value }) => {
let parameter = parameter.as_str();
let value = value.as_str();
GlobalConfig::set_defaults(&config, parameter, value);
log(
LogLevel::Log,
format!("Setting {} to {}", parameter, value).as_str(),
);
std::process::exit(0);
}
None => {
log(LogLevel::Error, "Rust is broken");
std::process::exit(1);
}
}
}
let mut gen_cc = false;
if args.gen_cc {
gen_cc = true;
bin_flags::pre_gen_cc();
}
let mut gen_vsc = false;
if args.gen_vsc {
gen_vsc = true;
bin_flags::pre_gen_vsc();
}
let (build_config, targets, packages) = bin_flags::parse_config();
if args.clean_packages {
bin_flags::clean_packages(&packages);
std::process::exit(0);
}
if args.update_packages {
bin_flags::update_packages(&packages);
std::process::exit(0);
}
if args.restore_packages {
bin_flags::restore_packages(&packages);
std::process::exit(0);
}
if args.clean {
log(LogLevel::Log, "Cleaning...");
bin_flags::clean(&targets);
}
if args.build {
log(LogLevel::Log, "Building...");
bin_flags::build(&build_config, &targets, gen_cc, gen_vsc, &packages);
}
if args.run {
let bin_args: Vec<String> = args.bin_args;
log(LogLevel::Log, "Running...");
let exe_target = targets.iter().find(|x| x.typ == "exe").unwrap();
let bin_args = if bin_args.is_empty() {
None
} else {
Some(bin_args.iter().map(|s| s.as_str()).collect::<Vec<&str>>())
};
bin_flags::run(bin_args, &build_config, exe_target, &targets, &packages);
}
}