From 6382f8b7038e757ecd588a71ce8eb63787b370cb Mon Sep 17 00:00:00 2001 From: ReeseHatfield Date: Fri, 23 Jan 2026 13:40:03 -0500 Subject: [PATCH 1/8] begin adding the flags --- scripts/test-init.sh | 5 +---- src/cmd/init.rs | 20 +++++++++++++++----- src/config.rs | 6 ++++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/scripts/test-init.sh b/scripts/test-init.sh index dd315fb..66f21cc 100755 --- a/scripts/test-init.sh +++ b/scripts/test-init.sh @@ -3,16 +3,13 @@ rm -rf test/* mkdir -p test - - set -e ./scripts/build.sh cp target/release/oseda test - cd test pwd -./oseda init +./oseda init --title rahhhhhhhh diff --git a/src/cmd/init.rs b/src/cmd/init.rs index 784ce45..912c2f7 100644 --- a/src/cmd/init.rs +++ b/src/cmd/init.rs @@ -20,9 +20,19 @@ use crate::{config, template::Template}; /// Options for the `oseda init` command #[derive(Args, Debug)] pub struct InitOptions { - /// Unused for now - #[arg(long, required = false)] - sentation_only: bool, + #[arg(long)] + title: Option, + + // Todo convert this to tags + #[arg(long)] + categories: Option>, + + #[arg(long)] + color: Option, + + #[arg(long)] + template: Option, + } // embed all the static markdown template files into binary @@ -54,8 +64,8 @@ const HTML_FERRIS: &[u8] = include_bytes!("../static/html-templates/ferris.png") /// # Returns /// * `Ok(())` if project initialization is suceeded /// * `Err` if any step (npm, file write, config generation etc) fails -pub fn init(_opts: InitOptions) -> Result<(), Box> { - let conf = config::create_conf()?; +pub fn init(opts: InitOptions) -> Result<(), Box> { + let conf = config::create_conf(opts)?; let template: Template = prompt_template()?; diff --git a/src/config.rs b/src/config.rs index 1297111..2d1c0cb 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,6 +10,7 @@ use strum::IntoEnumIterator; use crate::tags::Tag; use crate::cmd::check::OsedaCheckError; +use crate::cmd::init::InitOptions; use crate::color::Color; use crate::github; @@ -112,10 +113,11 @@ pub struct OsedaConfig { /// # Returns /// * `Ok(OsedaConfig)` containing validated project config options /// * `Err` if a required input conf is invalid -pub fn create_conf() -> Result> { +pub fn create_conf(options: InitOptions) -> Result> { // let mut title = String::new(); // std::io::std in().read_line(&mut title)?; - + println!("Options: {:?}", options); + let validator = |input: &str| { if input.chars().count() < 2 { Ok(Validation::Invalid( From fb50cb29d0c4864aaf25fbaa130b5ffd213c3ee4 Mon Sep 17 00:00:00 2001 From: ReeseHatfield Date: Fri, 23 Jan 2026 15:50:23 -0500 Subject: [PATCH 2/8] separate into inquire functions --- scripts/test-init.sh | 2 +- src/config.rs | 42 ++++++++++++++++++++++++++++-------------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/scripts/test-init.sh b/scripts/test-init.sh index 66f21cc..3553707 100755 --- a/scripts/test-init.sh +++ b/scripts/test-init.sh @@ -12,4 +12,4 @@ cd test pwd -./oseda init --title rahhhhhhhh +./oseda init diff --git a/src/config.rs b/src/config.rs index 2d1c0cb..945ca9e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -108,16 +108,9 @@ pub struct OsedaConfig { pub color: String, } -/// Prompts the user for everything needed to generate a new OsedaConfig -/// -/// # Returns -/// * `Ok(OsedaConfig)` containing validated project config options -/// * `Err` if a required input conf is invalid -pub fn create_conf(options: InitOptions) -> Result> { - // let mut title = String::new(); - // std::io::std in().read_line(&mut title)?; - println!("Options: {:?}", options); - + + +pub fn prompt_for_title() -> Result> { let validator = |input: &str| { if input.chars().count() < 2 { Ok(Validation::Invalid( @@ -128,14 +121,30 @@ pub fn create_conf(options: InitOptions) -> Result> } }; - let mut title = inquire::Text::new("Title: ") + Ok(inquire::Text::new("Title: ") .with_validator(validator) - .prompt()?; + .prompt()?) +} +/// Prompts the user for everything needed to generate a new OsedaConfig +/// +/// # Returns +/// * `Ok(OsedaConfig)` containing validated project config options +/// * `Err` if a required input conf is invalid +pub fn create_conf(options: InitOptions) -> Result> { + // let mut title = String::new(); + // std::io::std in().read_line(&mut title)?; + println!("Options: {:?}", options); + - title = title.replace(" ", "-"); + let mut title = prompt_for_title()?.replace(" ", "-"); +<<<<<<< HEAD let tags = get_tags()?; let color = get_color()?; +======= + let categories = prompt_for_categories()?; + let color = prompt_for_color()?; +>>>>>>> 4643b35 (separate into inquire functions) let user_name = github::get_config_from_user_git("user.name") .ok_or("Could not get github username. Please ensure you are signed into github")?; @@ -154,8 +163,13 @@ pub fn create_conf(options: InitOptions) -> Result> /// # Returns /// * `Ok(Vec)` with selected categories /// * `Err` if the prompting went wrong somewhere +<<<<<<< HEAD fn get_tags() -> Result, Box> { let options: Vec = Tag::iter().collect(); +======= +fn prompt_for_categories() -> Result, Box> { + let options: Vec = Category::iter().collect(); +>>>>>>> 4643b35 (separate into inquire functions) println!("Select tags that match your course's meaning and purpose."); println!("(You can always add custom tags later!)"); @@ -171,7 +185,7 @@ fn get_tags() -> Result, Box> { Ok(selected_tags) } -fn get_color() -> Result> { +fn prompt_for_color() -> Result> { let options: Vec = Color::iter().collect(); let selected_color = inquire::Select::new( From f0617a100e46e5382ae67ef09b6aa04670e91907 Mon Sep 17 00:00:00 2001 From: ReeseHatfield Date: Fri, 23 Jan 2026 17:53:57 -0500 Subject: [PATCH 3/8] tags as argument --- scripts/test-init.sh | 2 +- src/cmd/init.rs | 11 ++++----- src/config.rs | 58 ++++++++++++++++++++++++-------------------- src/tags.rs | 4 +-- 4 files changed, 40 insertions(+), 35 deletions(-) diff --git a/scripts/test-init.sh b/scripts/test-init.sh index 3553707..0b8ca4b 100755 --- a/scripts/test-init.sh +++ b/scripts/test-init.sh @@ -12,4 +12,4 @@ cd test pwd -./oseda init +./oseda init --title rahhhhhh --tags Economics ComputerScience diff --git a/src/cmd/init.rs b/src/cmd/init.rs index 912c2f7..daf786e 100644 --- a/src/cmd/init.rs +++ b/src/cmd/init.rs @@ -21,17 +21,16 @@ use crate::{config, template::Template}; #[derive(Args, Debug)] pub struct InitOptions { #[arg(long)] - title: Option, + pub title: Option, - // Todo convert this to tags - #[arg(long)] - categories: Option>, + #[arg(long, num_args = 1.., value_delimiter=' ')] + pub tags: Option>, #[arg(long)] - color: Option, + pub color: Option, #[arg(long)] - template: Option, + pub template: Option, } diff --git a/src/config.rs b/src/config.rs index 945ca9e..3c1aef1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,7 @@ use std::error::Error; use std::fs::File; use std::io::BufWriter; +use std::str::FromStr; use std::{ffi::OsString, fs}; use chrono::{DateTime, Utc}; @@ -134,17 +135,27 @@ pub fn create_conf(options: InitOptions) -> Result> // let mut title = String::new(); // std::io::std in().read_line(&mut title)?; println!("Options: {:?}", options); - - let mut title = prompt_for_title()?.replace(" ", "-"); + let title = match options.title { + Some(arg_title) => arg_title, + None => prompt_for_title()?.replace(" ", "-") + }; + + + + let tags = match options.tags { + Some(arg_tags) => { + arg_tags + .iter() + .map(|arg_tag| Tag::from_str(arg_tag)) + .collect::, _>>() + .map_err(|_| format!("Invalid tag. Custom Tags may be added to the oseda-config.json after initialization"))? + }, + None => prompt_for_tags()? + }; + // let categories = prompt_for_categories()?; -<<<<<<< HEAD - let tags = get_tags()?; - let color = get_color()?; -======= - let categories = prompt_for_categories()?; let color = prompt_for_color()?; ->>>>>>> 4643b35 (separate into inquire functions) let user_name = github::get_config_from_user_git("user.name") .ok_or("Could not get github username. Please ensure you are signed into github")?; @@ -152,7 +163,7 @@ pub fn create_conf(options: InitOptions) -> Result> Ok(OsedaConfig { title: title.trim().to_owned(), author: user_name, - tags, + tags: tags, last_updated: get_time(), color: color.into_hex(), }) @@ -161,25 +172,18 @@ pub fn create_conf(options: InitOptions) -> Result> /// Prompts user for categories associated with their Oseda project /// /// # Returns -/// * `Ok(Vec)` with selected categories +/// * `Ok(Vec)` with selected categories /// * `Err` if the prompting went wrong somewhere -<<<<<<< HEAD -fn get_tags() -> Result, Box> { +fn prompt_for_tags() -> Result, Box> { let options: Vec = Tag::iter().collect(); -======= -fn prompt_for_categories() -> Result, Box> { - let options: Vec = Category::iter().collect(); ->>>>>>> 4643b35 (separate into inquire functions) - println!("Select tags that match your course's meaning and purpose."); - println!("(You can always add custom tags later!)"); let selected_tags = - inquire::MultiSelect::new("Select tags (type to search):", options.clone()) + inquire::MultiSelect::new("Select categories (type to search):", options.clone()) .prompt()?; println!("You selected:"); - for tag in selected_tags.iter() { - println!("- {:?}", tag); + for tags in selected_tags.iter() { + println!("- {:?}", tags); } Ok(selected_tags) @@ -246,6 +250,8 @@ mod test { use std::path::Path; use tempfile::tempdir; + use crate::tags; + use super::*; #[allow(dead_code)] @@ -254,7 +260,7 @@ mod test { { "title": "TestableRust", "author": "JaneDoe", - "tags": ["ComputerScience"], + "category": ["ComputerScience"], "last_updated": "2024-07-10T12:34:56Z" } "# @@ -276,7 +282,7 @@ mod test { let conf = OsedaConfig { title: "my-project".to_string(), author: "JaneDoe".to_string(), - tags: vec![Tag::ComputerScience], + tags: vec![tags::ComputerScience], last_updated: chrono::Utc::now(), color: Color::Black.into_hex(), }; @@ -293,7 +299,7 @@ mod test { let conf = OsedaConfig { title: "my-project".to_string(), author: "JaneDoe".to_string(), - tags: vec![Tag::ComputerScience], + tags: vec![tags::ComputerScience], last_updated: chrono::Utc::now(), color: Color::Black.into_hex(), }; @@ -310,7 +316,7 @@ mod test { let conf = OsedaConfig { title: "correct-name".to_string(), author: "JaneDoe".to_string(), - tags: vec![Tag::ComputerScience], + tags: vec![tags::ComputerScience], last_updated: chrono::Utc::now(), color: Color::Black.into_hex(), }; @@ -329,7 +335,7 @@ mod test { let conf = OsedaConfig { title: "oseda".to_string(), author: "JaneDoe".to_string(), - tags: vec![Tag::ComputerScience], + tags: vec![tags::ComputerScience], last_updated: chrono::Utc::now(), color: Color::Black.into_hex(), }; diff --git a/src/tags.rs b/src/tags.rs index f2ba701..6e89011 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -1,8 +1,8 @@ use serde::{Deserialize, Serialize}; use strum::IntoEnumIterator; -use strum_macros::{Display, EnumIter}; +use strum_macros::{Display, EnumIter, EnumString}; -#[derive(Serialize, Deserialize, Debug, Clone, Copy, Display, EnumIter)] +#[derive(Serialize, Deserialize, Debug, Clone, Copy, Display, EnumIter, EnumString)] pub enum Tag { Aerospace, Business, From c350e6cde919043b7f42e3388e9814974989d561 Mon Sep 17 00:00:00 2001 From: ReeseHatfield Date: Fri, 23 Jan 2026 18:00:07 -0500 Subject: [PATCH 4/8] colors as argument --- scripts/test-init.sh | 2 +- src/color.rs | 4 ++-- src/config.rs | 10 ++++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/scripts/test-init.sh b/scripts/test-init.sh index 0b8ca4b..299b559 100755 --- a/scripts/test-init.sh +++ b/scripts/test-init.sh @@ -12,4 +12,4 @@ cd test pwd -./oseda init --title rahhhhhh --tags Economics ComputerScience +./oseda init --title rahhhhhh --tags Economics ComputerScience --color asdfasdfas diff --git a/src/color.rs b/src/color.rs index 6ad9ae7..9fafa6c 100644 --- a/src/color.rs +++ b/src/color.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; -use strum_macros::{Display, EnumIter}; +use strum_macros::{Display, EnumIter, EnumString}; -#[derive(Serialize, Deserialize, Debug, Clone, Copy, Display, EnumIter)] +#[derive(Serialize, Deserialize, Debug, Clone, Copy, Display, EnumIter, EnumString)] pub enum Color { Black, White, diff --git a/src/config.rs b/src/config.rs index 3c1aef1..4bf37a4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -153,9 +153,15 @@ pub fn create_conf(options: InitOptions) -> Result> }, None => prompt_for_tags()? }; - // let categories = prompt_for_categories()?; - let color = prompt_for_color()?; + + let color = match options.color { + Some(arg_color) => { + Color::from_str(&arg_color) + .map_err(|_| format!("Invalid color. Please use traditional english color names"))? + }, + None => prompt_for_color()? + }; let user_name = github::get_config_from_user_git("user.name") .ok_or("Could not get github username. Please ensure you are signed into github")?; From 718d02e3aed15fd1e7a2d40bb3e00bd485e86ab3 Mon Sep 17 00:00:00 2001 From: ReeseHatfield Date: Fri, 23 Jan 2026 19:31:57 -0500 Subject: [PATCH 5/8] make template arg --- scripts/test-init.sh | 2 +- src/cmd/init.rs | 14 ++++++++++++-- src/template.rs | 4 ++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/scripts/test-init.sh b/scripts/test-init.sh index 299b559..5fb3114 100755 --- a/scripts/test-init.sh +++ b/scripts/test-init.sh @@ -12,4 +12,4 @@ cd test pwd -./oseda init --title rahhhhhh --tags Economics ComputerScience --color asdfasdfas +./oseda init --title rahhhhhh --tags Economics ComputerScience --color Red --template Markdown diff --git a/src/cmd/init.rs b/src/cmd/init.rs index daf786e..62616b4 100644 --- a/src/cmd/init.rs +++ b/src/cmd/init.rs @@ -9,7 +9,7 @@ touch vite.config.js -> add the plugin, write this by hand use std::{ error::Error, fs::{self}, - process::Command, + process::Command, str::FromStr, }; use clap::Args; @@ -64,9 +64,19 @@ const HTML_FERRIS: &[u8] = include_bytes!("../static/html-templates/ferris.png") /// * `Ok(())` if project initialization is suceeded /// * `Err` if any step (npm, file write, config generation etc) fails pub fn init(opts: InitOptions) -> Result<(), Box> { + + let template = match opts.template{ + Some(ref arg_template) => { + Template::from_str(&arg_template) + .map_err(|_| format!("Invalid template"))? + } + None => prompt_template()?, + }; + + let conf = config::create_conf(opts)?; - let template: Template = prompt_template()?; + // let template: Template = prompt_template()?; std::fs::create_dir_all(&conf.title)?; diff --git a/src/template.rs b/src/template.rs index 6575439..236d178 100644 --- a/src/template.rs +++ b/src/template.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; -use strum_macros::{Display, EnumIter}; +use strum_macros::{Display, EnumIter, EnumString}; -#[derive(Serialize, Deserialize, Debug, Clone, Copy, Display, EnumIter)] +#[derive(Serialize, Deserialize, Debug, Clone, Copy, Display, EnumIter, EnumString)] pub enum Template { Markdown, HTML, From 3afdb098be944933043538a99d523440b059f58c Mon Sep 17 00:00:00 2001 From: ReeseHatfield Date: Fri, 23 Jan 2026 19:45:23 -0500 Subject: [PATCH 6/8] case insensitive --- scripts/test-init.sh | 2 +- src/color.rs | 1 + src/tags.rs | 1 + src/template.rs | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/test-init.sh b/scripts/test-init.sh index 5fb3114..7c6dff8 100755 --- a/scripts/test-init.sh +++ b/scripts/test-init.sh @@ -12,4 +12,4 @@ cd test pwd -./oseda init --title rahhhhhh --tags Economics ComputerScience --color Red --template Markdown +./oseda init --title rahhhhhh --tags economics ComPuterScience --color red --template MaRKDoWN diff --git a/src/color.rs b/src/color.rs index 9fafa6c..b6fef3d 100644 --- a/src/color.rs +++ b/src/color.rs @@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize}; use strum_macros::{Display, EnumIter, EnumString}; #[derive(Serialize, Deserialize, Debug, Clone, Copy, Display, EnumIter, EnumString)] +#[strum(ascii_case_insensitive)] pub enum Color { Black, White, diff --git a/src/tags.rs b/src/tags.rs index 6e89011..e95f061 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -3,6 +3,7 @@ use strum::IntoEnumIterator; use strum_macros::{Display, EnumIter, EnumString}; #[derive(Serialize, Deserialize, Debug, Clone, Copy, Display, EnumIter, EnumString)] +#[strum(ascii_case_insensitive)] pub enum Tag { Aerospace, Business, diff --git a/src/template.rs b/src/template.rs index 236d178..e483da9 100644 --- a/src/template.rs +++ b/src/template.rs @@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize}; use strum_macros::{Display, EnumIter, EnumString}; #[derive(Serialize, Deserialize, Debug, Clone, Copy, Display, EnumIter, EnumString)] +#[strum(ascii_case_insensitive)] pub enum Template { Markdown, HTML, From 00e603cdde0424c46bd7b62915e82b4288bd1d69 Mon Sep 17 00:00:00 2001 From: ReeseHatfield Date: Fri, 23 Jan 2026 19:55:56 -0500 Subject: [PATCH 7/8] remove extraneous output --- scripts/test-init.sh | 2 +- src/cmd/init.rs | 1 - src/config.rs | 5 ----- src/github.rs | 2 -- 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/scripts/test-init.sh b/scripts/test-init.sh index 7c6dff8..ab26c40 100755 --- a/scripts/test-init.sh +++ b/scripts/test-init.sh @@ -12,4 +12,4 @@ cd test pwd -./oseda init --title rahhhhhh --tags economics ComPuterScience --color red --template MaRKDoWN +./oseda init --title ExampleProject --tags economics ComPuterScience --color red --template MaRKDoWN diff --git a/src/cmd/init.rs b/src/cmd/init.rs index 62616b4..235105f 100644 --- a/src/cmd/init.rs +++ b/src/cmd/init.rs @@ -76,7 +76,6 @@ pub fn init(opts: InitOptions) -> Result<(), Box> { let conf = config::create_conf(opts)?; - // let template: Template = prompt_template()?; std::fs::create_dir_all(&conf.title)?; diff --git a/src/config.rs b/src/config.rs index 4bf37a4..9a1f520 100644 --- a/src/config.rs +++ b/src/config.rs @@ -132,17 +132,12 @@ pub fn prompt_for_title() -> Result> { /// * `Ok(OsedaConfig)` containing validated project config options /// * `Err` if a required input conf is invalid pub fn create_conf(options: InitOptions) -> Result> { - // let mut title = String::new(); - // std::io::std in().read_line(&mut title)?; - println!("Options: {:?}", options); let title = match options.title { Some(arg_title) => arg_title, None => prompt_for_title()?.replace(" ", "-") }; - - let tags = match options.tags { Some(arg_tags) => { arg_tags diff --git a/src/github.rs b/src/github.rs index 70610d6..6263fc6 100644 --- a/src/github.rs +++ b/src/github.rs @@ -30,8 +30,6 @@ pub fn get_config_from_user_git(key: &str) -> Option { let conf_out = String::from_utf8(handle.stdout).ok()?; - println!("{conf_out}"); - get_key_from_conf(key, &conf_out) } From c90b4c3e633a97034afd053c1672fd9e9d95fdb9 Mon Sep 17 00:00:00 2001 From: ReeseHatfield Date: Fri, 23 Jan 2026 20:07:43 -0500 Subject: [PATCH 8/8] fix tests --- src/config.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/config.rs b/src/config.rs index 9a1f520..68447d3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -283,7 +283,7 @@ mod test { let conf = OsedaConfig { title: "my-project".to_string(), author: "JaneDoe".to_string(), - tags: vec![tags::ComputerScience], + tags: vec![Tag::ComputerScience], last_updated: chrono::Utc::now(), color: Color::Black.into_hex(), }; @@ -300,7 +300,7 @@ mod test { let conf = OsedaConfig { title: "my-project".to_string(), author: "JaneDoe".to_string(), - tags: vec![tags::ComputerScience], + tags: vec![Tag::ComputerScience], last_updated: chrono::Utc::now(), color: Color::Black.into_hex(), }; @@ -317,7 +317,7 @@ mod test { let conf = OsedaConfig { title: "correct-name".to_string(), author: "JaneDoe".to_string(), - tags: vec![tags::ComputerScience], + tags: vec![Tag::ComputerScience], last_updated: chrono::Utc::now(), color: Color::Black.into_hex(), }; @@ -336,7 +336,7 @@ mod test { let conf = OsedaConfig { title: "oseda".to_string(), author: "JaneDoe".to_string(), - tags: vec![tags::ComputerScience], + tags: vec![Tag::ComputerScience], last_updated: chrono::Utc::now(), color: Color::Black.into_hex(), };