Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [Command] add options for spark optimize command #9054

Open
wants to merge 9 commits into
base: 4.6
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 135 additions & 23 deletions system/Commands/Utilities/Optimize.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
*/
final class Optimize extends BaseCommand
{
private const CONFIG_CACHE = '$configCacheEnabled';
private const LOCATOR_CACHE = '$locatorCacheEnabled';
private const CONFIG_PATH = APPPATH . 'Config/Optimize.php';
private const CACHE_PATH = WRITEPATH . 'cache/FactoriesCache_config';

/**
* The group the command is lumped under
* when listing commands.
Expand Down Expand Up @@ -52,17 +57,37 @@ final class Optimize extends BaseCommand
*
* @var string
*/
protected $usage = 'optimize';
protected $usage = 'optimize [-c] [-l] [-d]';

/**
* The Command's options
*
* @var array<string, string>
*/
protected $options = [
'c' => 'Enable only config caching.',
'l' => 'Enable only locator caching.',
'd' => 'Disable config and locator caching.',
];

/**
* {@inheritDoc}
*/
public function run(array $params)
{
// Parse options
$enableConfigCache = CLI::getOption('c');
$enableLocatorCache = CLI::getOption('l');
$disable = CLI::getOption('d');

try {
$this->enableCaching();
$this->runCaching($enableConfigCache, $enableLocatorCache, $disable);
$this->clearCache();
$this->removeDevPackages();
if ($disable === true) {
$this->reinstallDevPackages();
} else {
$this->removeDevPackages();
}
} catch (RuntimeException) {
CLI::error('The "spark optimize" failed.');

Expand All @@ -78,8 +103,7 @@ private function clearCache(): void
$locator->deleteCache();
CLI::write('Removed FileLocatorCache.', 'green');

$cache = WRITEPATH . 'cache/FactoriesCache_config';
$this->removeFile($cache);
$this->removeFile(self::CACHE_PATH);
}

private function removeFile(string $cache): void
Expand All @@ -99,32 +123,100 @@ private function removeFile(string $cache): void
}
}

private function enableCaching(): void
private function runCaching(?bool $enableConfigCache, ?bool $enableLocatorCache, ?bool $disable): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what the runConfig() method dose when I see the method name.
Is updateConfigFile() better?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I see the method name disableCaching(), I imagine the method disables caching.
But this method just returns an array.
Therefore the method name or the implementation is not good.

If disabelCaching() and enableCaching() does its job completely, I don't think runCaching() is needed any more. we just need a process like this.

public function run(array $params)
    {
        // Parse options
        $enableConfigCache  = CLI::getOption('c');
        $enableLocatorCache = CLI::getOption('l');
        $disable            = CLI::getOption('d');

        try {
            if ($disable === true) {
                $this->disableCaching();
                $this->reinstallDevPackages();
            } else {
                $this->enableCaching(['config' => $enableConfigCache, 'locator' => $enableLocatorCache]);
                $this->removeDevPackages();
            }

            $this->clearCache();

        } catch (RuntimeException) {
            CLI::error('The "spark optimize" failed.');

            return EXIT_ERROR;
        }

        return EXIT_SUCCESS;
    }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good! That will be easier to understand.

{
$publisher = new Publisher(APPPATH, APPPATH);
// Prepare search and replace mappings
$searchReplace = [];

$config = APPPATH . 'Config/Optimize.php';
if ($disable === true) {
$searchReplace = $this->disableCaching();
} else {
$searchReplace = $this->enableCaching(['config' => $enableConfigCache, 'locator' => $enableLocatorCache]);
}

$result = $publisher->replace(
$config,
[
'public bool $configCacheEnabled = false;' => 'public bool $configCacheEnabled = true;',
'public bool $locatorCacheEnabled = false;' => 'public bool $locatorCacheEnabled = true;',
]
);
// Apply replacements if necessary
if ($searchReplace !== []) {
$publisher = new Publisher(APPPATH, APPPATH);

if ($result) {
CLI::write(
'Config Caching and FileLocator Caching are enabled in "app/Config/Optimize.php".',
'green'
);
$result = $publisher->replace(self::CONFIG_PATH, $searchReplace);

return;
if ($result === true) {
$messages = [];

if (in_array('public bool ' . self::CONFIG_CACHE . ' = true;', $searchReplace, true)) {
$messages[] = 'Config Caching is enabled in "app/Config/Optimize.php".';
}

if (in_array('public bool ' . self::LOCATOR_CACHE . ' = true;', $searchReplace, true)) {
$messages[] = 'FileLocator Caching is enabled in "app/Config/Optimize.php".';
}

if (in_array('public bool ' . self::CONFIG_CACHE . ' = false;', $searchReplace, true)) {
$messages[] = 'Config Caching is disabled in "app/Config/Optimize.php".';
}

if (in_array('public bool ' . self::LOCATOR_CACHE . ' = false;', $searchReplace, true)) {
$messages[] = 'FileLocator Caching is disabled in "app/Config/Optimize.php".';
}

foreach ($messages as $message) {
CLI::write($message, 'green');
CLI::newLine();
}

CLI::newLine();

return;
}

CLI::error('Error in updating file: ' . clean_path(self::CONFIG_PATH));

throw new RuntimeException(__METHOD__);
}
CLI::write('No changes to caching settings.', 'yellow');
}

CLI::error('Error in updating file: ' . clean_path($config));
/**
* Disable Caching
*
* @return array<string, string>
*/
private function disableCaching(): array
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I see the method name disableCaching(), I imagine the method disables caching.
But this method just returns an array.
Therefore the method name or the implementation is not good.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i will send an update, this makes it more flexible.

{
return [
'public bool ' . self::CONFIG_CACHE . ' = true;' => 'public bool ' . self::CONFIG_CACHE . ' = false;',
'public bool ' . self::LOCATOR_CACHE . ' = true;' => 'public bool ' . self::LOCATOR_CACHE . ' = false;',
];
}

throw new RuntimeException(__METHOD__);
/**
* Enable Caching
*
* @param array<string, bool|null> $options
*
* @return array<string, string>
*/
private function enableCaching(array $options): array
{
$searchReplace = [];

if ($options['config'] === true) {
$searchReplace['public bool ' . self::CONFIG_CACHE . ' = false;'] = 'public bool ' . self::CONFIG_CACHE . ' = true;';
}

if ($options['locator'] === true) {
$searchReplace['public bool ' . self::LOCATOR_CACHE . ' = false;'] = 'public bool ' . self::LOCATOR_CACHE . ' = true;';
}

// If no options provided, update both
if ($options['config'] === null && $options['locator'] === null) {
$searchReplace = [
'public bool ' . self::CONFIG_CACHE . ' = false;' => 'public bool ' . self::CONFIG_CACHE . ' = true;',
'public bool ' . self::LOCATOR_CACHE . ' = false;' => 'public bool ' . self::LOCATOR_CACHE . ' = true;',
];
}

return $searchReplace;
}

private function removeDevPackages(): void
Expand All @@ -146,4 +238,24 @@ private function removeDevPackages(): void

throw new RuntimeException(__METHOD__);
}

