silverstripe /
moduleratings-plugin
| 1 | <?php |
||||
| 2 | |||||
| 3 | namespace SilverStripe\ModuleRatingsPlugin\Command; |
||||
| 4 | |||||
| 5 | use Composer\Command\BaseCommand; |
||||
| 6 | use InvalidArgumentException; |
||||
| 7 | use SilverStripe\ModuleRatings\Check; |
||||
| 8 | use SilverStripe\ModuleRatings\CheckSuite; |
||||
| 9 | use Symfony\Component\Console\Helper\ProgressBar; |
||||
| 10 | use Symfony\Component\Console\Helper\Table; |
||||
| 11 | use Symfony\Component\Console\Helper\TableSeparator; |
||||
| 12 | use Symfony\Component\Console\Input\InputArgument; |
||||
| 13 | use Symfony\Component\Console\Input\InputInterface; |
||||
| 14 | use Symfony\Component\Console\Input\InputOption; |
||||
| 15 | use Symfony\Component\Console\Output\OutputInterface; |
||||
| 16 | |||||
| 17 | class RateModuleCommand extends BaseCommand |
||||
| 18 | { |
||||
| 19 | protected function configure() |
||||
| 20 | { |
||||
| 21 | $this |
||||
| 22 | ->setName('rate-module') |
||||
| 23 | ->setDescription('Assesses a module\'s quality and provides a rating') |
||||
| 24 | ->setDefinition([ |
||||
| 25 | new InputArgument( |
||||
| 26 | 'module-path', |
||||
| 27 | InputArgument::REQUIRED, |
||||
| 28 | 'The path to the module folder, relative to the current working directory' |
||||
| 29 | ), |
||||
| 30 | new InputOption( |
||||
| 31 | 'slug', |
||||
| 32 | null, |
||||
| 33 | InputOption::VALUE_OPTIONAL, |
||||
| 34 | "The module's GitHub repository slug, e.g. silverstripe/silverstripe-blog - used for API checks" |
||||
| 35 | ), |
||||
| 36 | ])->setHelp(<<<TEXT |
||||
| 37 | This command will assess the provided module based on a selection of pre-defined quality checks, and provide a rating |
||||
| 38 | out of 100. |
||||
| 39 | |||||
| 40 | You must provide the <info>module-path</info> to map the path from the current working directory to the source code |
||||
| 41 | of the module, and you may optionally provide the <info>slug</info> argument which will enable API based status checks. |
||||
| 42 | |||||
| 43 | Note that without providing <info>slug</info> the module will never be able to achieve a 100% score. |
||||
| 44 | TEXT |
||||
| 45 | ); |
||||
| 46 | } |
||||
| 47 | |||||
| 48 | protected function execute(InputInterface $input, OutputInterface $output) |
||||
| 49 | { |
||||
| 50 | // Ensure autoloader is included |
||||
| 51 | $vendorDir = $this->getComposer()->getConfig()->get('vendor-dir'); |
||||
| 52 | require_once $vendorDir . '/autoload.php'; |
||||
| 53 | |||||
| 54 | $modulePath = $input->getArgument('module-path'); |
||||
| 55 | if (empty($modulePath) || !file_exists($modulePath)) { |
||||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
| 56 | throw new InvalidArgumentException('Provided module path "' . $modulePath . '" does not exist!'); |
||||
|
0 ignored issues
–
show
Are you sure
$modulePath of type null|string|string[] can be used in concatenation?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 57 | } |
||||
| 58 | |||||
| 59 | // Make path absolute |
||||
| 60 | $modulePath = realpath($modulePath); |
||||
|
0 ignored issues
–
show
It seems like
$modulePath can also be of type string[]; however, parameter $path of realpath() does only seem to accept string, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 61 | |||||
| 62 | $checkSuite = new CheckSuite(); |
||||
| 63 | |||||
| 64 | $checkSuite->setModuleRoot($modulePath); |
||||
| 65 | if ($slug = $input->getOption('slug')) { |
||||
| 66 | $checkSuite->setRepositorySlug($slug); |
||||
| 67 | } |
||||
| 68 | |||||
| 69 | // Get a callback we can use to monitor the check suite progress |
||||
| 70 | $progressBar = new ProgressBar($output, count($checkSuite->getChecks())); |
||||
| 71 | $progressBar->setFormatDefinition('checksuite', ' %current%/%max% [%bar%] %message%'); |
||||
| 72 | $progressBar->setFormat('checksuite'); |
||||
| 73 | $progressBar->setMessage('Loading check suite...'); |
||||
| 74 | $progressBar->start(); |
||||
| 75 | $callback = $this->getCheckCallback($progressBar); |
||||
| 76 | |||||
| 77 | $checkSuite->run($callback); |
||||
| 78 | |||||
| 79 | $progressBar->finish(); |
||||
| 80 | $progressBar->clear(); |
||||
| 81 | |||||
| 82 | $tableRows = $checkSuite->getCheckDetails(); |
||||
| 83 | $tableRows[] = new TableSeparator(); |
||||
| 84 | $tableRows[] = ['TOTAL SCORE (normalised)', $checkSuite->getScore(), '100']; |
||||
| 85 | |||||
| 86 | $table = new Table($output); |
||||
| 87 | $table |
||||
| 88 | ->setHeaders(['Check description', 'Points', 'Maximum']) |
||||
| 89 | ->setRows($tableRows); |
||||
| 90 | $table->render(); |
||||
| 91 | } |
||||
| 92 | |||||
| 93 | protected function getCheckCallback(ProgressBar $progressBar) |
||||
| 94 | { |
||||
| 95 | return function (Check $check, callable $delegate) use ($progressBar) { |
||||
| 96 | $progressBar->setMessage('Running check: ' . $check->getKey()); |
||||
| 97 | $delegate(); |
||||
| 98 | $progressBar->advance(); |
||||
| 99 | }; |
||||
| 100 | } |
||||
| 101 | } |
||||
| 102 |