Skip to content
This repository was archived by the owner on Mar 27, 2023. It is now read-only.

Commit 29d8c2e

Browse files
committed
chore(commitlint): updating commitlint configuration
Adjusting the commitlint configuration for the new commit strategy. Every commit has to follow the structure of `$type($project/$projectScope): $subject` e.g. We added a feature to Button component in Clarity Core. The commit message will look like `feat(core/button): added a feature x.y.z` Signed-off-by: Bogdan Bogdanov <[email protected]>
1 parent 4e83cfc commit 29d8c2e

File tree

10 files changed

+865
-233
lines changed

10 files changed

+865
-233
lines changed

commitlint.config.js

Lines changed: 134 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,141 @@
1-
const scopes = [
2-
'a11y',
3-
'accordion',
4-
'alert',
5-
'badge',
6-
'breadcrumb',
7-
'build',
8-
'button',
9-
'card',
10-
'checkbox',
11-
'color',
12-
'combobox',
13-
'datagrid',
14-
'datalist',
15-
'date-picker',
16-
'dropdown',
17-
'form',
18-
'form-group',
19-
'grid',
20-
'header',
21-
'i18n',
22-
'input',
23-
'label',
24-
'list',
25-
'login',
26-
'modal',
27-
'navigation',
28-
'pagination',
29-
'password',
30-
'progress-bar',
31-
'radio',
32-
'schematics',
33-
'select',
34-
'sidenav',
35-
'signpost',
36-
'spinner',
37-
'stack-view',
38-
'stepper',
39-
'table',
40-
'tabs',
41-
'textarea',
42-
'timeline',
43-
'toggle',
44-
'tooltip',
45-
'tree-view',
46-
'vertical-nav',
47-
'wizard',
48-
'icons',
49-
'range',
50-
'website',
51-
'panel',
52-
];
1+
/* eslint-disable @typescript-eslint/no-var-requires */
2+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
3+
4+
const { resolve } = require('path');
5+
const commitLintConfig = require('@commitlint/config-conventional');
6+
7+
const core = require('./scripts/commitlint/coreScopes');
8+
const angular = require('./scripts/commitlint/angularScopes');
9+
const website = require('./scripts/commitlint/websiteScopes');
10+
const packages = require('./scripts/commitlint/packagesScopes');
11+
const custom = require('./scripts/commitlint/customScopes');
12+
13+
const coreScopes = core.getScopes(resolve(process.cwd(), './packages/core'));
14+
const angularScopes = angular.getScopes(resolve(process.cwd(), './packages/angular'));
15+
const websiteScopes = website.getScopes(resolve(process.cwd(), './apps/website'));
16+
const packagesScopes = packages.getScopes(resolve(process.cwd(), './packages'));
17+
const customScopes = custom.getScopes();
18+
19+
const scopes = new Set([...customScopes, ...coreScopes, ...angularScopes, ...websiteScopes, ...packagesScopes]);
20+
21+
// Merging what @commitlint/config-convensional has with our new two types of commit
22+
const types = ['a11y', 'release'].concat(commitLintConfig.rules['type-enum'][2]);
5323

