Skip to content

Commit b63de71

Browse files
authored
Merge pull request #192 from xHeaven/feat/benchmark-markdown
Add markdown renderer for phpbench
2 parents 9cd386c + 8f08b86 commit b63de71

5 files changed

Lines changed: 176 additions & 4 deletions

File tree

.github/workflows/benchmark-comment.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,11 @@ jobs:
5656
5757
Comparison of `${{ steps.bench.outputs.head-ref }}` against `${{ steps.bench.outputs.base-ref }}` (`${{ steps.bench.outputs.base-sha }}`).
5858
59-
```
59+
<details>
60+
<summary>Open to see the benchmark results</summary>
61+
6062
${{ steps.bench.outputs.result }}
61-
```
63+
64+
</details>
6265
6366
<sub>Generated by phpbench against commit ${{ steps.bench.outputs.head-sha }}</sub>

.github/workflows/benchmark.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
run: |
4040
git checkout ${{ github.event.pull_request.head.sha }}
4141
composer install --no-interaction --prefer-dist --quiet
42-
vendor/bin/phpbench run --tag=pr --store --ref=base --report=aggregate --progress=none 2>&1 | tee benchmark-result.txt || true
42+
vendor/bin/phpbench run --tag=pr --store --ref=base --report=aggregate --progress=none --output=markdown | tee benchmark-result.txt || true
4343
4444
- name: Prepare artifact
4545
run: |

phpbench.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@
22
"$schema": "./vendor/phpbench/phpbench/phpbench.schema.json",
33
"runner.bootstrap": "vendor/autoload.php",
44
"runner.path": "tests/Bench",
5-
"runner.file_pattern": "*Bench.php"
5+
"runner.file_pattern": "*Bench.php",
6+
"core.extensions": [
7+
"Tempest\\Highlight\\Tests\\Bench\\Extension\\MarkdownExtension"
8+
]
69
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Highlight\Tests\Bench\Extension;
6+
7+
use PhpBench\DependencyInjection\Container;
8+
use PhpBench\DependencyInjection\ExtensionInterface;
9+
use PhpBench\Extension\ConsoleExtension;
10+
use PhpBench\Extension\ExpressionExtension;
11+
use PhpBench\Extension\ReportExtension;
12+
use Symfony\Component\OptionsResolver\OptionsResolver;
13+
14+
final class MarkdownExtension implements ExtensionInterface
15+
{
16+
public function configure(OptionsResolver $resolver): void
17+
{
18+
}
19+
20+
public function load(Container $container): void
21+
{
22+
$container->register(MarkdownRenderer::class, function (Container $container) {
23+
return new MarkdownRenderer(
24+
$container->get(ConsoleExtension::SERVICE_OUTPUT_STD),
25+
$container->get(ExpressionExtension::SERVICE_PLAIN_PRINTER),
26+
);
27+
}, [
28+
ReportExtension::TAG_REPORT_RENDERER => [
29+
'name' => 'markdown',
30+
],
31+
]);
32+
}
33+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Highlight\Tests\Bench\Extension;
6+
7+
use PhpBench\Expression\Ast\Node;
8+
use PhpBench\Expression\Printer;
9+
use PhpBench\Registry\Config;
10+
use PhpBench\Report\Model\Reports;
11+
use PhpBench\Report\Model\Table;
12+
use PhpBench\Report\Model\TableRow;
13+
use PhpBench\Report\RendererInterface;
14+
use RuntimeException;
15+
use Symfony\Component\Console\Output\OutputInterface;
16+
use Symfony\Component\OptionsResolver\OptionsResolver;
17+
18+
final readonly class MarkdownRenderer implements RendererInterface
19+
{
20+
public function __construct(
21+
private OutputInterface $output,
22+
private Printer $printer,
23+
) {
24+
}
25+
26+
public function render(Reports $reports, Config $config): void
27+
{
28+
$content = $this->renderContent($reports);
29+
$file = $config['file'];
30+
31+
if ($file === null) {
32+
$this->output->write($content);
33+
34+
return;
35+
}
36+
37+
$this->writeFile($file, $content);
38+
}
39+
40+
public function configure(OptionsResolver $options): void
41+
{
42+
$options->setDefaults([
43+
'file' => null,
44+
]);
45+
$options->setAllowedTypes('file', ['null', 'string']);
46+
}
47+
48+
private function renderContent(Reports $reports): string
49+
{
50+
$lines = [];
51+
52+
foreach ($reports->tables() as $table) {
53+
array_push($lines, ...$this->renderTable($table));
54+
}
55+
56+
return implode("\n", $lines) . "\n";
57+
}
58+
59+
private function renderTable(Table $table): array
60+
{
61+
$lines = [];
62+
$title = $table->title();
63+
64+
if ($title !== null && $title !== '') {
65+
$lines[] = "## {$title}";
66+
$lines[] = '';
67+
}
68+
69+
$columns = $table->columnNames();
70+
71+
if ($columns === []) {
72+
return $lines;
73+
}
74+
75+
$lines[] = $this->renderRow($columns);
76+
$lines[] = $this->renderSeparatorRow($columns);
77+
78+
foreach ($table as $row) {
79+
$lines[] = $this->renderDataRow($row);
80+
}
81+
82+
$lines[] = '';
83+
84+
return $lines;
85+
}
86+
87+
private function renderRow(array $cells): string
88+
{
89+
return '| ' . implode(' | ', $cells) . ' |';
90+
}
91+
92+
private function renderSeparatorRow(array $columns): string
93+
{
94+
return $this->renderRow(array_map(
95+
fn (string $column): string => str_repeat('-', max(3, mb_strlen($column))),
96+
$columns,
97+
));
98+
}
99+
100+
private function renderDataRow(TableRow $row): string
101+
{
102+
$cells = array_map($this->formatCell(...), iterator_to_array($row));
103+
104+
return $this->renderRow($cells);
105+
}
106+
107+
private function formatCell(Node $node): string
108+
{
109+
return str_replace('|', '\\|', trim($this->printer->print($node)));
110+
}
111+
112+
private function writeFile(string $file, string $content): void
113+
{
114+
$this->createDirectory(dirname($file));
115+
116+
if (file_put_contents($file, $content) === false) {
117+
throw new RuntimeException(sprintf('Could not write to file "%s"', $file));
118+
}
119+
120+
$this->output->writeln("Written markdown report to: {$file}");
121+
}
122+
123+
private function createDirectory(string $directory): void
124+
{
125+
if (is_dir($directory)) {
126+
return;
127+
}
128+
129+
if (! mkdir($directory, 0o777, true) && ! is_dir($directory)) {
130+
throw new RuntimeException(sprintf('Could not create directory "%s"', $directory));
131+
}
132+
}
133+
}

0 commit comments

Comments
 (0)