Skip to content

Commit 18c79e6

Browse files
authored
[Docs] Update docs (#34)
* Add examples * update docs * up getting started * update docs * up doc * up rules doc * up rules doc * Add conditions page * upd readme * update docs * Add TitleStartsWithTaskNumberRule * add test * update doc for custom rule * add tests * add docs for notifications * up version * up examples page * update development doc * up notifications doc * up docs * Add EvaluatorTest * add test * up test * Add EventDispatcherTest * remove unless methods * coverage ignore * add test * upd changelog * fix lint
1 parent 82d3b09 commit 18c79e6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+891
-310
lines changed

CHANGELOG.MD

+6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
This file contains changelogs.
44

5+
v0.10.1
6+
--------------------
7+
#### Added
8+
* Documentation for conditions
9+
* Rule `@mr-linter/title_starts_with_task_number` for checking task number in request title
10+
511
v0.10.0
612
--------------------
713
#### Added

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ docker-pub-try:
6060
docs:
6161
php docs/Builder/build_rules.php
6262
php docs/Builder/build_config_json_schema.php
63+
php docs/Builder/build_conditions.php
6364

6465
deps-check:
6566
@test -f composer-require-checker.phar || wget \

README.MD

+14-166
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Merge Request Linter
1+
<h1 align="center">MR Linter - merge/pull request validator</h1>
22

33
![Testing](https://github.com/ArtARTs36/php-merge-request-linter/workflows/Testing/badge.svg?branch=master)
44
[![codecov](https://codecov.io/gh/ArtARTs36/php-merge-request-linter/branch/master/graph/badge.svg?token=OGRWW81OHH)](https://codecov.io/gh/ArtARTs36/php-merge-request-linter)
@@ -7,174 +7,22 @@
77
![Total Downloads](https://poser.pugx.org/artarts36/merge-request-linter/d/total.svg)
88
![Docker Pulls](https://img.shields.io/docker/pulls/artarts36/merge-request-linter)
99

10-
This package provides tools for validating merge requests
10+
This project provides tools for validating merge/pull requests.
1111

12-
[Show validation rules](docs/rules.md)
12+
Supported CI Systems: **GitHub Actions**, **Gitlab CI**.
1313

14-
[Creating custom rule](docs/custom_rule.md)
14+
## Documentation
1515

16-
[Docker Image](https://hub.docker.com/repository/docker/artarts36/merge-request-linter)
17-
18-
## Installation
19-
20-
Add config file with name `.mr-linter.yml` or `.mr-linter.json`.
21-
Examples:
22-
* https://github.com/ArtARTs36/php-merge-request-linter/blob/master/stubs/.mr-linter.yaml
23-
* https://github.com/ArtARTs36/php-merge-request-linter/blob/master/stubs/.mr-linter.json
24-
25-
## ➜ Usage with GitHub Actions
26-
27-
[View on Marketplace](https://github.com/marketplace/actions/merge-request-linter)
28-
29-
Implementation example: https://github.com/ArtARTs36/ShellCommand/pull/11
30-
31-
1. Generate token on [page](https://github.com/settings/tokens/new)
32-
2. Open https://github.com/{owner}/{repo}/settings/secrets/actions/new. Add new secret "MR_LINTER_GITHUB_HTTP_TOKEN" with your personal access token
33-
3. Add new workflow file **.github/workflows/review.yml**:
34-
```yml
35-
name: PR Review
36-
37-
on:
38-
pull_request:
39-
branches: [ master ]
40-
41-
jobs:
42-
build:
43-
44-
runs-on: ubuntu-latest
45-
46-
steps:
47-
- uses: actions/checkout@v2
48-
49-
- name: Lint Pull Request
50-
uses: mr-linter/[email protected]
51-
env:
52-
MR_LINTER_GITHUB_TOKEN: ${{ secrets.MR_LINTER_GITHUB_HTTP_TOKEN }}
53-
```
54-
55-
## ➜ Usage with Gitlab CI
56-
57-
[See example](https://gitlab.com/artem_ukrainsky/mr-linter-testing/)
58-
59-
1. Generate token on `https://{gitlab-host}/-/profile/personal_access_tokens`
60-
2. Open `https://{gitlab-host}/group/project/-/settings/ci_cd`. Add new variable "MR_LINTER_GITLAB_HTTP_TOKEN" with your personal access token
61-
3. Add new step into **.gitlab-ci.yml**
62-
```yaml
63-
mr-lint:
64-
image: artarts36/merge-request-linter:0.8.0
65-
stage: test
66-
only:
67-
- merge_requests
68-
script:
69-
- mr-linter lint
70-
```
71-
72-
## Run in Docker
73-
74-
Simple bash:
75-
```shell
76-
docker run \
77-
-it \
78-
-e GITHUB_ACTIONS=1 \
79-
-e GITHUB_REPOSITORY=artarts36/php-merge-request-linter \
80-
-e GITHUB_GRAPHQL_URL=https://api.github.com/graphql \
81-
-e GITHUB_REF_NAME=${MR_ID}/merge \
82-
-e MR_LINTER_GITHUB_HTTP_TOKEN=${TOKEN} \
83-
-v "${PWD}/.mr-linter.json:/app/.mr-linter.json:ro" \
84-
artarts36/merge-request-linter:${MR_LINTER_VERSION} lint
85-
```
86-
87-
## Available Commands
88-
89-
| Command | Description |
90-
|----------------------------------------------|---------------------------------------------------------------|
91-
| ./vendor/bin/mr-linter install | Install this tool (copy configuration file to work directory) |
92-
| ./vendor/bin/mr-linter install --format=yaml | Install this tool (copy configuration file to work directory) |
93-
| ./vendor/bin/mr-linter dump | Print current rules |
94-
| ./vendor/bin/mr-linter lint | Run lint to current merge request |
95-
| ./vendor/bin/mr-linter info | Print info about MR Linter |
96-
97-
98-
## JSON Config
99-
100-
[See JsonSchema](mr-linter-config-schema.json)
101-
102-
```json
103-
{
104-
"rules": {
105-
"@mr-linter/changed_files_limit": {
106-
"limit": 20
107-
},
108-
"@mr-linter/jira/has_issue_link": {
109-
"domain": "jira.com",
110-
"projectCode": "MYPROJECT",
111-
"when": {
112-
"title": {
113-
"starts": "WIP-REQUEST"
114-
}
115-
}
116-
},
117-
"@mr-linter/description_not_empty": {
118-
"when": {
119-
"targetBranch": {
120-
"equals": "master"
121-
}
122-
}
123-
}
124-
},
125-
"credentials": {
126-
"github_actions": "env(MR_LINTER_GITHUB_HTTP_TOKEN)"
127-
}
128-
}
129-
```
130-
131-
## YAML Config
132-
133-
[See JsonSchema](mr-linter-config-schema.json)
134-
135-
```yaml
136-
rules:
137-
"@mr-linter/changed_files_limit":
138-
limit: 20
139-
140-
"@mr-linter/jira/has_issue_link":
141-
domain: "jira.com"
142-
projectCode: "MYPROJECT"
143-
when:
144-
title:
145-
starts: "WIP-REQUEST"
146-
147-
"@mr-linter/description_not_empty":
148-
when:
149-
targetBranch:
150-
equals: "master"
151-
152-
custom:
153-
- definition: "Title must include 'BUG'"
154-
rules:
155-
title:
156-
match: "/BUG/i"
157-
when:
158-
targetBranch:
159-
equals: master
160-
161-
credentials:
162-
github_actions: "env(MR_LINTER_GITHUB_HTTP_TOKEN)"
163-
```
164-
165-
## Development Commands
166-
167-
| Command | Description |
168-
|--------------------------|------------------------------------------------------|
169-
| composer test | Run tests (via PHPUnit) |
170-
| composer lint | Run lint (via PHPCsFixer) |
171-
| composer deptrac | Run deptrac |
172-
| make deps-check | Check composer requires (via ComposerRequireChecker) |
173-
| make check | Run test, lint, stat-analyse, deptrac |
174-
| make docs | Build docs (rule page, Config JSON Schema) |
175-
| make env | Add .env file |
176-
| make try MR_ID=10 | Run MR-Linter on really pull request |
177-
| make try-gitlab MR_ID=10 | Run MR-Linter on really merge request |
16+
* [Getting Started](docs/getting-started.md)
17+
* [Examples of usage](docs/examples.md)
18+
* [Show validation rules](docs/rules.md)
19+
* [Conditions](docs/conditions.md)
20+
* [Creating custom rule](docs/custom-rule.md)
21+
* [Docker Image](https://hub.docker.com/repository/docker/artarts36/merge-request-linter)
22+
* [Config JSON Schema](mr-linter-config-schema.json)
23+
* [Notifications](docs/notifications.md)
24+
* [Run in Docker](docs/run-in-docker.md)
25+
* [Development](docs/development.md)
17826

17927
## Console output example
18028

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace ArtARTs36\MergeRequestLinter\DocBuilder;
4+
5+
use ArtARTs36\MergeRequestLinter\DocBuilder\ConfigJsonSchema\OperatorMetadataLoader;
6+
use ArtARTs36\MergeRequestLinter\Infrastructure\Text\Renderer\TwigRenderer;
7+
use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap;
8+
9+
class ConditionsPageBuilder
10+
{
11+
public function __construct(
12+
private readonly OperatorMetadataLoader $metadataLoader = new OperatorMetadataLoader(),
13+
) {
14+
//
15+
}
16+
17+
public function build(): string
18+
{
19+
$operators = $this->metadataLoader->load();
20+
21+
return TwigRenderer::create()
22+
->render(
23+
file_get_contents(__DIR__ . '/templates/conditions.md.twig'),
24+
new ArrayMap([
25+
'operators' => $operators,
26+
]),
27+
);
28+
}
29+
}

docs/Builder/RulesPageBuilder.php

+38-47
Original file line numberDiff line numberDiff line change
@@ -2,74 +2,65 @@
22

33
namespace ArtARTs36\MergeRequestLinter\DocBuilder;
44

5+
use ArtARTs36\MergeRequestLinter\Application\Rule\Rules\CustomRule;
6+
use ArtARTs36\MergeRequestLinter\Application\Rule\Rules\DefaultRules;
7+
use ArtARTs36\MergeRequestLinter\DocBuilder\ConfigJsonSchema\JsonType;
8+
use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Rule\RuleConstructorFinder;
9+
use ArtARTs36\MergeRequestLinter\Infrastructure\Rule\Constructor\ConstructorFinder;
10+
use ArtARTs36\MergeRequestLinter\Infrastructure\Text\Renderer\TwigRenderer;
11+
use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap;
512
use ArtARTs36\MergeRequestLinter\Shared\Reflector\ClassSummary;
6-
use ArtARTs36\Str\Str;
713

814
class RulesPageBuilder
915
{
1016
protected string $namespace = 'ArtARTs36\MergeRequestLinter\\Application\\Rule\\Rules\\';
1117

1218
protected string $dir = __DIR__ . '/../../src/Application/Rule/Rules';
1319

20+
public function __construct(
21+
private RuleConstructorFinder $ruleConstructorFinder = new ConstructorFinder(),
22+
) {
23+
//
24+
}
25+
1426
public function build(): string
1527
{
16-
$files = glob(realpath($this->dir) . '/*Rule.php');
17-
18-
$descriptions = Str::fromEmpty();
19-
20-
$id = 0;
21-
22-
foreach ($files as $file) {
23-
$filename = pathinfo($file, PATHINFO_FILENAME);
24-
$class = $this->namespace . $filename;
25-
$comment = $this->getFirstDocCommentWhenNotAbstract($file);
28+
$rules = [];
2629

27-
if ($comment === null) {
30+
foreach (DefaultRules::map() as $ruleName => $ruleClass) {
31+
if ($ruleClass === CustomRule::class) {
2832
continue;
2933
}
3034

31-
if (! defined("$class::NAME")) {
32-
continue;
33-
}
35+
$reflector = new \ReflectionClass($ruleClass);
3436

35-
$ruleName = $class::NAME;
37+
$comment = ClassSummary::findInPhpDocComment($reflector->getDocComment());
3638

37-
$id++;
39+
$path = '..' . str_replace(dirname(__DIR__, 2), '', $reflector->getFileName());
3840

39-
$comment = ClassSummary::findInPhpDocComment($comment);
41+
$params = [];
4042

41-
if ($id === 1) {
42-
$descriptions = $descriptions->append("| $id | $ruleName | $class | $comment |");
43-
} else {
44-
$descriptions = $descriptions->appendLine("| $id | $ruleName | $class | $comment |");
43+
foreach ($this->ruleConstructorFinder->find($ruleClass)->params() as $paramName => $param) {
44+
$params[] = [
45+
'name' => $paramName,
46+
'type' => JsonType::to($param->name()),
47+
'generic' => $param->isGeneric() ? JsonType::to($param->generic) : null,
48+
];
4549
}
46-
}
47-
48-
return <<<HTML
49-
# Available Rules
5050

51-
Currently is available that rules:
52-
53-
| # | Name | Class | Description |
54-
| ------------ | ------------ | ------------ | ------------ |
55-
$descriptions
56-
HTML;
57-
}
58-
59-
protected function getFirstDocCommentWhenNotAbstract(string $filePath): ?string
60-
{
61-
$tokens = token_get_all(file_get_contents($filePath));
62-
63-
foreach ($tokens as [$tokenIndex, $value]) {
64-
if ($tokenIndex === T_ABSTRACT) {
65-
return null;
66-
}
67-
68-
if ($tokenIndex === T_DOC_COMMENT) {
69-
return $value;
70-
}
51+
$rules[] = [
52+
'name' => $ruleName,
53+
'params' => $params,
54+
'description' => $comment,
55+
'path' => $path,
56+
];
7157
}
7258

73-
return null;
59+
return TwigRenderer::create()->render(
60+
file_get_contents(__DIR__ . '/templates/rules.md.twig'),
61+
new ArrayMap([
62+
'rules' => $rules,
63+
])
64+
);
7465
}
7566
}

docs/Builder/build_conditions.php

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
use ArtARTs36\MergeRequestLinter\DocBuilder\ConditionsPageBuilder;
4+
use ArtARTs36\MergeRequestLinter\DocBuilder\Saver;
5+
6+
require __DIR__ . '/../../vendor/autoload.php';
7+
8+
$path = __DIR__ . '/../conditions.md';
9+
[$builder, $saver] = [new ConditionsPageBuilder(), new Saver()];
10+
11+
$updated = $saver->save($path, $builder->build());
12+
13+
fputs(STDOUT, $updated ? '-> Documentation page updated' : '-> Documentation page is actually');
14+
fputs(STDOUT, "\n");
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
## Condition Operators
2+
3+
Currently is available that operators:
4+
5+
| Name | Description | Parameter |
6+
|------| ------------ | ----------- |
7+
{% for operator in operators %}
8+
{% for operatorName in operator.names %}
9+
| {{ operatorName }} | {{ operator.description }} | {% for parameter in operator.parameters %}
10+
{{ parameter.jsonType }}{% if parameter.generic %} of {{ parameter.generic }}s{% endif %}{% if loop.last == false %} / {% endif %}
11+
{% endfor%} |
12+
{% endfor %}
13+
{% endfor %}
14+

docs/Builder/templates/rules.md.twig

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Available Rules
2+
3+
Currently is available that rules:
4+
5+
| Name | Description | Parameters |
6+
| ------------ | ------------ | ------------ |
7+
{% for rule in rules %}
8+
| {{ rule.name }} | {{ rule.description }} |{% if rule.params|length == 0 %} None {% endif %}
9+
{% for param in rule.params%} `{{ param.name }}` - {{ param.type }} {% if param.generic %} of {{ param.generic }}s {% endif %} <br/> {% endfor%} |
10+
{% endfor %}

0 commit comments

Comments
 (0)