Created
February 16, 2022 13:39
-
-
Save dnahrebecki/375b8a360441599bc3cfbb9eb8059442 to your computer and use it in GitHub Desktop.
Command for generating LOC statistics for a Symfony project
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
<?php | |
namespace App\Command; | |
use Symfony\Component\Console\Command\Command; | |
use Symfony\Component\Console\Input\InputArgument; | |
use Symfony\Component\Console\Input\InputDefinition; | |
use Symfony\Component\Console\Input\InputInterface; | |
use Symfony\Component\Console\Input\InputOption; | |
use Symfony\Component\Console\Output\OutputInterface; | |
use Symfony\Component\Console\Style\SymfonyStyle; | |
use Symfony\Component\Finder\Finder; | |
use Symfony\Component\Serializer\Encoder\CsvEncoder; | |
use Symfony\Component\Serializer\Serializer; | |
/** | |
* Make sure cloc is installed (@link https://github.com/AlDanial/cloc) | |
*/ | |
class EstimateClocCommand extends Command | |
{ | |
public const DEFAULT_OUTPUT_FILE = '/tmp/upgrade.csv'; | |
public const DEFAULT_DEPTH = 0; // first level only | |
/** @var string */ | |
protected static $defaultName = 'devtools:estimate:cloc'; | |
/** | |
* {@inheritdoc} | |
*/ | |
protected function configure() | |
{ | |
$this | |
->setDefinition($this->createDefinition()) | |
->setDescription('Generate CLOC statistics.') | |
->addUsage('/var/www/oro/src --depth=2 --trimPath=/var/www/oro/src --outputFile=/tmp/results.csv'); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getNativeDefinition() | |
{ | |
return $this->createDefinition(); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
protected function execute(InputInterface $input, OutputInterface $output) | |
{ | |
$io = new SymfonyStyle($input, $output); | |
$io->newLine(); | |
$directory = $input->getArgument('directory'); | |
$omitCsv = $input->getOption('omitCsv'); | |
$outputFilePath = $input->getOption('outputFile'); | |
$depth = $input->getOption('depth'); | |
$trimPath = $input->getOption('trimPath'); | |
$finder = new Finder(); | |
$finder->directories()->sortByName()->depth($depth)->in($directory); | |
if (!$finder->hasResults()) { | |
$io->error(sprintf('No directories in the path %s provided', $directory)); | |
return; | |
} | |
$results = []; | |
$keys = ['directory', 'php_files', 'php_code', 'js_files', 'js_code', 'twig_files', 'twig_code', 'yaml_files', 'yaml_code']; | |
foreach ($finder as $dir) { | |
$currentDirectory = $trimPath ? str_replace($trimPath, '', $dir->getRealPath()) : $dir->getRealPath(); | |
$io->text(sprintf('Processing %s...', $currentDirectory)); | |
$jsonOutput = shell_exec(sprintf('cloc %s --json', $dir->getRealPath())); | |
$stats = json_decode($jsonOutput, true); | |
$dirResult = [ | |
'directory' => $currentDirectory, | |
'php_files' => $stats['PHP']['nFiles'] ?? '-', | |
'php_code' => $stats['PHP']['code'] ?? '-', | |
'js_files' => $stats['JavaScript']['nFiles'] ?? '-', | |
'js_code' => $stats['JavaScript']['code'] ?? '-', | |
'twig_files' => $stats['Twig']['nFiles'] ?? '-', | |
'twig_code' => $stats['Twig']['code'] ?? '-', | |
'yaml_files' => $stats['YAML']['nFiles'] ?? '-', | |
'yaml_code' => $stats['YAML']['code'] ?? '-', | |
]; | |
$results[] = $dirResult; | |
} | |
$io->table($keys, $results); | |
if ($omitCsv === false) { | |
$serializer = new Serializer([], [new CsvEncoder()]); | |
file_put_contents($outputFilePath, $serializer->encode($results, 'csv')); | |
} | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
private function createDefinition() | |
{ | |
// phpcs:disable | |
return new InputDefinition([ | |
new InputArgument('directory', InputArgument::REQUIRED, 'Directory on which cloc performs calculations'), | |
new InputOption('omitCsv', null, InputOption::VALUE_NONE, 'Generate csv with results'), | |
new InputOption('outputFile', null, InputOption::VALUE_REQUIRED, 'Filepath for generating csv.', self::DEFAULT_OUTPUT_FILE), | |
new InputOption('depth', null, InputOption::VALUE_REQUIRED, 'How deeply directory should be traversed.', self::DEFAULT_DEPTH), | |
new InputOption('trimPath', null, InputOption::VALUE_OPTIONAL, 'Optionally trim part of a filepath'), | |
]); | |
// phpcs:enable | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment