Skip to content

Commit 1c79a08

Browse files
authored
Merge pull request #254 from dritter/exclude_cachelist
Add ability to exclude files from opcode cache listing
2 parents fe49fbd + e7ee134 commit 1c79a08

File tree

4 files changed

+136
-7
lines changed

4 files changed

+136
-7
lines changed

src/Command/AbstractCommand.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace CacheTool\Command;
1313

14+
use CacheTool\CacheTool;
1415
use Symfony\Component\Console\Command\Command;
1516
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
1617
use Symfony\Component\DependencyInjection\ContainerInterface;

src/Command/OpcacheStatusScriptsCommand.php

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use CacheTool\Util\Formatter;
1515
use Symfony\Component\Console\Helper\Table;
1616
use Symfony\Component\Console\Input\InputInterface;
17+
use Symfony\Component\Console\Input\InputOption;
1718
use Symfony\Component\Console\Output\OutputInterface;
1819

1920
class OpcacheStatusScriptsCommand extends AbstractOpcacheCommand
@@ -26,7 +27,13 @@ protected function configure()
2627
$this
2728
->setName('opcache:status:scripts')
2829
->setDescription('Show scripts in the opcode cache')
29-
->setHelp('');
30+
->setHelp('')
31+
->addOption(
32+
'exclude',
33+
'e',
34+
InputOption::VALUE_OPTIONAL,
35+
'Exclude scripts that match this regex. Example: `.*vendor.*`. Delimiters are not needed.'
36+
);
3037
}
3138

