Skip to content

Commit

Permalink
Add TablewView and TableRow to make use object api (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Aug 19, 2023
1 parent dac8818 commit fb17880
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 108 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/code_analysis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ jobs:

-
name: 'Run "measure" command'
run: |
bin/lines measure src --ansi
run: bin/lines measure src --ansi

# try json output
bin/lines measure src --json --ansi
-
name: 'Run "measure" with json command'
run: bin/lines measure src --json --ansi

-
name: 'PHPStan'
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ For json output, just add `--json`:
vendor/bin/lines measure src --json
```

Also, you can combine them (very handy for blog posts and tweets):

```bash
vendor/bin/lines measure src --short --json
```

## The Measured Items

For the text output, you'll get data like these:
Expand Down
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"php": "^8.1",
"ext-json": "*",
"symfony/console": "^6.3",
"symfony/process": "^6.3",
"symfony/finder": "^6.3",
"illuminate/container": "^10.16",
"webmozart/assert": "^1.11",
Expand Down
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ parameters:
- bin
- src
- tests
- views

excludePaths:
- tests/Fixture/*
Expand Down
2 changes: 1 addition & 1 deletion src/Console/OutputFormatter/JsonOutputFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ public function printMeasurement(Measurements $measurements, bool $isShort): voi
$jsonString = json_encode($arrayData, JSON_PRETTY_PRINT);
Assert::string($jsonString);

echo $jsonString;
echo $jsonString . PHP_EOL;
}
}
119 changes: 59 additions & 60 deletions src/Console/OutputFormatter/TextOutputFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,63 @@

namespace TomasVotruba\Lines\Console\OutputFormatter;

use Symfony\Component\Console\Style\SymfonyStyle;
use TomasVotruba\Lines\Console\ViewRenderer;
use TomasVotruba\Lines\Contract\OutputFormatterInterface;
use TomasVotruba\Lines\Helpers\NumberFormat;
use TomasVotruba\Lines\Measurements;
use TomasVotruba\Lines\ValueObject\TableRow;
use TomasVotruba\Lines\ValueObject\TableView;
use Webmozart\Assert\Assert;

final class TextOutputFormatter implements OutputFormatterInterface
{
public function __construct(
private readonly ViewRenderer $viewRenderer
private readonly ViewRenderer $viewRenderer,
private readonly SymfonyStyle $symfonyStyle,
) {
}

public function printMeasurement(Measurements $measurements, bool $isShort): void
{
$this->viewRenderer->newLine();
$this->symfonyStyle->newLine();

$this->printFilesAndDirectories($measurements);
$this->printLinesOfCode($measurements);

if ($isShort) {
$this->viewRenderer->newLine();
$this->symfonyStyle->newLine();

return;
}

$this->printStructure($measurements);
$this->printMethods($measurements);

$this->viewRenderer->newLine();
$this->symfonyStyle->newLine();
}

private function printFilesAndDirectories(Measurements $measurements): void
{
$this->viewRenderer->render('table', [
'title' => 'Metric',
'label' => 'Count',
'rows' => $this->formatRows([
['Directories', $measurements->getDirectoryCount()],
['Files', $measurements->getFileCount()],
]),
$tableRows = $this->formatRows([
['Directories', $measurements->getDirectoryCount()],
['Files', $measurements->getFileCount()],
]);

$tableView = new TableView('Metric', 'Count', $tableRows);
$this->viewRenderer->renderTableView($tableView);
}

private function printLinesOfCode(Measurements $measurements): void
{
$this->viewRenderer->render('table', [
'title' => 'Lines of code',
'label' => 'Count',
'includeRelative' => true,
'rows' => $this->formatRows([
['Code', $measurements->getNonCommentLines(), $measurements->getNonCommentLinesRelative()],
['Comments', $measurements->getCommentLines(), $measurements->getCommentLinesRelative()],
['Total', $measurements->getLines(), 100.0],
]),
$tableRows = $this->formatRows([
['Code', $measurements->getNonCommentLines(), $measurements->getNonCommentLinesRelative()],
['Comments', $measurements->getCommentLines(), $measurements->getCommentLinesRelative()],
['Total', $measurements->getLines(), 100.0],
]);

$tableView = new TableView('Lines of code', 'Count', $tableRows, true);
$this->viewRenderer->renderTableView($tableView);
}

private function printMethods(Measurements $measurements): void
Expand All @@ -67,59 +69,56 @@ private function printMethods(Measurements $measurements): void
return;
}

$this->viewRenderer->render('table', [
'title' => 'Methods',
'label' => 'Count',
'includeRelative' => true,
'rows' => $this->formatRows([
['Non-static', $measurements->getNonStaticMethods(), $measurements->getNonStaticMethodsRelative()],
['Static', $measurements->getStaticMethods(), $measurements->getStaticMethodsRelative()],
[],
['Public', $measurements->getPublicMethods(), $measurements->getPublicMethodsRelative()],
['Protected', $measurements->getProtectedMethods(), $measurements->getProtectedMethodsRelative()],
['Private', $measurements->getPrivateMethods(), $measurements->getPrivateMethodsRelative()],
]),
$tableRows = $this->formatRows([
['Non-static', $measurements->getNonStaticMethods(), $measurements->getNonStaticMethodsRelative()],
['Static', $measurements->getStaticMethods(), $measurements->getStaticMethodsRelative()],
]);

$tableView = new TableView('Method access', 'Count', $tableRows, true);
$this->viewRenderer->renderTableView($tableView);

$tableRows = $this->formatRows([
['Public', $measurements->getPublicMethods(), $measurements->getPublicMethodsRelative()],
['Protected', $measurements->getProtectedMethods(), $measurements->getProtectedMethodsRelative()],
['Private', $measurements->getPrivateMethods(), $measurements->getPrivateMethodsRelative()],
]);

$tableView = new TableView('Method visibility', 'Count', $tableRows, true);
$this->viewRenderer->renderTableView($tableView);
}

private function printStructure(Measurements $measurements): void
{
$this->viewRenderer->render('table', [
'title' => 'Structure',
'label' => 'Count',
'rows' => $this->formatRows([
['Namespaces', $measurements->getNamespaceCount()],
['Classes', $measurements->getClassCount()],
['* Constants', $measurements->getClassConstantCount(), null, true],
['* Methods', $measurements->getMethodCount(), null, true],
['Interfaces', $measurements->getInterfaceCount()],
['Traits', $measurements->getTraitCount()],
['Enums', $measurements->getEnumCount()],
['Functions', $measurements->getFunctionCount()],
['Global constants', $measurements->getGlobalConstantCount()],
]),
$tableRows = $this->formatRows([
['Namespaces', $measurements->getNamespaceCount()],
['Classes', $measurements->getClassCount()],
['* Constants', $measurements->getClassConstantCount(), null, true],
['* Methods', $measurements->getMethodCount(), null, true],
['Interfaces', $measurements->getInterfaceCount()],
['Traits', $measurements->getTraitCount()],
['Enums', $measurements->getEnumCount()],
['Functions', $measurements->getFunctionCount()],
['Global constants', $measurements->getGlobalConstantCount()],
]);

$tableView = new TableView('Structure', 'Count', $tableRows);
$this->viewRenderer->renderTableView($tableView);
}

/**
* @param array<array{0?: string, 1?: int|float, 2?: float|null, 3?: bool}> $rows
* @return array<array{}|array{name: string, count: int|float|string, percent: float|string|null, isChild: bool}>>
* @return TableRow[]
*/
private function formatRows(array $rows): array
{
return array_map(static function (array $row): array {
if ($row === []) {
return [];
}

return [
'name' => $row[0],
// make big numbers separated with space, e.g. "1 234"
'count' => NumberFormat::pretty($row[1]),
// optional float relatives
'percent' => isset($row[2]) ? NumberFormat::percent($row[2]) : null,
'isChild' => $row[3] ?? false,
];
return array_map(static function (array $row): TableRow {
Assert::notEmpty($row);

$prettyNumber = NumberFormat::pretty($row[1]);

return new TableRow($row[0], $prettyNumber, isset($row[2]) ? NumberFormat::percent(
$row[2]
) : null, $row[3] ?? false);
}, $rows);
}
}
31 changes: 7 additions & 24 deletions src/Console/ViewRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,25 @@

namespace TomasVotruba\Lines\Console;

use Symfony\Component\Console\Style\SymfonyStyle;
use TomasVotruba\Lines\ValueObject\TableView;
use function Termwind\render;

final class ViewRenderer
{
public function __construct(
private readonly SymfonyStyle $symfonyStyle,
) {
}

public function newLine(): void
public function renderTableView(TableView $tableView): void
{
$this->symfonyStyle->writeln('');
}
$viewContent = $this->getFileContents($tableView);

/**
* @param array<string, mixed> $data
*/
public function render(string $view, array $data): void
{
$viewContent = $this->getViewContent($view, $data);
render($viewContent);
}

/**
* @param array<string, mixed> $data
*/
private function getViewContent(string $view, array $data): string
private function getFileContents(TableView $tableView): string
{
extract($data);

ob_start();
include __DIR__ . '/../../views/' . $view . '.php';
$content = (string) ob_get_contents();
require $tableView->getTemplateFilePath();
$viewContent = (string) ob_get_contents();
ob_end_clean();

return $content;
return $viewContent;
}
}
39 changes: 39 additions & 0 deletions src/ValueObject/TableRow.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace TomasVotruba\Lines\ValueObject;

/**
* @api used in templates
*/
final class TableRow
{
public function __construct(
private readonly string $name,
private readonly string $count,
private readonly ?string $percent,
private readonly bool $isChild,
) {
}

public function getName(): string
{
return $this->name;
}

public function getCount(): string
{
return $this->count;
}

public function getPercent(): ?string
{
return $this->percent;
}

public function isChild(): bool
{
return $this->isChild;
}
}
53 changes: 53 additions & 0 deletions src/ValueObject/TableView.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace TomasVotruba\Lines\ValueObject;

use Webmozart\Assert\Assert;

/**
* @api used in templates
*/
final class TableView
{
/**
* @param TableRow[] $tableRows
*/
public function __construct(
private readonly string $title,
private readonly string $label,
private readonly array $tableRows,
private readonly bool $shouldIncludeRelative = false,
) {
Assert::allIsInstanceOf($tableRows, TableRow::class);
}

public function getTitle(): string
{
return $this->title;
}

public function getLabel(): string
{
return $this->label;
}

public function isShouldIncludeRelative(): bool
{
return $this->shouldIncludeRelative;
}

/**
* @return TableRow[]
*/
public function getRows(): array
{
return $this->tableRows;
}

public function getTemplateFilePath(): string
{
return __DIR__ . '/../../views/table.php';
}
}
Loading

0 comments on commit fb17880

Please sign in to comment.