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

Add ddev robo cache:disable|enable #705

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
195 changes: 195 additions & 0 deletions RoboFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
declare(strict_types=1);

use Drupal\Core\DrupalKernel;
use Robo\Exception\TaskException;
use Robo\Tasks;
use RoboComponents\BootstrapTrait;
use RoboComponents\DeploymentTrait;
Expand All @@ -14,6 +15,8 @@
use RoboComponents\TranslationManagement\ImportToConfig;
use RoboComponents\TranslationManagement\ImportToUi;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Yaml;

$GLOBALS['drupal_autoloader'] = require_once 'web/autoload.php';

Expand Down Expand Up @@ -48,6 +51,16 @@ class RoboFile extends Tasks {
'es',
];

/**
* Defines cache bins in settings.local.php.
*/
const CACHE_BINS = [
'Internal Page Cache' => '$settings[\'cache\'][\'bins\'][\'page\'] = \'cache.backend.null\';',
'Render Cache' => '$settings[\'cache\'][\'bins\'][\'render\'] = \'cache.backend.null\';',
'Dynamic Page Cache' => '$settings[\'cache\'][\'bins\'][\'dynamic_page_cache\'] = \'cache.backend.null\';',
'Migrations Cache' => '$settings[\'cache\'][\'bins\'][\'discovery_migration\'] = \'cache.backend.memory\';',
];

/**
* Bootstraps Drupal 8 in addition to Robo.
*
Expand All @@ -71,4 +84,186 @@ public function __construct() {
}
}

/**
* Helper to get settings.local.php file.
Copy link
Member

Choose a reason for hiding this comment

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

Put all these into a trait, let's say DevelopmentTrait under robo-components. We decided to keep RoboFile minimal.

*
* @return string
* 'settings.local.php' path.
*
* @throws \Robo\Exception\TaskException
*/
protected function ensureSettingsLocalFileExists(): string {
// Step 1: Make sure settings.local.php exists.
$settings_file = 'web/sites/settings.local.php';
$example_settings_file = 'web/sites/example.settings.local.php';

if (!file_exists($settings_file)) {
if (file_exists($example_settings_file)) {
copy($example_settings_file, $settings_file);
$this->say("Copied 'example.settings.local.php' to 'settings.local.php'");
}
else {
$this->say("File 'example.settings.local.php' does not exist.");
throw new TaskException($this, "Command failed: 'settings.local.php' or 'example.settings.local.php' do not exist.");
}
}

// Step 2: Make sure 'settings.local.php' is included in 'settings.php`.
$default_settings_file = 'web/sites/default/settings.php';

if (!file_exists($default_settings_file)) {
$this->say("settings.php not found.");
throw new TaskException($this, "Command failed: 'settings.php' does not exist.");
}

// Read the settings file content.
$settings_content = file_get_contents($default_settings_file);

// Set block of code that includes 'settings.local.php'.
$local_settings_enable = <<<PHP
if (file_exists(\$app_root . '/sites/settings.local.php')) {
include \$app_root . '/sites/settings.local.php';
}
PHP;

if (strpos($settings_content, $local_settings_enable) === FALSE) {
$this->say("Including 'settings.local.php' file.");
$this->taskWriteToFile($default_settings_file)
->append(TRUE)
->text($local_settings_enable)
->run();
$this->say("Local settings enabled.");
}
else {
$this->say("Skipping: Including 'settings.local.php' file (already included).");
}

return $settings_file;
}

/**
* Enable Drupal cache.
*
* @throws \Robo\Exception\TaskException
*/
public function cacheEnable() {
$this->say("Enabling Drupal caching...");

$this->say("Enabling Twig caching...");

$servicesFile = 'web/sites/development.services.yml';

if (!file_exists($servicesFile)) {
$this->say("File 'development.services.yml' not found.");
return;
}

try {
// Parse the YAML file into an array.
$yamlData = Yaml::parseFile($servicesFile);

// Modifying the twig.config values.
if (isset($yamlData['parameters']['twig.config']['cache']) && $yamlData['parameters']['twig.config']['cache'] == FALSE) {
$yamlData['parameters']['twig.config']['cache'] = TRUE;
// Dump the modified array back into the YAML file.
// 4 for indentation, 2 for spaces.
file_put_contents($servicesFile, Yaml::dump($yamlData, 4, 2));
$this->say("Twig caching enabled.");
}
else {
$this->say("Skipping: Twig cache (already enabled).");
}
}
catch (ParseException $e) {
$this->say('Unable to parse the YAML string: ' . $e->getMessage());
}

// Ensure settings.local.php exists.
$settings_file = $this->ensureSettingsLocalFileExists();
// Read the settings.local.php file content.
$settings_content = file_get_contents($settings_file);

foreach (self::CACHE_BINS as $label => $cache_bin) {
// Check if the line is already commented out with a single #.
if (strpos($settings_content, "# $cache_bin") !== FALSE) {
$this->say('Skipping: ' . $label . ' (already enabled)');
}
elseif (strpos($settings_content, $cache_bin) !== FALSE) {
$this->say('Enabling: ' . $label);
// Comment out the settings for the cache bin.
$this->taskReplaceInFile($settings_file)
->from($cache_bin)
->to("# $cache_bin")
->run();
}
}
// Clear Drupal cache.
$this->taskExec('drush cr')->run();

$this->say("Drupal caching enabled.");
}

/**
* Disable Drupal cache.
*
* @throws \Robo\Exception\TaskException
*/
public function cacheDisable() {
$this->say("Disabling Drupal caching...");

$this->say("Disabling Twig caching...");

$servicesFile = 'web/sites/development.services.yml';

if (!file_exists($servicesFile)) {
$this->say("File 'development.services.yml' not found.");
return;
}

try {
// Parse the YAML file into an array.
$yamlData = Yaml::parseFile($servicesFile);

// Modifying the twig.config values.
if (isset($yamlData['parameters']['twig.config']['cache']) && $yamlData['parameters']['twig.config']['cache'] == TRUE) {
$yamlData['parameters']['twig.config']['cache'] = FALSE;
// Dump the modified array back into the YAML file.
// 4 for indentation, 2 for spaces.
file_put_contents($servicesFile, Yaml::dump($yamlData, 4, 2));
$this->say("Twig caching disabled.");
}
else {
$this->say("Skipping: Twig cache (already disabled).");
}
}
catch (ParseException $e) {
$this->say('Unable to parse the YAML string: ' . $e->getMessage());
}

// Ensure settings.local.php exists.
$settings_file = $this->ensureSettingsLocalFileExists();
// Read the 'settings.local.php' file content.
$settings_content = file_get_contents($settings_file);

foreach (self::CACHE_BINS as $label => $cache_bin) {
// Check if the line is not commented out with a single #.
if (strpos($settings_content, "# $cache_bin") !== FALSE) {
$this->say('Disabling: ' . $label);
// Uncomment the settings for the cache bin.
$this->taskReplaceInFile($settings_file)
->from("# $cache_bin")
->to($cache_bin)
->run();
}
elseif (strpos($settings_content, $cache_bin) !== FALSE) {
$this->say('Skipping: ' . $label . ' (already disabled)');
}
}

// Clear Drupal cache.
$this->taskExec('drush cr')->run();

$this->say("Drupal caching disabled.");
Copy link
Member

Choose a reason for hiding this comment

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

We do some file manipulations only, I'd try to verify it programmatically if the changes are truly effective and this way, we could do some error handling. Like doing some HTTP requests and check the headers or try to retrieve the config bits via the API, then we could have a conditional branch where we explain what went wrong and set a non-zero exit code. Same for the other direction.

}

}