5424
module.exports = {
5525
extends: ['@commitlint/config-conventional'],
5626
rules: {
57-
'scope-enum': [2, 'always', scopes],
27+
'scope-enum': [2, 'always', [...scopes]],
28+
'type-enum': [2, 'always', types],
5829
'header-max-length': [2, 'always', 100],
5930
},
31+
prompt: {
32+
messages: {
33+
skip: ':skip',
34+
max: 'upper %d chars',
35+
min: '%d chars at least',
36+
emptyWarning: 'can not be empty',
37+
upperLimitWarning: 'over limit',
38+
lowerLimitWarning: 'below limit',
39+
},
40+
questions: {
41+
type: {
42+
description: "Select the type of change that you're committing:",
43+
enum: {
44+
a11y: {
45+
description: 'Commit that provides Accessibility change',
46+
title: 'Accessibility',
47+
emoji: '♿️',
48+
},
49+
release: {
50+
description: 'Commit that specifies a release',
51+
title: 'Release',
52+
emoji: '🏭',
53+
},
54+
feat: {
55+
description: 'A new feature',
56+
title: 'Features',
57+
emoji: '✨',
58+
},
59+
fix: {
60+
description: 'A bug fix',
61+
title: 'Bug Fixes',
62+
emoji: '🐞',
63+
},
64+
docs: {
65+
description: 'Documentation only changes',
66+
title: 'Documentation',
67+
emoji: '📚',
68+
},
69+
style: {
70+
description:
71+
'Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)',
72+
title: 'Styles',
73+
emoji: '💎',
74+
},
75+
refactor: {
76+
description: 'A code change that neither fixes a bug nor adds a feature',
77+
title: 'Code Refactoring',
78+
emoji: '📦',
79+
},
80+
perf: {
81+
description: 'A code change that improves performance',
82+
title: 'Performance Improvements',
83+
emoji: '🚀',
84+
},
85+
test: {
86+
description: 'Adding missing tests or correcting existing tests',
87+
title: 'Tests',
88+
emoji: '🚨',
89+
},
90+
build: {
91+
description:
92+
'Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)',
93+
title: 'Builds',
94+
emoji: '🛠',
95+
},
96+
ci: {
97+
description:
98+
'Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)',
99+
title: 'Continuous Integrations',
100+
emoji: '🤖',
101+
},
102+
chore: {
103+
description: "Other changes that don't modify src or test files",
104+
title: 'Chores',
105+
emoji: '🧹',
106+
},
107+
revert: {
108+
description: 'Reverts a previous commit',
109+
title: 'Reverts',
110+
emoji: '🗑',
111+
},
112+
},
113+
},
114+
scope: {
115+
description: 'What is the scope of this change (e.g. core/alert )',
116+
},
117+
body: {
118+
description: 'Provide a GitHub issue or explanation what this change does if the commit message is not enough',
119+
},
120+
isBreaking: {
121+
description: 'Are there any breaking changes?',
122+
},
123+
breakingBody: {
124+
description: 'A BREAKING CHANGE commit requires a body. Please enter a longer description of the commit itself',
125+
},
126+
breaking: {
127+
description: 'Describe the breaking changes',
128+
},
129+
isIssueAffected: {
130+
description: 'Does this change affect any open issues?',
131+
},
132+
issuesBody: {
133+
description:
134+
'If issues are closed, the commit requires a body. Please enter a longer description of the commit itself',
135+
},
136+
issues: {
137+
description: 'Add issue references (e.g. "fix #123", "re #123".)',
138+
},
139+
},
140+
},
60141
};

