Skip to content

Commit

Permalink
feat: add --verbose option to the CLI to pretty print commits
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinDeJong-TomTom committed Jan 9, 2024
1 parent 7403705 commit ca4282c
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 48 deletions.
130 changes: 109 additions & 21 deletions dist/cli/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,21 @@ Usage: commisery check [options] [TARGET...]
Checks whether commit messages adhere to the Conventional Commits standard.

Arguments:
TARGET The `TARGET` can be:
TARGET The `TARGET` can be:
- a single commit hash
- a file containing the commit message to check
- a revision range that `git rev-list` can interpret
When TARGET is omitted, 'HEAD' is implied.

Options:
-h, --help display help for command
-v, --verbose also print commit message metadata (default: false)
-h, --help display help for command
```

> :bulb: flag will provide an overview of the parsed Conventional Commits elements for each correct message encountered.
> This can be valuable to investigate scenarios in which you expected a different version bump than
> the actual output of the `bump`-action.
### (Pre-) Commit hook

You can use the CLI as a hook in Git to check messages you wrote by creating a `.git/hooks/commit-msg` file with these contents:
Expand Down
54 changes: 32 additions & 22 deletions src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,15 @@ import * as core from "@actions/core";
import * as fs from "fs";
import * as os from "os";

import * as Color from "./colors";

import { ConventionalCommitMessage } from "../commit";
import { Configuration } from "../config";
import { ConventionalCommitError } from "../errors";
import { Command } from "commander";
import { getCommitMessages } from "./utils";
import { getCommitMessages, prettyPrintCommitMessage } from "./utils";

const program = new Command();
const gray = "\x1b[90m";
const red = "\x1b[91m";
const green = "\x1b[92m";
const yellow = "\x1b[93m";
const reset = "\x1b[0m";

program
.name("commisery")
Expand All @@ -44,6 +41,7 @@ program
.description(
"Checks whether commit messages adhere to the Conventional Commits standard."
)
.option("-v, --verbose", "also print commit message metadata.", false)
.argument(
"[TARGET...]",
`The \`TARGET\` can be:
Expand All @@ -52,23 +50,36 @@ program
- a revision range that \`git rev-list\` can interpret
When TARGET is omitted, 'HEAD' is implied.`
)
.action(async (target: string[]) => {
.action(async (target: string[], options) => {
const config = new Configuration(program.opts().config);

if (target.length === 0) {
target = ["HEAD"];
}

let messages: string[] = [];
let messages: { sha: string; body: string }[] = [];
if (fs.existsSync(target.join(" "))) {
messages = [fs.readFileSync(target.join(" "), "utf8")];
messages = [
{
sha: target.join(" "),
body: fs.readFileSync(target.join(" "), "utf8"),
},
];
} else {
messages = await getCommitMessages(target);
}

for (const message of messages) {
try {
new ConventionalCommitMessage(message, undefined, config);
const commitmessage = new ConventionalCommitMessage(
message.body,
message.sha,
config
);

if (options.verbose) {
prettyPrintCommitMessage(commitmessage);
}
} catch (error: unknown) {
if (error instanceof ConventionalCommitError) {
for (const err of error.errors) {
Expand Down Expand Up @@ -99,10 +110,10 @@ program
for (const key in config.tags) {
const bumps: string =
config.tags[key].bump && key !== "fix"
? ` ${yellow}(bumps patch)${reset}`
? ` ${Color.YELLOW("(bumps patch)")}`
: "";
core.info(
`${key}: ${gray}${config.tags[key].description}${reset}${bumps}`
`${key}: ${Color.GRAY(config.tags[key].description ?? "")}${bumps}`
);
}

Expand All @@ -112,21 +123,20 @@ program
dedent(`
Commisery Validation rules
--------------------------
[${green}o${reset}]: ${gray}rule is enabled${reset}, [${red}x${reset}]: ${gray}rule is disabled${reset}
[${Color.GREEN("o")}]: ${Color.GRAY("rule is enabled")}, [${Color.RED(
"x"
)}]: ${Color.GRAY("rule is disabled")}
`)
);

core.info(os.EOL);

for (const rule in config.rules) {
const status: string = config.rules.get(rule)?.enabled
? `${green}o${reset}`
: `${red}x${reset}`;
core.info(
`[${status}] ${rule}: ${gray}${config.rules.get(rule)
?.description}${reset}`
);
}
config.rules.forEach((rule, key) => {
const status: string = rule.enabled
? `${Color.GREEN("o")}`
: `${Color.RED("x")}`;
core.info(`[${status}] ${key}: ${Color.GRAY(rule.description ?? "")}`);
});
});

program.parse();
20 changes: 20 additions & 0 deletions src/cli/colors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Copyright (C) 2023, TomTom (http://tomtom.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export const GRAY = (message: string): string => `\x1b[90m${message}\x1b[0m`;
export const RED = (message: string): string => `\x1b[91m${message}\x1b[0m`;
export const GREEN = (message: string): string => `\x1b[92m${message}\x1b[0m`;
export const YELLOW = (message: string): string => `\x1b[93m${message}\x1b[0m`;
Loading

0 comments on commit ca4282c

Please sign in to comment.