Browse Source

Merge pull request #17187 from cnizzardini/cache-command-clear-cache-groups

Adds cake cache clear_group command
Mark Story 2 years ago
parent
commit
81e6fbb2dd

+ 107 - 0
src/Command/CacheClearGroupCommand.php

@@ -0,0 +1,107 @@
+<?php
+declare(strict_types=1);
+
+/**
+ * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
+ * @link          https://cakephp.org CakePHP(tm) Project
+ * @since         4.5.0
+ * @license       https://opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\Command;
+
+use Cake\Cache\Cache;
+use Cake\Cache\Exception\InvalidArgumentException;
+use Cake\Console\Arguments;
+use Cake\Console\ConsoleIo;
+use Cake\Console\ConsoleOptionParser;
+
+/**
+ * Cache Clear Group command.
+ */
+class CacheClearGroupCommand extends Command
+{
+    /**
+     * Get the command name.
+     *
+     * @return string
+     */
+    public static function defaultName(): string
+    {
+        return 'cache clear_group';
+    }
+
+    /**
+     * Hook method for defining this command's option parser.
+     *
+     * @see https://book.cakephp.org/4/en/console-commands/option-parsers.html
+     * @param \Cake\Console\ConsoleOptionParser $parser The parser to be defined
+     * @return \Cake\Console\ConsoleOptionParser The built parser.
+     */
+    public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser
+    {
+        $parser = parent::buildOptionParser($parser);
+        $parser->setDescription('Clear all data in a single cache group.');
+        $parser->addArgument('group', [
+            'help' => 'The cache group to clear. For example, `cake cache clear_group mygroup` will clear ' .
+                'all cache items belonging to group "mygroup".',
+            'required' => true,
+        ]);
+        $parser->addArgument('config', [
+            'help' => 'Name of the configuration to use. Defaults to no value which clears all cache configurations.',
+        ]);
+
+        return $parser;
+    }
+
+    /**
+     * Clears the cache group
+     *
+     * @param \Cake\Console\Arguments $args The command arguments.
+     * @param \Cake\Console\ConsoleIo $io The console io
+     * @return int|null The exit code or null for success
+     */
+    public function execute(Arguments $args, ConsoleIo $io): ?int
+    {
+        $group = (string)$args->getArgument('group');
+        try {
+            $groupConfigs = Cache::groupConfigs($group);
+        } catch (InvalidArgumentException $e) {
+            $io->error(sprintf('Cache group "%s" not found', $group));
+
+            return static::CODE_ERROR;
+        }
+
+        $config = $args->getArgument('config');
+        if ($config !== null && Cache::getConfig($config) === null) {
+            $io->error(sprintf('Cache config "%s" not found', $config));
+
+            return static::CODE_ERROR;
+        }
+
+        foreach ($groupConfigs[$group] as $groupConfig) {
+            if ($config !== null && $config !== $groupConfig) {
+                continue;
+            }
+
+            if (!Cache::clearGroup($group, $groupConfig)) {
+                $io->error(sprintf(
+                    'Error encountered clearing group "%s". Was unable to clear entries for "%s".',
+                    $group,
+                    $groupConfig
+                ));
+                $this->abort();
+            } else {
+                $io->success(sprintf('Group "%s" was cleared.', $group));
+            }
+        }
+
+        return static::CODE_SUCCESS;
+    }
+}

+ 1 - 1
src/Console/BaseCommand.php

@@ -239,7 +239,7 @@ abstract class BaseCommand implements CommandInterface
     abstract public function execute(Arguments $args, ConsoleIo $io);
 
     /**
-     * Halt the the current process with a StopException.
+     * Halt the current process with a StopException.
      *
      * @param int $code The exit code to use.
      * @throws \Cake\Console\Exception\StopException

+ 39 - 1
tests/TestCase/Command/CacheCommandsTest.php

@@ -34,7 +34,8 @@ class CacheCommandsTest extends TestCase
     public function setUp(): void
     {
         parent::setUp();
-        Cache::setConfig('test', ['engine' => 'File', 'path' => CACHE]);
+        Cache::setConfig('test', ['engine' => 'File', 'path' => CACHE, 'groups' => ['test_group']]);
+        Cache::setConfig('test2', ['engine' => 'File', 'path' => CACHE, 'groups' => ['test_group']]);
         $this->setAppNamespace();
         $this->useCommandRunner();
     }
@@ -46,6 +47,7 @@ class CacheCommandsTest extends TestCase
     {
         parent::tearDown();
         Cache::drop('test');
+        Cache::drop('test2');
     }
 
     /**
@@ -141,4 +143,40 @@ class CacheCommandsTest extends TestCase
         $this->assertNull(Cache::read('key', 'test'));
         $this->assertNull(Cache::read('key', '_cake_core_'));
     }
+
+    public function testClearGroup(): void
+    {
+        Cache::add('key', 'value1', 'test');
+        Cache::add('key', 'value1', 'test2');
+        $this->exec('cache clear_group test_group');
+
+        $this->assertExitCode(Shell::CODE_SUCCESS);
+        $this->assertNull(Cache::read('key', 'test'));
+        $this->assertNull(Cache::read('key', 'test2'));
+    }
+
+    public function testClearGroupWithConfig(): void
+    {
+        Cache::add('key', 'value1', 'test');
+        $this->exec('cache clear_group test_group test');
+
+        $this->assertExitCode(Shell::CODE_SUCCESS);
+        $this->assertNull(Cache::read('key', 'test'));
+    }
+
+    public function testClearGroupInvalidConfig(): void
+    {
+        $this->exec('cache clear_group test_group does_not_exist');
+
+        $this->assertExitCode(Shell::CODE_ERROR);
+        $this->assertErrorContains('Cache config "does_not_exist" not found');
+    }
+
+    public function testClearInvalidGroup(): void
+    {
+        $this->exec('cache clear_group does_not_exist');
+
+        $this->assertExitCode(Shell::CODE_ERROR);
+        $this->assertErrorContains('Cache group "does_not_exist" not found');
+    }
 }