1
1
<?php
2
2
3
- namespace ArtARTs36 \MergeRequestLinter \Application \Rule \Rules ;
3
+ namespace ArtARTs36 \MergeRequestLinter \Application \Rule \Rules \ TitleConventionalRule ;
4
4
5
5
use ArtARTs36 \MergeRequestLinter \Application \Rule \Definition \Definition ;
6
+ use ArtARTs36 \MergeRequestLinter \Application \Rule \Regex \ProjectCode ;
7
+ use ArtARTs36 \MergeRequestLinter \Application \Rule \Rules \NamedRule ;
6
8
use ArtARTs36 \MergeRequestLinter \Domain \Note \LintNote ;
9
+ use ArtARTs36 \MergeRequestLinter \Domain \Note \Note ;
7
10
use ArtARTs36 \MergeRequestLinter \Domain \Request \MergeRequest ;
8
11
use ArtARTs36 \MergeRequestLinter \Domain \Rule \RuleDefinition ;
9
12
use ArtARTs36 \MergeRequestLinter \Shared \Attributes \Description ;
10
13
use ArtARTs36 \MergeRequestLinter \Shared \Attributes \Example ;
11
14
use ArtARTs36 \MergeRequestLinter \Shared \Attributes \Generic ;
12
15
use ArtARTs36 \MergeRequestLinter \Shared \DataStructure \Arrayee ;
16
+ use ArtARTs36 \Str \Str ;
13
17
14
18
/**
15
19
* The title must match conventional commit pattern https://www.conventionalcommits.org/en/v1.0.0.
@@ -19,7 +23,7 @@ final class TitleConventionalRule extends NamedRule
19
23
{
20
24
public const NAME = '@mr-linter/title_conventional ' ;
21
25
22
- private const REGEX = '/^([a-z]+){1}(\([\w\-\.]+\))?(!)?: ([\w ])+([\s\S]*)/mis ' ;
26
+ private const REGEX = '/^(?<type>( [a-z]+)) {1}(?<module> \([\w\-\.]+\))?(!)?: (?<description>( [\w ])+([\s\S]*) )/mis ' ;
23
27
24
28
private const DEFAULT_TYPES = [
25
29
'build ' ,
@@ -41,6 +45,7 @@ final class TitleConventionalRule extends NamedRule
41
45
public function __construct (
42
46
#[Generic(Generic::OF_STRING )]
43
47
private readonly Arrayee $ types ,
48
+ private readonly ?TitleConventionalTask $ task ,
44
49
) {
45
50
}
46
51
@@ -62,10 +67,12 @@ public static function make(
62
67
#[Example('style ' )]
63
68
#[Example('test ' )]
64
69
?Arrayee $ types = null ,
70
+ #[Description('Check if title contains task number ' )]
71
+ ?TitleConventionalTask $ task = null ,
65
72
): self {
66
73
$ types ??= new Arrayee (self ::DEFAULT_TYPES );
67
74
68
- return new self ($ types );
75
+ return new self ($ types, $ task );
69
76
}
70
77
71
78
public function lint (MergeRequest $ request ): array
@@ -74,17 +81,24 @@ public function lint(MergeRequest $request): array
74
81
75
82
preg_match (self ::REGEX , $ request ->title , $ matches );
76
83
77
- if (! array_key_exists (1 , $ matches ) || ! is_string ($ matches [1 ])) {
84
+ if (! array_key_exists (' type ' , $ matches ) || ! is_string ($ matches [' type ' ])) {
78
85
return [new LintNote ('The title must matches with conventional commit ' )];
79
86
}
80
87
81
- $ type = $ matches [1 ];
88
+ $ type = $ matches ['type ' ];
89
+ $ description = Str::make ($ matches ['description ' ]);
90
+
91
+ $ notes = [];
92
+
93
+ if (($ taskNotes = $ this ->checkTask ($ description ))) {
94
+ $ notes = $ taskNotes ;
95
+ }
82
96
83
97
if (! $ this ->types ->contains ($ type )) {
84
- return [ new LintNote (sprintf ('Title conventional: type "%s" is unknown ' , $ type ))] ;
98
+ $ notes [] = new LintNote (sprintf ('Title conventional: type "%s" is unknown ' , $ type ));
85
99
}
86
100
87
- return [] ;
101
+ return $ notes ;
88
102
}
89
103
90
104
/**
@@ -97,4 +111,39 @@ public function getDefinition(): RuleDefinition
97
111
$ this ->types ->implode (', ' ),
98
112
));
99
113
}
114
+
115
+ /**
116
+ * @return array<Note>
117
+ */
118
+ private function checkTask (Str $ description ): array
119
+ {
120
+ if ($ this ->task === null ) {
121
+ return [];
122
+ }
123
+
124
+ $ projectCode = ProjectCode::findInStart ($ description );
125
+
126
+ if ($ projectCode === null ) {
127
+ if (! $ this ->task ->projectCodes ->isEmpty ()) {
128
+ return [new LintNote (
129
+ sprintf (
130
+ 'Description of title must starts with task number of projects ["%s"] ' ,
131
+ $ this ->task ->projectCodes ->implode (', ' ),
132
+ )
133
+ ),
134
+ ];
135
+ }
136
+
137
+ return [new LintNote ('Description of title must starts with task number ' )];
138
+ }
139
+
140
+ if (! $ this ->task ->projectCodes ->isEmpty () && ! $ this ->task ->projectCodes ->contains ($ projectCode ->__toString ())) {
141
+ return [new LintNote (sprintf (
142
+ 'The title contains unknown project code "%s" ' ,
143
+ $ projectCode ,
144
+ ))];
145
+ }
146
+
147
+ return [];
148
+ }
100
149
}
0 commit comments