Skip to content

Commit 197cf3d

Browse files
committed
Initial commit
0 parents  commit 197cf3d

23 files changed

+1301
-0
lines changed

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
* text=auto
2+
/.gitattributes export-ignore
3+
/.gitignore export-ignore

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.idea/
2+
vendor/
3+
composer.lock

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 andrey-tech
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# PHPUnit Cobertura Formatter
2+
3+
## Authors and Maintainers
4+
5+
The author and maintainer of PHPUnit Cobertura Formatter is [andrey-tech](https://github.com/andrey-tech).
6+
7+
## License
8+
9+
This tool is licensed under the [MIT license](./LICENSE).

bin/phpunit-cobertura-formatter

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
/**
5+
* @author andrey-tech
6+
* @copyright 2025 andrey-tech
7+
* @link https://github.com/andrey-tech/
8+
* @license MIT
9+
*/
10+
11+
declare(strict_types=1);
12+
13+
use AndreyTech\PHPUnit\Cobertura\Formatter\Application;
14+
15+
(static function() {
16+
$counter = 0;
17+
$path = 'vendor';
18+
do {
19+
$counter++;
20+
$path = '/../' . $path;
21+
$autoloadFile = __DIR__ . $path . '/autoload.php';
22+
23+
if (is_file($autoloadFile)) {
24+
if (is_readable($autoloadFile)) {
25+
require_once $autoloadFile;
26+
27+
return;
28+
}
29+
30+
throw new RuntimeException('Cannot read Composer file "autoload.php".');
31+
}
32+
} while ($counter <= 5);
33+
34+
throw new RuntimeException('Cannot find Composer file "autoload.php".');
35+
})();
36+
37+
(new class
38+
{
39+
public function __invoke(): void
40+
{
41+
exit((new Application())->run());
42+
}
43+
})();

composer.json

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"name": "andrey-tech/phpunit-cobertura-formatter-php",
3+
"description": "Tool to show code coverage metrics, measured by PHP Unit in Cobertura format, in console and CI/CD pipeline",
4+
"keywords": [
5+
"test",
6+
"coverage",
7+
"metrics",
8+
"phpunit",
9+
"cobertura",
10+
"console"
11+
],
12+
"homepage": "https://github.com/andrey-tech/phpunit-cobertura-formatter-php",
13+
"minimum-stability": "dev",
14+
"license": "MIT",
15+
"authors": [
16+
{
17+
"name": "andrey-tech",
18+
"homepage": "https://github.com/andrey-tech/",
19+
"role": "Developer"
20+
}
21+
],
22+
"support": {
23+
"issues": "https://github.com/andrey-tech/phpunit-cobertura-formatter-php/issues",
24+
"source": "https://github.com/andrey-tech/phpunit-cobertura-formatter-php"
25+
},
26+
"require": {
27+
"php": "^8.3",
28+
"justinrainbow/json-schema": "^6.0",
29+
"symfony/console": "^5.4 || ^6.4 || ^7.3",
30+
"symfony/yaml": "^5.4 || ^6.4 || ^7.3"
31+
},
32+
"require-dev": {
33+
},
34+
"conflict": {
35+
},
36+
"suggest": {
37+
},
38+
"config": {
39+
"sort-packages": true,
40+
"allow-plugins": {
41+
}
42+
},
43+
"autoload": {
44+
"psr-4": {
45+
"AndreyTech\\": "src/"
46+
}
47+
},
48+
"bin": [
49+
"bin/phpunit-cobertura-formatter"
50+
],
51+
"scripts": {
52+
"post-install-cmd": [
53+
"AndreyTech\\PHPUnit\\Cobertura\\Formatter\\Installer::postInstall"
54+
]
55+
}
56+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
3+
/**
4+
* @author andrey-tech
5+
* @copyright 2025 andrey-tech
6+
* @link https://github.com/andrey-tech/
7+
* @license MIT
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace AndreyTech\PHPUnit\Cobertura\Formatter;
13+
14+
use AndreyTech\PHPUnit\Cobertura\Formatter\Config\CommandLine;
15+
use AndreyTech\PHPUnit\Cobertura\Formatter\Config\File as ConfigFile;
16+
use AndreyTech\PHPUnit\Cobertura\Formatter\Parser\File as CoberturaFile;
17+
use AndreyTech\PHPUnit\Cobertura\Formatter\Renderer\Colorizer;
18+
use Symfony\Component\Console\Output\ConsoleOutput;
19+
use Throwable;
20+
21+
use function sprintf;
22+
23+
final class Application
24+
{
25+
private const int EXIT_CODE_OK = 0;
26+
private const int EXIT_CODE_ERROR = 1;
27+
28+
private ConsoleOutput $consoleOutput;
29+
private Stats $stats;
30+
31+
public function __construct()
32+
{
33+
$this->consoleOutput = new ConsoleOutput();
34+
$this->stats = new Stats();
35+
}
36+
37+
public function run(): int
38+
{
39+
$this->stats->start();
40+
41+
try {
42+
$exitCode = $this->doRun();
43+
} catch (Throwable $exception) {
44+
$exitCode = self::EXIT_CODE_ERROR;
45+
$this->error(
46+
sprintf('ERROR: %s', $exception->getMessage())
47+
);
48+
}
49+
50+
$this->stats->finish();
51+
$this->showStats($exitCode);
52+
53+
return $exitCode;
54+
}
55+
56+
private function doRun(): int
57+
{
58+
(new Renderer(
59+
$this->consoleOutput,
60+
new Colorizer(
61+
new ConfigFile()
62+
)
63+
))->render(
64+
(new Parser())->parse(
65+
new CoberturaFile(
66+
(new CommandLine())->coberturaFile()
67+
)
68+
)
69+
);
70+
71+
return self::EXIT_CODE_OK;
72+
}
73+
74+
private function message(string $message): void
75+
{
76+
$this->consoleOutput->writeln($message);
77+
}
78+
79+
private function error(string $message): void
80+
{
81+
$this->consoleOutput->writeln(
82+
sprintf('<fg=red;options=bold>%s</>', $message)
83+
);
84+
}
85+
86+
private function showStats(int $exitCode): void
87+
{
88+
$this->message(
89+
sprintf(
90+
'Exit code: %s, Time: %s, Memory: %s.',
91+
$exitCode,
92+
$this->stats->time(),
93+
$this->stats->memory()
94+
)
95+
);
96+
}
97+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/**
4+
* @author andrey-tech
5+
* @copyright 2025 andrey-tech
6+
* @link https://github.com/andrey-tech/
7+
* @license MIT
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace AndreyTech\PHPUnit\Cobertura\Formatter\Config;
13+
14+
use RuntimeException;
15+
use Symfony\Component\Console\Input\ArgvInput;
16+
use Symfony\Component\Console\Input\InputArgument;
17+
use Symfony\Component\Console\Input\InputDefinition;
18+
19+
final readonly class CommandLine
20+
{
21+
private ArgvInput $input;
22+
23+
public function __construct()
24+
{
25+
$this->input = $this->buildArgvInput();
26+
}
27+
28+
public function buildArgvInput(): ArgvInput
29+
{
30+
$definition = new InputDefinition();
31+
32+
$argument = new InputArgument('cobertura-file', InputArgument::REQUIRED);
33+
$definition->addArgument($argument);
34+
35+
return new ArgvInput(null, $definition);
36+
}
37+
38+
public function coberturaFile(): string
39+
{
40+
$coberturaFile = (string) $this->input->getArgument('cobertura-file');
41+
42+
if ('' === $coberturaFile) {
43+
throw new RuntimeException('Missing required argument <path to cobertura XML file>.');
44+
}
45+
46+
return $coberturaFile;
47+
}
48+
}

0 commit comments

Comments
 (0)