Skip to content

Commit cb205ae

Browse files
authored
[Feature] Add Rule "description template" (#65)
* Add DescriptionTemplateRule * remove has_any_labels_of * up doc * up doc * add release tag placeholder * clean * up self config * up version
1 parent 872ab1a commit cb205ae

23 files changed

+270
-168
lines changed

.mr-linter.yml

+18-23
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,29 @@
11
rules:
2-
"@mr-linter/has_any_labels_of":
2+
"@mr-linter/has_any_labels":
33
labels:
44
- Feature
55
- Bug
66
- Docs
77
- Tests
88
- Optimization
99

10+
"@mr-linter/description_template":
11+
- definition: description must have list of features
12+
template: |
13+
## Added
14+
{text_multiline}
15+
when:
16+
labels:
17+
has: "Feature"
18+
19+
- definition: description must have list of fixed bugs
20+
template: |
21+
## Fixed
22+
{text_multiline}
23+
when:
24+
labels:
25+
has: "Bug"
26+
1027
"@mr-linter/title_must_starts_with_any_prefix":
1128
prefixes:
1229
- '[Feature]'
@@ -53,28 +70,6 @@ rules:
5370
sourceBranch:
5471
isKebabCase: true
5572

56-
- definition: "Labels must be in StudlyCase"
57-
rules:
58-
labels:
59-
$all:
60-
isStudlyCase: true
61-
62-
- definition: "Description must have list of fixed bugs"
63-
rules:
64-
descriptionMarkdown:
65-
containsHeading2: "Fixed"
66-
when:
67-
labels:
68-
has: "Bug"
69-
70-
- definition: "Description must have list of features"
71-
rules:
72-
descriptionMarkdown:
73-
containsHeading2: "Added"
74-
when:
75-
labels:
76-
has: "Feature"
77-
7873
- definition: "Split feature / bug PR"
7974
rules:
8075
labels:

CHANGELOG.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ This file contains changelogs.
66

77
## [Unreleased](https://github.com/ArtARTs36/php-merge-request-linter/compare/0.19.1..master)
88

9+
## [v0.20.0 (2023-09-12)](https://github.com/ArtARTs36/php-merge-request-linter/compare/0.19.1..0.20.0)
10+
11+
### Added
12+
* Added Rule `@mr-linter/description_template` for check description on defined template
13+
14+
### Removed
15+
* Removed rule `@mr-linter/has_any_labels_of`
16+
17+
[💾 Assets](https://github.com/ArtARTs36/php-merge-request-linter/releases/tag/0.20.0)
18+
919
## [v0.19.1 (2023-09-12)](https://github.com/ArtARTs36/php-merge-request-linter/compare/0.19.0..0.19.1)
1020

1121
### Added
@@ -181,7 +191,6 @@ This file contains changelogs.
181191

182192
[💾 Assets](https://github.com/ArtARTs36/php-merge-request-linter/releases/tag/0.14.1)
183193

184-
185194
-----------------------------------------------------------------
186195

187196
## [v0.14.0 (2023-05-27)](https://github.com/ArtARTs36/php-merge-request-linter/compare/0.13.1..0.14.0)

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ docker-pub-try:
9191
-v "${PWD}/.mr-linter.yml:/app/.mr-linter.yml:ro" \
9292
artarts36/merge-request-linter:${MR_LINTER_VERSION} lint
9393

94-
docs: ## Build documentation
94+
docs: docker-build ## Build documentation
9595
docker run \
9696
--rm \
9797
--volume ./:/app \

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
],
1111
"require": {
1212
"php": "^8.2",
13-
"artarts36/str": "^2.5.0",
13+
"artarts36/str": "^2.6.0",
1414
"symfony/console": "^4.0 | ^5.0 | ^6.0",
1515
"guzzlehttp/psr7": "^2",
1616
"artarts36/local-file-system": "^0.1.2",

composer.lock

+7-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/examples.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ You can also specify a list of allowed labels.
2828
2929
```yaml
3030
rules:
31-
"@mr-linter/has_any_labels_of":
31+
"@mr-linter/has_any_labels":
3232
labels:
3333
- Feature
3434
- Bug

docs/rules.md

+13-7
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ The following rules are available:
99
| @mr-linter/description_contains_links_of_all_domains | Merge Request must contain links of all {domains}. |
1010
| @mr-linter/description_not_empty | The description must be filled. |
1111
| @mr-linter/has_all_labels | Merge Request must have all {labels} |
12-
| @mr-linter/has_any_labels | Merge Request must have any labels. |
13-
| @mr-linter/has_any_labels_of | Merge Request must have any {labels}. |
12+
| @mr-linter/has_any_labels | Merge Request must have any {labels}. |
1413
| @mr-linter/jira/has_issue_link | The description must have a link to Jira on a {domain} with {projectCode}. |
1514
| @mr-linter/youtrack/has_issue_link | The description must have a link to YouTrack issue on a {domain} with {projectCode}. |
1615
| @mr-linter/title_must_starts_with_any_prefix | The title must starts with any {prefixes} |
@@ -23,6 +22,7 @@ The following rules are available:
2322
| @mr-linter/no_ssh_keys | Prevent ssh keys from being included in the merge request. |
2423
| @mr-linter/disable_file_extensions | Disable adding files of certain extensions. |
2524
| @mr-linter/title_conventional | The title must match conventional commit pattern https://www.conventionalcommits.org/en/v1.0.0. |
25+
| @mr-linter/description_template | The description must match defined template. Available placeholders: {text}, {text_multiline}, {number}, {word}, {release_tag} |
2626

2727
## Global parameters
2828

@@ -79,11 +79,6 @@ Merge Request must have all {labels}
7979

8080
## @mr-linter/has_any_labels
8181

82-
Merge Request must have any labels.
83-
84-
85-
## @mr-linter/has_any_labels_of
86-
8782
Merge Request must have any {labels}.
8883

8984
### Parameters
@@ -223,3 +218,14 @@ The title must match conventional commit pattern https://www.conventionalcommits
223218
| types | Commit types | array of strings | false | `[build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test]` | "build", "chore", "ci", "docs", "feat", "fix", "perf", "refactor", "revert", "style", "test" |
224219
| task | Check if title contains task number | object | false | NULL | |
225220
| task.projectCodes | Project codes. Empty list allowed for any projects | array of strings | false | | "ABC" |
221+
222+
## @mr-linter/description_template
223+
224+
The description must match defined template. Available placeholders: {text}, {text_multiline}, {number}, {word}, {release_tag}
225+
226+
### Parameters
227+
228+
| Name | Description | Type | Required | Default value |
229+
|------|-------------|------|----------|---------------|
230+
| template | Template for description | string | true | |
231+
| definition | Custom definition | string | false | NULL |

mr-linter-config-schema.json

+41-30
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
]
8282
},
8383
"@mr-linter/has_any_labels": {
84-
"description": "Merge Request must have any labels.",
84+
"description": "Merge Request must have any {labels}.",
8585
"oneOf": [
8686
{
8787
"$ref": "#/definitions/rules_properties_@mr-linter_has_any_labels"
@@ -95,21 +95,6 @@
9595
}
9696
]
9797
},
98-
"@mr-linter/has_any_labels_of": {
99-
"description": "Merge Request must have any {labels}.",
100-
"oneOf": [
101-
{
102-
"$ref": "#/definitions/rules_properties_@mr-linter_has_any_labels_of"
103-
},
104-
{
105-
"type": "array",
106-
"items": {
107-
"$ref": "#/definitions/rules_properties_@mr-linter_has_any_labels_of"
108-
},
109-
"minItems": 1
110-
}
111-
]
112-
},
11398
"@mr-linter/jira/has_issue_link": {
11499
"description": "The description must have a link to Jira on a {domain} with {projectCode}.",
115100
"oneOf": [
@@ -304,6 +289,21 @@
304289
"minItems": 1
305290
}
306291
]
292+
},
293+
"@mr-linter/description_template": {
294+
"description": "The description must match defined template. Available placeholders: {text}, {text_multiline}, {number}, {word}, {release_tag}",
295+
"oneOf": [
296+
{
297+
"$ref": "#/definitions/rules_properties_@mr-linter_description_template"
298+
},
299+
{
300+
"type": "array",
301+
"items": {
302+
"$ref": "#/definitions/rules_properties_@mr-linter_description_template"
303+
},
304+
"minItems": 1
305+
}
306+
]
307307
}
308308
},
309309
"additionalProperties": false
@@ -6273,20 +6273,6 @@
62736273
]
62746274
},
62756275
"rules_properties_@mr-linter_has_any_labels": {
6276-
"type": "object",
6277-
"properties": {
6278-
"critical": {
6279-
"type": "boolean",
6280-
"default": true
6281-
},
6282-
"when": {
6283-
"description": "Conditions that determine whether the rule should run.",
6284-
"$ref": "#/definitions/rule_conditions"
6285-
}
6286-
},
6287-
"additionalProperties": false
6288-
},
6289-
"rules_properties_@mr-linter_has_any_labels_of": {
62906276
"type": "object",
62916277
"properties": {
62926278
"critical": {
@@ -6725,6 +6711,31 @@
67256711
},
67266712
"additionalProperties": false
67276713
},
6714+
"rules_properties_@mr-linter_description_template": {
6715+
"type": "object",
6716+
"properties": {
6717+
"critical": {
6718+
"type": "boolean",
6719+
"default": true
6720+
},
6721+
"when": {
6722+
"description": "Conditions that determine whether the rule should run.",
6723+
"$ref": "#/definitions/rule_conditions"
6724+
},
6725+
"template": {
6726+
"type": "string",
6727+
"description": "Template for description"
6728+
},
6729+
"definition": {
6730+
"type": "string",
6731+
"description": "Custom definition"
6732+
}
6733+
},
6734+
"additionalProperties": false,
6735+
"required": [
6736+
"template"
6737+
]
6738+
},
67286739
"notifications_channel_telegram_bot": {
67296740
"properties": {
67306741
"type": {

src/Application/Rule/Rules/DefaultRules.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ final class DefaultRules
1919
DescriptionNotEmptyRule::NAME => DescriptionNotEmptyRule::class,
2020
HasAllLabelsOfRule::NAME => HasAllLabelsOfRule::class,
2121
HasAnyLabelsRule::NAME => HasAnyLabelsRule::class,
22-
HasAnyLabelsOfRule::NAME => HasAnyLabelsOfRule::class,
2322
HasLinkToJiraTaskRule::NAME => HasLinkToJiraTaskRule::class,
2423
HasLinkToYouTrackIssueRule::NAME => HasLinkToYouTrackIssueRule::class,
2524
TitleStartsWithAnyPrefixRule::NAME => TitleStartsWithAnyPrefixRule::class,
@@ -33,6 +32,7 @@ final class DefaultRules
3332
NoSshKeysRule::NAME => NoSshKeysRule::class,
3433
DisableFileExtensionsRule::NAME => DisableFileExtensionsRule::class,
3534
TitleConventionalRule::NAME => TitleConventionalRule::class,
35+
DescriptionTemplateRule::NAME => DescriptionTemplateRule::class,
3636
];
3737

3838
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace ArtARTs36\MergeRequestLinter\Application\Rule\Rules;
4+
5+
use ArtARTs36\MergeRequestLinter\Application\Rule\Definition\Definition;
6+
use ArtARTs36\MergeRequestLinter\Domain\Request\MergeRequest;
7+
use ArtARTs36\MergeRequestLinter\Domain\Rule\RuleDefinition;
8+
use ArtARTs36\MergeRequestLinter\Shared\Attributes\Description;
9+
use ArtARTs36\Str\Facade\Str;
10+
use ArtARTs36\Str\Template\TemplatePlaceholders;
11+
12+
#[Description('The description must match defined template. Available placeholders: {text}, {text_multiline}, {number}, {word}, {release_tag}')]
13+
final class DescriptionTemplateRule extends AbstractRule
14+
{
15+
public const NAME = '@mr-linter/description_template';
16+
private const TAG_PLACEHOLDER_REGEX = '(v?[0-9]+.[0-9]+.[0-9]+)(\-(\w+))?';
17+
18+
public function __construct(
19+
#[Description('Template for description')]
20+
private readonly string $template,
21+
#[Description('Custom definition')]
22+
private readonly ?string $definition = null,
23+
) {
24+
}
25+
26+
protected function doLint(MergeRequest $request): bool
27+
{
28+
return $request
29+
->descriptionMarkdown
30+
->str()
31+
->trim()
32+
->replace([
33+
"\r\n" => "\n",
34+
])
35+
->matchTemplate(
36+
Str::trim($this->template),
37+
TemplatePlaceholders::default()
38+
->add('release_tag', self::TAG_PLACEHOLDER_REGEX),
39+
)
40+
->matched;
41+
}
42+
43+
public function getDefinition(): RuleDefinition
44+
{
45+
return new Definition(sprintf(
46+
'Description template: %s',
47+
$this->definition ?? 'the description must match template',
48+
));
49+
}
50+
}

src/Application/Rule/Rules/HasAnyLabelsOfRule.php

-27
This file was deleted.

0 commit comments

Comments
 (0)