conventional-changelog / conventional-changelog/commitlint
Feature Request(rules): Multiple/escalating rule levels
- Dominant language
- TypeScript
- Stars
- 18.7k
- Forks
- 970
- Avg merge
- 7h 33m
- Merged PRs (30d)
- 49
Description
I would like to be able to set escalating limitations of values for particular rules. For example, setting a warning at `header-max-length>=50` but an error at `header-max-length>72`.
We should be able to either
1. Have rule functions that are passed the commit message's attribute value so they can conditionally return the appropriate rule level, applicability, and value.
1. Allow specifying multiple rule levels at once (an array of rule conditions, only one rule condition(i.e. value+applicability) per level)
I set a function for each of the rules, and they don't seem to be passed any values at all. I can't seem to find an existing issue or anything on the [roadmap](https://github.com/conventional-changelog/commitlint#roadmap) that talks about this feature.
Thanks for your consideration!
## Expected Behavior
```javascript
{
"header-max-length": [[2, "always", 72], [1, "always", 50]]
}
// currently throws Error: level for rule header-max-length must be number, received [ 2, 'always', 72 ] of type object
// or
{
"header-max-length": (value) => value >= 50 ? [[2, "always", 72] : [1, "always", 50]]
}
// or
{
"header-max-length": async (value) => value >= 50 ? [[2, "always", 72] : [1, "always", 50]]
}
// or
{
"header-max-length": (value) => Promise.resolve(value >= 50 ? [[2, "always", 72] : [1, "always", 50]])
}
```
## Current Behavior
The [current docs](https://commitlint.js.org/#/reference-rules) say that we can do the following:
```javascript
{
"header-max-length": [0, "always", 72]
}
// or
{
"header-max-length": () => [0, "always", 72]
}
// or
{
"header-max-length": async () => [0, "always", 72]
}
// or
{
"header-max-length": () => Promise.resolve([0, "always", 72])
}
```
## Affected packages
* [ ] cli
* [x] core
* [ ] prompt
* [ ] config-angular
## Possible Solution
Change the rules map/object `Map` to `Map` where ruleConditions removes the `level` index in the latter config.
I believe the actual work running all the rules (runtime commit msg adding to the built rules) is [done here](https://github.com/conventional-changelog/commitlint/blob/8e47985806c9cebdde9e2a5e8919dc98d7c4b235/%40commitlint/cli/src/cli.js#L159-L161). I think we need to make `loaded.rules` a function instead of an object.
## Steps to Reproduce (for bugs)
N/A
## Context
Obviously this is a breaking change, so we should be cautious. I think the most important part is agreeing that this functionality is desired.
I liked that the rules config accepted functions for the conditions, but I was really surprised that the functions aren't passed any information at all. It seems like the execution of the rules is supposed to be a [build-time](https://github.com/conventional-changelog/commitlint/blob/master/%40commitlint/load/src/index.js#L85) [execution](https://github.com/conventional-changelog/commitlint/blob/master/%40commitlint/execute-rule/src/index.ts#L20) and not a run-time execution, so it would be a non-trivial undertaking to add this functionality.
Am I understanding the code correctly?
## Your Environment
| Executable | Version |
| ---: | :--- |
| `commitlint --version` | 8.1.0 |
| `git --version` | 2.22.0 |
| `node --version` | v12.6.0 |
Contributor guide
Assessment
This issue has not been assessed yet.