commitlint
commitlint copied to clipboard
How to use parser headerPattern
The task is to use commitlint to prevent commits from being commited. I use husky as well
when I test it and run
echo "bla bla bla" | npx commitlint
It doesn't catch anything and shows no errors found
⧗ input: bla bla bla
✔ found 0 problems, 0 warnings
Please, help, why it ignores parserOpts.headerPattern
?
Also some other notice:
I need at least one rule, otherwise commitlint
doesn't want to run
Do I need to add headerCorrespondence
to make it work or I can have headerPattern
only?
Can I customize report message in case if I headerPattern
is not matched?
commitlint.config.js
module.exports = {
rules: {
'header-min-length': [2, 'always', 20],
},
parserPreset: {
parserOpts: {
headerPattern: /^(feat|fix|perf|test|BREAKING CHANGE):.*\[REF-(\d{3,}|N\\A)\] \S+ \S+ \S+ \S+ \S+/,
headerCorrespondence: ['type', 'scope', 'subject']
}
}
};
husky in package.json
"husky": {
"hooks": {
"pre-push": "npm test",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
I installed the next
"@commitlint/cli": "^7.5.2",
"@commitlint/parse": "^7.5.0",
Hi @blackswanny,
you're right, this is a bit weird.
With your described config I get this output:
echo "bla bla bla" | npx commitlint
⧗ input: bla bla bla
✖ header must not be shorter than 20 characters, current length is 11 [header-min-length]
✖ found 1 problems, 0 warnings
(Need help? -> https://github.com/conventional-changelog/commitlint#what-is-commitlint )
Using this reduced config...
module.exports = {
parserPreset: {
parserOpts: {
headerPattern: /^(feat|fix|perf|test|BREAKING CHANGE):.*\[REF-(\d{3,}|N\\A)\] \S+ \S+ \S+ \S+ \S+/,
}
}
};
...output is:
echo "bla bla bla bla bla bla bla" | npx commitlint
⧗ input: bla bla bla bla bla bla bla
✖ Please add rules to your `commitlint.config.js`
- Getting started guide: https://git.io/fhHij
- Example config: https://git.io/fhHip [empty-rules]
✖ found 1 problems, 0 warnings
(Need help? -> https://github.com/conventional-changelog/commitlint#what-is-commitlint )
When adding this:
rules: {
'header-min-length': [2, 'always', 20],
},
I get:
echo "bla bla bla bla bla bla bla" | npx commitlint
⧗ input: bla bla bla bla bla bla bla
✔ found 0 problems, 0 warnings
(Need help? -> https://github.com/conventional-changelog/commitlint#what-is-commitlint )
But if the regex is correct I would have expected an error. I guess we need to look into this. What do you think @byCedric ?
I simplified this to be very simple config. The regex below is obviously correct. However, it does not work still
module.exports = {
rules: {
'header-min-length': [2, 'always', 2]
},
parserPreset: {
parserOpts: {
headerPattern: /^feat/,
headerCorrespondence: ['type']
}
}
};
I have been playing with this for a few hours with no avail; wanted to implement a way to at least warn devs that they needed to add the ticket # in the commit message.
Upon finding this tool I was eager to try it, but the parserOpts I give are never used. After fiddling with everything and finding this issue, I installed @commitlint/parser
besides @commitlint/cli
but nothing changed.
I have a commitlint.config.js
similar to the posted above and also tried with the commitlint example (that encourages you to add it to the package.json
but it's missing all the double quotes for JSON format?) and still can commit with any random message.
I'm subscribing particularly to this issue to track and try in a future personal project; I love the idea behind this and am sure it will be great, but the general feel the overall package gives to me is a bit broken (rules being required, documentation and installing modules a bit fuzzy, parsers not being used, the constant 'need help?' message, etc.).
Hey @maeriens , checking for #
in the reference works here for example: https://github.com/sumcumo/node-modules-check/blob/master/commitlint.config.js
If you have questions regarding this you can find me in the commitlint room here: https://devtoolscommunity.herokuapp.com/
ok, i debugged and I know why we think it doesn't work.
-
The parser takes
headerPattern
and runsregex.match
for commit message. Match results are put into output json under names provided inheaderCorrespondence
. SoheaderCorrespondence
is a must have or nothing is saved. For instance['type', 'reference']
https://github.com/conventional-changelog/conventional-changelog/blob/master/packages/conventional-commits-parser/lib/parser.js -
Then tools is looping through only rules and try to ask each rule if it fails against that output. If you have no rule, nothing to be caught.
https://github.com/conventional-changelog/commitlint/blob/master/%40commitlint/lint/src/index.js
- However, the last thing is that we can check only against existing rules, which all expect exact fields in parser output. For instance rule
type-empty
expects thatparsed.type
should be present, which can only happen if we usedheaderCorrespondence: ['type']
. So literally there is no custom check via thisparserOpts
and it totally sticks to rules of commitlint itself. So I have to usetype-empty
rule even if I don't havetype
as my first match in commit message, but something else.
@blackswanny Thanks for the summary! This is essentially a consequence of our decision to leak the commits-parser
configuration as is to commitlint users.
I still think it is right to do so to enable some more complicated use cases but we could def. do a better job on explaining that parserOpts
are considered "advanced" usage.
I expect most users to specify plugins they want to use (which might enable certain parserOpts) instead of touching the low level options like these directly. Could you outline what you tried to achieve with your parserOpts
commitlint rule combination?
@marionebl i just wanted every commit to match this regEx.
/^(feat|fix|perf|test|BREAKING CHANGE):.*\[REF-(\d{3,}|N\\A)\] \S+ \S+ \S+ \S+ \S+/
Plugins would solve the issue, but they are not yet released, waiting for it
I have ben following and would like to implement this same functionality on some projects.
I have tested the following regex:
/^(\w*)(?:\(([JIRA]+-[a-zA-Z0-9_.-]+)\))?\: (.*)$/g

You can see in the image, the groups are correct which also match the pattern I have in my config file.
and the error I receive

@jasonhodges did you manage to resolve the issue, i've been looking at achieving something similar
ok, i debugged and I know why we think it doesn't work.
- The parser takes
headerPattern
and runsregex.match
for commit message. Match results are put into output json under names provided inheaderCorrespondence
. SoheaderCorrespondence
is a must have or nothing is saved. For instance['type', 'reference']
https://github.com/conventional-changelog/conventional-changelog/blob/master/packages/conventional-commits-parser/lib/parser.js![]()
- Then tools is looping through only rules and try to ask each rule if it fails against that output. If you have no rule, nothing to be caught.
https://github.com/conventional-changelog/commitlint/blob/master/%40commitlint/lint/src/index.js
- However, the last thing is that we can check only against existing rules, which all expect exact fields in parser output. For instance rule
type-empty
expects thatparsed.type
should be present, which can only happen if we usedheaderCorrespondence: ['type']
. So literally there is no custom check via thisparserOpts
and it totally sticks to rules of commitlint itself. So I have to usetype-empty
rule even if I don't havetype
as my first match in commit message, but something else.
@blackswanny Hey, Did you find a workaround for your case? I have the same issue...
I also tried to use a similar regex as @jasonhodges did, with the same result.
If I extend @commitlint/config-conventional
on the commitlint.config.js
file, I'll get the same 2 errors:
✖ subject may not be empty [subject-empty]
✖ type may not be empty [type-empty]
However, if I remove that extend, the headerPattern
is simply ignored, and lets any message go through.
This is the regex I tried: https://regex101.com/r/SF1P42/1
@marionebl Hi Mario, Thank you for this awasome tool. Is any news/plans for this issue?
i tried to set none of any keys and values in the rules when i use local custom parser in the commitlint.config.js
file,the headerPattern can be matched.
const types = [
'build', // 构建执行
'ci', // CI 相关
'chore', // 构建工具相关
'docs', // 文档更新
'feat', // 新功能
'fix', // bug 修复
'pref', // 性能优化
'refactor', // 功能重构
'revert', // 回滚操作
'style', // 样式变动
'test' // 单元测试
];
typeEnum = {
rules: {
'type-enum': [2, 'always', types]
},
value: () => types
}
// Level,0-2:0表示禁用这条规则、1表示警告、2表示错误。
// Applicable,always|never:always表示使用规则,never表示不使用规则。
// Value:用于这条规则的值。
// https://commitlint.js.org/#/reference-rules
module.exports = {
extends: [
"@commitlint/config-conventional",
"@commitlint/parse"
],
rules: {
// 'body-leading-blank': [1, 'always'],
// 'footer-leading-blank': [1, 'always'],
// 'header-max-length': [2, 'always', 72],
// 'header-min-length': [2, 'always', 20],
// 'scope-empty': [0, 'never'],
// 'scope-case': [0],
// 'subject-full-stop': [0, 'never'],
// 'subject-case': [0, 'never'],
// 'type-case': [0, 'always', 'lower-case'],
// 'type-empty': [0, 'never'],
// 'type-enum': typeEnum.rules['type-enum']
},
parserPreset: {
parserOpts: {
headerPattern: /^(build|ci|chore|docs|feat|fix|pref|refactor|revert|style|test)(\(\d+\.\d+\.\d+\)): (\S{20,})$/,
headerCorrespondence: ['type', 'scope', 'subject']
}
}
};
- subject less than 20 letter, error, because i set the subject as
(\S{20,})
echo "fix(1.12.1): dajkdajjkk" | npx commitlint
⧗ input: fix(1.12.1): dajkdajjkk
✖ subject may not be empty [subject-empty]
✖ type may not be empty [type-empty]
✖ found 2 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
then i changed the (\S{20,})
to (\S{5,})
, there is no error any more.
so, don't use any rules when use local parser!!!
Okay, I'm having this problem, and I want to ask, Who requires that 'commitlint.config.js' must exist?
Why is it necessary to add this rule, even though the intention is good, It's like forcing me to drink water. It's disgusting .
I have the same problem and wanted to ask if there is a solution in the meantime?
Here is my demo commit to customize commit lint rules with help from here
There is missing the document about parserPreset
and parserOpts
. :(
This guide, by strdr4605 is a great starting point for how to write a custom parser. Cross-references in #3336 as something to reference while documenting parserOpts
and headerPattern
.
I'm still looking for a solution to only configure headerPattern
without breaking everything.
"parserPreset": {
"parserOpts": {
"headerPattern": "^(.[[A-Z]{1,7}-\\d{1,7}.]) \\s*(build|ci|docs|feat|fix|perf|refactor|test)(?:\\(\\S*(animations|bazel|benchpress|common|compiler|compiler-cli|core|elements|forms|http|language-service|localize|platform-browser|platform-browser-dynamic|platform-server|router|service-worker|upgrade|zone.js|packaging|changelog|docs-infra|migrations|devtools)\\))?\\S* (.+)$",
"headerCorrespondence": ["ticketReference", "type", "scope", "subject"]
}
}
Here is working Regex for angular commit pattern with optional scope group. The problem with yours regex is that you have non-grouping groups and headerCorrespondence
can't recognize subject.