3239
/**
@@ -39,26 +46,31 @@ protected function execute(InputInterface $input, OutputInterface $output): int
3946
$info = $this->getCacheTool()->opcache_get_status(true);
4047
$this->ensureSuccessfulOpcacheCall($info);
4148

49+
$exclude = $input->getOption('exclude') ?? null;
50+
4251
$table = new Table($output);
4352
$table
4453
->setHeaders([
4554
'Hits',
4655
'Memory',
4756
'Filename'
4857
])
49-
->setRows($this->processFilelist($info['scripts']))
58+
->setRows($this->processFilelist($info['scripts'], $exclude))
5059
;
5160

5261
$table->render();
5362

5463
return 0;
5564
}
5665

57-
protected function processFileList(array $cacheList)
58-
{
66+
protected function processFileList(
67+
array $cacheList,
68+
string $exclude = null
69+
) {
5970
$list = [];
6071

61-
foreach ($cacheList as $item) {
72+
$filteredList = $exclude ? $this->excludeFiles($cacheList, $exclude) : $cacheList;
73+
foreach ($filteredList as $item) {
6274
$list[] = [
6375
number_format($item['hits']),
6476
Formatter::bytes($item['memory_consumption']),
@@ -68,4 +80,9 @@ protected function processFileList(array $cacheList)
6880

6981
return $list;
7082
}
83+
84+
protected function excludeFiles(array $cacheList, string $exclude = null): array
85+
{
86+
return array_intersect_key($cacheList, array_flip(preg_grep("({$exclude})", array_keys($cacheList), \PREG_GREP_INVERT)));
87+
}
7188
}

tests/Command/CommandTest.php

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,57 @@
22

33
namespace CacheTool\Command;
44

5+
use CacheTool\CacheTool;
6+
use CacheTool\Code;
57
use CacheTool\Console\Application;
68
use CacheTool\Console\Config;
9+
use Symfony\Component\Console\Input\InputInterface;
710
use Symfony\Component\Console\Input\StringInput;
811
use Symfony\Component\Console\Output\BufferedOutput;
912

1013
abstract class CommandTest extends \PHPUnit\Framework\TestCase
1114
{
12-
public function runCommand($cmd)
15+
public function runCommand($cmd, $mockData = null)
1316
{
14-
$app = new Application(new Config(['adapter' => 'cli']));
17+
$app = new class($mockData, new Config(['adapter' => 'cli'])) extends Application {
18+
protected $mockData;
19+
public function __construct($mockData, Config $config)
20+
{
21+
parent::__construct($config);
22+
23+
$this->mockData = $mockData;
24+
}
25+
26+
public function buildContainer(InputInterface $input)
27+
{
28+
$container = parent::buildContainer($input);
29+
30+
$cacheTool = CacheTool::factory(
31+
new class($this->mockData) extends \CacheTool\Adapter\Cli {
32+
public function __construct(protected $mockData)
33+
{}
34+
35+
public function doRun(Code $code)
36+
{
37+
if ($this->mockData) {
38+
$wrappedMockData = [
39+
'errors' => null,
40+
'result' => $this->mockData,
41+
];
42+
return serialize($wrappedMockData);
43+
}
44+
45+
return parent::doRun($code);
46+
}
47+
},
48+
$this->config['temp_dir'],
49+
$this->logger
50+
);
51+
$container->set('cachetool', $cacheTool);
52+
53+
return $container;
54+
}
55+
};
1556
$app->setAutoExit(false);
1657

1758
$input = new StringInput($cmd);

tests/Command/OpcacheStatusScriptsCommandTest.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,74 @@ public function testCommand()
1515
$this->assertStringContainsString('Memory', $result);
1616
$this->assertStringContainsString('Filename', $result);
1717
}
18+
19+
public function testExcludingScriptsWorksAsExpected()
20+
{
21+
$this->assertHasOpcache();
22+
23+
$scriptsMock = [
24+
'/vendor/somefile.php' => [
25+
'full_path' => '/vendor/somefile.php',
26+
'hits' => 1,
27+
'memory_consumption' => 1024,
28+
],
29+
'/src/my/path/to/somefile.php' => [
30+
'full_path' => '/src/my/path/to/somefile.php',
31+
'hits' => 2,
32+
'memory_consumption' => 1024,
33+
],
34+
'/src/my/other/path/to/somefile.php' => [
35+
'full_path' => '/src/my/other/path/to/somefile.php',
36+
'hits' => 3,
37+
'memory_consumption' => 1024,
38+
],
39+
'/vendor/someotherfile.php' => [
40+
'full_path' => '/vendor/someotherfile.php',
41+
'hits' => 4,
42+
'memory_consumption' => 1024,
43+
],
44+
];
45+
46+
$result = $this->runCommand('opcache:status:scripts -v -e vendor', ['scripts' => $scriptsMock]);
47+
48+
$this->assertStringContainsString('opcache_get_status(true)', $result);
49+
$this->assertStringContainsString('/src/my/path/to/somefile.php', $result);
50+
$this->assertStringNotContainsString('vendor', $result); // No findings of "vendor" expected!
51+
}
52+
53+
public function testNoScriptsAreExcludedByDefault()
54+
{
55+
$this->assertHasOpcache();
56+
57+
$scriptsMock = [
58+
'/vendor/somefile.php' => [
59+
'full_path' => '/vendor/somefile.php',
60+
'hits' => 1,
61+
'memory_consumption' => 1024,
62+
],
63+
'/src/my/path/to/somefile.php' => [
64+
'full_path' => '/src/my/path/to/somefile.php',
65+
'hits' => 2,
66+
'memory_consumption' => 1024,
67+
],
68+
'/src/my/other/path/to/somefile.php' => [
69+
'full_path' => '/src/my/other/path/to/somefile.php',
70+
'hits' => 3,
71+
'memory_consumption' => 1024,
72+
],
73+
'/vendor/someotherfile.php' => [
74+
'full_path' => '/vendor/someotherfile.php',
75+
'hits' => 4,
76+
'memory_consumption' => 1024,
77+
],
78+
];
79+
80+
$result = $this->runCommand('opcache:status:scripts -v', ['scripts' => $scriptsMock]);
81+
82+
$this->assertStringContainsString('opcache_get_status(true)', $result);
83+
$this->assertStringContainsString('/vendor/somefile.php', $result);
84+
$this->assertStringContainsString('/src/my/path/to/somefile.php', $result);
85+
$this->assertStringContainsString('/src/my/other/path/to/somefile.php', $result);
86+
$this->assertStringContainsString('/vendor/someotherfile.php', $result);
87+
}
1888
}

0 commit comments

Comments
 (0)