Skip to content

Commit 31add36

Browse files
committed
feat: add commit types description
1 parent 503c632 commit 31add36

4 files changed

Lines changed: 49 additions & 32 deletions

File tree

lib/commands/git/commit-msg.js

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ git commit -m"feat(core)!: commit description"
3838
const pkg = this._findGitPackage();
3939
if ( !pkg ) return;
4040

41+
// prepare types
42+
const types = {};
43+
for ( const [ type, config ] of Object.entries( pkg.cliConfig?.commits.types || {} ) ) {
44+
if ( !config ) continue;
45+
46+
types[ type ] = {
47+
...config,
48+
type,
49+
};
50+
}
51+
4152
const message = fs.readFileSync( process.cli.arguments.path, "utf8" ),
4253
isRevert = fs.existsSync( ".git/REVERT_HEAD" );
4354

@@ -53,7 +64,7 @@ git commit -m"feat(core)!: commit description"
5364
// merge commit
5465
if ( commit.isMerge ) {
5566

56-
// merge commit shoild have default message
67+
// merge commit should have default message
5768
if ( !commit.hasDefaultMergeSubject ) {
5869
return this.#throwError( `Merge commit message should start with "Merge" keyword.` );
5970
}
@@ -79,28 +90,17 @@ git commit -m"feat(core)!: commit description"
7990
return this.#throwError( `Commit message subject should not ends with ".".` );
8091
}
8192

82-
const type = pkg.cliConfig?.commits.types[ commit.type ] || null,
83-
scopes = new Set( Object.entries( pkg.cliConfig?.commits[ type?.primaryChange
93+
const type = types[ commit.type ],
94+
scopes = new Map( Object.entries( pkg.cliConfig?.commits[ type?.primaryChange
8495
? "primaryScopes"
85-
: "secondaryScopes" ] || {} )
86-
.map( ( [ key, value ] ) => ( value
87-
? key
88-
: null ) )
89-
.filter( item => item ) );
96+
: "secondaryScopes" ] || {} ).filter( ( [ key, value ] ) => value ) );
9097

9198
// check strict type
9299
if ( pkg.cliConfig?.commits.strictType ) {
93100

94101
// commit type is not valid
95102
if ( !type ) {
96-
return this.#throwError( `Commit type is not valid. Allowed types: ${ Object.entries( pkg.cliConfig.commits.types )
97-
.map( ( key, value ) => ( value
98-
? key
99-
: null ) )
100-
.filter( item => item )
101-
.sort()
102-
.map( item => `"${ item }"` )
103-
.join( ", " ) }.` );
103+
return this.#throwError( `Commit type is not valid. Allowed types:\n${ this.#getAllowedTypes( types ) }` );
104104
}
105105
}
106106

@@ -113,10 +113,7 @@ git commit -m"feat(core)!: commit description"
113113
// commit scope is not valid
114114
if ( !scopes.has( commit.scope ) ) {
115115
if ( scopes.size ) {
116-
return this.#throwError( `Commit scope is not valid. Allowed scopes for this commit type are: ${ [ ...scopes ]
117-
.sort()
118-
.map( item => `"${ item }"` )
119-
.join( ", " ) }.` );
116+
return this.#throwError( `Commit scope is not valid. Allowed scopes for this commit type are:\n${ this.#getAllowedScopes( scopes ) }` );
120117
}
121118
else {
122119
return this.#throwError( `Commit scope is not allowed for this commit type.` );
@@ -127,10 +124,7 @@ git commit -m"feat(core)!: commit description"
127124

128125
// commit scope is required
129126
else if ( type.requireScope && scopes.size ) {
130-
return this.#throwError( `Commit scope is required. Allowed scopes for this commit type are: ${ [ ...scopes ]
131-
.sort()
132-
.map( item => `"${ item }"` )
133-
.join( ", " ) }.` );
127+
return this.#throwError( `Commit scope is required. Allowed scopes for this commit type are:\n${ this.#getAllowedScopes( scopes ) }` );
134128
}
135129

136130
// restrict breaking changes to the primary changes only
@@ -148,11 +142,21 @@ git commit -m"feat(core)!: commit description"
148142

149143
// commit type is required
150144
else if ( pkg.cliConfig?.commits.requireType ) {
151-
return this.#throwError( `Commit message must follow conventional commits syntax.` );
145+
return this.#throwError( `Commit type is required. Allowed types:\n${ this.#getAllowedTypes( types ) }` );
152146
}
153147
}
154148

155149
// private
150+
#getAllowedTypes ( types ) {
151+
return Object.values( types )
152+
.map( type => ` - "${ type.type }": ${ type.description };` )
153+
.join( "\n" );
154+
}
155+
156+
#getAllowedScopes ( scopes ) {
157+
return [ ...scopes.keys() ].map( scope => ` - "${ scope }": ${ scopes.get( scope ) };` ).join( "\n" );
158+
}
159+
156160
#throwError ( message ) {
157161
throw result( [ 500, `${ message }\nRefer to the documentation: ${ ansi.link( "https://www.conventionalcommits.org/en/" ) }.` ] );
158162
}

lib/git/changelog.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ export default class GitChangelog {
6262
return this.#changes.hasBreakingChanges;
6363
}
6464

65+
get hasFeatureChanges () {
66+
return this.#changes.hasFeatureChanges;
67+
}
68+
69+
get hasFixChanges () {
70+
return this.#changes.hasFixChanges;
71+
}
72+
6573
// public
6674
async createChangelog ( { currentRelease, header, text, ansi = true } = {} ) {
6775
currentRelease ||= this.#currentRelease;

resources/cli.config.yaml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,25 @@ commits:
6161

6262
types:
6363
feat:
64+
description: a commit that introduces a new feature to the codebase (MINOR in Semantic Versioning)
6465
primaryChange: true
6566
notableChange: true
6667
requireScope: true
6768
strictScope: true
6869
fix:
70+
description: a commit that patches a bug in your codebase (PATCH in Semantic Versioning)
6971
primaryChange: true
7072
notableChange: true
7173
requireScope: true
7274
strictScope: true
7375
refactor:
76+
description: a code change that neither fixes a bug nor adds a feature
7477
primaryChange: true
7578
notableChange: false
7679
requireScope: true
7780
strictScope: true
7881
chore:
82+
description: a commit that does not affect main codebase
7983
primaryChange: false
8084
notableChange: false
8185
requireScope: true
@@ -84,11 +88,11 @@ commits:
8488
primaryScopes: ~
8589

8690
secondaryScopes:
87-
build: Package build related changes
88-
deps: Package dependencies updates
89-
docs: Documentation changes
90-
metadata: Package metadata changes
91-
release: Package release
92-
style: Code stylistic changes
91+
build: package build related changes
92+
deps: package dependencies updates
93+
docs: documentation changes
94+
metadata: package metadata changes
95+
release: package release
96+
style: code stylistic changes
9397

9498
docs: ~

resources/schemas/cli.config.schema.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,13 @@ properties:
156156
- type: object
157157
properties:
158158
title: { type: string }
159+
description: { type: string }
159160
primaryChange: { type: boolean }
160161
notableChange: { type: boolean }
161162
requireScope: { type: boolean }
162163
strictScope: { type: boolean }
163164
additionalProperties: false
164-
required: [primaryChange, notableChange, requireScope, strictScope]
165+
required: [description, primaryChange, notableChange, requireScope, strictScope]
165166

166167
primaryScopes:
167168
anyOf:

0 commit comments

Comments
 (0)