Skip to content

Commit

Permalink
feat(cli): add file parameter to verify command
Browse files Browse the repository at this point in the history
"cog verify" can now read the commit message from a file with the "-f" or "--file" parameter. This parameter is mutually exclusive with the "message" argument.

implement #279
  • Loading branch information
sebasnabas authored and oknozor committed May 4, 2023
1 parent af08a7e commit 5e02aef
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 3 deletions.
29 changes: 26 additions & 3 deletions src/bin/cog/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod commit;

use std::fs;
use std::path::PathBuf;

use cocogitto::conventional::changelog::template::{RemoteContext, Template};
Expand Down Expand Up @@ -168,7 +169,12 @@ enum Command {
/// Verify a single commit message
Verify {
/// The commit message
message: String,

#[arg(conflicts_with = "file", required_unless_present = "file")]
message: Option<String>,

#[arg(long, short)]
file: Option<PathBuf>,

/// Ignore merge commit messages
#[arg(short, long)]
Expand All @@ -187,7 +193,7 @@ enum Command {

/// Generate the changelog with the given template.
///
/// Possible values are 'remote', 'full_hash', 'default' or the path to your template.
/// Possible values are 'remote', 'full_hash', 'default' or the path to your template.
/// If not specified cog will use cog.toml template config or fallback to 'default'.
#[arg(long, short)]
template: Option<String>,
Expand Down Expand Up @@ -388,14 +394,31 @@ fn main() -> Result<()> {
}
Command::Verify {
message,
file,
ignore_merge_commits,
} => {
let ignore_merge_commits = ignore_merge_commits || SETTINGS.ignore_merge_commits;
let author = CocoGitto::get()
.map(|cogito| cogito.get_committer().unwrap())
.ok();

conv_commit::verify(author, &message, ignore_merge_commits)?;
let commit_message = match (message, file) {
(Some(message), None) => message,
(None, Some(file_path)) => {
if !file_path.exists() {
bail!("File {file_path:#?} does not exist");
}

match fs::read_to_string(file_path) {
Err(e) => bail!("Could not read the file ({e})"),
Ok(msg) => msg,
}
}
(None, None) => unreachable!(),
(Some(_), Some(_)) => unreachable!(),
};

conv_commit::verify(author, &commit_message, ignore_merge_commits)?;
}
Command::Check {
from_latest_tag,
Expand Down
1 change: 1 addition & 0 deletions tests/assets/commit_message.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
chore: a commit message
64 changes: 64 additions & 0 deletions tests/cog_tests/verify.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::process::Command;

use crate::helpers::*;
Expand Down Expand Up @@ -148,3 +150,65 @@ fn should_ignore_merge_commit_via_config() -> Result<()> {

Ok(())
}

#[sealed_test(files = ["tests/assets/commit_message.txt"])]
fn verify_file_ok() -> Result<()> {
// Arrange
git_init()?;
let expected = indoc!(
"a commit message (not committed) - now
\tAuthor: Tom
\tType: chore
\tScope: none
",
);

// Act
Command::cargo_bin("cog")?
.arg("verify")
.arg("--file")
.arg("commit_message.txt")
// Assert
.assert()
.success()
.stderr(expected);

Ok(())
}

#[test]
fn verify_with_not_existing_file_fails() -> Result<()> {
// Act
Command::cargo_bin("cog")?
.arg("verify")
.arg("--file")
.arg("not_existing_file.txt")
// Assert
.assert()
.failure();

Ok(())
}

#[cfg(target_family = "unix")]
#[sealed_test(files = ["tests/assets/commit_message.txt"])]
fn verify_with_unreadable_file_fails() -> Result<()> {
let file_name = "commit_message.txt";

// Arrange
let mut perms = fs::metadata(file_name)?.permissions();
perms.set_mode(0o333); // write-only
fs::set_permissions(file_name, perms)?;

// Act
Command::cargo_bin("cog")?
.arg("verify")
.arg("--file")
.arg(file_name)
// Assert
.assert()
.failure();

Ok(())
}

0 comments on commit 5e02aef

Please sign in to comment.