Skip to content

Commit 03bd709

Browse files
committed
Add in ability to save output report to a file. Particularly useful with json output
1 parent 32d751e commit 03bd709

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Run these commands to see some sample behavior:
1818
composer audit
1919
composer audit --format=simple
2020
composer audit --format=json
21+
composer audit --format=json --output-file=report.json
2122
composer validate
2223
composer require symfony/symfony --update-with-all-dependencies
2324
composer audit

src/Command/AuditCommand.php

+13-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use FancyGuy\Composer\SecurityCheck\Formatter\JsonFormatter;
1212
use FancyGuy\Composer\SecurityCheck\Formatter\SimpleFormatter;
1313
use FancyGuy\Composer\SecurityCheck\Formatter\TextFormatter;
14+
use FancyGuy\Composer\SecurityCheck\Output\FileOutput;
1415
use Symfony\Component\Console\Input\InputOption;
1516
use Symfony\Component\Console\Input\InputInterface;
1617
use Symfony\Component\Console\Output\OutputInterface;
@@ -26,6 +27,7 @@ protected function configure()
2627
->setDefinition(array(
2728
new InputOption('audit-db', '', InputOption::VALUE_REQUIRED, 'Path to the advisory database'),
2829
new InputOption('format', '', InputOption::VALUE_REQUIRED, 'Output format', 'text'),
30+
new InputOption('output-file', '', InputOption::VALUE_REQUIRED, 'File to append the report output to'),
2931
new InputOption('endpoint', '', InputOption::VALUE_REQUIRED, 'Security checker server URL', HttpCheckerInterface::DEFAULT_ENDPOINT),
3032
new InputOption('timeout', '', InputOption::VALUE_REQUIRED, 'HTTP timeout in seconds', HttpCheckerInterface::DEFAULT_TIMEOUT),
3133
new InputOption('file', '', InputOption::VALUE_REQUIRED, 'Path to composer.lock file', './composer.lock'),
@@ -87,7 +89,17 @@ protected function execute(InputInterface $input, OutputInterface $output)
8789
return 127;
8890
}
8991

90-
$formatter->displayResults($output, $composerFile, $vulnerabilities);
92+
if ($outputFile = $input->getOption('output-file')) {
93+
$formatter->displayResults(
94+
new FileOutput($outputFile, $output->getVerbosity(), $output->isDecorated(), $output->getFormatter()),
95+
$composerFile,
96+
$vulnerabilities
97+
);
98+
$output->writeln(sprintf('Report written to: %s', $outputFile));
99+
} else {
100+
$formatter->displayResults($output, $composerFile, $vulnerabilities);
101+
}
102+
91103

92104
if ($checker->getLastVulnerabilityCount() > 0) {
93105
return 1;

src/Output/FileOutput.php

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace FancyGuy\Composer\SecurityCheck\Output;
4+
5+
use FancyGuy\Composer\SecurityCheck\Exception\RuntimeException;
6+
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
7+
use Symfony\Component\Console\Output\StreamOutput;
8+
9+
class FileOutput extends StreamOutput
10+
{
11+
/**
12+
* @param string $filePath Full path to the file to append to
13+
* @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
14+
* @param bool|null $decorated Whether to decorate messages (null for auto-guessing)
15+
* @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
16+
*
17+
* @see Symfony\Component\Console\Output\StreamOutput::__construct
18+
*/
19+
public function __construct(string $filePath, int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null)
20+
{
21+
if (false === ($writeStream = fopen($filePath, 'a', false))) {
22+
throw new RuntimeException(sprintf('Could not open write stream to: %s', $filePath));
23+
}
24+
parent::__construct($writeStream, $verbosity, $decorated, $formatter);
25+
}
26+
27+
/**
28+
* @throws RuntimeException Unable to close output file stream handle
29+
*/
30+
public function __destruct()
31+
{
32+
if (!fclose($this->getStream())) {
33+
throw new RuntimeException('Unable to close output file stream handle');
34+
}
35+
}
36+
}

0 commit comments

Comments
 (0)