package.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
]
3333
},
3434
"scripts": {
35+
"commit": "git-cz",
3536
"ng": "ng",
3637
"clean:modules": "del ./**/node_modules",
3738
"clean": "del ./dist && yarn run schematics:clean",
@@ -106,8 +107,10 @@
106107
"eslint-rule:test": "yarn --cwd packages/eslint-plugin-clarity-adoption test"
107108
},
108109
"devDependencies": {
109-
"@commitlint/cli": "8.0.0",
110-
"@commitlint/config-conventional": "8.0.0",
110+
"@commitlint/cli": "^13.0.0",
111+
"@commitlint/config-conventional": "^13.0.0",
112+
"@commitlint/prompt": "^13.0.0",
113+
"commitizen": "^4.2.4",
111114
"@types/node": "^12.11.1",
112115
"@typescript-eslint/eslint-plugin": "2.27.0",
113116
"@typescript-eslint/parser": "2.27.0",
@@ -146,6 +149,11 @@
146149
"ts-node": "8.2.0",
147150
"typescript": "3.7.5"
148151
},
152+
"config": {
153+
"commitizen": {
154+
"path": "@commitlint/prompt"
155+
}
156+
},
149157
"engines": {
150158
"node": ">=14 <15",
151159
"yarn": ">=1.22.4 <2",

scripts/commitlint/angularScopes.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
2+
3+
const components = [
4+
'accordion',
5+
'alert',
6+
'badge',
7+
'breadcrumb',
8+
'button',
9+
'card',
10+
'checkbox',
11+
'combobox',
12+
'datagrid',
13+
'datalist',
14+
'date-picker',
15+
'dropdown',
16+
'form-group',
17+
'form',
18+
'grid',
19+
'header',
20+
'i18n',
21+
'icon',
22+
'input',
23+
'label',
24+
'list',
25+
'login',
26+
'modal',
27+
'navigation',
28+
'pagination',
29+
'panel',
30+
'password',
31+
'progress-bar',
32+
'radio',
33+
'range',
34+
'select',
35+
'sidenav',
36+
'signpost',
37+
'spinner',
38+
'stack-view',
39+
'stepper',
40+
'table',
41+
'tabs',
42+
'textarea',
43+
'timeline',
44+
'toggle',
45+
'tooltip',
46+
'tree-view',
47+
'vertical-nav',
48+
'wizard',
49+
];
50+
51+
module.exports = {
52+
components,
53+
getScopes: () => {
54+
return components.map(c => `angular/${c}`).concat(['angular']);
55+
},
56+
};

scripts/commitlint/common.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
2+
const { readdirSync } = require('fs');
3+
4+
/**
5+
* Searches for scopes based on predicate
6+
*
7+
* @param {String} path of folder
8+
* @param {Function} predicate that will verify the folder is a scope one
9+
* @param {Boolean} topLevel continues with next direct child directory if the predicate is met
10+
*
11+
* @returns {Array<string>} all scope names
12+
*/
13+
const findScopes = (path, predicate, topLevel) => {
14+
let scopes = [];
15+
16+
const dir = readdirSync(path, { withFileTypes: true });
17+
18+
dir
19+
.filter(x => x.isDirectory())
20+
.filter(x => x.name !== 'node_modules')
21+
.forEach(element => {
22+
const elementPath = `${path}/${element.name}`;
23+
24+
if (predicate(elementPath)) {
25+
scopes.push(element.name);
26+
}
27+
28+
if (topLevel) {
29+
return;
30+
}
31+
32+
scopes = scopes.concat(findScopes(elementPath, predicate));
33+
});
34+
35+
return scopes;
36+
};
37+
38+
module.exports = {
39+
findScopes,
40+
};

scripts/commitlint/coreScopes.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* eslint-disable @typescript-eslint/no-var-requires */
2+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
3+
const { readdirSync } = require('fs');
4+
const { findScopes } = require('./common');
5+
6+
const isScopeDirectory = directory => {
7+
const dir = readdirSync(directory, { withFileTypes: true });
8+
9+
const isScope = dir.find(el => el.isFile() && el.name.includes('.element.ts'));
10+
11+
if (isScope) {
12+
return true;
13+
}
14+
15+
return false;
16+
};
17+
18+
module.exports = {
19+
getScopes: coreProjectPath => {
20+
const elements = findScopes(`${coreProjectPath}/src`, isScopeDirectory);
21+
22+
const core = elements.map(x => `core/${x}`);
23+
const react = elements.map(x => `react/${x}`);
24+
25+
const design = findScopes(`${coreProjectPath}/src/styles`, () => true).map(x => `core/${x}`);
26+
27+
return new Set([...core, ...react, ...design, 'core', 'react']);
28+
},
29+
};

scripts/commitlint/customScopes.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
2+
const { readFileSync } = require('fs');
3+
const { resolve } = require('path');
4+
5+
const getJsonData = path => {
6+
const json = readFileSync(path, 'utf8');
7+
8+
try {
9+
return JSON.parse(json);
10+
} catch {
11+
throw new Error(`${path} has invalid syntax`);
12+
}
13+
};
14+
15+
const generateCommitLintScopes = projects => {
16+
let _scopes = [];
17+
18+
Object.entries(projects).forEach(([project, scopes]) => {
19+
const projectScopes = scopes.map(scope => `${project}/${scope}`);
20+
_scopes = _scopes.concat([project, ...projectScopes]);
21+
});
22+
23+
return _scopes;
24+
};
25+
26+
const getScopes = path => {
27+
if (!path) {
28+
path = resolve(process.cwd(), './scripts/commitlint/customScopes.json');
29+
}
30+
31+
const scopes = getJsonData(path);
32+
33+
if (scopes) {
34+
return new Set(generateCommitLintScopes(scopes));
35+
}
36+
37+
return new Set([]);
38+
};
39+
40+
module.exports = {
41+
getScopes,
42+
};

0 commit comments

Comments
 (0)