From 2d558682d449eb9050ed08191c5de478fe680e22 Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 00:04:41 +0100 Subject: [PATCH 01/20] feat: add #[cfg_attr(feature = schemars, derive(schemars::JsonSchema))] to all rules & config --- cli/Cargo.toml | 4 +++- cli/src/config.rs | 1 + cli/src/rule.rs | 2 ++ cli/src/rule/body_empty.rs | 1 + cli/src/rule/body_max_length.rs | 1 + cli/src/rule/description_empty.rs | 1 + cli/src/rule/description_format.rs | 1 + cli/src/rule/description_max_length.rs | 1 + cli/src/rule/footers_empty.rs | 1 + cli/src/rule/scope.rs | 1 + cli/src/rule/scope_empty.rs | 11 +++-------- cli/src/rule/scope_format.rs | 1 + cli/src/rule/scope_max_length.rs | 1 + cli/src/rule/subject_empty.rs | 6 ++---- cli/src/rule/type.rs | 1 + cli/src/rule/type_empty.rs | 1 + cli/src/rule/type_format.rs | 1 + cli/src/rule/type_max_length.rs | 1 + 18 files changed, 24 insertions(+), 13 deletions(-) diff --git a/cli/Cargo.toml b/cli/Cargo.toml index effea1d..d4b8efd 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -17,7 +17,7 @@ edition.workspace = true clap = { version = "4.5.4", features = ["derive", "env", "string"] } futures = "0.3.30" regex = "1.10.5" -schemars = "0.8.21" +schemars = { version = "0.8.21", optional = true } serde = { version = "1.0.201", features = ["derive"] } serde_json = "1.0.121" serde_yaml = "0.9.34" @@ -30,3 +30,5 @@ path = "src/main.rs" [package.metadata.binstall] pkg-url = "{ repo }/releases/download/v{ version }/commitlint-v{ version }-{ target }{ archive-suffix }" +[features] +schemars = ["dep:schemars"] diff --git a/cli/src/config.rs b/cli/src/config.rs index e5b46ac..2d7be77 100644 --- a/cli/src/config.rs +++ b/cli/src/config.rs @@ -19,6 +19,7 @@ const DEFAULT_CONFIG_FILE: [&str; 4] = [ /// Config represents the configuration of commitlint. #[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Config { /// Rules represents the rules of commitlint. pub rules: Rules, diff --git a/cli/src/rule.rs b/cli/src/rule.rs index 18a975d..ffa9c42 100644 --- a/cli/src/rule.rs +++ b/cli/src/rule.rs @@ -30,6 +30,7 @@ pub mod type_max_length; /// Rules represents the rules of commitlint. /// See: https://commitlint.js.org/#/reference-rules #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Rules { #[serde(rename = "body-empty")] #[serde(skip_serializing_if = "Option::is_none")] @@ -227,6 +228,7 @@ pub trait Rule: Default { /// Level represents the level of a rule. #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub enum Level { #[serde(rename = "error")] Error, diff --git a/cli/src/rule/body_empty.rs b/cli/src/rule/body_empty.rs index 6231930..ecfb444 100644 --- a/cli/src/rule/body_empty.rs +++ b/cli/src/rule/body_empty.rs @@ -5,6 +5,7 @@ use super::Level; /// BodyEmpty represents the body-empty rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct BodyEmpty { /// Level represents the level of the rule. /// diff --git a/cli/src/rule/body_max_length.rs b/cli/src/rule/body_max_length.rs index b7a3afc..ea8b869 100644 --- a/cli/src/rule/body_max_length.rs +++ b/cli/src/rule/body_max_length.rs @@ -5,6 +5,7 @@ use super::Level; /// BodyMaxLength represents the body-max-length rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct BodyMaxLength { /// Level represents the level of the rule. /// diff --git a/cli/src/rule/description_empty.rs b/cli/src/rule/description_empty.rs index d853f5a..4c7e7a2 100644 --- a/cli/src/rule/description_empty.rs +++ b/cli/src/rule/description_empty.rs @@ -5,6 +5,7 @@ use super::Level; /// DescriptionEmpty represents the subject-empty rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct DescriptionEmpty { /// Level represents the level of the rule. /// diff --git a/cli/src/rule/description_format.rs b/cli/src/rule/description_format.rs index 0b5c3db..dc54ff4 100644 --- a/cli/src/rule/description_format.rs +++ b/cli/src/rule/description_format.rs @@ -5,6 +5,7 @@ use super::Level; /// DescriptionFormat represents the description-format rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct DescriptionFormat { /// Level represents the level of the rule. /// diff --git a/cli/src/rule/description_max_length.rs b/cli/src/rule/description_max_length.rs index de0f01a..babed77 100644 --- a/cli/src/rule/description_max_length.rs +++ b/cli/src/rule/description_max_length.rs @@ -5,6 +5,7 @@ use super::Level; /// DescriptionMaxLength represents the description-max-length rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct DescriptionMaxLength { /// Level represents the level of the rule. /// diff --git a/cli/src/rule/footers_empty.rs b/cli/src/rule/footers_empty.rs index 9f5abe9..f4970c3 100644 --- a/cli/src/rule/footers_empty.rs +++ b/cli/src/rule/footers_empty.rs @@ -5,6 +5,7 @@ use super::Level; /// FootersEmpty represents the footer-empty rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct FootersEmpty { /// Level represents the level of the rule. /// diff --git a/cli/src/rule/scope.rs b/cli/src/rule/scope.rs index d3947bd..57bd7b5 100644 --- a/cli/src/rule/scope.rs +++ b/cli/src/rule/scope.rs @@ -5,6 +5,7 @@ use super::Level; /// Scope represents the subject-empty rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Scope { /// Level represents the level of the rule. /// diff --git a/cli/src/rule/scope_empty.rs b/cli/src/rule/scope_empty.rs index 96a5f00..e2d0219 100644 --- a/cli/src/rule/scope_empty.rs +++ b/cli/src/rule/scope_empty.rs @@ -5,6 +5,7 @@ use super::Level; /// ScopeEmpty represents the subject-empty rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct ScopeEmpty { /// Level represents the level of the rule. /// @@ -79,10 +80,7 @@ mod tests { let violation = rule.validate(&message); assert!(violation.is_some()); assert_eq!(violation.clone().unwrap().level, Level::Error); - assert_eq!( - violation.unwrap().message, - "scope is empty".to_string() - ); + assert_eq!(violation.unwrap().message, "scope is empty".to_string()); } #[test] @@ -101,9 +99,6 @@ mod tests { let violation = rule.validate(&message); assert!(violation.is_some()); assert_eq!(violation.clone().unwrap().level, Level::Error); - assert_eq!( - violation.unwrap().message, - "scope is empty".to_string() - ); + assert_eq!(violation.unwrap().message, "scope is empty".to_string()); } } diff --git a/cli/src/rule/scope_format.rs b/cli/src/rule/scope_format.rs index ca2abd6..e567834 100644 --- a/cli/src/rule/scope_format.rs +++ b/cli/src/rule/scope_format.rs @@ -5,6 +5,7 @@ use super::Level; /// ScopeFormat represents the scope-format rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct ScopeFormat { /// Level represents the level of the rule. /// diff --git a/cli/src/rule/scope_max_length.rs b/cli/src/rule/scope_max_length.rs index e490496..f33da11 100644 --- a/cli/src/rule/scope_max_length.rs +++ b/cli/src/rule/scope_max_length.rs @@ -5,6 +5,7 @@ use super::Level; /// ScopeMaxLength represents the description-max-length rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct ScopeMaxLength { /// Level represents the level of the rule. /// diff --git a/cli/src/rule/subject_empty.rs b/cli/src/rule/subject_empty.rs index 513a818..9b65adb 100644 --- a/cli/src/rule/subject_empty.rs +++ b/cli/src/rule/subject_empty.rs @@ -5,6 +5,7 @@ use super::Level; /// SubjectEmpty represents the subject-empty rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct SubjectEmpty { /// Level represents the level of the rule. /// @@ -85,9 +86,6 @@ Hello world" let violation = rule.validate(&message); assert!(violation.is_some()); assert_eq!(violation.clone().unwrap().level, Level::Error); - assert_eq!( - violation.unwrap().message, - "subject is empty".to_string() - ); + assert_eq!(violation.unwrap().message, "subject is empty".to_string()); } } diff --git a/cli/src/rule/type.rs b/cli/src/rule/type.rs index 26f3e94..39599a0 100644 --- a/cli/src/rule/type.rs +++ b/cli/src/rule/type.rs @@ -5,6 +5,7 @@ use super::Level; /// Type represents the subject-empty rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Type { /// Level represents the level of the rule. /// diff --git a/cli/src/rule/type_empty.rs b/cli/src/rule/type_empty.rs index 2030467..f9e425b 100644 --- a/cli/src/rule/type_empty.rs +++ b/cli/src/rule/type_empty.rs @@ -5,6 +5,7 @@ use super::Level; /// TypeEmpty represents the type-empty rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct TypeEmpty { /// Level represents the level of the rule. /// diff --git a/cli/src/rule/type_format.rs b/cli/src/rule/type_format.rs index 672549c..364d017 100644 --- a/cli/src/rule/type_format.rs +++ b/cli/src/rule/type_format.rs @@ -5,6 +5,7 @@ use super::Level; /// TypeFormat represents the type-format rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct TypeFormat { /// Level represents the level of the rule. /// diff --git a/cli/src/rule/type_max_length.rs b/cli/src/rule/type_max_length.rs index 5562218..1df8dbb 100644 --- a/cli/src/rule/type_max_length.rs +++ b/cli/src/rule/type_max_length.rs @@ -5,6 +5,7 @@ use super::Level; /// TypeMaxLength represents the description-max-length rule. #[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct TypeMaxLength { /// Level represents the level of the rule. /// From 91dd7c9fc3bc384d1785b9e636d48b6ca2bad1a6 Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 00:13:57 +0100 Subject: [PATCH 02/20] feat: write json-schema/config.json in generate_json_schema --- cli/Cargo.toml | 1 + cli/json-schema/config.json | 523 ++++++++++++++++++++++++++++++++++++ cli/src/config.rs | 14 + 3 files changed, 538 insertions(+) create mode 100644 cli/json-schema/config.json diff --git a/cli/Cargo.toml b/cli/Cargo.toml index d4b8efd..a451538 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -32,3 +32,4 @@ path = "src/main.rs" pkg-url = "{ repo }/releases/download/v{ version }/commitlint-v{ version }-{ target }{ archive-suffix }" [features] schemars = ["dep:schemars"] +default = [] diff --git a/cli/json-schema/config.json b/cli/json-schema/config.json new file mode 100644 index 0000000..91010be --- /dev/null +++ b/cli/json-schema/config.json @@ -0,0 +1,523 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Config", + "description": "Config represents the configuration of commitlint.", + "type": "object", + "required": [ + "rules" + ], + "properties": { + "rules": { + "description": "Rules represents the rules of commitlint.", + "allOf": [ + { + "$ref": "#/definitions/Rules" + } + ] + } + }, + "definitions": { + "BodyEmpty": { + "description": "BodyEmpty represents the body-empty rule.", + "type": "object", + "properties": { + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + } + } + }, + "BodyMaxLength": { + "description": "BodyMaxLength represents the body-max-length rule.", + "type": "object", + "required": [ + "length" + ], + "properties": { + "length": { + "description": "Length represents the maximum length of the body.", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + } + } + }, + "DescriptionEmpty": { + "description": "DescriptionEmpty represents the subject-empty rule.", + "type": "object", + "properties": { + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + } + } + }, + "DescriptionFormat": { + "description": "DescriptionFormat represents the description-format rule.", + "type": "object", + "properties": { + "format": { + "description": "Format represents the format of the description.", + "type": [ + "string", + "null" + ] + }, + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + } + } + }, + "DescriptionMaxLength": { + "description": "DescriptionMaxLength represents the description-max-length rule.", + "type": "object", + "required": [ + "length" + ], + "properties": { + "length": { + "description": "Length represents the maximum length of the description.", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + } + } + }, + "FootersEmpty": { + "description": "FootersEmpty represents the footer-empty rule.", + "type": "object", + "properties": { + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + } + } + }, + "Level": { + "description": "Level represents the level of a rule.", + "type": "string", + "enum": [ + "error", + "ignore", + "warning" + ] + }, + "Rules": { + "description": "Rules represents the rules of commitlint. See: https://commitlint.js.org/#/reference-rules", + "type": "object", + "properties": { + "body-empty": { + "anyOf": [ + { + "$ref": "#/definitions/BodyEmpty" + }, + { + "type": "null" + } + ] + }, + "body-max-length": { + "anyOf": [ + { + "$ref": "#/definitions/BodyMaxLength" + }, + { + "type": "null" + } + ] + }, + "description-empty": { + "anyOf": [ + { + "$ref": "#/definitions/DescriptionEmpty" + }, + { + "type": "null" + } + ] + }, + "description-format": { + "anyOf": [ + { + "$ref": "#/definitions/DescriptionFormat" + }, + { + "type": "null" + } + ] + }, + "description-max-length": { + "anyOf": [ + { + "$ref": "#/definitions/DescriptionMaxLength" + }, + { + "type": "null" + } + ] + }, + "footers-empty": { + "anyOf": [ + { + "$ref": "#/definitions/FootersEmpty" + }, + { + "type": "null" + } + ] + }, + "scope": { + "anyOf": [ + { + "$ref": "#/definitions/Scope" + }, + { + "type": "null" + } + ] + }, + "scope-empty": { + "anyOf": [ + { + "$ref": "#/definitions/ScopeEmpty" + }, + { + "type": "null" + } + ] + }, + "scope-format": { + "anyOf": [ + { + "$ref": "#/definitions/ScopeFormat" + }, + { + "type": "null" + } + ] + }, + "scope-max-length": { + "anyOf": [ + { + "$ref": "#/definitions/ScopeMaxLength" + }, + { + "type": "null" + } + ] + }, + "subject-empty": { + "anyOf": [ + { + "$ref": "#/definitions/SubjectEmpty" + }, + { + "type": "null" + } + ] + }, + "type": { + "anyOf": [ + { + "$ref": "#/definitions/Type" + }, + { + "type": "null" + } + ] + }, + "type-empty": { + "anyOf": [ + { + "$ref": "#/definitions/TypeEmpty" + }, + { + "type": "null" + } + ] + }, + "type-format": { + "anyOf": [ + { + "$ref": "#/definitions/TypeFormat" + }, + { + "type": "null" + } + ] + }, + "type-max-length": { + "anyOf": [ + { + "$ref": "#/definitions/TypeMaxLength" + }, + { + "type": "null" + } + ] + } + } + }, + "Scope": { + "description": "Scope represents the subject-empty rule.", + "type": "object", + "required": [ + "optional", + "options" + ], + "properties": { + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + }, + "optional": { + "description": "Optional scope. If true, even if the scope is not present, it is allowed.", + "type": "boolean" + }, + "options": { + "description": "Options represents the options of the rule. If the option is empty, it means that no scope is allowed.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "ScopeEmpty": { + "description": "ScopeEmpty represents the subject-empty rule.", + "type": "object", + "properties": { + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + } + } + }, + "ScopeFormat": { + "description": "ScopeFormat represents the scope-format rule.", + "type": "object", + "properties": { + "format": { + "description": "Format represents the format of the scope.", + "type": [ + "string", + "null" + ] + }, + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + } + } + }, + "ScopeMaxLength": { + "description": "ScopeMaxLength represents the description-max-length rule.", + "type": "object", + "required": [ + "length" + ], + "properties": { + "length": { + "description": "Length represents the maximum length of the scope.", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + } + } + }, + "SubjectEmpty": { + "description": "SubjectEmpty represents the subject-empty rule.", + "type": "object", + "properties": { + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + } + } + }, + "Type": { + "description": "Type represents the subject-empty rule.", + "type": "object", + "required": [ + "options" + ], + "properties": { + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + }, + "options": { + "description": "Options represents the options of the rule. If the option is empty, it means that no Type is allowed.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "TypeEmpty": { + "description": "TypeEmpty represents the type-empty rule.", + "type": "object", + "properties": { + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + } + } + }, + "TypeFormat": { + "description": "TypeFormat represents the type-format rule.", + "type": "object", + "properties": { + "format": { + "description": "Format represents the format of the type.", + "type": [ + "string", + "null" + ] + }, + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + } + } + }, + "TypeMaxLength": { + "description": "TypeMaxLength represents the description-max-length rule.", + "type": "object", + "required": [ + "length" + ], + "properties": { + "length": { + "description": "Length represents the maximum length of the type.", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "level": { + "description": "Level represents the level of the rule.", + "anyOf": [ + { + "$ref": "#/definitions/Level" + }, + { + "type": "null" + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/cli/src/config.rs b/cli/src/config.rs index 2d7be77..e197922 100644 --- a/cli/src/config.rs +++ b/cli/src/config.rs @@ -125,3 +125,17 @@ async fn load_unknown_config_file(path: PathBuf) -> Result { path.display() )) } +#[cfg(test)] +mod tests { + #[cfg(feature = "schemars")] + #[test] + // TODO assert insta snapshot + fn generate_json_schema() { + use std::fs; + + use crate::config::Config; + let config_schema = schemars::schema_for!(Config); + let config_schema_json = serde_json::to_string_pretty(&config_schema).unwrap(); + fs::write("json-schema/config.json", config_schema_json).unwrap(); + } +} From dc6b00dae29b132ebaf7852f392ac9be365e1964 Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 00:18:42 +0100 Subject: [PATCH 03/20] docs: broken link --- cli/json-schema/config.json | 2 +- cli/src/git.rs | 12 +++++++++--- cli/src/rule.rs | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/cli/json-schema/config.json b/cli/json-schema/config.json index 91010be..ef5191c 100644 --- a/cli/json-schema/config.json +++ b/cli/json-schema/config.json @@ -154,7 +154,7 @@ ] }, "Rules": { - "description": "Rules represents the rules of commitlint. See: https://commitlint.js.org/#/reference-rules", + "description": "Rules represents the rules of commitlint. See: https://commitlint.js.org/reference/rules.html", "type": "object", "properties": { "body-empty": { diff --git a/cli/src/git.rs b/cli/src/git.rs index eca382b..99d82bc 100644 --- a/cli/src/git.rs +++ b/cli/src/git.rs @@ -117,7 +117,7 @@ pub fn parse_commit_message( /// /// Note that exclamation mark is not respected as the existing commitlint /// does not have any rules for it. -/// See: https://commitlint.js.org/#/reference-rules +/// See: https://commitlint.js.org/reference/rules.html pub fn parse_subject(subject: &str) -> (Option, Option, Option) { let re = regex::Regex::new( r"^(?P\w+)(?:\((?P[^\)]+)\))?(?:!)?\:\s?(?P.*)$", @@ -188,8 +188,14 @@ Link: Hello"; let mut f = HashMap::new(); f.insert("Link".to_string(), "Hello".to_string()); assert_eq!(subject, "feat(cli): add dummy option"); - assert_eq!(body, Some("Hello, there! -I'm from Japan!".to_string())); + assert_eq!( + body, + Some( + "Hello, there! +I'm from Japan!" + .to_string() + ) + ); assert!(footer.is_some()); assert_eq!(f.get("Link"), Some(&"Hello".to_string())); } diff --git a/cli/src/rule.rs b/cli/src/rule.rs index ffa9c42..12a2727 100644 --- a/cli/src/rule.rs +++ b/cli/src/rule.rs @@ -28,7 +28,7 @@ pub mod type_format; pub mod type_max_length; /// Rules represents the rules of commitlint. -/// See: https://commitlint.js.org/#/reference-rules +/// See: https://commitlint.js.org/reference/rules.html #[derive(Clone, Debug, Deserialize, Serialize)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Rules { From ba0ab0569a33e672a329de21ce54c7127b5824ab Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 00:25:16 +0100 Subject: [PATCH 04/20] chore: fmt --- cli/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/config.rs b/cli/src/config.rs index e197922..8c96e68 100644 --- a/cli/src/config.rs +++ b/cli/src/config.rs @@ -131,9 +131,9 @@ mod tests { #[test] // TODO assert insta snapshot fn generate_json_schema() { + use crate::config::Config; use std::fs; - use crate::config::Config; let config_schema = schemars::schema_for!(Config); let config_schema_json = serde_json::to_string_pretty(&config_schema).unwrap(); fs::write("json-schema/config.json", config_schema_json).unwrap(); From dfbcda2a6b2e00e9ff3aa3e079a05d337ca2ee16 Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 00:35:02 +0100 Subject: [PATCH 05/20] chore: add cspell words --- cspell.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 cspell.yml diff --git a/cspell.yml b/cspell.yml new file mode 100644 index 0000000..67e3333 --- /dev/null +++ b/cspell.yml @@ -0,0 +1 @@ +words: [commitlint, schemars, commitlintrc, Keke] \ No newline at end of file From 16c78016f95823e23ac28a4e4dfc1ad9f1b066f8 Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 01:01:10 +0100 Subject: [PATCH 06/20] feat: add make_length_rule & make_rule macros to reduce boilerplate --- cli/src/rule.rs | 45 ++++++++++++++++++++++++++ cli/src/rule/body_empty.rs | 16 +++------ cli/src/rule/body_max_length.rs | 20 +++--------- cli/src/rule/description_empty.rs | 16 +++------ cli/src/rule/description_format.rs | 21 ++++-------- cli/src/rule/description_max_length.rs | 19 +++-------- cli/src/rule/footers_empty.rs | 16 +++------ cspell.yml | 2 +- 8 files changed, 74 insertions(+), 81 deletions(-) diff --git a/cli/src/rule.rs b/cli/src/rule.rs index 12a2727..5c6b094 100644 --- a/cli/src/rule.rs +++ b/cli/src/rule.rs @@ -239,3 +239,48 @@ pub enum Level { #[serde(rename = "warning")] Warning, } +#[macro_export] +macro_rules! make_length_rule { + ( + $ident:ident, + $doc:expr, + $length_of_what:literal + ) => { + crate::make_rule! { + $ident, + $doc, + #[doc = concat!("Length represents the maximum length of the ", stringify!(length_of_what), ".")] + length: usize + } + }; +} + +#[macro_export] +macro_rules! make_rule { + ( + $ident:ident, + $doc:expr, + $( + $( + #[$field_meta:meta] + )* + $field_name:ident: $field_type:ty + ),*) => { + #[doc = $doc] + #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] + #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] + pub struct $ident { + /// Level represents the level of the rule. + /// + // Note that currently the default literal is not supported. + // See: https://github.com/serde-rs/serde/issues/368 + level: Option, + $( + $( + #[$field_meta] + )* + $field_name: $field_type + ),* + } + }; +} diff --git a/cli/src/rule/body_empty.rs b/cli/src/rule/body_empty.rs index ecfb444..13cd70d 100644 --- a/cli/src/rule/body_empty.rs +++ b/cli/src/rule/body_empty.rs @@ -1,17 +1,9 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; - use super::Level; +use crate::{make_rule, message::Message, result::Violation, rule::Rule}; -/// BodyEmpty represents the body-empty rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct BodyEmpty { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, +make_rule! { + BodyEmpty, + "BodyEmpty represents the body-empty rule.", } /// BodyEmpty represents the body-empty rule. diff --git a/cli/src/rule/body_max_length.rs b/cli/src/rule/body_max_length.rs index ea8b869..3035d7f 100644 --- a/cli/src/rule/body_max_length.rs +++ b/cli/src/rule/body_max_length.rs @@ -1,20 +1,10 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; +use crate::{make_length_rule, message::Message, result::Violation, rule::Rule}; use super::Level; - -/// BodyMaxLength represents the body-max-length rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct BodyMaxLength { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, - - /// Length represents the maximum length of the body. - length: usize, +make_length_rule! { + BodyMaxLength, + "BodyMaxLength represents the body-max-length rule.", + "body" } /// BodyMaxLength represents the body-max-length rule. diff --git a/cli/src/rule/description_empty.rs b/cli/src/rule/description_empty.rs index 4c7e7a2..8b973a3 100644 --- a/cli/src/rule/description_empty.rs +++ b/cli/src/rule/description_empty.rs @@ -1,17 +1,9 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; +use crate::{make_rule, message::Message, result::Violation, rule::Rule}; use super::Level; - -/// DescriptionEmpty represents the subject-empty rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct DescriptionEmpty { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, +make_rule! { + DescriptionEmpty, + "DescriptionEmpty represents the description-empty rule", } /// DescriptionEmpty represents the description-empty rule. diff --git a/cli/src/rule/description_format.rs b/cli/src/rule/description_format.rs index dc54ff4..b410c4c 100644 --- a/cli/src/rule/description_format.rs +++ b/cli/src/rule/description_format.rs @@ -1,20 +1,11 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; +use crate::{make_rule, message::Message, result::Violation, rule::Rule}; use super::Level; - -/// DescriptionFormat represents the description-format rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct DescriptionFormat { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, - - /// Format represents the format of the description. - format: Option, +make_rule! { + DescriptionFormat, + "DescriptionFormat represents the description-format rule.", + #[doc = "Format represents the format of the description."] + format: Option } /// DescriptionFormat represents the description-format rule. diff --git a/cli/src/rule/description_max_length.rs b/cli/src/rule/description_max_length.rs index babed77..7478234 100644 --- a/cli/src/rule/description_max_length.rs +++ b/cli/src/rule/description_max_length.rs @@ -1,20 +1,11 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; +use crate::{make_length_rule, message::Message, result::Violation, rule::Rule}; use super::Level; -/// DescriptionMaxLength represents the description-max-length rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct DescriptionMaxLength { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, - - /// Length represents the maximum length of the description. - length: usize, +make_length_rule! { + DescriptionMaxLength, + "DescriptionMaxLength represents the description-max-length rule.", + "description" } /// DescriptionMaxLength represents the description-max-length rule. diff --git a/cli/src/rule/footers_empty.rs b/cli/src/rule/footers_empty.rs index f4970c3..9ed7c40 100644 --- a/cli/src/rule/footers_empty.rs +++ b/cli/src/rule/footers_empty.rs @@ -1,17 +1,9 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; +use crate::{make_rule, message::Message, result::Violation, rule::Rule}; use super::Level; - -/// FootersEmpty represents the footer-empty rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct FootersEmpty { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, +make_rule! { + FootersEmpty, + "FootersEmpty represents the footer-empty rule", } /// FooterEmpty represents the footer-empty rule. diff --git a/cspell.yml b/cspell.yml index 67e3333..a18bdb5 100644 --- a/cspell.yml +++ b/cspell.yml @@ -1 +1 @@ -words: [commitlint, schemars, commitlintrc, Keke] \ No newline at end of file +words: [commitlint, schemars, commitlintrc, Keke, insta, binstall, serde, Keisuke, astrojs, splitn] \ No newline at end of file From 5dbe770f768a295858ab8110947d0b8bb223103b Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 11:23:31 +0100 Subject: [PATCH 07/20] feat: add make_format_rule & make_options_rule --- cli/src/rule.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/cli/src/rule.rs b/cli/src/rule.rs index 5c6b094..514125a 100644 --- a/cli/src/rule.rs +++ b/cli/src/rule.rs @@ -255,6 +255,50 @@ macro_rules! make_length_rule { }; } +#[macro_export] +macro_rules! make_format_rule { + ( + $ident:ident, + $doc:expr, + $format_of_what:literal + ) => { + crate::make_rule! { + $ident, + $doc, + #[doc = concat!("Format represents the format of the ", stringify!(length_of_what), ".")] + format: Option + } + }; +} + +#[macro_export] +macro_rules! make_options_rule { + ( + $ident:ident, + $doc:expr, + $options_what: literal, + $( + $( + #[$field_meta:meta] + )* + $field_name:ident: $field_type:ty + ),*) => { + crate::make_rule! { + $ident, + $doc, + $( + $( + #[$field_meta] + )* + $field_name: $field_type, + + ),* + #[doc = concat!("Options represents the options of the rule. If the option is empty, it means that no ",stringify!(options_what)," is allowed.")] + options: Vec + } + }; +} + #[macro_export] macro_rules! make_rule { ( From 13f6bdeac1c778080112dde60206dbdbf242a9bc Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 11:27:28 +0100 Subject: [PATCH 08/20] feat: mig all rules to make_*_rule macro, sadly schemars 0.8 does not handle #[doc = ...], but let's see with v1 https://graham.cool/schemars/examples/6-doc_comments/ --- cli/json-schema/config.json | 23 +++++++---------------- cli/src/rule/description_format.rs | 9 ++++----- cli/src/rule/scope.rs | 29 ++++++++--------------------- cli/src/rule/scope_empty.rs | 16 ++++------------ cli/src/rule/scope_format.rs | 20 +++++--------------- cli/src/rule/scope_max_length.rs | 21 ++++++--------------- cli/src/rule/subject_empty.rs | 15 ++++----------- cli/src/rule/type.rs | 21 +++++---------------- cli/src/rule/type_empty.rs | 16 ++++------------ cli/src/rule/type_format.rs | 20 +++++--------------- cli/src/rule/type_max_length.rs | 19 +++++-------------- 11 files changed, 57 insertions(+), 152 deletions(-) diff --git a/cli/json-schema/config.json b/cli/json-schema/config.json index ef5191c..859b1a4 100644 --- a/cli/json-schema/config.json +++ b/cli/json-schema/config.json @@ -42,7 +42,6 @@ ], "properties": { "length": { - "description": "Length represents the maximum length of the body.", "type": "integer", "format": "uint", "minimum": 0.0 @@ -61,7 +60,7 @@ } }, "DescriptionEmpty": { - "description": "DescriptionEmpty represents the subject-empty rule.", + "description": "DescriptionEmpty represents the description-empty rule", "type": "object", "properties": { "level": { @@ -82,7 +81,6 @@ "type": "object", "properties": { "format": { - "description": "Format represents the format of the description.", "type": [ "string", "null" @@ -109,7 +107,6 @@ ], "properties": { "length": { - "description": "Length represents the maximum length of the description.", "type": "integer", "format": "uint", "minimum": 0.0 @@ -128,7 +125,7 @@ } }, "FootersEmpty": { - "description": "FootersEmpty represents the footer-empty rule.", + "description": "FootersEmpty represents the footer-empty rule", "type": "object", "properties": { "level": { @@ -310,7 +307,7 @@ } }, "Scope": { - "description": "Scope represents the subject-empty rule.", + "description": "Scope represents the subject rule.", "type": "object", "required": [ "optional", @@ -333,7 +330,6 @@ "type": "boolean" }, "options": { - "description": "Options represents the options of the rule. If the option is empty, it means that no scope is allowed.", "type": "array", "items": { "type": "string" @@ -342,7 +338,7 @@ } }, "ScopeEmpty": { - "description": "ScopeEmpty represents the subject-empty rule.", + "description": "FootersEmpty represents the subject-empty rule", "type": "object", "properties": { "level": { @@ -363,7 +359,6 @@ "type": "object", "properties": { "format": { - "description": "Format represents the format of the scope.", "type": [ "string", "null" @@ -383,14 +378,13 @@ } }, "ScopeMaxLength": { - "description": "ScopeMaxLength represents the description-max-length rule.", + "description": "ScopeMaxLength represents the scope-max-length rule.", "type": "object", "required": [ "length" ], "properties": { "length": { - "description": "Length represents the maximum length of the scope.", "type": "integer", "format": "uint", "minimum": 0.0 @@ -426,7 +420,7 @@ } }, "Type": { - "description": "Type represents the subject-empty rule.", + "description": "Type represents the type rule.", "type": "object", "required": [ "options" @@ -444,7 +438,6 @@ ] }, "options": { - "description": "Options represents the options of the rule. If the option is empty, it means that no Type is allowed.", "type": "array", "items": { "type": "string" @@ -474,7 +467,6 @@ "type": "object", "properties": { "format": { - "description": "Format represents the format of the type.", "type": [ "string", "null" @@ -494,14 +486,13 @@ } }, "TypeMaxLength": { - "description": "TypeMaxLength represents the description-max-length rule.", + "description": "TypeMaxLength represents the type-max-length rule.", "type": "object", "required": [ "length" ], "properties": { "length": { - "description": "Length represents the maximum length of the type.", "type": "integer", "format": "uint", "minimum": 0.0 diff --git a/cli/src/rule/description_format.rs b/cli/src/rule/description_format.rs index b410c4c..d5804df 100644 --- a/cli/src/rule/description_format.rs +++ b/cli/src/rule/description_format.rs @@ -1,11 +1,10 @@ -use crate::{make_rule, message::Message, result::Violation, rule::Rule}; - use super::Level; -make_rule! { +use crate::{make_format_rule, message::Message, result::Violation, rule::Rule}; + +make_format_rule! { DescriptionFormat, "DescriptionFormat represents the description-format rule.", - #[doc = "Format represents the format of the description."] - format: Option + "description" } /// DescriptionFormat represents the description-format rule. diff --git a/cli/src/rule/scope.rs b/cli/src/rule/scope.rs index 57bd7b5..3cc6deb 100644 --- a/cli/src/rule/scope.rs +++ b/cli/src/rule/scope.rs @@ -1,25 +1,12 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; - use super::Level; - -/// Scope represents the subject-empty rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct Scope { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, - - /// Options represents the options of the rule. - /// If the option is empty, it means that no scope is allowed. - options: Vec, - - /// Optional scope. - /// If true, even if the scope is not present, it is allowed. - optional: bool, +use crate::{make_options_rule, message::Message, result::Violation, rule::Rule}; + +make_options_rule! { + Scope, + "Scope represents the subject rule.", + "scope", + #[doc ="Optional scope. If true, even if the scope is not present, it is allowed."] + optional: bool } /// Scope represents the scope rule. diff --git a/cli/src/rule/scope_empty.rs b/cli/src/rule/scope_empty.rs index e2d0219..46bbc5f 100644 --- a/cli/src/rule/scope_empty.rs +++ b/cli/src/rule/scope_empty.rs @@ -1,17 +1,9 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; - use super::Level; +use crate::{make_rule, message::Message, result::Violation, rule::Rule}; -/// ScopeEmpty represents the subject-empty rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct ScopeEmpty { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, +make_rule! { + ScopeEmpty, + "FootersEmpty represents the subject-empty rule", } /// ScopeEmpty represents the scope-empty rule. diff --git a/cli/src/rule/scope_format.rs b/cli/src/rule/scope_format.rs index e567834..077c9fe 100644 --- a/cli/src/rule/scope_format.rs +++ b/cli/src/rule/scope_format.rs @@ -1,20 +1,10 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; +use crate::{make_format_rule, message::Message, result::Violation, rule::Rule}; use super::Level; - -/// ScopeFormat represents the scope-format rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct ScopeFormat { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, - - /// Format represents the format of the scope. - format: Option, +make_format_rule! { + ScopeFormat, + "ScopeFormat represents the scope-format rule.", + "scope" } /// ScopeFormat represents the scope-format rule. diff --git a/cli/src/rule/scope_max_length.rs b/cli/src/rule/scope_max_length.rs index f33da11..64ac003 100644 --- a/cli/src/rule/scope_max_length.rs +++ b/cli/src/rule/scope_max_length.rs @@ -1,21 +1,12 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; - use super::Level; +use crate::{make_length_rule, message::Message, result::Violation, rule::Rule}; -/// ScopeMaxLength represents the description-max-length rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct ScopeMaxLength { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, - - /// Length represents the maximum length of the scope. - length: usize, +make_length_rule! { + ScopeMaxLength, + "ScopeMaxLength represents the scope-max-length rule.", + "scope" } +/// ScopeMaxLength represents the description-max-length rule. /// ScopeMaxLength represents the scope-max-length rule. impl Rule for ScopeMaxLength { diff --git a/cli/src/rule/subject_empty.rs b/cli/src/rule/subject_empty.rs index 9b65adb..7c9bd43 100644 --- a/cli/src/rule/subject_empty.rs +++ b/cli/src/rule/subject_empty.rs @@ -1,17 +1,10 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; +use crate::{make_rule, message::Message, result::Violation, rule::Rule}; use super::Level; -/// SubjectEmpty represents the subject-empty rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct SubjectEmpty { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, +make_rule! { + SubjectEmpty, + "SubjectEmpty represents the subject-empty rule.", } /// SubjectEmpty represents the subject-empty rule. diff --git a/cli/src/rule/type.rs b/cli/src/rule/type.rs index 39599a0..e2ab6a5 100644 --- a/cli/src/rule/type.rs +++ b/cli/src/rule/type.rs @@ -1,21 +1,10 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; +use crate::{make_options_rule, message::Message, result::Violation, rule::Rule}; use super::Level; - -/// Type represents the subject-empty rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct Type { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, - - /// Options represents the options of the rule. - /// If the option is empty, it means that no Type is allowed. - options: Vec, +make_options_rule! { + Type, + "Type represents the type rule.", + "type", } /// Type represents the type rule. diff --git a/cli/src/rule/type_empty.rs b/cli/src/rule/type_empty.rs index f9e425b..d987910 100644 --- a/cli/src/rule/type_empty.rs +++ b/cli/src/rule/type_empty.rs @@ -1,17 +1,9 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; +use crate::{make_rule, message::Message, result::Violation, rule::Rule}; use super::Level; - -/// TypeEmpty represents the type-empty rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct TypeEmpty { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, +make_rule! { + TypeEmpty, + "TypeEmpty represents the type-empty rule.", } /// TypeEmpty represents the type-empty rule. diff --git a/cli/src/rule/type_format.rs b/cli/src/rule/type_format.rs index 364d017..2734c18 100644 --- a/cli/src/rule/type_format.rs +++ b/cli/src/rule/type_format.rs @@ -1,20 +1,10 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; +use crate::{make_format_rule, message::Message, result::Violation, rule::Rule}; use super::Level; - -/// TypeFormat represents the type-format rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct TypeFormat { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, - - /// Format represents the format of the type. - format: Option, +make_format_rule! { + TypeFormat, + "TypeFormat represents the type-format rule.", + "type" } /// TypeFormat represents the type-format rule. diff --git a/cli/src/rule/type_max_length.rs b/cli/src/rule/type_max_length.rs index 1df8dbb..8230c83 100644 --- a/cli/src/rule/type_max_length.rs +++ b/cli/src/rule/type_max_length.rs @@ -1,20 +1,11 @@ -use crate::{message::Message, result::Violation, rule::Rule}; -use serde::{Deserialize, Serialize}; +use crate::{make_length_rule, message::Message, result::Violation, rule::Rule}; use super::Level; -/// TypeMaxLength represents the description-max-length rule. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct TypeMaxLength { - /// Level represents the level of the rule. - /// - // Note that currently the default literal is not supported. - // See: https://github.com/serde-rs/serde/issues/368 - level: Option, - - /// Length represents the maximum length of the type. - length: usize, +make_length_rule! { + TypeMaxLength, + "TypeMaxLength represents the type-max-length rule.", + "type" } /// TypeMaxLength represents the type-max-length rule. From 1fecf548132ac1ee51f622aabe58f9afc0b39b15 Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 11:29:26 +0100 Subject: [PATCH 09/20] feat: use schemars v1 (alpha) to get the json schema descriptions out of #[doc] attributes --- Cargo.lock | 29 ++++++- cli/Cargo.toml | 2 +- cli/json-schema/config.json | 163 +++++++++++++++++++----------------- 3 files changed, 110 insertions(+), 84 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0fd57b9..9fcab0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -435,6 +435,26 @@ dependencies = [ "bitflags", ] +[[package]] +name = "ref-cast" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "regex" version = "1.11.1" @@ -478,11 +498,12 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "schemars" -version = "0.8.21" +version = "1.0.0-alpha.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" +checksum = "8e467e37661682d17a6db96cf0526f8a2ccf3a642d94624a9ba9a61a1f5ed729" dependencies = [ "dyn-clone", + "ref-cast", "schemars_derive", "serde", "serde_json", @@ -490,9 +511,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.21" +version = "1.0.0-alpha.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" +checksum = "e2af93b12c2850cd3231ca5194ffbfcbaa8a1c7e2bb550e5e8a3a77bcdb3ebec" dependencies = [ "proc-macro2", "quote", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index a451538..b6ca35f 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -17,7 +17,7 @@ edition.workspace = true clap = { version = "4.5.4", features = ["derive", "env", "string"] } futures = "0.3.30" regex = "1.10.5" -schemars = { version = "0.8.21", optional = true } +schemars = { version = "1.0.0-alpha.16", optional = true } serde = { version = "1.0.201", features = ["derive"] } serde_json = "1.0.121" serde_yaml = "0.9.34" diff --git a/cli/json-schema/config.json b/cli/json-schema/config.json index 859b1a4..c550b47 100644 --- a/cli/json-schema/config.json +++ b/cli/json-schema/config.json @@ -1,22 +1,18 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Config", "description": "Config represents the configuration of commitlint.", "type": "object", - "required": [ - "rules" - ], "properties": { "rules": { "description": "Rules represents the rules of commitlint.", - "allOf": [ - { - "$ref": "#/definitions/Rules" - } - ] + "$ref": "#/$defs/Rules" } }, - "definitions": { + "required": [ + "rules" + ], + "$defs": { "BodyEmpty": { "description": "BodyEmpty represents the body-empty rule.", "type": "object", @@ -25,7 +21,7 @@ "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" @@ -37,27 +33,28 @@ "BodyMaxLength": { "description": "BodyMaxLength represents the body-max-length rule.", "type": "object", - "required": [ - "length" - ], "properties": { "length": { + "description": "Length represents the maximum length of the length_of_what.", "type": "integer", "format": "uint", - "minimum": 0.0 + "minimum": 0 }, "level": { "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" } ] } - } + }, + "required": [ + "length" + ] }, "DescriptionEmpty": { "description": "DescriptionEmpty represents the description-empty rule", @@ -67,7 +64,7 @@ "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" @@ -81,6 +78,7 @@ "type": "object", "properties": { "format": { + "description": "Format represents the format of the length_of_what.", "type": [ "string", "null" @@ -90,7 +88,7 @@ "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" @@ -102,27 +100,28 @@ "DescriptionMaxLength": { "description": "DescriptionMaxLength represents the description-max-length rule.", "type": "object", - "required": [ - "length" - ], "properties": { "length": { + "description": "Length represents the maximum length of the length_of_what.", "type": "integer", "format": "uint", - "minimum": 0.0 + "minimum": 0 }, "level": { "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" } ] } - } + }, + "required": [ + "length" + ] }, "FootersEmpty": { "description": "FootersEmpty represents the footer-empty rule", @@ -132,7 +131,7 @@ "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" @@ -151,13 +150,23 @@ ] }, "Rules": { - "description": "Rules represents the rules of commitlint. See: https://commitlint.js.org/reference/rules.html", + "description": "Rules represents the rules of commitlint.\n See: https://commitlint.js.org/reference/rules.html", "type": "object", "properties": { + "type": { + "anyOf": [ + { + "$ref": "#/$defs/Type" + }, + { + "type": "null" + } + ] + }, "body-empty": { "anyOf": [ { - "$ref": "#/definitions/BodyEmpty" + "$ref": "#/$defs/BodyEmpty" }, { "type": "null" @@ -167,7 +176,7 @@ "body-max-length": { "anyOf": [ { - "$ref": "#/definitions/BodyMaxLength" + "$ref": "#/$defs/BodyMaxLength" }, { "type": "null" @@ -177,7 +186,7 @@ "description-empty": { "anyOf": [ { - "$ref": "#/definitions/DescriptionEmpty" + "$ref": "#/$defs/DescriptionEmpty" }, { "type": "null" @@ -187,7 +196,7 @@ "description-format": { "anyOf": [ { - "$ref": "#/definitions/DescriptionFormat" + "$ref": "#/$defs/DescriptionFormat" }, { "type": "null" @@ -197,7 +206,7 @@ "description-max-length": { "anyOf": [ { - "$ref": "#/definitions/DescriptionMaxLength" + "$ref": "#/$defs/DescriptionMaxLength" }, { "type": "null" @@ -207,7 +216,7 @@ "footers-empty": { "anyOf": [ { - "$ref": "#/definitions/FootersEmpty" + "$ref": "#/$defs/FootersEmpty" }, { "type": "null" @@ -217,7 +226,7 @@ "scope": { "anyOf": [ { - "$ref": "#/definitions/Scope" + "$ref": "#/$defs/Scope" }, { "type": "null" @@ -227,7 +236,7 @@ "scope-empty": { "anyOf": [ { - "$ref": "#/definitions/ScopeEmpty" + "$ref": "#/$defs/ScopeEmpty" }, { "type": "null" @@ -237,7 +246,7 @@ "scope-format": { "anyOf": [ { - "$ref": "#/definitions/ScopeFormat" + "$ref": "#/$defs/ScopeFormat" }, { "type": "null" @@ -247,7 +256,7 @@ "scope-max-length": { "anyOf": [ { - "$ref": "#/definitions/ScopeMaxLength" + "$ref": "#/$defs/ScopeMaxLength" }, { "type": "null" @@ -257,17 +266,7 @@ "subject-empty": { "anyOf": [ { - "$ref": "#/definitions/SubjectEmpty" - }, - { - "type": "null" - } - ] - }, - "type": { - "anyOf": [ - { - "$ref": "#/definitions/Type" + "$ref": "#/$defs/SubjectEmpty" }, { "type": "null" @@ -277,7 +276,7 @@ "type-empty": { "anyOf": [ { - "$ref": "#/definitions/TypeEmpty" + "$ref": "#/$defs/TypeEmpty" }, { "type": "null" @@ -287,7 +286,7 @@ "type-format": { "anyOf": [ { - "$ref": "#/definitions/TypeFormat" + "$ref": "#/$defs/TypeFormat" }, { "type": "null" @@ -297,7 +296,7 @@ "type-max-length": { "anyOf": [ { - "$ref": "#/definitions/TypeMaxLength" + "$ref": "#/$defs/TypeMaxLength" }, { "type": "null" @@ -309,16 +308,12 @@ "Scope": { "description": "Scope represents the subject rule.", "type": "object", - "required": [ - "optional", - "options" - ], "properties": { "level": { "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" @@ -330,12 +325,17 @@ "type": "boolean" }, "options": { + "description": "Options represents the options of the rule. If the option is empty, it means that no options_what is allowed.", "type": "array", "items": { "type": "string" } } - } + }, + "required": [ + "optional", + "options" + ] }, "ScopeEmpty": { "description": "FootersEmpty represents the subject-empty rule", @@ -345,7 +345,7 @@ "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" @@ -359,6 +359,7 @@ "type": "object", "properties": { "format": { + "description": "Format represents the format of the length_of_what.", "type": [ "string", "null" @@ -368,7 +369,7 @@ "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" @@ -380,27 +381,28 @@ "ScopeMaxLength": { "description": "ScopeMaxLength represents the scope-max-length rule.", "type": "object", - "required": [ - "length" - ], "properties": { "length": { + "description": "Length represents the maximum length of the length_of_what.", "type": "integer", "format": "uint", - "minimum": 0.0 + "minimum": 0 }, "level": { "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" } ] } - } + }, + "required": [ + "length" + ] }, "SubjectEmpty": { "description": "SubjectEmpty represents the subject-empty rule.", @@ -410,7 +412,7 @@ "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" @@ -422,15 +424,12 @@ "Type": { "description": "Type represents the type rule.", "type": "object", - "required": [ - "options" - ], "properties": { "level": { "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" @@ -438,12 +437,16 @@ ] }, "options": { + "description": "Options represents the options of the rule. If the option is empty, it means that no options_what is allowed.", "type": "array", "items": { "type": "string" } } - } + }, + "required": [ + "options" + ] }, "TypeEmpty": { "description": "TypeEmpty represents the type-empty rule.", @@ -453,7 +456,7 @@ "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" @@ -467,6 +470,7 @@ "type": "object", "properties": { "format": { + "description": "Format represents the format of the length_of_what.", "type": [ "string", "null" @@ -476,7 +480,7 @@ "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" @@ -488,27 +492,28 @@ "TypeMaxLength": { "description": "TypeMaxLength represents the type-max-length rule.", "type": "object", - "required": [ - "length" - ], "properties": { "length": { + "description": "Length represents the maximum length of the length_of_what.", "type": "integer", "format": "uint", - "minimum": 0.0 + "minimum": 0 }, "level": { "description": "Level represents the level of the rule.", "anyOf": [ { - "$ref": "#/definitions/Level" + "$ref": "#/$defs/Level" }, { "type": "null" } ] } - } + }, + "required": [ + "length" + ] } } } \ No newline at end of file From f7f3ad3049eda4d34314171cacf99d0a83e37a77 Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 11:32:01 +0100 Subject: [PATCH 10/20] test: use insta to assert_yaml_snapshot on config json schema --- cli/Cargo.toml | 6 + cli/src/config.rs | 3 +- ...__config__tests__generate_json_schema.snap | 283 ++++++++++++++++++ 3 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap diff --git a/cli/Cargo.toml b/cli/Cargo.toml index b6ca35f..83c6851 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -33,3 +33,9 @@ pkg-url = "{ repo }/releases/download/v{ version }/commitlint-v{ version }-{ tar [features] schemars = ["dep:schemars"] default = [] + +[dev-dependencies] +insta = { version = "1.41.1", features = ["yaml"] } +[profile.dev.package] +insta.opt-level = 3 +similar.opt-level = 3 diff --git a/cli/src/config.rs b/cli/src/config.rs index 8c96e68..6f252ff 100644 --- a/cli/src/config.rs +++ b/cli/src/config.rs @@ -129,13 +129,14 @@ async fn load_unknown_config_file(path: PathBuf) -> Result { mod tests { #[cfg(feature = "schemars")] #[test] - // TODO assert insta snapshot fn generate_json_schema() { use crate::config::Config; + use insta::assert_yaml_snapshot; use std::fs; let config_schema = schemars::schema_for!(Config); let config_schema_json = serde_json::to_string_pretty(&config_schema).unwrap(); + assert_yaml_snapshot!(config_schema); fs::write("json-schema/config.json", config_schema_json).unwrap(); } } diff --git a/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap b/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap new file mode 100644 index 0000000..9c6985f --- /dev/null +++ b/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap @@ -0,0 +1,283 @@ +--- +source: cli/src/config.rs +expression: config_schema +snapshot_kind: text +--- +$schema: "https://json-schema.org/draft/2020-12/schema" +title: Config +description: Config represents the configuration of commitlint. +type: object +properties: + rules: + description: Rules represents the rules of commitlint. + $ref: "#/$defs/Rules" +required: + - rules +$defs: + BodyEmpty: + description: BodyEmpty represents the body-empty rule. + type: object + properties: + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + BodyMaxLength: + description: BodyMaxLength represents the body-max-length rule. + type: object + properties: + length: + description: Length represents the maximum length of the length_of_what. + type: integer + format: uint + minimum: 0 + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + required: + - length + DescriptionEmpty: + description: DescriptionEmpty represents the description-empty rule + type: object + properties: + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + DescriptionFormat: + description: DescriptionFormat represents the description-format rule. + type: object + properties: + format: + description: Format represents the format of the length_of_what. + type: + - string + - "null" + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + DescriptionMaxLength: + description: DescriptionMaxLength represents the description-max-length rule. + type: object + properties: + length: + description: Length represents the maximum length of the length_of_what. + type: integer + format: uint + minimum: 0 + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + required: + - length + FootersEmpty: + description: FootersEmpty represents the footer-empty rule + type: object + properties: + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + Level: + description: Level represents the level of a rule. + type: string + enum: + - error + - ignore + - warning + Rules: + description: "Rules represents the rules of commitlint.\n See: https://commitlint.js.org/reference/rules.html" + type: object + properties: + type: + anyOf: + - $ref: "#/$defs/Type" + - type: "null" + body-empty: + anyOf: + - $ref: "#/$defs/BodyEmpty" + - type: "null" + body-max-length: + anyOf: + - $ref: "#/$defs/BodyMaxLength" + - type: "null" + description-empty: + anyOf: + - $ref: "#/$defs/DescriptionEmpty" + - type: "null" + description-format: + anyOf: + - $ref: "#/$defs/DescriptionFormat" + - type: "null" + description-max-length: + anyOf: + - $ref: "#/$defs/DescriptionMaxLength" + - type: "null" + footers-empty: + anyOf: + - $ref: "#/$defs/FootersEmpty" + - type: "null" + scope: + anyOf: + - $ref: "#/$defs/Scope" + - type: "null" + scope-empty: + anyOf: + - $ref: "#/$defs/ScopeEmpty" + - type: "null" + scope-format: + anyOf: + - $ref: "#/$defs/ScopeFormat" + - type: "null" + scope-max-length: + anyOf: + - $ref: "#/$defs/ScopeMaxLength" + - type: "null" + subject-empty: + anyOf: + - $ref: "#/$defs/SubjectEmpty" + - type: "null" + type-empty: + anyOf: + - $ref: "#/$defs/TypeEmpty" + - type: "null" + type-format: + anyOf: + - $ref: "#/$defs/TypeFormat" + - type: "null" + type-max-length: + anyOf: + - $ref: "#/$defs/TypeMaxLength" + - type: "null" + Scope: + description: Scope represents the subject rule. + type: object + properties: + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + optional: + description: "Optional scope. If true, even if the scope is not present, it is allowed." + type: boolean + options: + description: "Options represents the options of the rule. If the option is empty, it means that no options_what is allowed." + type: array + items: + type: string + required: + - optional + - options + ScopeEmpty: + description: FootersEmpty represents the subject-empty rule + type: object + properties: + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + ScopeFormat: + description: ScopeFormat represents the scope-format rule. + type: object + properties: + format: + description: Format represents the format of the length_of_what. + type: + - string + - "null" + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + ScopeMaxLength: + description: ScopeMaxLength represents the scope-max-length rule. + type: object + properties: + length: + description: Length represents the maximum length of the length_of_what. + type: integer + format: uint + minimum: 0 + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + required: + - length + SubjectEmpty: + description: SubjectEmpty represents the subject-empty rule. + type: object + properties: + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + Type: + description: Type represents the type rule. + type: object + properties: + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + options: + description: "Options represents the options of the rule. If the option is empty, it means that no options_what is allowed." + type: array + items: + type: string + required: + - options + TypeEmpty: + description: TypeEmpty represents the type-empty rule. + type: object + properties: + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + TypeFormat: + description: TypeFormat represents the type-format rule. + type: object + properties: + format: + description: Format represents the format of the length_of_what. + type: + - string + - "null" + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + TypeMaxLength: + description: TypeMaxLength represents the type-max-length rule. + type: object + properties: + length: + description: Length represents the maximum length of the length_of_what. + type: integer + format: uint + minimum: 0 + level: + description: Level represents the level of the rule. + anyOf: + - $ref: "#/$defs/Level" + - type: "null" + required: + - length From 446d582e89524af753031b3e2f3d5ca10cde9d04 Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 11:32:32 +0100 Subject: [PATCH 11/20] fix: lockfile --- Cargo.lock | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 9fcab0f..5f5f5e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,6 +166,7 @@ version = "0.2.0" dependencies = [ "clap", "futures", + "insta", "regex", "schemars", "serde", @@ -174,12 +175,30 @@ dependencies = [ "tokio", ] +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "dyn-clone" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "equivalent" version = "1.0.1" @@ -309,6 +328,19 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "insta" +version = "1.41.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e9ffc4d4892617c50a928c52b2961cb5174b6fc6ebf252b2fac9d21955c48b8" +dependencies = [ + "console", + "lazy_static", + "linked-hash-map", + "serde", + "similar", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -321,12 +353,24 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "lock_api" version = "0.4.12" @@ -592,6 +636,12 @@ dependencies = [ "libc", ] +[[package]] +name = "similar" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" + [[package]] name = "slab" version = "0.4.9" From b9aa496ec037fc250fa1c6b2bfa1d07256780738 Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 11:55:14 +0100 Subject: [PATCH 12/20] feat: use paste to generate all rule structs doc attr, unfortunately can not convert to dash-case only snake_case --- Cargo.lock | 7 +++++++ cli/Cargo.toml | 2 +- cli/src/rule.rs | 18 ++++++------------ cli/src/rule/body_empty.rs | 1 - cli/src/rule/body_max_length.rs | 1 - cli/src/rule/description_empty.rs | 1 - cli/src/rule/description_format.rs | 1 - cli/src/rule/description_max_length.rs | 1 - cli/src/rule/footers_empty.rs | 1 - cli/src/rule/scope.rs | 1 - cli/src/rule/scope_empty.rs | 1 - cli/src/rule/scope_format.rs | 1 - cli/src/rule/scope_max_length.rs | 1 - cli/src/rule/subject_empty.rs | 1 - cli/src/rule/type.rs | 1 - cli/src/rule/type_empty.rs | 1 - cli/src/rule/type_format.rs | 1 - cli/src/rule/type_max_length.rs | 1 - 18 files changed, 14 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f5f5e5..01ed1ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -167,6 +167,7 @@ dependencies = [ "clap", "futures", "insta", + "paste", "regex", "schemars", "serde", @@ -440,6 +441,12 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "pin-project-lite" version = "0.2.15" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 83c6851..83b02a6 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -22,7 +22,7 @@ serde = { version = "1.0.201", features = ["derive"] } serde_json = "1.0.121" serde_yaml = "0.9.34" tokio = { version = "1.37.0", features = ["full"] } - +paste = "1.0.15" [[bin]] name = "commitlint" diff --git a/cli/src/rule.rs b/cli/src/rule.rs index 514125a..e248675 100644 --- a/cli/src/rule.rs +++ b/cli/src/rule.rs @@ -1,7 +1,6 @@ -use std::fmt::Debug; - use crate::{message::Message, result::Violation}; use serde::{Deserialize, Serialize}; +use std::fmt::Debug; use self::{ body_empty::BodyEmpty, body_max_length::BodyMaxLength, description_empty::DescriptionEmpty, @@ -243,12 +242,10 @@ pub enum Level { macro_rules! make_length_rule { ( $ident:ident, - $doc:expr, $length_of_what:literal ) => { crate::make_rule! { $ident, - $doc, #[doc = concat!("Length represents the maximum length of the ", stringify!(length_of_what), ".")] length: usize } @@ -259,12 +256,10 @@ macro_rules! make_length_rule { macro_rules! make_format_rule { ( $ident:ident, - $doc:expr, $format_of_what:literal ) => { crate::make_rule! { $ident, - $doc, #[doc = concat!("Format represents the format of the ", stringify!(length_of_what), ".")] format: Option } @@ -275,7 +270,6 @@ macro_rules! make_format_rule { macro_rules! make_options_rule { ( $ident:ident, - $doc:expr, $options_what: literal, $( $( @@ -285,7 +279,6 @@ macro_rules! make_options_rule { ),*) => { crate::make_rule! { $ident, - $doc, $( $( #[$field_meta] @@ -303,14 +296,14 @@ macro_rules! make_options_rule { macro_rules! make_rule { ( $ident:ident, - $doc:expr, $( $( #[$field_meta:meta] )* $field_name:ident: $field_type:ty - ),*) => { - #[doc = $doc] + ),*) => { paste::paste! { + + #[doc = concat!(stringify!($ident), "represents the ", stringify!([<$ident:snake>])," rule.")] #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct $ident { @@ -326,5 +319,6 @@ macro_rules! make_rule { $field_name: $field_type ),* } - }; + } +}; } diff --git a/cli/src/rule/body_empty.rs b/cli/src/rule/body_empty.rs index 13cd70d..097dca8 100644 --- a/cli/src/rule/body_empty.rs +++ b/cli/src/rule/body_empty.rs @@ -3,7 +3,6 @@ use crate::{make_rule, message::Message, result::Violation, rule::Rule}; make_rule! { BodyEmpty, - "BodyEmpty represents the body-empty rule.", } /// BodyEmpty represents the body-empty rule. diff --git a/cli/src/rule/body_max_length.rs b/cli/src/rule/body_max_length.rs index 3035d7f..cf3a66e 100644 --- a/cli/src/rule/body_max_length.rs +++ b/cli/src/rule/body_max_length.rs @@ -3,7 +3,6 @@ use crate::{make_length_rule, message::Message, result::Violation, rule::Rule}; use super::Level; make_length_rule! { BodyMaxLength, - "BodyMaxLength represents the body-max-length rule.", "body" } diff --git a/cli/src/rule/description_empty.rs b/cli/src/rule/description_empty.rs index 8b973a3..b3d964c 100644 --- a/cli/src/rule/description_empty.rs +++ b/cli/src/rule/description_empty.rs @@ -3,7 +3,6 @@ use crate::{make_rule, message::Message, result::Violation, rule::Rule}; use super::Level; make_rule! { DescriptionEmpty, - "DescriptionEmpty represents the description-empty rule", } /// DescriptionEmpty represents the description-empty rule. diff --git a/cli/src/rule/description_format.rs b/cli/src/rule/description_format.rs index d5804df..cae74d5 100644 --- a/cli/src/rule/description_format.rs +++ b/cli/src/rule/description_format.rs @@ -3,7 +3,6 @@ use crate::{make_format_rule, message::Message, result::Violation, rule::Rule}; make_format_rule! { DescriptionFormat, - "DescriptionFormat represents the description-format rule.", "description" } diff --git a/cli/src/rule/description_max_length.rs b/cli/src/rule/description_max_length.rs index 7478234..0d9d7b6 100644 --- a/cli/src/rule/description_max_length.rs +++ b/cli/src/rule/description_max_length.rs @@ -4,7 +4,6 @@ use super::Level; make_length_rule! { DescriptionMaxLength, - "DescriptionMaxLength represents the description-max-length rule.", "description" } diff --git a/cli/src/rule/footers_empty.rs b/cli/src/rule/footers_empty.rs index 9ed7c40..966be42 100644 --- a/cli/src/rule/footers_empty.rs +++ b/cli/src/rule/footers_empty.rs @@ -3,7 +3,6 @@ use crate::{make_rule, message::Message, result::Violation, rule::Rule}; use super::Level; make_rule! { FootersEmpty, - "FootersEmpty represents the footer-empty rule", } /// FooterEmpty represents the footer-empty rule. diff --git a/cli/src/rule/scope.rs b/cli/src/rule/scope.rs index 3cc6deb..dcf7beb 100644 --- a/cli/src/rule/scope.rs +++ b/cli/src/rule/scope.rs @@ -3,7 +3,6 @@ use crate::{make_options_rule, message::Message, result::Violation, rule::Rule}; make_options_rule! { Scope, - "Scope represents the subject rule.", "scope", #[doc ="Optional scope. If true, even if the scope is not present, it is allowed."] optional: bool diff --git a/cli/src/rule/scope_empty.rs b/cli/src/rule/scope_empty.rs index 46bbc5f..ec553c1 100644 --- a/cli/src/rule/scope_empty.rs +++ b/cli/src/rule/scope_empty.rs @@ -3,7 +3,6 @@ use crate::{make_rule, message::Message, result::Violation, rule::Rule}; make_rule! { ScopeEmpty, - "FootersEmpty represents the subject-empty rule", } /// ScopeEmpty represents the scope-empty rule. diff --git a/cli/src/rule/scope_format.rs b/cli/src/rule/scope_format.rs index 077c9fe..cc2c0ff 100644 --- a/cli/src/rule/scope_format.rs +++ b/cli/src/rule/scope_format.rs @@ -3,7 +3,6 @@ use crate::{make_format_rule, message::Message, result::Violation, rule::Rule}; use super::Level; make_format_rule! { ScopeFormat, - "ScopeFormat represents the scope-format rule.", "scope" } diff --git a/cli/src/rule/scope_max_length.rs b/cli/src/rule/scope_max_length.rs index 64ac003..b396ae5 100644 --- a/cli/src/rule/scope_max_length.rs +++ b/cli/src/rule/scope_max_length.rs @@ -3,7 +3,6 @@ use crate::{make_length_rule, message::Message, result::Violation, rule::Rule}; make_length_rule! { ScopeMaxLength, - "ScopeMaxLength represents the scope-max-length rule.", "scope" } /// ScopeMaxLength represents the description-max-length rule. diff --git a/cli/src/rule/subject_empty.rs b/cli/src/rule/subject_empty.rs index 7c9bd43..f5d6235 100644 --- a/cli/src/rule/subject_empty.rs +++ b/cli/src/rule/subject_empty.rs @@ -4,7 +4,6 @@ use super::Level; make_rule! { SubjectEmpty, - "SubjectEmpty represents the subject-empty rule.", } /// SubjectEmpty represents the subject-empty rule. diff --git a/cli/src/rule/type.rs b/cli/src/rule/type.rs index e2ab6a5..b4158d3 100644 --- a/cli/src/rule/type.rs +++ b/cli/src/rule/type.rs @@ -3,7 +3,6 @@ use crate::{make_options_rule, message::Message, result::Violation, rule::Rule}; use super::Level; make_options_rule! { Type, - "Type represents the type rule.", "type", } diff --git a/cli/src/rule/type_empty.rs b/cli/src/rule/type_empty.rs index d987910..31881e0 100644 --- a/cli/src/rule/type_empty.rs +++ b/cli/src/rule/type_empty.rs @@ -3,7 +3,6 @@ use crate::{make_rule, message::Message, result::Violation, rule::Rule}; use super::Level; make_rule! { TypeEmpty, - "TypeEmpty represents the type-empty rule.", } /// TypeEmpty represents the type-empty rule. diff --git a/cli/src/rule/type_format.rs b/cli/src/rule/type_format.rs index 2734c18..4f65b2a 100644 --- a/cli/src/rule/type_format.rs +++ b/cli/src/rule/type_format.rs @@ -3,7 +3,6 @@ use crate::{make_format_rule, message::Message, result::Violation, rule::Rule}; use super::Level; make_format_rule! { TypeFormat, - "TypeFormat represents the type-format rule.", "type" } diff --git a/cli/src/rule/type_max_length.rs b/cli/src/rule/type_max_length.rs index 8230c83..f7a71fa 100644 --- a/cli/src/rule/type_max_length.rs +++ b/cli/src/rule/type_max_length.rs @@ -4,7 +4,6 @@ use super::Level; make_length_rule! { TypeMaxLength, - "TypeMaxLength represents the type-max-length rule.", "type" } From 5c099497ae7cca570770f61ec5b5e5845a93318b Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 12:13:00 +0100 Subject: [PATCH 13/20] docs: doc macro rules --- Cargo.toml | 3 ++ cli/Cargo.toml | 3 -- cli/json-schema/config.json | 28 +++++++++---------- cli/src/rule.rs | 8 ++++-- ...__config__tests__generate_json_schema.snap | 28 +++++++++---------- 5 files changed, 36 insertions(+), 34 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6d58bc5..0e6ef3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,6 @@ readme = "README.md" repository = "https://github.com/KeisukeYamashita/commitlint-rs" exclude = ["/web"] edition = "2021" +[profile.dev.package] +insta.opt-level = 3 +similar.opt-level = 3 diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 83b02a6..03dedc1 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -36,6 +36,3 @@ default = [] [dev-dependencies] insta = { version = "1.41.1", features = ["yaml"] } -[profile.dev.package] -insta.opt-level = 3 -similar.opt-level = 3 diff --git a/cli/json-schema/config.json b/cli/json-schema/config.json index c550b47..7f073a9 100644 --- a/cli/json-schema/config.json +++ b/cli/json-schema/config.json @@ -14,7 +14,7 @@ ], "$defs": { "BodyEmpty": { - "description": "BodyEmpty represents the body-empty rule.", + "description": "BodyEmpty represents the body_empty rule.", "type": "object", "properties": { "level": { @@ -31,7 +31,7 @@ } }, "BodyMaxLength": { - "description": "BodyMaxLength represents the body-max-length rule.", + "description": "BodyMaxLength represents the body_max_length rule.", "type": "object", "properties": { "length": { @@ -57,7 +57,7 @@ ] }, "DescriptionEmpty": { - "description": "DescriptionEmpty represents the description-empty rule", + "description": "DescriptionEmpty represents the description_empty rule.", "type": "object", "properties": { "level": { @@ -74,7 +74,7 @@ } }, "DescriptionFormat": { - "description": "DescriptionFormat represents the description-format rule.", + "description": "DescriptionFormat represents the description_format rule.", "type": "object", "properties": { "format": { @@ -98,7 +98,7 @@ } }, "DescriptionMaxLength": { - "description": "DescriptionMaxLength represents the description-max-length rule.", + "description": "DescriptionMaxLength represents the description_max_length rule.", "type": "object", "properties": { "length": { @@ -124,7 +124,7 @@ ] }, "FootersEmpty": { - "description": "FootersEmpty represents the footer-empty rule", + "description": "FootersEmpty represents the footers_empty rule.", "type": "object", "properties": { "level": { @@ -306,7 +306,7 @@ } }, "Scope": { - "description": "Scope represents the subject rule.", + "description": "Scope represents the scope rule.", "type": "object", "properties": { "level": { @@ -338,7 +338,7 @@ ] }, "ScopeEmpty": { - "description": "FootersEmpty represents the subject-empty rule", + "description": "ScopeEmpty represents the scope_empty rule.", "type": "object", "properties": { "level": { @@ -355,7 +355,7 @@ } }, "ScopeFormat": { - "description": "ScopeFormat represents the scope-format rule.", + "description": "ScopeFormat represents the scope_format rule.", "type": "object", "properties": { "format": { @@ -379,7 +379,7 @@ } }, "ScopeMaxLength": { - "description": "ScopeMaxLength represents the scope-max-length rule.", + "description": "ScopeMaxLength represents the scope_max_length rule.", "type": "object", "properties": { "length": { @@ -405,7 +405,7 @@ ] }, "SubjectEmpty": { - "description": "SubjectEmpty represents the subject-empty rule.", + "description": "SubjectEmpty represents the subject_empty rule.", "type": "object", "properties": { "level": { @@ -449,7 +449,7 @@ ] }, "TypeEmpty": { - "description": "TypeEmpty represents the type-empty rule.", + "description": "TypeEmpty represents the type_empty rule.", "type": "object", "properties": { "level": { @@ -466,7 +466,7 @@ } }, "TypeFormat": { - "description": "TypeFormat represents the type-format rule.", + "description": "TypeFormat represents the type_format rule.", "type": "object", "properties": { "format": { @@ -490,7 +490,7 @@ } }, "TypeMaxLength": { - "description": "TypeMaxLength represents the type-max-length rule.", + "description": "TypeMaxLength represents the type_max_length rule.", "type": "object", "properties": { "length": { diff --git a/cli/src/rule.rs b/cli/src/rule.rs index e248675..f86a632 100644 --- a/cli/src/rule.rs +++ b/cli/src/rule.rs @@ -238,6 +238,7 @@ pub enum Level { #[serde(rename = "warning")] Warning, } +/// Create a struct with length field that should impl [Rule] #[macro_export] macro_rules! make_length_rule { ( @@ -251,7 +252,7 @@ macro_rules! make_length_rule { } }; } - +/// Create a struct with format field that should impl [Rule] #[macro_export] macro_rules! make_format_rule { ( @@ -265,7 +266,7 @@ macro_rules! make_format_rule { } }; } - +/// Create a struct with options field that should impl [Rule] #[macro_export] macro_rules! make_options_rule { ( @@ -292,6 +293,7 @@ macro_rules! make_options_rule { }; } +/// Create a struct that should impl [Rule] #[macro_export] macro_rules! make_rule { ( @@ -303,7 +305,7 @@ macro_rules! make_rule { $field_name:ident: $field_type:ty ),*) => { paste::paste! { - #[doc = concat!(stringify!($ident), "represents the ", stringify!([<$ident:snake>])," rule.")] + #[doc = concat!(stringify!($ident), " represents the ", stringify!([<$ident:snake>])," rule.")] #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct $ident { diff --git a/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap b/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap index 9c6985f..c51135d 100644 --- a/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap +++ b/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap @@ -15,7 +15,7 @@ required: - rules $defs: BodyEmpty: - description: BodyEmpty represents the body-empty rule. + description: BodyEmpty represents the body_empty rule. type: object properties: level: @@ -24,7 +24,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" BodyMaxLength: - description: BodyMaxLength represents the body-max-length rule. + description: BodyMaxLength represents the body_max_length rule. type: object properties: length: @@ -40,7 +40,7 @@ $defs: required: - length DescriptionEmpty: - description: DescriptionEmpty represents the description-empty rule + description: DescriptionEmpty represents the description_empty rule. type: object properties: level: @@ -49,7 +49,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" DescriptionFormat: - description: DescriptionFormat represents the description-format rule. + description: DescriptionFormat represents the description_format rule. type: object properties: format: @@ -63,7 +63,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" DescriptionMaxLength: - description: DescriptionMaxLength represents the description-max-length rule. + description: DescriptionMaxLength represents the description_max_length rule. type: object properties: length: @@ -79,7 +79,7 @@ $defs: required: - length FootersEmpty: - description: FootersEmpty represents the footer-empty rule + description: FootersEmpty represents the footers_empty rule. type: object properties: level: @@ -159,7 +159,7 @@ $defs: - $ref: "#/$defs/TypeMaxLength" - type: "null" Scope: - description: Scope represents the subject rule. + description: Scope represents the scope rule. type: object properties: level: @@ -179,7 +179,7 @@ $defs: - optional - options ScopeEmpty: - description: FootersEmpty represents the subject-empty rule + description: ScopeEmpty represents the scope_empty rule. type: object properties: level: @@ -188,7 +188,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" ScopeFormat: - description: ScopeFormat represents the scope-format rule. + description: ScopeFormat represents the scope_format rule. type: object properties: format: @@ -202,7 +202,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" ScopeMaxLength: - description: ScopeMaxLength represents the scope-max-length rule. + description: ScopeMaxLength represents the scope_max_length rule. type: object properties: length: @@ -218,7 +218,7 @@ $defs: required: - length SubjectEmpty: - description: SubjectEmpty represents the subject-empty rule. + description: SubjectEmpty represents the subject_empty rule. type: object properties: level: @@ -243,7 +243,7 @@ $defs: required: - options TypeEmpty: - description: TypeEmpty represents the type-empty rule. + description: TypeEmpty represents the type_empty rule. type: object properties: level: @@ -252,7 +252,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" TypeFormat: - description: TypeFormat represents the type-format rule. + description: TypeFormat represents the type_format rule. type: object properties: format: @@ -266,7 +266,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" TypeMaxLength: - description: TypeMaxLength represents the type-max-length rule. + description: TypeMaxLength represents the type_max_length rule. type: object properties: length: From 307ac78377d38c983aef63756ca0fca67c676db7 Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 12:14:58 +0100 Subject: [PATCH 14/20] chore: fmt --- cli/src/rule/scope.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/rule/scope.rs b/cli/src/rule/scope.rs index dcf7beb..cdecc9b 100644 --- a/cli/src/rule/scope.rs +++ b/cli/src/rule/scope.rs @@ -4,7 +4,7 @@ use crate::{make_options_rule, message::Message, result::Violation, rule::Rule}; make_options_rule! { Scope, "scope", - #[doc ="Optional scope. If true, even if the scope is not present, it is allowed."] + #[doc = "Optional scope. If true, even if the scope is not present, it is allowed."] optional: bool } From a78b8fe5bcff272f07dc2f3a73eb0a23f1a28e7e Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 12:23:33 +0100 Subject: [PATCH 15/20] fix: make_length_rule & make_format_rule & make_options_rule generating incorrect docs --- cli/json-schema/config.json | 18 +++++++++--------- cli/src/rule.rs | 6 +++--- ...t__config__tests__generate_json_schema.snap | 18 +++++++++--------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/cli/json-schema/config.json b/cli/json-schema/config.json index 7f073a9..3a4af31 100644 --- a/cli/json-schema/config.json +++ b/cli/json-schema/config.json @@ -35,7 +35,7 @@ "type": "object", "properties": { "length": { - "description": "Length represents the maximum length of the length_of_what.", + "description": "Length represents the maximum length of the \"body\".", "type": "integer", "format": "uint", "minimum": 0 @@ -78,7 +78,7 @@ "type": "object", "properties": { "format": { - "description": "Format represents the format of the length_of_what.", + "description": "Format represents the format of the \"description\".", "type": [ "string", "null" @@ -102,7 +102,7 @@ "type": "object", "properties": { "length": { - "description": "Length represents the maximum length of the length_of_what.", + "description": "Length represents the maximum length of the \"description\".", "type": "integer", "format": "uint", "minimum": 0 @@ -325,7 +325,7 @@ "type": "boolean" }, "options": { - "description": "Options represents the options of the rule. If the option is empty, it means that no options_what is allowed.", + "description": "Options represents the options of the rule. If the option is empty, it means that no \"scope\" is allowed.", "type": "array", "items": { "type": "string" @@ -359,7 +359,7 @@ "type": "object", "properties": { "format": { - "description": "Format represents the format of the length_of_what.", + "description": "Format represents the format of the \"scope\".", "type": [ "string", "null" @@ -383,7 +383,7 @@ "type": "object", "properties": { "length": { - "description": "Length represents the maximum length of the length_of_what.", + "description": "Length represents the maximum length of the \"scope\".", "type": "integer", "format": "uint", "minimum": 0 @@ -437,7 +437,7 @@ ] }, "options": { - "description": "Options represents the options of the rule. If the option is empty, it means that no options_what is allowed.", + "description": "Options represents the options of the rule. If the option is empty, it means that no \"type\" is allowed.", "type": "array", "items": { "type": "string" @@ -470,7 +470,7 @@ "type": "object", "properties": { "format": { - "description": "Format represents the format of the length_of_what.", + "description": "Format represents the format of the \"type\".", "type": [ "string", "null" @@ -494,7 +494,7 @@ "type": "object", "properties": { "length": { - "description": "Length represents the maximum length of the length_of_what.", + "description": "Length represents the maximum length of the \"type\".", "type": "integer", "format": "uint", "minimum": 0 diff --git a/cli/src/rule.rs b/cli/src/rule.rs index f86a632..dd40066 100644 --- a/cli/src/rule.rs +++ b/cli/src/rule.rs @@ -247,7 +247,7 @@ macro_rules! make_length_rule { ) => { crate::make_rule! { $ident, - #[doc = concat!("Length represents the maximum length of the ", stringify!(length_of_what), ".")] + #[doc = concat!("Length represents the maximum length of the ",stringify!($length_of_what),".")] length: usize } }; @@ -261,7 +261,7 @@ macro_rules! make_format_rule { ) => { crate::make_rule! { $ident, - #[doc = concat!("Format represents the format of the ", stringify!(length_of_what), ".")] + #[doc = concat!("Format represents the format of the ",stringify!($format_of_what),".")] format: Option } }; @@ -287,7 +287,7 @@ macro_rules! make_options_rule { $field_name: $field_type, ),* - #[doc = concat!("Options represents the options of the rule. If the option is empty, it means that no ",stringify!(options_what)," is allowed.")] + #[doc = concat!("Options represents the options of the rule. If the option is empty, it means that no ",stringify!($options_what)," is allowed.")] options: Vec } }; diff --git a/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap b/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap index c51135d..b57a4ab 100644 --- a/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap +++ b/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap @@ -28,7 +28,7 @@ $defs: type: object properties: length: - description: Length represents the maximum length of the length_of_what. + description: "Length represents the maximum length of the \"body\"." type: integer format: uint minimum: 0 @@ -53,7 +53,7 @@ $defs: type: object properties: format: - description: Format represents the format of the length_of_what. + description: "Format represents the format of the \"description\"." type: - string - "null" @@ -67,7 +67,7 @@ $defs: type: object properties: length: - description: Length represents the maximum length of the length_of_what. + description: "Length represents the maximum length of the \"description\"." type: integer format: uint minimum: 0 @@ -171,7 +171,7 @@ $defs: description: "Optional scope. If true, even if the scope is not present, it is allowed." type: boolean options: - description: "Options represents the options of the rule. If the option is empty, it means that no options_what is allowed." + description: "Options represents the options of the rule. If the option is empty, it means that no \"scope\" is allowed." type: array items: type: string @@ -192,7 +192,7 @@ $defs: type: object properties: format: - description: Format represents the format of the length_of_what. + description: "Format represents the format of the \"scope\"." type: - string - "null" @@ -206,7 +206,7 @@ $defs: type: object properties: length: - description: Length represents the maximum length of the length_of_what. + description: "Length represents the maximum length of the \"scope\"." type: integer format: uint minimum: 0 @@ -236,7 +236,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" options: - description: "Options represents the options of the rule. If the option is empty, it means that no options_what is allowed." + description: "Options represents the options of the rule. If the option is empty, it means that no \"type\" is allowed." type: array items: type: string @@ -256,7 +256,7 @@ $defs: type: object properties: format: - description: Format represents the format of the length_of_what. + description: "Format represents the format of the \"type\"." type: - string - "null" @@ -270,7 +270,7 @@ $defs: type: object properties: length: - description: Length represents the maximum length of the length_of_what. + description: "Length represents the maximum length of the \"type\"." type: integer format: uint minimum: 0 From 7dd7651a6a2b35b3b1bad3713055e0a771628ca7 Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 15:09:04 +0100 Subject: [PATCH 16/20] feat: use patched paste to support :dash modifier --- Cargo.lock | 3 +- cli/Cargo.toml | 2 +- cli/json-schema/config.json | 30 +++++++++---------- cli/src/rule.rs | 2 +- ...__config__tests__generate_json_schema.snap | 30 +++++++++---------- 5 files changed, 33 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 01ed1ad..8a6fbea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -444,8 +444,7 @@ dependencies = [ [[package]] name = "paste" version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +source = "git+https://github.com/elcoosp/paste?branch=feat/dash#4efa1dd157f1a9bc8994fffd653bb2e1c744828a" [[package]] name = "pin-project-lite" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 03dedc1..69dc990 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -22,7 +22,7 @@ serde = { version = "1.0.201", features = ["derive"] } serde_json = "1.0.121" serde_yaml = "0.9.34" tokio = { version = "1.37.0", features = ["full"] } -paste = "1.0.15" +paste = { git = "https://github.com/elcoosp/paste", branch = "feat/dash" } [[bin]] name = "commitlint" diff --git a/cli/json-schema/config.json b/cli/json-schema/config.json index 3a4af31..cb8a03b 100644 --- a/cli/json-schema/config.json +++ b/cli/json-schema/config.json @@ -14,7 +14,7 @@ ], "$defs": { "BodyEmpty": { - "description": "BodyEmpty represents the body_empty rule.", + "description": "[BodyEmpty] represents the `body-empty` rule.", "type": "object", "properties": { "level": { @@ -31,7 +31,7 @@ } }, "BodyMaxLength": { - "description": "BodyMaxLength represents the body_max_length rule.", + "description": "[BodyMaxLength] represents the `body-max-length` rule.", "type": "object", "properties": { "length": { @@ -57,7 +57,7 @@ ] }, "DescriptionEmpty": { - "description": "DescriptionEmpty represents the description_empty rule.", + "description": "[DescriptionEmpty] represents the `description-empty` rule.", "type": "object", "properties": { "level": { @@ -74,7 +74,7 @@ } }, "DescriptionFormat": { - "description": "DescriptionFormat represents the description_format rule.", + "description": "[DescriptionFormat] represents the `description-format` rule.", "type": "object", "properties": { "format": { @@ -98,7 +98,7 @@ } }, "DescriptionMaxLength": { - "description": "DescriptionMaxLength represents the description_max_length rule.", + "description": "[DescriptionMaxLength] represents the `description-max-length` rule.", "type": "object", "properties": { "length": { @@ -124,7 +124,7 @@ ] }, "FootersEmpty": { - "description": "FootersEmpty represents the footers_empty rule.", + "description": "[FootersEmpty] represents the `footers-empty` rule.", "type": "object", "properties": { "level": { @@ -306,7 +306,7 @@ } }, "Scope": { - "description": "Scope represents the scope rule.", + "description": "[Scope] represents the `scope` rule.", "type": "object", "properties": { "level": { @@ -338,7 +338,7 @@ ] }, "ScopeEmpty": { - "description": "ScopeEmpty represents the scope_empty rule.", + "description": "[ScopeEmpty] represents the `scope-empty` rule.", "type": "object", "properties": { "level": { @@ -355,7 +355,7 @@ } }, "ScopeFormat": { - "description": "ScopeFormat represents the scope_format rule.", + "description": "[ScopeFormat] represents the `scope-format` rule.", "type": "object", "properties": { "format": { @@ -379,7 +379,7 @@ } }, "ScopeMaxLength": { - "description": "ScopeMaxLength represents the scope_max_length rule.", + "description": "[ScopeMaxLength] represents the `scope-max-length` rule.", "type": "object", "properties": { "length": { @@ -405,7 +405,7 @@ ] }, "SubjectEmpty": { - "description": "SubjectEmpty represents the subject_empty rule.", + "description": "[SubjectEmpty] represents the `subject-empty` rule.", "type": "object", "properties": { "level": { @@ -422,7 +422,7 @@ } }, "Type": { - "description": "Type represents the type rule.", + "description": "[Type] represents the `type` rule.", "type": "object", "properties": { "level": { @@ -449,7 +449,7 @@ ] }, "TypeEmpty": { - "description": "TypeEmpty represents the type_empty rule.", + "description": "[TypeEmpty] represents the `type-empty` rule.", "type": "object", "properties": { "level": { @@ -466,7 +466,7 @@ } }, "TypeFormat": { - "description": "TypeFormat represents the type_format rule.", + "description": "[TypeFormat] represents the `type-format` rule.", "type": "object", "properties": { "format": { @@ -490,7 +490,7 @@ } }, "TypeMaxLength": { - "description": "TypeMaxLength represents the type_max_length rule.", + "description": "[TypeMaxLength] represents the `type-max-length` rule.", "type": "object", "properties": { "length": { diff --git a/cli/src/rule.rs b/cli/src/rule.rs index dd40066..fb10e1d 100644 --- a/cli/src/rule.rs +++ b/cli/src/rule.rs @@ -305,7 +305,7 @@ macro_rules! make_rule { $field_name:ident: $field_type:ty ),*) => { paste::paste! { - #[doc = concat!(stringify!($ident), " represents the ", stringify!([<$ident:snake>])," rule.")] + #[doc = "[" $ident "] represents the `"[<$ident:dash>]"` rule."] #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct $ident { diff --git a/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap b/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap index b57a4ab..6073200 100644 --- a/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap +++ b/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap @@ -15,7 +15,7 @@ required: - rules $defs: BodyEmpty: - description: BodyEmpty represents the body_empty rule. + description: "[BodyEmpty] represents the `body-empty` rule." type: object properties: level: @@ -24,7 +24,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" BodyMaxLength: - description: BodyMaxLength represents the body_max_length rule. + description: "[BodyMaxLength] represents the `body-max-length` rule." type: object properties: length: @@ -40,7 +40,7 @@ $defs: required: - length DescriptionEmpty: - description: DescriptionEmpty represents the description_empty rule. + description: "[DescriptionEmpty] represents the `description-empty` rule." type: object properties: level: @@ -49,7 +49,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" DescriptionFormat: - description: DescriptionFormat represents the description_format rule. + description: "[DescriptionFormat] represents the `description-format` rule." type: object properties: format: @@ -63,7 +63,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" DescriptionMaxLength: - description: DescriptionMaxLength represents the description_max_length rule. + description: "[DescriptionMaxLength] represents the `description-max-length` rule." type: object properties: length: @@ -79,7 +79,7 @@ $defs: required: - length FootersEmpty: - description: FootersEmpty represents the footers_empty rule. + description: "[FootersEmpty] represents the `footers-empty` rule." type: object properties: level: @@ -159,7 +159,7 @@ $defs: - $ref: "#/$defs/TypeMaxLength" - type: "null" Scope: - description: Scope represents the scope rule. + description: "[Scope] represents the `scope` rule." type: object properties: level: @@ -179,7 +179,7 @@ $defs: - optional - options ScopeEmpty: - description: ScopeEmpty represents the scope_empty rule. + description: "[ScopeEmpty] represents the `scope-empty` rule." type: object properties: level: @@ -188,7 +188,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" ScopeFormat: - description: ScopeFormat represents the scope_format rule. + description: "[ScopeFormat] represents the `scope-format` rule." type: object properties: format: @@ -202,7 +202,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" ScopeMaxLength: - description: ScopeMaxLength represents the scope_max_length rule. + description: "[ScopeMaxLength] represents the `scope-max-length` rule." type: object properties: length: @@ -218,7 +218,7 @@ $defs: required: - length SubjectEmpty: - description: SubjectEmpty represents the subject_empty rule. + description: "[SubjectEmpty] represents the `subject-empty` rule." type: object properties: level: @@ -227,7 +227,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" Type: - description: Type represents the type rule. + description: "[Type] represents the `type` rule." type: object properties: level: @@ -243,7 +243,7 @@ $defs: required: - options TypeEmpty: - description: TypeEmpty represents the type_empty rule. + description: "[TypeEmpty] represents the `type-empty` rule." type: object properties: level: @@ -252,7 +252,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" TypeFormat: - description: TypeFormat represents the type_format rule. + description: "[TypeFormat] represents the `type-format` rule." type: object properties: format: @@ -266,7 +266,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" TypeMaxLength: - description: TypeMaxLength represents the type_max_length rule. + description: "[TypeMaxLength] represents the `type-max-length` rule." type: object properties: length: From 8ee0bf70d39e89a87e937b757677bb0593fda20f Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 15:22:48 +0100 Subject: [PATCH 17/20] feat: add link to docs on all rules --- cli/json-schema/config.json | 30 +++++++++---------- cli/src/rule.rs | 3 +- ...__config__tests__generate_json_schema.snap | 30 +++++++++---------- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/cli/json-schema/config.json b/cli/json-schema/config.json index cb8a03b..a622a28 100644 --- a/cli/json-schema/config.json +++ b/cli/json-schema/config.json @@ -14,7 +14,7 @@ ], "$defs": { "BodyEmpty": { - "description": "[BodyEmpty] represents the `body-empty` rule.", + "description": "[BodyEmpty] represents the `[body-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/body-empty)` rule.", "type": "object", "properties": { "level": { @@ -31,7 +31,7 @@ } }, "BodyMaxLength": { - "description": "[BodyMaxLength] represents the `body-max-length` rule.", + "description": "[BodyMaxLength] represents the `[body-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/body-max-length)` rule.", "type": "object", "properties": { "length": { @@ -57,7 +57,7 @@ ] }, "DescriptionEmpty": { - "description": "[DescriptionEmpty] represents the `description-empty` rule.", + "description": "[DescriptionEmpty] represents the `[description-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/description-empty)` rule.", "type": "object", "properties": { "level": { @@ -74,7 +74,7 @@ } }, "DescriptionFormat": { - "description": "[DescriptionFormat] represents the `description-format` rule.", + "description": "[DescriptionFormat] represents the `[description-format](https://keisukeyamashita.github.io/commitlint-rs/rules/description-format)` rule.", "type": "object", "properties": { "format": { @@ -98,7 +98,7 @@ } }, "DescriptionMaxLength": { - "description": "[DescriptionMaxLength] represents the `description-max-length` rule.", + "description": "[DescriptionMaxLength] represents the `[description-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/description-max-length)` rule.", "type": "object", "properties": { "length": { @@ -124,7 +124,7 @@ ] }, "FootersEmpty": { - "description": "[FootersEmpty] represents the `footers-empty` rule.", + "description": "[FootersEmpty] represents the `[footers-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/footers-empty)` rule.", "type": "object", "properties": { "level": { @@ -306,7 +306,7 @@ } }, "Scope": { - "description": "[Scope] represents the `scope` rule.", + "description": "[Scope] represents the `[scope](https://keisukeyamashita.github.io/commitlint-rs/rules/scope)` rule.", "type": "object", "properties": { "level": { @@ -338,7 +338,7 @@ ] }, "ScopeEmpty": { - "description": "[ScopeEmpty] represents the `scope-empty` rule.", + "description": "[ScopeEmpty] represents the `[scope-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-empty)` rule.", "type": "object", "properties": { "level": { @@ -355,7 +355,7 @@ } }, "ScopeFormat": { - "description": "[ScopeFormat] represents the `scope-format` rule.", + "description": "[ScopeFormat] represents the `[scope-format](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-format)` rule.", "type": "object", "properties": { "format": { @@ -379,7 +379,7 @@ } }, "ScopeMaxLength": { - "description": "[ScopeMaxLength] represents the `scope-max-length` rule.", + "description": "[ScopeMaxLength] represents the `[scope-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-max-length)` rule.", "type": "object", "properties": { "length": { @@ -405,7 +405,7 @@ ] }, "SubjectEmpty": { - "description": "[SubjectEmpty] represents the `subject-empty` rule.", + "description": "[SubjectEmpty] represents the `[subject-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/subject-empty)` rule.", "type": "object", "properties": { "level": { @@ -422,7 +422,7 @@ } }, "Type": { - "description": "[Type] represents the `type` rule.", + "description": "[Type] represents the `[type](https://keisukeyamashita.github.io/commitlint-rs/rules/type)` rule.", "type": "object", "properties": { "level": { @@ -449,7 +449,7 @@ ] }, "TypeEmpty": { - "description": "[TypeEmpty] represents the `type-empty` rule.", + "description": "[TypeEmpty] represents the `[type-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/type-empty)` rule.", "type": "object", "properties": { "level": { @@ -466,7 +466,7 @@ } }, "TypeFormat": { - "description": "[TypeFormat] represents the `type-format` rule.", + "description": "[TypeFormat] represents the `[type-format](https://keisukeyamashita.github.io/commitlint-rs/rules/type-format)` rule.", "type": "object", "properties": { "format": { @@ -490,7 +490,7 @@ } }, "TypeMaxLength": { - "description": "[TypeMaxLength] represents the `type-max-length` rule.", + "description": "[TypeMaxLength] represents the `[type-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/type-max-length)` rule.", "type": "object", "properties": { "length": { diff --git a/cli/src/rule.rs b/cli/src/rule.rs index fb10e1d..3ed4b4b 100644 --- a/cli/src/rule.rs +++ b/cli/src/rule.rs @@ -304,8 +304,7 @@ macro_rules! make_rule { )* $field_name:ident: $field_type:ty ),*) => { paste::paste! { - - #[doc = "[" $ident "] represents the `"[<$ident:dash>]"` rule."] + #[doc = "[" $ident "] represents the [`"[<$ident:dash>]"`](https://keisukeyamashita.github.io/commitlint-rs/rules/"[<$ident:dash>]") rule."] #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct $ident { diff --git a/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap b/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap index 6073200..bba0784 100644 --- a/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap +++ b/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap @@ -15,7 +15,7 @@ required: - rules $defs: BodyEmpty: - description: "[BodyEmpty] represents the `body-empty` rule." + description: "[BodyEmpty] represents the `[body-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/body-empty)` rule." type: object properties: level: @@ -24,7 +24,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" BodyMaxLength: - description: "[BodyMaxLength] represents the `body-max-length` rule." + description: "[BodyMaxLength] represents the `[body-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/body-max-length)` rule." type: object properties: length: @@ -40,7 +40,7 @@ $defs: required: - length DescriptionEmpty: - description: "[DescriptionEmpty] represents the `description-empty` rule." + description: "[DescriptionEmpty] represents the `[description-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/description-empty)` rule." type: object properties: level: @@ -49,7 +49,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" DescriptionFormat: - description: "[DescriptionFormat] represents the `description-format` rule." + description: "[DescriptionFormat] represents the `[description-format](https://keisukeyamashita.github.io/commitlint-rs/rules/description-format)` rule." type: object properties: format: @@ -63,7 +63,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" DescriptionMaxLength: - description: "[DescriptionMaxLength] represents the `description-max-length` rule." + description: "[DescriptionMaxLength] represents the `[description-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/description-max-length)` rule." type: object properties: length: @@ -79,7 +79,7 @@ $defs: required: - length FootersEmpty: - description: "[FootersEmpty] represents the `footers-empty` rule." + description: "[FootersEmpty] represents the `[footers-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/footers-empty)` rule." type: object properties: level: @@ -159,7 +159,7 @@ $defs: - $ref: "#/$defs/TypeMaxLength" - type: "null" Scope: - description: "[Scope] represents the `scope` rule." + description: "[Scope] represents the `[scope](https://keisukeyamashita.github.io/commitlint-rs/rules/scope)` rule." type: object properties: level: @@ -179,7 +179,7 @@ $defs: - optional - options ScopeEmpty: - description: "[ScopeEmpty] represents the `scope-empty` rule." + description: "[ScopeEmpty] represents the `[scope-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-empty)` rule." type: object properties: level: @@ -188,7 +188,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" ScopeFormat: - description: "[ScopeFormat] represents the `scope-format` rule." + description: "[ScopeFormat] represents the `[scope-format](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-format)` rule." type: object properties: format: @@ -202,7 +202,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" ScopeMaxLength: - description: "[ScopeMaxLength] represents the `scope-max-length` rule." + description: "[ScopeMaxLength] represents the `[scope-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-max-length)` rule." type: object properties: length: @@ -218,7 +218,7 @@ $defs: required: - length SubjectEmpty: - description: "[SubjectEmpty] represents the `subject-empty` rule." + description: "[SubjectEmpty] represents the `[subject-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/subject-empty)` rule." type: object properties: level: @@ -227,7 +227,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" Type: - description: "[Type] represents the `type` rule." + description: "[Type] represents the `[type](https://keisukeyamashita.github.io/commitlint-rs/rules/type)` rule." type: object properties: level: @@ -243,7 +243,7 @@ $defs: required: - options TypeEmpty: - description: "[TypeEmpty] represents the `type-empty` rule." + description: "[TypeEmpty] represents the `[type-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/type-empty)` rule." type: object properties: level: @@ -252,7 +252,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" TypeFormat: - description: "[TypeFormat] represents the `type-format` rule." + description: "[TypeFormat] represents the `[type-format](https://keisukeyamashita.github.io/commitlint-rs/rules/type-format)` rule." type: object properties: format: @@ -266,7 +266,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" TypeMaxLength: - description: "[TypeMaxLength] represents the `type-max-length` rule." + description: "[TypeMaxLength] represents the `[type-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/type-max-length)` rule." type: object properties: length: From 82c66dfed581e5ab214dab8f1257cf7c8bae8d59 Mon Sep 17 00:00:00 2001 From: elcoosp Date: Mon, 2 Dec 2024 15:23:06 +0100 Subject: [PATCH 18/20] chore: cspell additions --- cspell.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cspell.yml b/cspell.yml index a18bdb5..1d7a0cd 100644 --- a/cspell.yml +++ b/cspell.yml @@ -1 +1 @@ -words: [commitlint, schemars, commitlintrc, Keke, insta, binstall, serde, Keisuke, astrojs, splitn] \ No newline at end of file +words: [commitlint, schemars, commitlintrc, Keke, insta, binstall, serde, Keisuke, astrojs, splitn, insta, schemars] \ No newline at end of file From e6473f0eda2ce5d85c2db965cf321b25b16e6bf7 Mon Sep 17 00:00:00 2001 From: elcoosp Date: Tue, 3 Dec 2024 12:25:02 +0100 Subject: [PATCH 19/20] fix(schema): move schema snap test to workspace member --- Cargo.lock | 4 +-- cli/json-schema/config.json | 30 ++++++++--------- cli/src/config.rs | 15 --------- schema/Cargo.toml | 4 ++- schema/src/main.rs | 12 +++++-- .../schema__tests__snap_json_schema.snap | 32 +++++++++---------- 6 files changed, 46 insertions(+), 51 deletions(-) rename cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap => schema/src/snapshots/schema__tests__snap_json_schema.snap (76%) diff --git a/Cargo.lock b/Cargo.lock index a28ef44..0c38f87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,7 +166,6 @@ version = "0.2.2" dependencies = [ "clap", "futures", - "insta", "paste", "regex", "schemars", @@ -444,7 +443,7 @@ dependencies = [ [[package]] name = "paste" version = "1.0.15" -source = "git+https://github.com/elcoosp/paste?branch=feat/dash#4efa1dd157f1a9bc8994fffd653bb2e1c744828a" +source = "git+https://github.com/elcoosp/paste?branch=feat%2Fdash#4efa1dd157f1a9bc8994fffd653bb2e1c744828a" [[package]] name = "pin-project-lite" @@ -552,6 +551,7 @@ version = "0.2.2" dependencies = [ "clap", "commitlint-rs", + "insta", "schemars", "serde", "serde_json", diff --git a/cli/json-schema/config.json b/cli/json-schema/config.json index a622a28..2df719e 100644 --- a/cli/json-schema/config.json +++ b/cli/json-schema/config.json @@ -14,7 +14,7 @@ ], "$defs": { "BodyEmpty": { - "description": "[BodyEmpty] represents the `[body-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/body-empty)` rule.", + "description": "[BodyEmpty] represents the [`body-empty`](https://keisukeyamashita.github.io/commitlint-rs/rules/body-empty) rule.", "type": "object", "properties": { "level": { @@ -31,7 +31,7 @@ } }, "BodyMaxLength": { - "description": "[BodyMaxLength] represents the `[body-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/body-max-length)` rule.", + "description": "[BodyMaxLength] represents the [`body-max-length`](https://keisukeyamashita.github.io/commitlint-rs/rules/body-max-length) rule.", "type": "object", "properties": { "length": { @@ -57,7 +57,7 @@ ] }, "DescriptionEmpty": { - "description": "[DescriptionEmpty] represents the `[description-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/description-empty)` rule.", + "description": "[DescriptionEmpty] represents the [`description-empty`](https://keisukeyamashita.github.io/commitlint-rs/rules/description-empty) rule.", "type": "object", "properties": { "level": { @@ -74,7 +74,7 @@ } }, "DescriptionFormat": { - "description": "[DescriptionFormat] represents the `[description-format](https://keisukeyamashita.github.io/commitlint-rs/rules/description-format)` rule.", + "description": "[DescriptionFormat] represents the [`description-format`](https://keisukeyamashita.github.io/commitlint-rs/rules/description-format) rule.", "type": "object", "properties": { "format": { @@ -98,7 +98,7 @@ } }, "DescriptionMaxLength": { - "description": "[DescriptionMaxLength] represents the `[description-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/description-max-length)` rule.", + "description": "[DescriptionMaxLength] represents the [`description-max-length`](https://keisukeyamashita.github.io/commitlint-rs/rules/description-max-length) rule.", "type": "object", "properties": { "length": { @@ -124,7 +124,7 @@ ] }, "FootersEmpty": { - "description": "[FootersEmpty] represents the `[footers-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/footers-empty)` rule.", + "description": "[FootersEmpty] represents the [`footers-empty`](https://keisukeyamashita.github.io/commitlint-rs/rules/footers-empty) rule.", "type": "object", "properties": { "level": { @@ -306,7 +306,7 @@ } }, "Scope": { - "description": "[Scope] represents the `[scope](https://keisukeyamashita.github.io/commitlint-rs/rules/scope)` rule.", + "description": "[Scope] represents the [`scope`](https://keisukeyamashita.github.io/commitlint-rs/rules/scope) rule.", "type": "object", "properties": { "level": { @@ -338,7 +338,7 @@ ] }, "ScopeEmpty": { - "description": "[ScopeEmpty] represents the `[scope-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-empty)` rule.", + "description": "[ScopeEmpty] represents the [`scope-empty`](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-empty) rule.", "type": "object", "properties": { "level": { @@ -355,7 +355,7 @@ } }, "ScopeFormat": { - "description": "[ScopeFormat] represents the `[scope-format](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-format)` rule.", + "description": "[ScopeFormat] represents the [`scope-format`](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-format) rule.", "type": "object", "properties": { "format": { @@ -379,7 +379,7 @@ } }, "ScopeMaxLength": { - "description": "[ScopeMaxLength] represents the `[scope-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-max-length)` rule.", + "description": "[ScopeMaxLength] represents the [`scope-max-length`](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-max-length) rule.", "type": "object", "properties": { "length": { @@ -405,7 +405,7 @@ ] }, "SubjectEmpty": { - "description": "[SubjectEmpty] represents the `[subject-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/subject-empty)` rule.", + "description": "[SubjectEmpty] represents the [`subject-empty`](https://keisukeyamashita.github.io/commitlint-rs/rules/subject-empty) rule.", "type": "object", "properties": { "level": { @@ -422,7 +422,7 @@ } }, "Type": { - "description": "[Type] represents the `[type](https://keisukeyamashita.github.io/commitlint-rs/rules/type)` rule.", + "description": "[Type] represents the [`type`](https://keisukeyamashita.github.io/commitlint-rs/rules/type) rule.", "type": "object", "properties": { "level": { @@ -449,7 +449,7 @@ ] }, "TypeEmpty": { - "description": "[TypeEmpty] represents the `[type-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/type-empty)` rule.", + "description": "[TypeEmpty] represents the [`type-empty`](https://keisukeyamashita.github.io/commitlint-rs/rules/type-empty) rule.", "type": "object", "properties": { "level": { @@ -466,7 +466,7 @@ } }, "TypeFormat": { - "description": "[TypeFormat] represents the `[type-format](https://keisukeyamashita.github.io/commitlint-rs/rules/type-format)` rule.", + "description": "[TypeFormat] represents the [`type-format`](https://keisukeyamashita.github.io/commitlint-rs/rules/type-format) rule.", "type": "object", "properties": { "format": { @@ -490,7 +490,7 @@ } }, "TypeMaxLength": { - "description": "[TypeMaxLength] represents the `[type-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/type-max-length)` rule.", + "description": "[TypeMaxLength] represents the [`type-max-length`](https://keisukeyamashita.github.io/commitlint-rs/rules/type-max-length) rule.", "type": "object", "properties": { "length": { diff --git a/cli/src/config.rs b/cli/src/config.rs index 6f252ff..2d7be77 100644 --- a/cli/src/config.rs +++ b/cli/src/config.rs @@ -125,18 +125,3 @@ async fn load_unknown_config_file(path: PathBuf) -> Result { path.display() )) } -#[cfg(test)] -mod tests { - #[cfg(feature = "schemars")] - #[test] - fn generate_json_schema() { - use crate::config::Config; - use insta::assert_yaml_snapshot; - use std::fs; - - let config_schema = schemars::schema_for!(Config); - let config_schema_json = serde_json::to_string_pretty(&config_schema).unwrap(); - assert_yaml_snapshot!(config_schema); - fs::write("json-schema/config.json", config_schema_json).unwrap(); - } -} diff --git a/schema/Cargo.toml b/schema/Cargo.toml index 567aa99..290d1b7 100644 --- a/schema/Cargo.toml +++ b/schema/Cargo.toml @@ -14,6 +14,8 @@ edition.workspace = true [dependencies] clap = { version = "4.5.21", features = ["derive"] } cli = { path = "../cli", features = ["schemars"], package = "commitlint-rs" } -schemars = { version = "0.8.21" } +schemars = { version = "1.0.0-alpha.16" } serde = { version = "1.0.215", features = ["derive"] } serde_json = "1.0.133" +[dev-dependencies] +insta = { version = "1.41.1", features = ["yaml"] } diff --git a/schema/src/main.rs b/schema/src/main.rs index 989d768..c47416c 100644 --- a/schema/src/main.rs +++ b/schema/src/main.rs @@ -1,7 +1,6 @@ use clap::Parser; use cli::config::Config; use std::fs; - /// CLI Arguments #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] @@ -13,8 +12,17 @@ struct Args { fn main() { let args = Args::parse(); - let config_schema = schemars::schema_for!(Config); let config_schema_json = serde_json::to_string_pretty(&config_schema).unwrap(); fs::write(&args.path, config_schema_json).unwrap(); } +#[cfg(test)] +mod tests { + #[test] + fn snap_json_schema() { + use cli::config::Config; + use insta::assert_yaml_snapshot; + let config_schema = schemars::schema_for!(Config); + assert_yaml_snapshot!(config_schema); + } +} diff --git a/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap b/schema/src/snapshots/schema__tests__snap_json_schema.snap similarity index 76% rename from cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap rename to schema/src/snapshots/schema__tests__snap_json_schema.snap index bba0784..9b4e197 100644 --- a/cli/src/snapshots/commitlint__config__tests__generate_json_schema.snap +++ b/schema/src/snapshots/schema__tests__snap_json_schema.snap @@ -1,5 +1,5 @@ --- -source: cli/src/config.rs +source: schema/src/main.rs expression: config_schema snapshot_kind: text --- @@ -15,7 +15,7 @@ required: - rules $defs: BodyEmpty: - description: "[BodyEmpty] represents the `[body-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/body-empty)` rule." + description: "[BodyEmpty] represents the [`body-empty`](https://keisukeyamashita.github.io/commitlint-rs/rules/body-empty) rule." type: object properties: level: @@ -24,7 +24,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" BodyMaxLength: - description: "[BodyMaxLength] represents the `[body-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/body-max-length)` rule." + description: "[BodyMaxLength] represents the [`body-max-length`](https://keisukeyamashita.github.io/commitlint-rs/rules/body-max-length) rule." type: object properties: length: @@ -40,7 +40,7 @@ $defs: required: - length DescriptionEmpty: - description: "[DescriptionEmpty] represents the `[description-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/description-empty)` rule." + description: "[DescriptionEmpty] represents the [`description-empty`](https://keisukeyamashita.github.io/commitlint-rs/rules/description-empty) rule." type: object properties: level: @@ -49,7 +49,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" DescriptionFormat: - description: "[DescriptionFormat] represents the `[description-format](https://keisukeyamashita.github.io/commitlint-rs/rules/description-format)` rule." + description: "[DescriptionFormat] represents the [`description-format`](https://keisukeyamashita.github.io/commitlint-rs/rules/description-format) rule." type: object properties: format: @@ -63,7 +63,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" DescriptionMaxLength: - description: "[DescriptionMaxLength] represents the `[description-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/description-max-length)` rule." + description: "[DescriptionMaxLength] represents the [`description-max-length`](https://keisukeyamashita.github.io/commitlint-rs/rules/description-max-length) rule." type: object properties: length: @@ -79,7 +79,7 @@ $defs: required: - length FootersEmpty: - description: "[FootersEmpty] represents the `[footers-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/footers-empty)` rule." + description: "[FootersEmpty] represents the [`footers-empty`](https://keisukeyamashita.github.io/commitlint-rs/rules/footers-empty) rule." type: object properties: level: @@ -159,7 +159,7 @@ $defs: - $ref: "#/$defs/TypeMaxLength" - type: "null" Scope: - description: "[Scope] represents the `[scope](https://keisukeyamashita.github.io/commitlint-rs/rules/scope)` rule." + description: "[Scope] represents the [`scope`](https://keisukeyamashita.github.io/commitlint-rs/rules/scope) rule." type: object properties: level: @@ -179,7 +179,7 @@ $defs: - optional - options ScopeEmpty: - description: "[ScopeEmpty] represents the `[scope-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-empty)` rule." + description: "[ScopeEmpty] represents the [`scope-empty`](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-empty) rule." type: object properties: level: @@ -188,7 +188,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" ScopeFormat: - description: "[ScopeFormat] represents the `[scope-format](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-format)` rule." + description: "[ScopeFormat] represents the [`scope-format`](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-format) rule." type: object properties: format: @@ -202,7 +202,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" ScopeMaxLength: - description: "[ScopeMaxLength] represents the `[scope-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-max-length)` rule." + description: "[ScopeMaxLength] represents the [`scope-max-length`](https://keisukeyamashita.github.io/commitlint-rs/rules/scope-max-length) rule." type: object properties: length: @@ -218,7 +218,7 @@ $defs: required: - length SubjectEmpty: - description: "[SubjectEmpty] represents the `[subject-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/subject-empty)` rule." + description: "[SubjectEmpty] represents the [`subject-empty`](https://keisukeyamashita.github.io/commitlint-rs/rules/subject-empty) rule." type: object properties: level: @@ -227,7 +227,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" Type: - description: "[Type] represents the `[type](https://keisukeyamashita.github.io/commitlint-rs/rules/type)` rule." + description: "[Type] represents the [`type`](https://keisukeyamashita.github.io/commitlint-rs/rules/type) rule." type: object properties: level: @@ -243,7 +243,7 @@ $defs: required: - options TypeEmpty: - description: "[TypeEmpty] represents the `[type-empty](https://keisukeyamashita.github.io/commitlint-rs/rules/type-empty)` rule." + description: "[TypeEmpty] represents the [`type-empty`](https://keisukeyamashita.github.io/commitlint-rs/rules/type-empty) rule." type: object properties: level: @@ -252,7 +252,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" TypeFormat: - description: "[TypeFormat] represents the `[type-format](https://keisukeyamashita.github.io/commitlint-rs/rules/type-format)` rule." + description: "[TypeFormat] represents the [`type-format`](https://keisukeyamashita.github.io/commitlint-rs/rules/type-format) rule." type: object properties: format: @@ -266,7 +266,7 @@ $defs: - $ref: "#/$defs/Level" - type: "null" TypeMaxLength: - description: "[TypeMaxLength] represents the `[type-max-length](https://keisukeyamashita.github.io/commitlint-rs/rules/type-max-length)` rule." + description: "[TypeMaxLength] represents the [`type-max-length`](https://keisukeyamashita.github.io/commitlint-rs/rules/type-max-length) rule." type: object properties: length: From 2ddc0f4da0184d000d7cb6375b80c057d12465f9 Mon Sep 17 00:00:00 2001 From: elcoosp Date: Tue, 3 Dec 2024 12:30:23 +0100 Subject: [PATCH 20/20] chore: fmt --- cli/Cargo.toml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 44a07e5..ef76d4d 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -11,8 +11,6 @@ repository.workspace = true license.workspace = true edition.workspace = true -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [[bin]] name = "commitlint" path = "src/main.rs" @@ -28,10 +26,9 @@ serde_json = "1.0.121" serde_yaml = "0.9.34" tokio = { version = "1.37.0", features = ["full"] } - -[package.metadata.binstall] -pkg-url = "{ repo }/releases/download/v{ version }/commitlint-v{ version }-{ target }{ archive-suffix }" - [features] schemars = ["dep:schemars"] default = [] + +[package.metadata.binstall] +pkg-url = "{ repo }/releases/download/v{ version }/commitlint-v{ version }-{ target }{ archive-suffix }"