diff --git a/src/error.rs b/src/error.rs index 3a1c940..eb2f9fd 100644 --- a/src/error.rs +++ b/src/error.rs @@ -54,4 +54,7 @@ pub enum AocError #[cfg(feature = "tally")] #[error("{0}")] RunError(String), + + #[error("Setup for year already exists")] + SetupExists, } diff --git a/src/main.rs b/src/main.rs index 4d8a2ae..eb4e5b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,11 +58,6 @@ async fn main() -> Result<(), AocError> .required(false) .default_value(OsStr::from(chrono::Utc::now().day().to_string())) .help("Day to run"), - Arg::new("year") - .short('y') - .required(false) - .default_value(OsStr::from(chrono::Utc::now().year().to_string())) - .help("Year for automatic download of input if not present"), Arg::new("test") .short('t') .long("test") diff --git a/src/run.rs b/src/run.rs index c033d17..c2f7da9 100644 --- a/src/run.rs +++ b/src/run.rs @@ -10,7 +10,7 @@ use crate::{ error::AocError, util::{ file::{cargo_path, day_path, download_input_file}, - get_day, get_time_symbol, get_year, + get_day, get_time_symbol, get_year_from_root, }, }; @@ -34,7 +34,7 @@ pub async fn run(matches: &ArgMatches) -> Result<(), AocError> if !dir.join("input").exists() { - let year = get_year(matches)?; + let year = get_year_from_root().await?; let current_year = Utc::now().year(); let current_month = Utc::now().month(); @@ -84,7 +84,7 @@ pub async fn run(matches: &ArgMatches) -> Result<(), AocError> if matches.get_flag("assert") { - let year = get_year(matches)?; + let year = get_year_from_root().await?; assert_answer(&out, day, year).await?; } @@ -92,7 +92,7 @@ pub async fn run(matches: &ArgMatches) -> Result<(), AocError> #[cfg(feature = "submit")] if let Some(task) = get_submit_task(matches).transpose()? { - let year = get_year(matches)?; + let year = get_year_from_root().await?; let output = submit::submit(&out, task, day, year).await?; println!("Task {}: {}", task, output); } diff --git a/src/setup.rs b/src/setup.rs index c4153df..eab76bd 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -1,22 +1,47 @@ +use std::path::Path; + use clap::ArgMatches; +use tokio::{fs::OpenOptions, io::AsyncWriteExt}; -use crate::{error::AocError, util::get_year}; +use crate::error::AocError; async fn setup_template_project(year: i32) -> Result<(), AocError> { - tokio::process::Command::new("cargo") + if Path::new(&format!("{year}")).exists() + { + return Err(AocError::SetupExists); + } + + let res = tokio::process::Command::new("cargo") .args(["new", &format!("year_{}", year)]) .output() .await?; - let template = format!("{}/template/template.rs", env!("CARGO_MANIFEST_DIR")); + if !res.status.success() + { + return Err(AocError::SetupExists); + } + + tokio::fs::rename(format!("year_{year}"), format!("{year}")).await?; + + let template_dir = format!("{}/template", env!("CARGO_MANIFEST_DIR")); + let bins = tokio::fs::read(Path::new(&template_dir).join("Cargo.toml.template")).await?; + + OpenOptions::new() + .append(true) + .open(format!("{}/Cargo.toml", year)) + .await? + .write_all(&bins) + .await?; + for i in 1..=25 { - let dir = format!("year_{year}/src/bin/day_{:0>2}", i); + let dir = format!("{year}/src/day_{:0>2}", i); tokio::fs::create_dir_all(&dir).await?; - tokio::fs::copy(&template, format!("{dir}/main.rs")).await?; + tokio::fs::copy(Path::new(&template_dir).join("template.rs"), format!("{dir}/main.rs")) + .await?; } - tokio::fs::remove_file(format!("year_{year}/src/main.rs")).await?; + tokio::fs::remove_file(format!("{year}/src/main.rs")).await?; Ok(()) } @@ -40,6 +65,19 @@ async fn get_session_token() -> Result<(), AocError> Ok(()) } +fn get_year(matches: &ArgMatches) -> Result +{ + let year = matches.get_one::("year").ok_or(AocError::ArgMatches)?; + if year.chars().count() == 2 + { + Ok(format!("20{}", year).parse()?) + } + else + { + Ok(year.parse()?) + } +} + pub async fn setup(args: &ArgMatches) -> Result<(), AocError> { let year = get_year(args)?; diff --git a/src/util/mod.rs b/src/util/mod.rs index 6c048f9..12fbeb9 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1,4 +1,7 @@ -use std::path::PathBuf; +use std::{ + io::{Error, ErrorKind}, + path::PathBuf, +}; use clap::ArgMatches; @@ -32,9 +35,16 @@ impl std::fmt::Display for Task } -pub fn get_year(matches: &ArgMatches) -> Result +pub async fn get_year_from_root() -> Result { - let year = matches.get_one::("year").ok_or(AocError::ArgMatches)?; + let root = cargo_path().await?; + let year = root + .file_name() + .ok_or_else(|| { + AocError::StdIoErr(Error::new(ErrorKind::NotFound, "could not find Cargo.toml file")) + })? + .to_string_lossy(); + if year.chars().count() == 2 { Ok(format!("20{}", year).parse()?) diff --git a/src/util/request.rs b/src/util/request.rs index aa2e1fa..d41ea96 100644 --- a/src/util/request.rs +++ b/src/util/request.rs @@ -12,7 +12,7 @@ pub struct AocRequest impl AocRequest { - const AOC_USER_AGENT: &str = + const AOC_USER_AGENT: &'static str = "github.com/seblj/cargo-aoc by sebastian@lyngjohansen.com and sivert-joh@hotmail.com"; pub fn new() -> AocRequest diff --git a/template/Cargo.toml.template b/template/Cargo.toml.template new file mode 100644 index 0000000..85e6da1 --- /dev/null +++ b/template/Cargo.toml.template @@ -0,0 +1,99 @@ +[[bin]] +name = "day_01" +path = "src/day_01/main.rs" + +[[bin]] +name = "day_02" +path = "src/day_02/main.rs" + +[[bin]] +name = "day_03" +path = "src/day_03/main.rs" + +[[bin]] +name = "day_04" +path = "src/day_04/main.rs" + +[[bin]] +name = "day_05" +path = "src/day_05/main.rs" + +[[bin]] +name = "day_06" +path = "src/day_06/main.rs" + +[[bin]] +name = "day_07" +path = "src/day_07/main.rs" + +[[bin]] +name = "day_08" +path = "src/day_08/main.rs" + +[[bin]] +name = "day_09" +path = "src/day_09/main.rs" + +[[bin]] +name = "day_10" +path = "src/day_10/main.rs" + +[[bin]] +name = "day_11" +path = "src/day_11/main.rs" + +[[bin]] +name = "day_12" +path = "src/day_12/main.rs" + +[[bin]] +name = "day_13" +path = "src/day_13/main.rs" + +[[bin]] +name = "day_14" +path = "src/day_14/main.rs" + +[[bin]] +name = "day_15" +path = "src/day_15/main.rs" + +[[bin]] +name = "day_16" +path = "src/day_16/main.rs" + +[[bin]] +name = "day_17" +path = "src/day_17/main.rs" + +[[bin]] +name = "day_18" +path = "src/day_18/main.rs" + +[[bin]] +name = "day_19" +path = "src/day_19/main.rs" + +[[bin]] +name = "day_20" +path = "src/day_20/main.rs" + +[[bin]] +name = "day_21" +path = "src/day_21/main.rs" + +[[bin]] +name = "day_22" +path = "src/day_22/main.rs" + +[[bin]] +name = "day_23" +path = "src/day_23/main.rs" + +[[bin]] +name = "day_24" +path = "src/day_24/main.rs" + +[[bin]] +name = "day_25" +path = "src/day_25/main.rs"