private function reinstallDevPackages(): void
{
if (! defined('VENDORPATH')) {
return;
}

chdir(ROOTPATH);
passthru('composer install', $status);

if ($status === 0) {
CLI::write('Installed Composer dev packages.', 'green');

return;
}

CLI::error('Error in installing Composer dev packages.');

throw new RuntimeException(__METHOD__);
}
}
99 changes: 99 additions & 0 deletions tests/system/Commands/Utilities/OptimizeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

declare(strict_types=1);

/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace CodeIgniter\Commands\Utilities;

use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\StreamFilterTrait;
use PHPUnit\Framework\Attributes\Group;

/**
* @internal
*/
#[Group('Others')]
final class OptimizeTest extends CIUnitTestCase
{
use StreamFilterTrait;

protected function setUp(): void
{
$this->resetServices();

parent::setUp();
}

protected function getBuffer(): string
{
return $this->getStreamFilterBuffer();
}

public function testEnableConfigCaching(): void
{
$command = new Optimize(service('logger'), service('commands'));

$runCaching = $this->getPrivateMethodInvoker($command, 'runCaching');

// private function runCaching(?bool $enableConfigCache, ?bool $enableLocatorCache, ?bool $disable): void
$runCaching(true, null, null);

// Check if config caching is enabled
$this->assertFileContains('public bool $configCacheEnabled = true;', APPPATH . 'Config/Optimize.php');
}

public function testEnableLocatorCaching(): void
{
$command = new Optimize(service('logger'), service('commands'));

$runCaching = $this->getPrivateMethodInvoker($command, 'runCaching');

// private function runCaching(?bool $enableConfigCache, ?bool $enableLocatorCache, ?bool $disable): void
$runCaching(null, true, null);

// Check if locator caching is enabled
$this->assertFileContains('public bool $locatorCacheEnabled = true;', APPPATH . 'Config/Optimize.php');
}

public function testDisableCaching(): void
{
$command = new Optimize(service('logger'), service('commands'));

$runCaching = $this->getPrivateMethodInvoker($command, 'runCaching');

// private function runCaching(?bool $enableConfigCache, ?bool $enableLocatorCache, ?bool $disable): void
$runCaching(null, null, true);

// Check if both caches are disabled
$this->assertFileContains('public bool $configCacheEnabled = false;', APPPATH . 'Config/Optimize.php');
$this->assertFileContains('public bool $locatorCacheEnabled = false;', APPPATH . 'Config/Optimize.php');
}

public function testWithoutOptions(): void
{
$command = new Optimize(service('logger'), service('commands'));

$runCaching = $this->getPrivateMethodInvoker($command, 'runCaching');

// private function runCaching(?bool $enableConfigCache, ?bool $enableLocatorCache, ?bool $disable): void
$runCaching(null, null, null);

// Check if both caches are disabled
$this->assertFileContains('public bool $configCacheEnabled = true;', APPPATH . 'Config/Optimize.php');
$this->assertFileContains('public bool $locatorCacheEnabled = true;', APPPATH . 'Config/Optimize.php');
}

protected function assertFileContains(string $needle, string $filePath): void
{
$this->assertFileExists($filePath);
$this->assertStringContainsString($needle, file_get_contents($filePath));
}
}
15 changes: 15 additions & 0 deletions user_guide_src/source/installation/deployment.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@ The ``spark optimize`` command performs the following optimizations:
- Enabling `Config Caching`_
- Enabling `FileLocator Caching`_

If you want disable or restore the actions above, run ``spark optimize -d``
it will do a restore to default settings, as follow:

.. versionadded:: 4.6.0

- Reinstall Dev Packages
- Disabling `Config Caching`_
- Disabling `FileLocator Caching`_

Available options:

- `-c` Enable only config caching.
- `-l` Enable only locator caching.
- `-d` Disable config and locator caching.

Composer Optimization
=====================

Expand Down
Loading