Skip to content

Commit 682c74d

Browse files
committed
feat: add new command to check-commit message
1 parent 7490db1 commit 682c74d

File tree

3 files changed

+109
-0
lines changed

3 files changed

+109
-0
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,29 @@ git push origin main
3030
git push origin --tags
3131
```
3232

33+
### `check-commits`
34+
35+
Validates commit messages against [Conventional Commits](https://www.conventionalcommits.org/) and custom rules:
36+
37+
| Section | Supported Prefixes |
38+
| -------------- | ------------------------------------------ |
39+
| **Added** | `feat` |
40+
| **Fixed** | `fix` |
41+
| **Changed** | `perf`, `refactor`, `style`, `ci`, `build` |
42+
| **Removed** | `removed` |
43+
| **Security** | `security` |
44+
| **Deprecated** | `deprecated` |
45+
46+
* Logs a warning for any invalid commit prefix.
47+
* Can be configured to fail the build if any invalid commit is found using the `failOnWarning` parameter:
48+
3349
## Usage
3450

3551
Add the plugin to your project or run it using the CLI:
3652

3753
```bash
54+
mvn io.github.zorin95670:semantic-version:check-commit
55+
mvn io.github.zorin95670:semantic-version:check-commit -DfailOnWarning=true
3856
mvn io.github.zorin95670:semantic-version:changelog
3957
mvn io.github.zorin95670:semantic-version:changelog -DdryRun=true
4058
mvn io.github.zorin95670:semantic-version:release
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.github.zorin95670.semver;
2+
3+
import io.github.zorin95670.semver.service.GitService;
4+
import org.apache.maven.plugin.AbstractMojo;
5+
import org.apache.maven.plugin.MojoFailureException;
6+
import org.apache.maven.plugins.annotations.LifecyclePhase;
7+
import org.apache.maven.plugins.annotations.Mojo;
8+
import org.apache.maven.plugins.annotations.Parameter;
9+
10+
import java.io.File;
11+
12+
@Mojo(name = "check-commit", defaultPhase = LifecyclePhase.NONE)
13+
public class CheckCommitMojo extends AbstractMojo {
14+
15+
@Parameter(property = "failOnWarning", defaultValue = "false")
16+
private boolean failOnWarning;
17+
18+
@Parameter(defaultValue = "${project.basedir}", readonly = true)
19+
private File basedir;
20+
21+
public void execute() throws MojoFailureException {
22+
getLog().info("Check commit plugin started");
23+
GitService gitService = new GitService(basedir);
24+
25+
gitService.checkCommitNames(failOnWarning, getLog());
26+
}
27+
}

src/main/java/io/github/zorin95670/semver/service/GitService.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.github.zorin95670.semver.service;
22

3+
import org.apache.maven.plugin.MojoFailureException;
4+
import org.apache.maven.plugin.logging.Log;
35
import org.eclipse.jgit.api.Git;
46
import org.eclipse.jgit.api.errors.*;
57
import org.eclipse.jgit.lib.ObjectId;
@@ -322,4 +324,66 @@ public String getUrl() {
322324

323325
return null;
324326
}
327+
328+
public void checkCommitNames(boolean failOnWarning, Log log) throws MojoFailureException {
329+
List<String> validPrefixes = Arrays.asList(
330+
"feat", "fix", "perf", "refactor", "style", "ci", "build",
331+
"removed", "security", "deprecated"
332+
);
333+
334+
Repository repo = git.getRepository();
335+
336+
Iterable<RevCommit> commits;
337+
338+
try {
339+
List<Ref> tagList = git.tagList().call();
340+
RevCommit lastTaggedCommit = null;
341+
342+
if (!tagList.isEmpty()) {
343+
RevWalk revWalk = new RevWalk(repo);
344+
RevCommit latest = null;
345+
for (Ref tag : tagList) {
346+
RevCommit commit = revWalk.parseCommit(repo.resolve(tag.getName()));
347+
if (latest == null || commit.getCommitTime() > latest.getCommitTime()) {
348+
latest = commit;
349+
}
350+
}
351+
lastTaggedCommit = latest;
352+
revWalk.dispose();
353+
}
354+
355+
if (lastTaggedCommit != null) {
356+
commits = git.log().add(repo.resolve("HEAD")).not(lastTaggedCommit).call();
357+
} else {
358+
commits = git.log().call();
359+
}
360+
} catch (GitAPIException | IOException e) {
361+
throw new RuntimeException(e);
362+
}
363+
364+
boolean hasError = false;
365+
boolean hasWarning = false;
366+
367+
for (RevCommit commit : commits) {
368+
String message = commit.getShortMessage();
369+
370+
if (!message.matches("^[a-z]+(\\([\\w\\-]+\\))?: .+")) {
371+
log.error("Invalid commit format: \"" + message + "\"");
372+
hasError = true;
373+
continue;
374+
}
375+
376+
String type = message.split("[:(]")[0];
377+
if (!validPrefixes.contains(type)) {
378+
log.warn("Unsupported commit prefix: \"" + message + "\"");
379+
hasWarning = true;
380+
}
381+
}
382+
383+
if (hasError || (failOnWarning && hasWarning)) {
384+
throw new MojoFailureException("Some commits do not follow the Conventional Commit format.");
385+
} else {
386+
log.info("✅ all commits are valid.");
387+
}
388+
}
325389
}

0 commit comments

Comments
 (0)