use std::env; use std::fs; use std::io; use std::process::exit; use std::collections::HashSet; const GLOBAL_DATA_PATH: &str = env!("GLOBAL_DATA_PATH"); fn main() { let user_data_file = get_user_data_file(); let args: Vec = env::args().collect(); let license_index; let outfile: &str; if args.len() < 2 || args[1] == "-h" { print_help(&user_data_file); return } else if args[1] == "-o" { outfile = get_outfile(&args).unwrap_or_else(|| exit(1)); license_index = 3; } else { outfile = "LICENSE"; license_index = 1; } if args.len() <= license_index { print_help(&user_data_file); return } let license_name = &args[license_index]; if license_name.contains("/") { eprintln!("error: malformatted license name: '{}'", license_name); exit(1) } copy_license(&license_name, outfile, &user_data_file); } fn copy_license(license: &str, outfile: &str, user_data_file: &String) { let user_path = user_data_file.to_owned() + "/" + license; let license_content = fs::read_to_string(user_path).unwrap_or_else(|_| { let global_path = GLOBAL_DATA_PATH.to_owned() + "/" + license; fs::read_to_string(global_path).unwrap_or_else(|_| { eprintln!("error: could not open license for reading: '{}'", license); exit(1) }) }); let _ = fs::write(outfile, license_content).or_else(|_| -> io::Result<()> { eprintln!("error: could not write license: '{}'", outfile); exit(1) }); } fn get_outfile(args: &Vec) -> Option<&str> { if args.len() < 3 { eprintln!("error: -o requires an option"); return None } Some(&args[2]) } fn print_help(user_data_file: &String) { println!("license-tool [-h] [-o OUTFILE] "); println!("User License Dir: {}", user_data_file); let mut user_dirs = HashSet::::new(); let user_dir = fs::read_dir(user_data_file); if user_dir.is_ok() { println!("User Licenses:"); let user_error_fun = |_| { eprintln!("error: could not read user data directory"); exit(1) }; for file in user_dir.unwrap() { let file_name = file.unwrap_or_else(user_error_fun).file_name() .to_string_lossy().to_string(); println!(" {}", file_name); user_dirs.insert(file_name); } } let global_dir = fs::read_dir(GLOBAL_DATA_PATH); if global_dir.is_ok() { println!("Global Licenses:"); let global_error_fun = |_| { eprintln!("error: error reading data directory"); exit(1) }; for file in global_dir.unwrap() { let file_name = file.unwrap_or_else(global_error_fun).file_name() .to_string_lossy().to_string(); if user_dirs.contains(&file_name) { println!(" {} [Overridden]", file_name); } else { println!(" {}", file_name); } } } } fn get_user_data_file() -> String { let xdg_config = env::var("XDG_CONFIG_HOME").unwrap_or_else(|_| { let home_dir = env::var("HOME").unwrap_or_else(|_| { eprintln!("error: '$HOME' not set"); exit(1) }); home_dir + "/.config" }); xdg_config + "/license-tool" }