-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from Aeliot-Tm/detector_implementaion
Base implementation
- Loading branch information
Showing
52 changed files
with
5,172 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[xdebug] | ||
zend_extension=xdebug.so | ||
|
||
xdebug.mode=debug,coverage | ||
xdebug.client_host=host.docker.internal | ||
xdebug.client_port=9003 | ||
xdebug.start_with_request=yes | ||
xdebug.idekey=PHPSTORM | ||
xdebug.log_level=0 | ||
xdebug.log=/app/var/xdebug.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
name: Automated Testing | ||
|
||
on: | ||
push: | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: | ||
composer: | ||
name: Validate composer files | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: shivammathur/setup-php@v2 | ||
with: | ||
php-version: 8.2 | ||
|
||
- uses: actions/checkout@v4 | ||
|
||
- name: Validate composer.json and composer.lock | ||
run: composer validate --strict | ||
|
||
phpunit: | ||
name: 'Tests: Unit' | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: shivammathur/setup-php@v2 | ||
with: | ||
php-version: 8.2 | ||
|
||
- uses: actions/checkout@v4 | ||
|
||
- name: Cache Composer packages | ||
id: composer-cache | ||
uses: actions/cache@v4 | ||
with: | ||
path: vendor | ||
key: "${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}" | ||
restore-keys: | | ||
${{ runner.os }}-php- | ||
- name: Install dependencies | ||
uses: ramsey/composer-install@v3 | ||
|
||
- name: 'Run all PHPUnit tests' | ||
run: composer run phpunit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
.idea | ||
.phpunit | ||
/var | ||
/vendor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
use Aeliot\TodoRegistrar\Config; | ||
use Aeliot\TodoRegistrar\Enum\RegistrarType; | ||
use Aeliot\TodoRegistrar\Service\File\Finder; | ||
|
||
return (new Config()) | ||
->setFinder((new Finder())->in(__DIR__)) | ||
->setRegistrar(RegistrarType::JIRA, [ | ||
'issue' => [ | ||
'addTagToLabels' => true, | ||
'components' => ['Component-1', 'Component-2'], | ||
'labels' => ['Label-1', 'Label-2'], | ||
'tagPrefix' => 'tag-', | ||
'type' => 'Bug', | ||
], | ||
'projectKey' => 'Todo', | ||
'service' => [ | ||
'host' => $_ENV['JIRA_HOST'] ?? 'localhost', | ||
'personalAccessToken' => $_ENV['JIRA_PERSONAL_ACCESS_TOKEN'] ?? null, | ||
'tokenBasedAuth' => true, | ||
] | ||
]) | ||
->setTags(['todo', 'fixme', 'a_custom_tag']); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# TODO Registrar | ||
|
||
Package responsible for registration of issues in Issue Trackers. | ||
|
||
## Installation | ||
|
||
1. Require package via Composer: | ||
```shell | ||
composer require --dev aeliot/todo-registrar | ||
``` | ||
2. Create configuration file. It expects ".todo-registrar.php" or ".todo-registrar.dist.php" at the root of the project. | ||
|
||
## Using | ||
|
||
1. Call script: | ||
```shell | ||
vendor/bin/todo-registrar | ||
``` | ||
You may pass option with it `--config=/custom/path/to/config`. Otherwise, it tries to use one of default files. | ||
2. Commit updated files. You may config your pipeline/job on CI which commits updates. | ||
|
||
## Configuration file | ||
|
||
Config file is php-file which returns instance of class `\Aeliot\TodoRegistrar\Config`. See [example](.todo-registrar.dist.php). | ||
|
||
It has setters: | ||
1. `setFinder` - accepts instance of configured finder of php-files. | ||
2. `setRegistrar` - responsible for configuration of registrar factory. It accepts as type of registrar with its config | ||
as instance of custom registrar factory. | ||
3. `setTags` - array of detected tags. It supports "todo" and "fixme" by default. | ||
You don't need to configure it when you want to use only this tags. Nevertheless, you have to set them | ||
when you want to use them together with your custom tags. | ||
|
||
### Supported patters of comments (examples): | ||
|
||
It detects TODO-tags in single-line comments started with both `//` and `#` symbols | ||
and multiple-line comments `/* ... */` and phpDoc `/** ... **/`. | ||
|
||
1. Tag and comment separated by semicolon | ||
```php | ||
// TODO: comment summary | ||
``` | ||
2. Tag and comment does not separated by semicolon | ||
```php | ||
// TODO comment summary | ||
``` | ||
3. Tag with assignee and comment separated by semicolon | ||
```php | ||
// TODO@assigne: comment summary | ||
``` | ||
4. Tag with assignee and comment does not separated by semicolon | ||
```php | ||
// TODO@assigne comment summary | ||
``` | ||
5. Multiline comment with complex description. All lines after the first one with tag MUST have indentation | ||
same to the text of the first line. So, all af them will be detected af part of description of TODO. | ||
Multiple line comments may have assignee and semicolon same as single-line comments/. | ||
```php | ||
/** | ||
* TODO: comment summary | ||
* and some complex description | ||
* which must have indentation same as end of one presented: | ||
* - semicolon | ||
* - assignee | ||
* - tag | ||
* So, all this text will be passed to registrar as description | ||
* without not meaning indentations (" * " in this case). | ||
* This line (and all after) will not be detected as part (description) of "TODO" | ||
* case they don't have expected indentation. | ||
*/ | ||
``` | ||
|
||
As a result of processing of such comments, ID of ISSUE will be injected before comment summary | ||
and after semicolon and assignee when they are presented. For example: | ||
1. Tag and comment separated by semicolon | ||
```php | ||
// TODO: XX-001 comment summary | ||
``` | ||
2. Tag and comment does not separated by semicolon | ||
```php | ||
// TODO XX-001 comment summary | ||
``` | ||
3. Tag with assignee and comment separated by semicolon | ||
```php | ||
// TODO@assigne: XX-001 comment summary | ||
``` | ||
4. Tag with assignee and comment does not separated by semicolon | ||
```php | ||
// TODO@assigne XX-001 comment summary | ||
``` | ||
5. Multiline comment with complex description. All lines after the first one with tag MUST have indentation | ||
same to the text of the first line. So, all af them will be detected af part of description of TODO. | ||
Multiple line comments may have assignee and semicolon same as single-line comments/. | ||
```php | ||
/** | ||
* TODO: XX-001 comment summary | ||
* and some complex description | ||
*/ | ||
``` | ||
|
||
### Assignee-part | ||
|
||
It is some "username" which separated of tag by symbol "@". It sticks to pattern `/[a-z0-9._-]+/i`. | ||
System pass it in payload to registrar with aim to be used as "identifier" of assignee in issue tracker. | ||
|
||
## Supported Issue Trackers | ||
|
||
Currently, todo-registrar supports the following issue trackers: | ||
|
||
| Issue Tracker | Description | | ||
|-------------------------------------------------|--------------------------| | ||
| [Jira](https://www.atlassian.com/software/jira) | Supported via API tokens | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#!/usr/bin/env php | ||
<?php | ||
|
||
use Aeliot\TodoRegistrar\ApplicationFactory; | ||
use Aeliot\TodoRegistrar\Config; | ||
|
||
$autoloaderPath = (static function (): string { | ||
$paths = [ | ||
__DIR__ . '/vendor/autoload.php', | ||
__DIR__ . '/../vendor/autoload.php', | ||
__DIR__ . '/../../vendor/autoload.php', | ||
__DIR__ . '/../../../vendor/autoload.php', | ||
__DIR__ . '/../../../../vendor/autoload.php', | ||
]; | ||
|
||
foreach ($paths as $path) { | ||
if (file_exists($path)) { | ||
return realpath($path); | ||
} | ||
} | ||
|
||
throw new RuntimeException('Cannot find autoloader'); | ||
})(); | ||
|
||
require_once $autoloaderPath; | ||
|
||
$projectPath = dirname($autoloaderPath, 2); | ||
|
||
$absolutePathMaker = static function (string $path) use ($projectPath): string { | ||
if (preg_match('#^(?:[[:alpha:]]:[/\\\\]|/)#', $path)) { | ||
return $path; | ||
} | ||
|
||
return $projectPath . '/' . $path; | ||
}; | ||
|
||
$configGuess = static function () use ($absolutePathMaker): string { | ||
$candidates = [ | ||
'.todo-registrar.php', | ||
'.todo-registrar.dist.php', | ||
]; | ||
foreach ($candidates as $candidate) { | ||
$path = $absolutePathMaker($candidate); | ||
if (file_exists($path)) { | ||
return $path; | ||
} | ||
} | ||
|
||
throw new \DomainException('Cannot detect default config file'); | ||
}; | ||
|
||
$options = (static function () use ($absolutePathMaker, $configGuess): array { | ||
$values = []; | ||
$options = getopt('c:', ['config']); | ||
$defaults = [ | ||
'config' => ['c', null], | ||
]; | ||
|
||
foreach ($defaults as $long => [$short, $default]) { | ||
if (isset($options[$short], $options[$long])) { | ||
throw new InvalidArgumentException(sprintf('Option %s is duplicated', $long)); | ||
} | ||
$values[$long] = $options[$short] ?? $options[$long] ?? $default; | ||
} | ||
|
||
if (!isset($values['config'])) { | ||
$values['config'] = $configGuess(); | ||
} | ||
|
||
return $values; | ||
})(); | ||
|
||
if (!file_exists($options['config'])) { | ||
throw new RuntimeException(sprintf('Config file "%s" does not exist', $options['config'])); | ||
} | ||
|
||
/** @var Config $config */ | ||
$config = require $options['config']; | ||
if (!$config instanceof Config) { | ||
throw new RuntimeException(sprintf('Config file "%s" does not return instance of config', $options['config'])); | ||
} | ||
|
||
(new ApplicationFactory())->create($config)->run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,47 @@ | ||
{ | ||
"name": "aeliot/todo-registrar", | ||
"type": "library", | ||
"type": "application", | ||
"description": "Register TODOs from source code in issue tracker", | ||
"license": "MIT", | ||
"minimum-stability": "dev", | ||
"prefer-stable": true, | ||
"autoload": { | ||
"psr-4": { | ||
"Aeliot\\TodoRegistrar\\": "src/" | ||
} | ||
}, | ||
"autoload-dev": { | ||
"psr-4": { | ||
"Aeliot\\TodoRegistrar\\Test\\": "tests/" | ||
} | ||
}, | ||
"bin": [ | ||
"bin/todo-registrar" | ||
], | ||
"config": { | ||
"allow-plugins": { | ||
"composer/*": true | ||
}, | ||
"sort-packages": true | ||
}, | ||
"require": { | ||
"php": "^8.2" | ||
"php": "^8.2", | ||
"ext-tokenizer": "*", | ||
"lesstif/php-jira-rest-client": "^5.8", | ||
"symfony/finder": "^5.4|^6.0|^7.0" | ||
}, | ||
"require-dev": { | ||
"dg/bypass-finals": "^1.7", | ||
"phpunit/phpunit": "^11.1", | ||
"roave/security-advisories": "dev-latest" | ||
}, | ||
"scripts": { | ||
"phpunit": "vendor/bin/phpunit" | ||
}, | ||
"suggest": { | ||
"staabm/phpstan-todo-by": "For the monitoring of outdated comments when ticket closed and TODO-comment should be removed" | ||
}, | ||
"support": { | ||
"issues": "https://github.com/Aeliot-Tm/todo-registrar/issues" | ||
} | ||
} |
Oops, something went wrong.