diff --git a/src/cmd/check.rs b/src/cmd/check.rs index 3f2193e..532fb89 100644 --- a/src/cmd/check.rs +++ b/src/cmd/check.rs @@ -86,8 +86,6 @@ pub enum OsedaProjectStatus { /// * `OsedaProjectStatus::DeployReady` if the project passes all checks /// * `OsedaProjectStatus::NotDeploymentReady(err)` if something fails that is commonly seen fn verify_project(port_num: u16) -> OsedaProjectStatus { - // TODO: document me -> assumes working directory is the project folder - let _conf = match config::read_and_validate_config() { Ok(conf) => conf, Err(err) => return OsedaProjectStatus::NotDeploymentReady(err), diff --git a/src/config.rs b/src/config.rs index 301a275..a528d62 100644 --- a/src/config.rs +++ b/src/config.rs @@ -12,8 +12,9 @@ use strum::IntoEnumIterator; use crate::cmd::check::OsedaCheckError; use crate::cmd::init::InitOptions; use crate::color::Color; -use crate::github; +use crate::license::License; use crate::tags::DefinedTag; +use crate::{github, license}; pub fn read_config_file>( path: P, @@ -121,6 +122,7 @@ pub struct OsedaConfig { pub color: String, // description must not be empty for check/deploy pub description: String, + pub license: License, } pub fn prompt_for_title() -> Result> { @@ -169,6 +171,8 @@ pub fn create_conf(options: InitOptions) -> Result> 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")?; + let license = prompt_for_license()?; + Ok(OsedaConfig { title: title.trim().to_owned(), author: user_name, @@ -178,11 +182,24 @@ pub fn create_conf(options: InitOptions) -> Result> .collect(), last_updated: get_time(), color: color.into_hex(), + license, // start them with empty description description: String::new(), }) } +fn prompt_for_license() -> Result> { + let options: Vec = license::License::iter() + .map(|lic: License| license::License::spdx_id(&lic)) + .map(|lic_str| lic_str.into()) + .collect(); + + let selected_license = + inquire::Select::new("Select license: (type to search):", options).prompt()?; + + Ok(License::try_from(selected_license)?) +} + /// Prompts user for categories associated with their Oseda project /// /// # Returns @@ -195,7 +212,7 @@ fn prompt_for_tags() -> Result, Box> { inquire::MultiSelect::new("Select categories (type to search):", options.clone()) .prompt()?; - println!("You selected:"); + println!("Selected Tags:"); for tags in selected_tags.iter() { println!("- {:?}", tags); } @@ -212,7 +229,7 @@ fn prompt_for_color() -> Result> { ) .prompt()?; - println!("You selected: {:?}", selected_color); + println!("Selected Color: {:?}", selected_color); Ok(selected_color) } @@ -297,6 +314,7 @@ mod test { author: "JaneDoe".to_string(), tags: vec![DefinedTag::ComputerScience.to_string()], last_updated: chrono::Utc::now(), + license: License::Apache2_0, color: Color::Black.into_hex(), description: String::from("Test Description"), }; @@ -315,6 +333,7 @@ mod test { author: "JaneDoe".to_string(), tags: vec![DefinedTag::ComputerScience.to_string()], last_updated: chrono::Utc::now(), + license: License::Mit, color: Color::Black.into_hex(), description: String::from("Test Description"), }; @@ -333,6 +352,7 @@ mod test { author: "JaneDoe".to_string(), tags: vec![DefinedTag::ComputerScience.to_string()], last_updated: chrono::Utc::now(), + license: License::Bsd3Clause, color: Color::Black.into_hex(), description: String::new(), }; @@ -354,6 +374,7 @@ mod test { tags: vec![DefinedTag::ComputerScience.to_string()], last_updated: chrono::Utc::now(), color: Color::Black.into_hex(), + license: License::Gpl3_0, description: String::from("Test Description"), }; diff --git a/src/lib.rs b/src/lib.rs index ddb94b3..2d616c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ pub mod cmd; pub mod color; pub mod config; pub mod github; +pub mod license; pub mod net; pub mod puppeteer; pub mod tags; diff --git a/src/license.rs b/src/license.rs new file mode 100644 index 0000000..32220e0 --- /dev/null +++ b/src/license.rs @@ -0,0 +1,91 @@ +use serde::{Deserialize, Serialize}; +use strum_macros::{EnumIter, EnumString, IntoStaticStr}; + +/// OSI approved license categorized as (popular / strong community) +#[derive( + Debug, Clone, PartialEq, Eq, Hash, EnumIter, IntoStaticStr, EnumString, Serialize, Deserialize, +)] +#[serde(into = "&'static str", try_from = "String")] +pub enum License { + // strum serialize is compatible with serde trait here + // this will basically allow a complex internal license representation + // but with ease of de/serialization with just the spdx id + #[strum(serialize = "Apache-2.0")] + Apache2_0, + #[strum(serialize = "MIT")] + Mit, + #[strum(serialize = "CDDL-1.0")] + Cddl1_0, + #[strum(serialize = "EPL-2.0")] + Epl2_0, + #[strum(serialize = "GPL-2.0")] + Gpl2_0, + #[strum(serialize = "GPL-3.0")] + Gpl3_0, + #[strum(serialize = "LGPL-2.1")] + Lgpl2_1, + #[strum(serialize = "LGPL-3.0")] + Lgpl3_0, + #[strum(serialize = "LGPL-2.0")] + Lgpl2_0, + #[strum(serialize = "MPL-2.0")] + Mpl2_0, + #[strum(serialize = "BSD-2-Clause")] + Bsd2Clause, + #[strum(serialize = "BSD-3-Clause")] + Bsd3Clause, +} + +impl License { + /// Get the full name of license. I'm not sure if this really ever be useful, but i figured its best to include it + pub const fn name(&self) -> &str { + match self { + Self::Apache2_0 => "Apache License, Version 2.0", + Self::Mit => "The MIT License", + Self::Cddl1_0 => "Common Development and Distribution License 1.0", + Self::Epl2_0 => "Eclipse Public License version 2.0", + Self::Gpl2_0 => "GNU General Public License version 2", + Self::Gpl3_0 => "GNU General Public License version 3", + Self::Lgpl2_1 => "GNU Lesser General Public License version 2.1", + Self::Lgpl3_0 => "GNU Lesser General Public License version 3", + Self::Lgpl2_0 => "GNU Library General Public License version 2", + Self::Mpl2_0 => "Mozilla Public License 2.0", + Self::Bsd2Clause => "The 2-Clause BSD License", + Self::Bsd3Clause => "The 3-Clause BSD License", + } + } + + /// Get the SPDX id associated with a license. + /// Internally, `oseda check` will recognize one of these strings + pub const fn spdx_id(&self) -> &'static str { + match self { + Self::Apache2_0 => "Apache-2.0", + Self::Mit => "MIT", + Self::Cddl1_0 => "CDDL-1.0", + Self::Epl2_0 => "EPL-2.0", + Self::Gpl2_0 => "GPL-2.0", + Self::Gpl3_0 => "GPL-3.0", + Self::Lgpl2_1 => "LGPL-2.1", + Self::Lgpl3_0 => "LGPL-3.0", + Self::Lgpl2_0 => "LGPL-2.0", + Self::Mpl2_0 => "MPL-2.0", + Self::Bsd2Clause => "BSD-2-Clause", + Self::Bsd3Clause => "BSD-3-Clause", + } + } +} + +impl std::fmt::Display for License { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.spdx_id()) + } +} + +// useful for oseda check attempting to parse a license spdx id +impl TryFrom for License { + type Error = strum::ParseError; + + fn try_from(s: String) -> Result { + s.parse() + } +}