From e39b8c7c3771459b728ea7cec3b2632a52e6d17f Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Thu, 24 Feb 2022 03:00:16 -0300 Subject: [PATCH 1/7] Create FUNDING.yml --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..537d1dc --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +liberapay: alt-art From 0d6d0fc13c2836df656f1f0e65b046d9e122ca8e Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Wed, 2 Mar 2022 00:05:37 -0300 Subject: [PATCH 2/7] refactor: Setup new clippy lints --- src/commit_message/message_build/mod.rs | 4 +-- src/commit_message/message_build/tests.rs | 31 ++++++++++------------- src/commit_message/mod.rs | 12 ++++----- src/commit_message/prompt.rs | 4 +-- src/config/mod.rs | 9 +++---- src/config/tests.rs | 8 +++--- src/main.rs | 9 +++++++ 7 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/commit_message/message_build/mod.rs b/src/commit_message/message_build/mod.rs index f386b03..fd99301 100644 --- a/src/commit_message/message_build/mod.rs +++ b/src/commit_message/message_build/mod.rs @@ -9,8 +9,8 @@ pub struct MessageBuilder { } impl MessageBuilder { - pub fn new(config: Config) -> MessageBuilder { - MessageBuilder { + pub const fn new(config: Config) -> Self { + Self { config, message: String::new(), } diff --git a/src/commit_message/message_build/tests.rs b/src/commit_message/message_build/tests.rs index e942c16..2f71286 100644 --- a/src/commit_message/message_build/tests.rs +++ b/src/commit_message/message_build/tests.rs @@ -1,6 +1,5 @@ use crate::commit_message::message_build::MessageBuilder; use crate::config::Config; -use anyhow::Result; fn message_with_config(config: Config) -> String { let mut builder = MessageBuilder::new(config); @@ -13,11 +12,11 @@ fn message_with_config(config: Config) -> String { } #[test] -fn message_builder_config_test() -> Result<()> { +fn message_builder_config_test() { let mut config = Config { - scope_prefix: "(".to_string(), - scope_suffix: ")".to_string(), - subject_separator: ": ".to_string(), + scope_prefix: "(".to_owned(), + scope_suffix: ")".to_owned(), + subject_separator: ": ".to_owned(), type_prefix: None, type_suffix: None, }; @@ -27,36 +26,35 @@ fn message_builder_config_test() -> Result<()> { "feat(test): description\n\nbody\n\nfooter" ); - config.type_prefix = Some("[".to_string()); - config.type_suffix = Some("]".to_string()); + config.type_prefix = Some("[".to_owned()); + config.type_suffix = Some("]".to_owned()); assert_eq!( message_with_config(config.clone()), "[feat](test): description\n\nbody\n\nfooter" ); - config.subject_separator = " ".to_string(); + config.subject_separator = " ".to_owned(); assert_eq!( message_with_config(config.clone()), "[feat](test) description\n\nbody\n\nfooter" ); - config.scope_prefix = "".to_string(); - config.scope_suffix = "".to_string(); + config.scope_prefix = "".to_owned(); + config.scope_suffix = "".to_owned(); assert_eq!( - message_with_config(config.clone()), + message_with_config(config), "[feat]test description\n\nbody\n\nfooter" ); - Ok(()) } #[test] -fn message_builder_test() -> Result<()> { +fn message_builder_test() { let config = Config { - scope_prefix: "(".to_string(), - scope_suffix: ")".to_string(), - subject_separator: ": ".to_string(), + scope_prefix: "(".to_owned(), + scope_suffix: ")".to_owned(), + subject_separator: ": ".to_owned(), type_prefix: None, type_suffix: None, }; @@ -76,5 +74,4 @@ fn message_builder_test() -> Result<()> { builder.set_footer("footer"); assert_eq!(builder.message, "feat(test): description\n\nbody\n\nfooter"); - Ok(()) } diff --git a/src/commit_message/mod.rs b/src/commit_message/mod.rs index 281b39c..535ad84 100644 --- a/src/commit_message/mod.rs +++ b/src/commit_message/mod.rs @@ -10,19 +10,19 @@ use prompt::Prompt; pub fn make_message_commit(pattern: CommitPattern) -> Result { let mut message_inquirer = MessageInquirer::new(pattern.clone()); let skip_commit = pattern.skip_commit; - if !skip_commit.contains(&"commit_type".to_string()) { + if !skip_commit.contains(&"commit_type".to_owned()) { message_inquirer.type_choice()?; } - if !skip_commit.contains(&"commit_scope".to_string()) { + if !skip_commit.contains(&"commit_scope".to_owned()) { message_inquirer.scope_choice()?; } - if !skip_commit.contains(&"commit_description".to_string()) { + if !skip_commit.contains(&"commit_description".to_owned()) { message_inquirer.description()?; } - if !skip_commit.contains(&"commit_body".to_string()) { + if !skip_commit.contains(&"commit_body".to_owned()) { message_inquirer.body()?; } - if !skip_commit.contains(&"commit_footer".to_string()) { + if !skip_commit.contains(&"commit_footer".to_owned()) { message_inquirer.footer()?; } message_inquirer.message() @@ -36,7 +36,7 @@ struct MessageInquirer { impl MessageInquirer { fn new(pattern: CommitPattern) -> Self { - MessageInquirer { + Self { commit_builder: MessageBuilder::new(pattern.config.clone()), prompt: Prompt::new(), pattern, diff --git a/src/commit_message/prompt.rs b/src/commit_message/prompt.rs index b168068..4e9a04e 100644 --- a/src/commit_message/prompt.rs +++ b/src/commit_message/prompt.rs @@ -13,11 +13,11 @@ pub struct Prompt { } impl Prompt { - pub fn new() -> Prompt { + pub fn new() -> Self { let default = RenderConfig::default(); let prompt_prefix = Styled::new("-").with_fg(Color::LightGreen); let current_config = default.with_prompt_prefix(prompt_prefix); - Prompt { + Self { config: current_config, } } diff --git a/src/config/mod.rs b/src/config/mod.rs index 6b3d9d8..414d5d6 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -4,8 +4,7 @@ mod tests; use anyhow::{anyhow, Context, Result}; use serde::Deserialize; use std::fmt::{Display, Formatter, Result as FmtResult}; -use std::fs::File; -use std::io::Read; +use std::fs; use std::path::Path; use std::path::PathBuf; @@ -52,9 +51,7 @@ pub struct CommitPattern { } fn get_config_path_content(config_path: impl AsRef) -> Result { - let mut file = File::open(config_path)?; - let mut content = String::new(); - file.read_to_string(&mut content)?; + let content = fs::read_to_string(config_path)?; Ok(content) } @@ -97,6 +94,6 @@ pub fn get_pattern(config_path: Option) -> Result { let default_pattern_str = DEFAULT_CONFIG_FILE; let selected_config_path = select_custom_config_path(config_path)?; let pattern_str = get_config_path_content(&selected_config_path) - .unwrap_or_else(|_| default_pattern_str.to_string()); + .unwrap_or_else(|_| default_pattern_str.to_owned()); serde_json::from_str(&pattern_str).context("Failed to parse commit pattern from file") } diff --git a/src/config/tests.rs b/src/config/tests.rs index 3cad57b..dab129e 100644 --- a/src/config/tests.rs +++ b/src/config/tests.rs @@ -18,16 +18,18 @@ fn select_custom_config_path_test() -> Result<()> { let selected_config_path = select_custom_config_path(Some(PathBuf::new())); match selected_config_path { Err(err) => assert_eq!(err.to_string(), "Config file does not exist: "), - _ => assert!(false), + _ => unreachable!(), } Ok(()) } #[test] fn get_config_path_test() -> Result<()> { - let config_file = dirs::config_dir().unwrap().join("commit/commit.json"); + let config_file = dirs::config_dir() + .ok_or(anyhow!("Could not find config directory"))? + .join("commit/commit.json"); let config_path = get_config_path(); - assert_eq!(config_file.to_str(), config_path.unwrap().to_str()); + assert_eq!(config_file.to_str(), config_path?.to_str()); Ok(()) } diff --git a/src/main.rs b/src/main.rs index 8dbb7d4..0948afd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,12 @@ +#![warn( + clippy::all, + clippy::pedantic, + clippy::nursery, + clippy::cargo, + clippy::str_to_string +)] +#![allow(clippy::module_name_repetitions)] + mod commit_message; mod config; From 0ce735c0bc0693c7635e3933ac446356673d93cd Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Wed, 2 Mar 2022 14:36:19 -0300 Subject: [PATCH 3/7] feat(commit): Flag to use the program as a hook --- Cargo.toml | 2 ++ src/commit.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 38 ++++++++++++++--------------------- 3 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 src/commit.rs diff --git a/Cargo.toml b/Cargo.toml index fb223d3..989f733 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,8 @@ homepage = "https://github.com/alt-art/commit" repository = "https://github.com/alt-art/commit" documentation = "https://github.com/alt-art/commit/wiki" description = "A tool to make patterned (conventional) commit messages" +categories = ["development-tools", "command-line-utilities"] +keywords = ["git", "commit","message", "conventional"] authors = ["Pedro H. M. "] readme = "README.md" license = "MIT" diff --git a/src/commit.rs b/src/commit.rs new file mode 100644 index 0000000..c1a0cbd --- /dev/null +++ b/src/commit.rs @@ -0,0 +1,55 @@ +use anyhow::{anyhow, Result}; + +use std::fs; +use std::io::Write; +use std::path::PathBuf; +use std::process::{exit, Command}; + +pub fn commit_as_hook(commit_message: &str) -> Result<()> { + let output = Command::new("git") + .args(&["rev-parse", "--absolute-git-dir"]) + .output(); + match output { + Ok(output) => { + if !output.status.success() { + return Err(anyhow!("Could not get git directory")); + } + let git_dir = PathBuf::from(String::from_utf8_lossy(&output.stdout).trim()); + let commit_file_path = git_dir.join("COMMIT_EDITMSG"); + fs::write(commit_file_path, commit_message)?; + } + Err(e) => { + return Err(anyhow!( + "Failed to run git. Make sure git is installed\nAdditional info: {}", + e + )); + } + } + Ok(()) +} + +pub fn commit(commit_message: &str) -> Result<()> { + let output = Command::new("git") + .arg("commit") + .arg("-m") + .arg(commit_message) + .output(); + match output { + Ok(output) => { + std::io::stdout().write_all(&output.stdout)?; + std::io::stderr().write_all(&output.stderr)?; + exit( + output + .status + .code() + .ok_or(anyhow!("Could not get exit code"))?, + ); + } + Err(e) => { + return Err(anyhow::anyhow!( + "Failed to run git. Make sure git is installed\nAdditional info: {}", + e + )); + } + }; +} diff --git a/src/main.rs b/src/main.rs index 0948afd..7e36b95 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,14 +7,15 @@ )] #![allow(clippy::module_name_repetitions)] +mod commit; mod commit_message; mod config; use anyhow::Result; use clap::Parser; use std::io::Write; + use std::path::PathBuf; -use std::process::{exit, Command}; use commit_message::make_message_commit; @@ -32,6 +33,8 @@ struct Opt { config: Option, #[clap(long, help = "Init custom configuration file")] init: bool, + #[clap(short, long, help = "Use as hook")] + hook: bool, } fn main() -> Result<()> { @@ -45,28 +48,17 @@ fn main() -> Result<()> { if opt.init { let mut file = std::fs::File::create("commit.json")?; file.write_all(DEFAULT_CONFIG_FILE.as_bytes())?; - Ok(()) - } else { - let pattern = config::get_pattern(opt.config)?; - let commit_message = make_message_commit(pattern)?; + return Ok(()); + } - let output = Command::new("git") - .arg("commit") - .arg("-m") - .arg(commit_message) - .output(); - match output { - Ok(output) => { - std::io::stdout().write_all(&output.stdout).unwrap(); - std::io::stderr().write_all(&output.stderr).unwrap(); - exit(output.status.code().unwrap()); - } - Err(e) => { - return Err(anyhow::anyhow!( - "Failed to run git. Make sure git is installed\nAdditional info: {}", - e - )); - } - }; + let pattern = config::get_pattern(opt.config)?; + let commit_message = make_message_commit(pattern)?; + + if opt.hook { + commit::commit_as_hook(&commit_message)?; + return Ok(()); } + + commit::commit(&commit_message)?; + Ok(()) } From 1da8bdc458e3986130b17ba9f13b7b40006f412d Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Thu, 3 Mar 2022 18:28:22 -0300 Subject: [PATCH 4/7] chore(cargo): Update dependecies --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 8 ++++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4904532..c03ae8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,15 +13,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.53" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" +checksum = "159bb86af3a200e19a068f4224eae4c8bb2d0fa054c7e5d1cacd5cef95e684cd" [[package]] name = "assert_fs" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633ff1df0788db09e2087fb93d05974e93acb886ac3aec4e67be1d6932e360e4" +checksum = "cf09bb72e00da477c2596865e8873227e2196d263cca35414048875dbbeea1be" dependencies = [ "doc-comment", "globwalk", @@ -71,9 +71,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.0.14" +version = "3.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63edc3f163b3c71ec8aa23f9bd6070f77edbf3d1d198b164afa90ff00e4ec62" +checksum = "ced1892c55c910c1219e98d6fc8d71f6bddba7905866ce740066d8bfea859312" dependencies = [ "atty", "bitflags", @@ -88,9 +88,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.0.5" +version = "3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41a0645a430ec9136d2d701e54a95d557de12649a9dd7109ced3187e648ac824" +checksum = "da95d038ede1a964ce99f49cbe27a7fb538d1da595e4b4f70b8c8f338d17bf16" dependencies = [ "heck", "proc-macro-error", @@ -630,9 +630,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" dependencies = [ "itoa", "ryu", @@ -723,9 +723,9 @@ checksum = "13a4ec180a2de59b57434704ccfad967f789b12737738798fa08798cd5824c16" [[package]] name = "textwrap" -version = "0.14.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" diff --git a/Cargo.toml b/Cargo.toml index 989f733..9843fab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,13 +16,13 @@ license = "MIT" [dependencies] inquire = "0.2.1" serde = { version = "1.0.136", features = ["derive"] } -serde_json = "1.0.78" -clap = { version = "3.0.14", features = ["derive"] } +serde_json = "1.0.79" +clap = { version = "3.1.5", features = ["derive"] } dirs = "4.0.0" -anyhow = "1.0.53" +anyhow = "1.0.55" [dev-dependencies] -assert_fs = "1.0.6" +assert_fs = "1.0.7" [package.metadata.deb] name = "commit" From c2f570e819648b58f957d5c1a783f072c843662e Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 12 Mar 2022 20:42:33 -0300 Subject: [PATCH 5/7] refactor: Use ok_or_else instead ok_or --- src/commit.rs | 2 +- src/config/mod.rs | 2 +- src/config/tests.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/commit.rs b/src/commit.rs index c1a0cbd..c68d9e1 100644 --- a/src/commit.rs +++ b/src/commit.rs @@ -42,7 +42,7 @@ pub fn commit(commit_message: &str) -> Result<()> { output .status .code() - .ok_or(anyhow!("Could not get exit code"))?, + .ok_or_else(|| anyhow!("Could not get exit code"))?, ); } Err(e) => { diff --git a/src/config/mod.rs b/src/config/mod.rs index 414d5d6..a945cd7 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -84,7 +84,7 @@ fn get_config_path() -> Result { Ok(current_file) } else { let config_file = dirs::config_dir() - .ok_or(anyhow!("Could not find config directory"))? + .ok_or_else(|| anyhow!("Could not find config directory"))? .join("commit/commit.json"); Ok(config_file) } diff --git a/src/config/tests.rs b/src/config/tests.rs index dab129e..c512a24 100644 --- a/src/config/tests.rs +++ b/src/config/tests.rs @@ -26,7 +26,7 @@ fn select_custom_config_path_test() -> Result<()> { #[test] fn get_config_path_test() -> Result<()> { let config_file = dirs::config_dir() - .ok_or(anyhow!("Could not find config directory"))? + .ok_or_else(|| anyhow!("Could not find config directory"))? .join("commit/commit.json"); let config_path = get_config_path(); assert_eq!(config_file.to_str(), config_path?.to_str()); From 86d95f555fc807851b1ea96d9e2c75e388f4c561 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 12 Mar 2022 20:45:46 -0300 Subject: [PATCH 6/7] chore(cargo): Update dependencies --- Cargo.lock | 8 ++++---- Cargo.toml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c03ae8e..7d1a5fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.55" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "159bb86af3a200e19a068f4224eae4c8bb2d0fa054c7e5d1cacd5cef95e684cd" +checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" [[package]] name = "assert_fs" @@ -71,9 +71,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.1.5" +version = "3.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced1892c55c910c1219e98d6fc8d71f6bddba7905866ce740066d8bfea859312" +checksum = "d8c93436c21e4698bacadf42917db28b23017027a4deccb35dbe47a7e7840123" dependencies = [ "atty", "bitflags", diff --git a/Cargo.toml b/Cargo.toml index 9843fab..142241e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,9 +17,9 @@ license = "MIT" inquire = "0.2.1" serde = { version = "1.0.136", features = ["derive"] } serde_json = "1.0.79" -clap = { version = "3.1.5", features = ["derive"] } +clap = { version = "3.1.6", features = ["derive"] } dirs = "4.0.0" -anyhow = "1.0.55" +anyhow = "1.0.56" [dev-dependencies] assert_fs = "1.0.7" From 37287e1e2c5b1fb6b5c9dc7af5caeb7aeb14b1a5 Mon Sep 17 00:00:00 2001 From: Pedro Mendes Date: Sat, 12 Mar 2022 20:49:54 -0300 Subject: [PATCH 7/7] Bump to 0.4.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7d1a5fb..d0d2dc7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,7 +101,7 @@ dependencies = [ [[package]] name = "commit" -version = "0.3.1" +version = "0.4.0" dependencies = [ "anyhow", "assert_fs", diff --git a/Cargo.toml b/Cargo.toml index 142241e..efcb9c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "commit" -version = "0.3.1" +version = "0.4.0" edition = "2021" homepage = "https://github.com/alt-art/commit" repository = "https://github.com/alt-art/commit"