diff --git a/src/bin/scaffold.rs b/src/bin/scaffold.rs index 0c77b4d..946c3f0 100644 --- a/src/bin/scaffold.rs +++ b/src/bin/scaffold.rs @@ -4,11 +4,11 @@ */ use std::{ fs::{File, OpenOptions}, - io::Write, - process, + io::{Error, Read, Seek, Write}, + process::{self, Command}, }; -const MODULE_TEMPLATE: &str = r###"pub fn part_one(input: &str) -> Option { +const MODULE_LIB_TEMPLATE: &str = r###"pub fn part_one(input: &str) -> Option { None } @@ -16,30 +16,33 @@ pub fn part_two(input: &str) -> Option { None } -fn main() { - let input = &advent_of_code::read_file("inputs", DAY); - advent_of_code::solve!(1, part_one, input); - advent_of_code::solve!(2, part_two, input); -} - #[cfg(test)] mod tests { use super::*; #[test] fn test_part_one() { - let input = advent_of_code::read_file("examples", DAY); + let input = crate::read_file("examples", DAY); assert_eq!(part_one(&input), None); } #[test] fn test_part_two() { - let input = advent_of_code::read_file("examples", DAY); + let input = crate::read_file("examples", DAY); assert_eq!(part_two(&input), None); } } "###; +const MODULE_BIN_TEMPLATE: &str = r###"use advent_of_code::dayDAYPAD::{part_one, part_two}; + +fn main() { + let input = &advent_of_code::read_file("inputs", DAY); + advent_of_code::solve!(1, part_one, input); + advent_of_code::solve!(2, part_two, input); +} +"###; + fn parse_args() -> Result { let mut args = pico_args::Arguments::from_env(); args.free_from_str() @@ -53,6 +56,46 @@ fn create_file(path: &str) -> Result { OpenOptions::new().write(true).create(true).open(path) } +fn modify_lib(day: u8) -> Result<(), Error> { + let lib_path = "src/lib.rs"; + + let mut file = OpenOptions::new() + .read(true) + .write(true) + .create(false) + .open(lib_path)?; + + let mut old_code = String::new(); + file.read_to_string(&mut old_code)?; + + file.rewind()?; + file.set_len(0)?; + + match file.write_all( + old_code + .replace( + &format!("// pub mod day{:02};", day), + &format!("pub mod day{:02};", day), + ) + .as_bytes(), + ) { + Ok(_) => { + println!("Updated lib.rs to include 'day{:02}' module", day); + } + Err(e) => { + eprintln!( + "Failed to write updateded lib.rs to include 'day{:02}' module: {}", + day, e + ); + process::exit(1); + } + } + + file.flush()?; + + Ok(()) +} + fn main() { let day = match parse_args() { Ok(day) => day, @@ -66,22 +109,59 @@ fn main() { let input_path = format!("src/inputs/{}.txt", day_padded); let example_path = format!("src/examples/{}.txt", day_padded); - let module_path = format!("src/bin/{}.rs", day_padded); + let module_bin_path = format!("src/bin/{}.rs", day_padded); + let module_lib_path = format!("src/day{}.rs", day_padded); - let mut file = match safe_create_file(&module_path) { + match modify_lib(day) { + Ok(_) => {} + Err(e) => { + eprintln!("Failed to update lib.rs file: {}", e); + process::exit(1); + } + } + + let mut bin_file = match safe_create_file(&module_bin_path) { Ok(file) => file, Err(e) => { - eprintln!("Failed to create module file: {}", e); + eprintln!("Failed to create module bin file: {}", e); process::exit(1); } }; - match file.write_all(MODULE_TEMPLATE.replace("DAY", &day.to_string()).as_bytes()) { + match bin_file.write_all( + MODULE_BIN_TEMPLATE + .replace("DAYPAD", &day_padded) + .replace("DAY", &day.to_string()) + .as_bytes(), + ) { Ok(_) => { - println!("Created module file \"{}\"", &module_path); + println!("Created module bin file \"{}\"", &module_bin_path); } Err(e) => { - eprintln!("Failed to write module contents: {}", e); + eprintln!("Failed to write bin module contents: {}", e); + process::exit(1); + } + } + + let mut lib_file = match safe_create_file(&module_lib_path) { + Ok(file) => file, + Err(e) => { + eprintln!("Failed to create module lib file: {}", e); + process::exit(1); + } + }; + + match lib_file.write_all( + MODULE_LIB_TEMPLATE + .replace("DAYPAD", &day_padded) + .replace("DAY", &day.to_string()) + .as_bytes(), + ) { + Ok(_) => { + println!("Created module lib file \"{}\"", &module_bin_path); + } + Err(e) => { + eprintln!("Failed to write lib module contents: {}", e); process::exit(1); } } @@ -106,6 +186,17 @@ fn main() { } } + // We need to execute cargo clean -p advent_of_code otherwise there can be cache issues when executing cargo check + // As far as I can tell this relates to https://github.com/rust-lang/cargo/issues/6529 + let clean_output = Command::new("cargo") + .args(["clean", "-p", "advent_of_code"]) + .output() + .unwrap(); + + if !clean_output.status.success() { + eprint!("Failed to execute 'cargo clean -p advent_of_code'."); + } + println!("---"); println!( "🎄 Type `cargo solve {}` to run your solution.", diff --git a/src/lib.rs b/src/lib.rs index 23acd28..4d3e650 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,32 @@ use std::env; use std::fs; +// modules for the different days are automatically uncomented by the scaffold command +pub mod day01; +pub mod day02; +// pub mod day03; +// pub mod day04; +// pub mod day05; +// pub mod day06; +// pub mod day07; +// pub mod day08; +// pub mod day09; +// pub mod day10; +// pub mod day11; +// pub mod day12; +// pub mod day13; +// pub mod day14; +// pub mod day15; +// pub mod day16; +// pub mod day17; +// pub mod day18; +// pub mod day19; +// pub mod day20; +// pub mod day21; +// pub mod day22; +// pub mod day23; +// pub mod day24; +// pub mod day25; pub mod helpers; pub const ANSI_ITALIC: &str = "\x1b[3m";