Skip to content

Commit

Permalink
Add text log
Browse files Browse the repository at this point in the history
  • Loading branch information
datashaman committed Apr 16, 2019
1 parent 174ea3f commit a65912c
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 17 deletions.
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ phpcheck-coverage-console:
phpcheck-coverage-text:
@phpcheck --coverage-text build/coverage.txt

phpcheck-log-junit:
@phpcheck --log-junit build/phpcheck.xml

phpcheck-log-text:
@phpcheck --log-text build/phpcheck.txt

phpcheck-no-defects:
@phpcheck -d

Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,12 @@ The `phpcheck` program accept a number of arguments and options:

Options:
--bootstrap[=BOOTSTRAP] A PHP script that is included before the checks run
--coverage-html[=COVERAGE-HTML] Generate code coverage report in HTML [default: false]
--coverage-text[=COVERAGE-TEXT] Generate code coverage report in text [default: false]
--coverage-html[=COVERAGE-HTML] Generate HTML code coverage report [default: false]
--coverage-text[=COVERAGE-TEXT] Generate text code coverage report [default: false]
-f, --filter[=FILTER] Filter the checks that will be run
-i, --iterations=ITERATIONS How many times each check will be run [default: 100]
-j, --log-junit[=LOG-JUNIT] Log check execution in JUnit XML format to file
-j, --log-junit[=LOG-JUNIT] Log check execution to JUnit XML file [default: false]
-t, --log-text[=LOG-TEXT] Log check execution to text file [default: false]
-d, --no-defects[=NO-DEFECTS] Ignore previous defects [default: false]
-h, --help Display this help message
-q, --quiet Do not output any message
Expand Down
7 changes: 4 additions & 3 deletions src/CheckCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ protected function configure(): void
$this
->setDescription('Run checks.')
->addOption('bootstrap', null, InputOption::VALUE_OPTIONAL, 'A PHP script that is included before the checks run')
->addOption('coverage-html', null, InputOption::VALUE_OPTIONAL, 'Generate code coverage report in HTML', false)
->addOption('coverage-text', null, InputOption::VALUE_OPTIONAL, 'Generate code coverage report in text', false)
->addOption('coverage-html', null, InputOption::VALUE_OPTIONAL, 'Generate HTML code coverage report', false)
->addOption('coverage-text', null, InputOption::VALUE_OPTIONAL, 'Generate text code coverage report', false)
->addOption('filter', 'f', InputOption::VALUE_OPTIONAL, 'Filter the checks that will be run')
->addOption('iterations', 'i', InputOption::VALUE_REQUIRED, 'How many times each check will be run', Runner::MAX_ITERATIONS)
->addOption('log-junit', 'j', InputOption::VALUE_OPTIONAL, 'Log check execution in JUnit XML format to file')
->addOption('log-junit', 'j', InputOption::VALUE_OPTIONAL, 'Log check execution to JUnit XML file', false)
->addOption('log-text', 't', InputOption::VALUE_OPTIONAL, 'Log check execution to text file', false)
->addOption('no-defects', 'd', InputOption::VALUE_OPTIONAL, 'Ignore previous defects', false)
->addOption('seed', 's', InputOption::VALUE_OPTIONAL, 'Seed the random number generator to get repeatable runs')
->addArgument('path', InputArgument::OPTIONAL, 'File or folder with checks', 'checks');
Expand Down
4 changes: 0 additions & 4 deletions src/Coverage/Coverage.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@
*/
namespace Datashaman\PHPCheck\Coverage;

use Datashaman\PHPCheck\CheckEvents;
use Datashaman\PHPCheck\Events;
use Datashaman\PHPCheck\Runner;
use SebastianBergmann\CodeCoverage\CodeCoverage;
use SebastianBergmann\CodeCoverage\Report\Text;

