-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathcommitlint.config.js
More file actions
87 lines (76 loc) · 2.57 KB
/
Copy pathcommitlint.config.js
File metadata and controls
87 lines (76 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
const { execSync } = require('child_process');
function getNxProjects() {
try {
const output = execSync('npx nx show projects --json', {
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'pipe'],
});
return JSON.parse(output);
} catch {
console.warn(
'commitlint: Could not load Nx projects — scope validation skipped.'
);
return null;
}
}
const validProjects = getNxProjects();
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'scope-case': [0],
'body-max-line-length': [0],
'scope-full-name-for-versioning': [2, 'always'],
},
plugins: [
{
rules: {
'scope-full-name-for-versioning': (parsed) => {
if (!validProjects) {
return [true];
}
const { type, header, notes } = parsed;
// Detect breaking change: header `!:` marker OR BREAKING CHANGE footer
const isBreaking =
!!(header && header.includes('!:')) ||
!!(notes && notes.some((n) => n.title === 'BREAKING CHANGE'));
const requiresFullScope = type === 'feat' || isBreaking;
if (!requiresFullScope) {
return [true];
}
// Use parsed scope if available, otherwise extract from raw header
// (fallback handles parsers that don't support the ! marker)
let scope = parsed.scope;
if (!scope && header) {
const match = header.match(/^\w+\(([^)]+)\)/);
if (match) {
scope = match[1];
}
}
if (!scope) {
const commitType = isBreaking ? 'breaking (!)/feat' : 'feat';
return [
false,
`Scope required for ${commitType} commits.\n` +
`Use: ${type}(@redhat-cloud-services/rbac-client): ...`
];
}
const projectSet = new Set(validProjects);
const scopes = scope.split(',');
for (const s of scopes) {
if (!projectSet.has(s)) {
const commitType = isBreaking ? 'breaking (!)/feat' : 'feat';
const hint = s.startsWith('@redhat-cloud-services/')
? `Project "${s}" not found. Run: npx nx show projects`
: `Use full project name like: ${type}(@redhat-cloud-services/rbac-client)${isBreaking ? '!' : ''}: ...`;
return [
false,
`Scope "${s}" must be a full Nx project name for ${commitType} commits.\n${hint}`,
];
}
}
return [true];
},
},
},
],
};