From 9626ae25c08aad2cfe709f5221fd6b12df74a3d1 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Fri, 12 Jul 2024 11:13:24 +0200 Subject: [PATCH] Add --longest option to spot longest files (#40) * Add --longest option to spot longest files * docs * bump deps * bump ci --- .github/workflows/code_analysis.yaml | 4 ++-- README.md | 8 +++++++ composer.json | 13 ++++++------ src/Console/Command/MeasureCommand.php | 8 ++++--- .../OutputFormatter/JsonOutputFormatter.php | 6 +++++- .../OutputFormatter/TextOutputFormatter.php | 13 +++++++++++- src/Contract/OutputFormatterInterface.php | 2 +- src/Measurements.php | 21 +++++++++++++++++++ 8 files changed, 61 insertions(+), 14 deletions(-) diff --git a/.github/workflows/code_analysis.yaml b/.github/workflows/code_analysis.yaml index d83c765a..4be893b9 100644 --- a/.github/workflows/code_analysis.yaml +++ b/.github/workflows/code_analysis.yaml @@ -21,8 +21,8 @@ jobs: run: bin/lines measure src --ansi - - name: 'Run "measure" with json command' - run: bin/lines measure src --json --ansi + name: 'Run "measure" with json and logest command' + run: bin/lines measure src --json --longest --ansi - name: 'PHPStan' diff --git a/README.md b/README.md index 82fa7a5e..a63801c7 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,14 @@ Also, you can combine them (very handy for blog posts and tweets): vendor/bin/lines measure src --short --json ``` +
+ +Are you looking for top 10 longest files? + +```bash +vendor/bin/lines measure src --longest +``` + ## The Measured Items For the text output, you'll get data like these: diff --git a/composer.json b/composer.json index 438a26d9..1792182f 100644 --- a/composer.json +++ b/composer.json @@ -8,9 +8,9 @@ ], "require": { "php": "^8.2", - "symfony/console": "^6.3", - "symfony/finder": "^6.3", - "illuminate/container": "^10.43", + "symfony/console": "^6.4", + "symfony/finder": "^6.4", + "illuminate/container": "^11.0", "webmozart/assert": "^1.11", "nikic/php-parser": "^4.18", "sebastian/lines-of-code": "^2.0", @@ -18,14 +18,15 @@ }, "require-dev": { "phpunit/phpunit": "^10.5", - "rector/rector": "^0.19.5", + "rector/rector": "^1.1", "phpstan/phpstan": "^1.10.57", "symplify/easy-coding-standard": "^12.1", "tracy/tracy": "^2.10", "tomasvotruba/class-leak": "^0.2", - "phpstan/extension-installer": "^1.3", + "phpstan/extension-installer": "^1.4", "symplify/vendor-patches": "^11.3", - "symplify/phpstan-rules": "^12.4" + "symplify/phpstan-rules": "^13.0", + "rector/type-perfect": "^0.1.8" }, "autoload": { "psr-4": { diff --git a/src/Console/Command/MeasureCommand.php b/src/Console/Command/MeasureCommand.php index 5c6fa14e..bde06d91 100644 --- a/src/Console/Command/MeasureCommand.php +++ b/src/Console/Command/MeasureCommand.php @@ -44,6 +44,7 @@ protected function configure(): void $this->addOption('json', null, InputOption::VALUE_NONE, 'Output in JSON format'); $this->addOption('short', null, InputOption::VALUE_NONE, 'Print short metrics only'); $this->addOption('allow-vendor', null, InputOption::VALUE_NONE, 'Allow /vendor directory to be scanned'); + $this->addOption('longest', null, InputOption::VALUE_NONE, 'Show top 10 longest files'); } /** @@ -56,6 +57,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $isJson = (bool) $input->getOption('json'); $isShort = (bool) $input->getOption('short'); $allowVendor = (bool) $input->getOption('allow-vendor'); + $showLongestFiles = (bool) $input->getOption('longest'); $filePaths = $this->phpFilesFinder->findInDirectories($paths, $excludes, $allowVendor); if ($filePaths === []) { @@ -64,13 +66,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $progressBarClosure = $this->createProgressBarClosure($isJson, $filePaths); - $measurement = $this->analyser->measureFiles($filePaths, $progressBarClosure); + $measurements = $this->analyser->measureFiles($filePaths, $progressBarClosure); // print results if ($isJson) { - $this->jsonOutputFormatter->printMeasurement($measurement, $isShort); + $this->jsonOutputFormatter->printMeasurement($measurements, $isShort, $showLongestFiles); } else { - $this->textOutputFormatter->printMeasurement($measurement, $isShort); + $this->textOutputFormatter->printMeasurement($measurements, $isShort, $showLongestFiles); } return Command::SUCCESS; diff --git a/src/Console/OutputFormatter/JsonOutputFormatter.php b/src/Console/OutputFormatter/JsonOutputFormatter.php index 391f9097..be215c64 100644 --- a/src/Console/OutputFormatter/JsonOutputFormatter.php +++ b/src/Console/OutputFormatter/JsonOutputFormatter.php @@ -10,7 +10,7 @@ final class JsonOutputFormatter implements OutputFormatterInterface { - public function printMeasurement(Measurements $measurements, bool $isShort): void + public function printMeasurement(Measurements $measurements, bool $isShort, bool $showLongestFiles): void { $arrayData = [ 'filesystem' => [ @@ -57,6 +57,10 @@ public function printMeasurement(Measurements $measurements, bool $isShort): voi ]; } + if ($showLongestFiles) { + $arrayData['longest_files'] = $measurements->getLongestFiles(); + } + $jsonString = json_encode($arrayData, JSON_PRETTY_PRINT); Assert::string($jsonString); diff --git a/src/Console/OutputFormatter/TextOutputFormatter.php b/src/Console/OutputFormatter/TextOutputFormatter.php index e798ba30..7353507f 100644 --- a/src/Console/OutputFormatter/TextOutputFormatter.php +++ b/src/Console/OutputFormatter/TextOutputFormatter.php @@ -21,7 +21,7 @@ public function __construct( ) { } - public function printMeasurement(Measurements $measurements, bool $isShort): void + public function printMeasurement(Measurements $measurements, bool $isShort, bool $showLongestFiles): void { $this->symfonyStyle->newLine(); @@ -37,6 +37,17 @@ public function printMeasurement(Measurements $measurements, bool $isShort): voi $this->printStructure($measurements); $this->printMethods($measurements); + if ($showLongestFiles) { + $rows = []; + foreach ($measurements->getLongestFiles() as $filePath => $linesCount) { + $rows[] = [$filePath, $linesCount]; + } + + $tableRows = $this->formatRows($rows); + $tableView = new TableView('Longest files', 'Line count', $tableRows); + $this->viewRenderer->renderTableView($tableView); + } + $this->symfonyStyle->newLine(); } diff --git a/src/Contract/OutputFormatterInterface.php b/src/Contract/OutputFormatterInterface.php index 6feb634a..62c7f419 100644 --- a/src/Contract/OutputFormatterInterface.php +++ b/src/Contract/OutputFormatterInterface.php @@ -8,5 +8,5 @@ interface OutputFormatterInterface { - public function printMeasurement(Measurements $measurements, bool $isShort): void; + public function printMeasurement(Measurements $measurements, bool $isShort, bool $showLongestFiles): void; } diff --git a/src/Measurements.php b/src/Measurements.php index 297588e8..556f8b05 100644 --- a/src/Measurements.php +++ b/src/Measurements.php @@ -48,10 +48,18 @@ final class Measurements */ private array $namespaceNames = []; + /** + * @var array + */ + private array $filesToSize = []; + public function addFile(string $filename): void { $this->directoryNames[] = dirname($filename); + $relativeFilePath = str_replace(getcwd() . '/', '', $filename); + $this->filesToSize[$relativeFilePath] = substr_count((string) file_get_contents($filename), "\n") + 1; + ++$this->fileCount; } @@ -134,6 +142,7 @@ public function getDirectoryCount(): int { $uniqueDirectoryNames = array_unique($this->directoryNames); return count($uniqueDirectoryNames) - 1; + } public function getFileCount(): int @@ -290,6 +299,18 @@ public function getEnumCount(): int return $this->enumCount; } + /** + * @return array + */ + public function getLongestFiles(): array + { + // longest files first + arsort($this->filesToSize); + + // get top 10 + return array_slice($this->filesToSize, 0, 10); + } + private function relative(int $partialNumber, int $totalNumber): float { $relative = ($partialNumber / $totalNumber) * 100;