abstract class Coverage
{
Expand Down
2 changes: 1 addition & 1 deletion src/Coverage/TextCoverage.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function __destruct()

if ($this->input->getOption('coverage-text')) {
$output = $writer->process($coverage, false);
file_put_contents($this->input->getOption('coverage-text'), $output);
\file_put_contents($this->input->getOption('coverage-text'), $output);

return;
}
Expand Down
27 changes: 22 additions & 5 deletions src/Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ public function execute(InputInterface $input, OutputInterface $output): void
$this->output = $output;

if ($input->getOption('coverage-html') !== false) {
if (is_null($input->getOption('coverage-html'))) {
$output->writeln('<error>You must specify a directory for coverage-html</error>');
exit(1);
}
$coverage = new Coverage\HtmlCoverage($this);
}

Expand All @@ -155,11 +159,24 @@ public function execute(InputInterface $input, OutputInterface $output): void

$this->dispatcher->addSubscriber(new Subscribers\ConsoleReporter($this));

if ($input->getOption('log-junit')) {
if ($input->getOption('log-junit') !== false) {
if (is_null($input->getOption('log-junit'))) {
$output->writeln('<error>You must specify a filename for log-junit</error>');
exit(1);
}
$reporter = new Subscribers\JUnitReporter($this);
$this->dispatcher->addSubscriber($reporter);
}

if ($input->getOption('log-text') !== false) {
if (is_null($input->getOption('log-text'))) {
$output->writeln('<error>You must specify a filename for log-text</error>');
exit(1);
}
$reporter = new Subscribers\TextReporter($this);
$this->dispatcher->addSubscriber($reporter);
}

$bootstrap = $input->getOption('bootstrap')
?: $config['bootstrap']
?? null;
Expand Down Expand Up @@ -256,16 +273,16 @@ function ($class) {
} catch (ExecutionFailure $failure) {
$event = new Events\FailureEvent(
$method,
$failure->args,
$failure->cause
$failure->getArgs(),
$failure->getCause()
);
$this->dispatcher->dispatch(CheckEvents::FAILURE, $event);
$status = 'FAILURE';
} catch (ExecutionError $error) {
$event = new Events\ErrorEvent(
$method,
$error->args,
$error->cause
$error->getArgs(),
$error->getCause()
);
$this->dispatcher->dispatch(CheckEvents::ERROR, $event);
$status = 'ERROR';
Expand Down
2 changes: 1 addition & 1 deletion src/Subscribers/JUnitReporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public function onFailure(Events\FailureEvent $event): void
);
}

public function onEndAll()
public function onEndAll(): void
{
$this->testsuite->asXML($this->input->getOption('log-junit'));
}
Expand Down
50 changes: 50 additions & 0 deletions src/Subscribers/Subscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php declare(strict_types=1);
/*
* This file is part of the phpcheck package.
*
* ©Marlin Forbes <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Datashaman\PHPCheck\Subscribers;

use Datashaman\PHPCheck\Runner;
use ReflectionMethod;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

abstract class Subscriber implements EventSubscriberInterface
{
protected $input;

protected $output;

protected $runner;

protected $state;

public function __construct(Runner $runner)
{
$this->input = $runner->getInput();
$this->output = $runner->getOutput();
$this->runner = $runner;
$this->state = $runner->getState();
}

protected function getMethodSignature(ReflectionMethod $method): string
{
return $method->getDeclaringClass()->getName() . '::' . $method->getName();
}

protected function convertBytes(int $bytes): string
{
if ($bytes == 0) {
return '0.00 B';
}

$suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
$exponent = (int) \floor(\log($bytes, 1024));

return \sprintf('%.2f %s', \round($bytes / 1024 ** $exponent, 2), $suffixes[$exponent]);
}
}
104 changes: 104 additions & 0 deletions src/Subscribers/TextReporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php declare(strict_types=1);
/*
* This file is part of the phpcheck package.
*
* ©Marlin Forbes <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Datashaman\PHPCheck\Subscribers;

use Datashaman\PHPCheck\CheckEvents;
use Datashaman\PHPCheck\Events;
use ReflectionClass;

class TextReporter extends Reporter
{
protected $file;

public static function getSubscribedEvents(): array
{
return [
CheckEvents::START_ALL => 'onStartAll',
CheckEvents::START => 'onStart',
CheckEvents::SUCCESS => 'onSuccess',
CheckEvents::ERROR => 'onError',
CheckEvents::FAILURE => 'onFailure',
CheckEvents::END_ALL => 'onEndAll',
];
}

public function onStartAll(Events\StartAllEvent $event): void
{
$this->file = fopen($this->input->getOption('log-text'), 'a');
$this->report('onStartAll', $event);
}

public function onEndAll(Events\EndAllEvent $event): void
{
$this->report('onEndAll', $event);

if (is_resource($this->file)) {
fclose($this->file);
}
}

public function __call(string $name, array $args)
{
$this->report($name, ...$args);
}

protected function report(string $name, Events\Event $event)
{
$shortName = preg_replace(
'/Event$/',
'',
(new ReflectionClass($event))->getShortName()
);
$message = sprintf(
'%s [%-10s]',
strftime('%F %T', (int) $event->time),
strtoupper($shortName)
);

if (
in_array(
$name,
[
'onError',
'onFailure',
'onStart',
'onSuccess',
]
)
) {
$message .= ' ' . $this->getMethodSignature($event->method);
}

if (
$event instanceof Events\ResultEvent
) {
if (!is_null($event->args)) {
$args = preg_replace(
[
'/^\[/',
'/\]$/',
],
'',
json_encode($event->args)
);

$message .= '(' . $args . ')';
}

if ($event->cause) {
$message .= ' caused ' . get_class($event->cause) . '("' . $event->cause->getMessage() . '")';
}
}

$message .= "\n";

fwrite($this->file, $message);
}
}

0 comments on commit a65912c

Please sign in to comment.