Skip to content
Snippets Groups Projects
Commit 2d8b2289 authored by Ted Bowman's avatar Ted Bowman
Browse files

Issue #3409491: Add handling of the Composer dependencies to the conversion script

parent e4fe8675
No related branches found
No related tags found
1 merge request!997Issue #3409491 add composer dependencies in conversion script
...@@ -29,14 +29,14 @@ ...@@ -29,14 +29,14 @@
"Composer\\Config::disableProcessTimeout", "Composer\\Config::disableProcessTimeout",
"scripts/phpunit.sh" "scripts/phpunit.sh"
], ],
"core-convert": "Drupal\\automatic_updates\\Development\\Converter::doConvert", "core-convert": "Drupal\\automatic_updates\\Development\\ConverterCommand",
"core-commit": "Drupal\\automatic_updates\\Development\\Converter::makeCommit" "core-commit": "Drupal\\automatic_updates\\Development\\ConverterCommand::makeCommit"
}, },
"scripts-descriptions": { "scripts-descriptions": {
"phpcbf": "Automatically fixes standards violations where possible.", "phpcbf": "Automatically fixes standards violations where possible.",
"phpcs": "Checks code for standards compliance.", "phpcs": "Checks code for standards compliance.",
"test": "Runs PHPUnit tests.", "test": "Runs PHPUnit tests.",
"core-convert": "Converts this module to a core merge request. Excepts 2 arguments. 1) The core clone directory. 2) The core merge request branch.", "core-convert": "Converts this module to a core merge request. For arguments and options see \\Drupal\\automatic_updates\\Development\\ConverterCommand::configure().",
"core-commit": "Converts this module to a core merge request. Excepts 1 arguments. The core clone directory." "core-commit": "Converts this module to a core merge request. Excepts 1 arguments. The core clone directory."
}, },
"autoload": { "autoload": {
......
...@@ -5,6 +5,11 @@ declare(strict_types = 1); ...@@ -5,6 +5,11 @@ declare(strict_types = 1);
namespace Drupal\automatic_updates\Development; namespace Drupal\automatic_updates\Development;
use Composer\Script\Event; use Composer\Script\Event;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Filesystem;
/** /**
...@@ -20,9 +25,114 @@ use Symfony\Component\Filesystem\Filesystem; ...@@ -20,9 +25,114 @@ use Symfony\Component\Filesystem\Filesystem;
* *
* The core clone should already have the core merge request locally. * The core clone should already have the core merge request locally.
*/ */
class Converter { class ConverterCommand extends Command {
private const RUN_CHECKS = TRUE; private string $core_dir;
private string $core_branch;
private string $contrib_branch;
private bool $package_manager_only;
private string $core_target_branch;
private string $contrib_dir;
private bool $no_commit;
private bool $skipCoreChecks;
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output) {
$this->core_dir = $input->getArgument('core_dir');
$this->core_branch = $input->getArgument('core_branch');
$this->contrib_branch = $input->getArgument('contrib_branch');
$this->package_manager_only = $input->getOption('package_manager_only');
$this->core_target_branch = $input->getOption('core_target_branch');
$this->contrib_dir = realpath(__DIR__ . '/../..');
$this->skipCoreChecks = $input->getOption('skip_core_checks');
$this->no_commit = $input->getOption('no_commit');
// Esnure core_dir is a directory.
if (!is_dir($this->core_dir)) {
throw new \Exception("$this->core_dir is not a directory.");
}
// Switch to core_target_branch to ensure it is clean.
chdir($this->core_dir);
static::switchToBranch($this->core_target_branch);
// Git pull to ensure we are up to date.
static::executeCommand('git pull');
// change back the previous directory.
chdir($this->contrib_dir);
// Ensure we are on the correct branches.
static::switchToBranches($this->core_dir, $this->core_branch, $this->contrib_branch);
// Switch to the core directory and checkout the files and folders that this
// conversion script will automatically update based on our composer.json
// file and our dictionary.txt file.
chdir($this->core_dir);
static::executeCommand("git checkout {$this->core_target_branch} -- composer.json");
static::executeCommand("git checkout {$this->core_target_branch} -- composer.lock");
static::executeCommand("git checkout {$this->core_target_branch} -- composer");
static::executeCommand("git checkout {$this->core_target_branch} -- core/composer.json");
static::executeCommand("git checkout {$this->core_target_branch} -- core/misc/cspell/dictionary.txt");
// Switch to the core directory and require all of the packages there are in
// this module's composer.json require section.
chdir('core');
$require_section = $this->getContribModuleComposerJsonSection('require');
// Hardcode symfony version to 6.4 for core.
$core_symfony_version_update = function ($package_name, $version): string {
if (str_starts_with($package_name, 'symfony/')) {
return '^6.4';
}
return $version;
};
foreach ($require_section as $package_name => $version) {
$version = $core_symfony_version_update($package_name, $version);
static::executeCommand("composer require $package_name:$version --no-update");
}
// Switch back to the parent directory.
chdir('..');
// Run composer update for just this packages.
static::executeCommand("composer update " . implode(' ', array_keys($require_section)));
$require_dev_section = $this->getContribModuleComposerJsonSection('require-dev');
foreach ($require_dev_section as $package_name => $version) {
$version = $core_symfony_version_update($package_name, $version);
static::executeCommand("composer require --dev $package_name:$version");
}
$this->doConvert();
return Command::SUCCESS;
}
/**
* Executes a command and throws an exception if it fails.
*
* @param string $cmd
* The command to execute.
*/
private static function executeCommand(string $cmd): void {
$result = NULL;
system($cmd, $result);
if ($result !== 0) {
throw new \Exception("Command failed: $cmd");
}
}
/**
* {@inheritdoc}
*/
protected function configure() {
$this->addArgument('core_dir', InputArgument::REQUIRED, 'The path to the root of Drupal Core');
$this->addArgument('core_branch', InputArgument::REQUIRED, 'The core merge request branch');
$this->addArgument('contrib_branch', InputArgument::OPTIONAL, 'The contrib branch to switch to', '3.0.x');
$this->addOption('package_manager_only', NULL, InputOption::VALUE_NONE, 'Only convert package manager');
$this->addOption('core_target_branch', NULL, InputOption::VALUE_REQUIRED, 'The core target branch', '11.x');
$this->addOption('skip_core_checks', NULL, InputOption::VALUE_NONE, 'Skip core checks');
$this->addOption('no_commit', NULL, InputOption::VALUE_NONE, 'Do not make commit');
}
/** /**
* Prints message. * Prints message.
...@@ -36,36 +146,15 @@ class Converter { ...@@ -36,36 +146,15 @@ class Converter {
/** /**
* Converts the contrib module to core merge request. * Converts the contrib module to core merge request.
*
* @param \Composer\Script\Event $event
* The Composer event.
*/ */
public static function doConvert(Event $event): void { private function doConvert(): void {
$args = $event->getArguments();
$count_arg = count($args);
if (!($count_arg === 3 || $count_arg === 4)) {
throw new \Exception("This scripts 3 required arguments: a directory that is a core clone and the branch and to convert either package_manager or automatic_updates.\nIt has 1 optional arguments: the branch of this module to use which defaults to 3.0.x");
}
$core_dir = $args[0];
$core_branch = $args[1];
if (!is_dir($core_dir)) {
throw new \Exception("$core_dir is not a directory.");
}
$package_manager_only = match($args[2]) {
'package_manager' => TRUE,
'automatic_updates' => FALSE,
default => throw new \UnexpectedValueException("The 3nd argument must be package_manager or automatic_updates"),
};
$contrib_branch = $count_arg === 3 ? '3.0.x' : $args[3];
$old_machine_name = 'automatic_updates'; $old_machine_name = 'automatic_updates';
$new_machine_name = 'auto_updates'; $new_machine_name = 'auto_updates';
static::switchToBranches($core_dir, $core_branch, $contrib_branch);
self::info('Switched branches'); self::info('Switched branches');
$fs = new Filesystem(); $fs = new Filesystem();
$core_module_path = static::getCoreModulePath($core_dir); $core_module_path = static::getCoreModulePath($this->core_dir);
$package_manager_core_path = $core_dir . "/core/modules/package_manager"; $package_manager_core_path = $this->core_dir . "/core/modules/package_manager";
// Remove old module. // Remove old module.
$fs->remove($core_module_path); $fs->remove($core_module_path);
self::info('Removed old core module'); self::info('Removed old core module');
...@@ -93,10 +182,10 @@ class Converter { ...@@ -93,10 +182,10 @@ class Converter {
} }
self::info('Replacements done.'); self::info('Replacements done.');
static::removeLines($core_dir); static::removeLines($this->core_dir);
self::info('Remove unneeded lines'); self::info('Remove unneeded lines');
self::moveScripts($core_dir, $core_module_path, $package_manager_only); self::moveScripts($this->core_dir, $core_module_path, $this->package_manager_only);
self::info('Moved scripts'); self::info('Moved scripts');
// Remove unneeded. // Remove unneeded.
...@@ -135,36 +224,39 @@ class Converter { ...@@ -135,36 +224,39 @@ class Converter {
$fs->rename("$core_module_path/package_manager", $package_manager_core_path); $fs->rename("$core_module_path/package_manager", $package_manager_core_path);
self::info('Move package manager'); self::info('Move package manager');
static::copyGenericTest($package_manager_core_path, $core_dir); static::copyGenericTest($package_manager_core_path, $this->core_dir);
// Run phpcbf because removing code from merge request may result in unused // Run phpcbf because removing code from merge request may result in unused
// use statements or multiple empty lines. // use statements or multiple empty lines.
system("composer phpcbf $package_manager_core_path"); system("composer phpcbf $package_manager_core_path");
if ($package_manager_only) { if ($this->package_manager_only) {
$fs->remove($core_module_path); $fs->remove($core_module_path);
} }
else { else {
static::copyGenericTest($core_module_path, $core_dir); static::copyGenericTest($core_module_path, $this->core_dir);
system("composer phpcbf $core_module_path"); system("composer phpcbf $core_module_path");
} }
static::addWordsToDictionary($core_dir, self::getContribDir() . "/dictionary.txt"); static::addWordsToDictionary($this->core_dir, self::getContribDir() . "/dictionary.txt");
self::info("Added to dictionary"); self::info("Added to dictionary");
chdir($core_dir); chdir($this->core_dir);
if (self::RUN_CHECKS) { if ($this->skipCoreChecks) {
static::runCoreChecks($core_dir); self::info('⚠️Skipped core checks');
self::info('Ran core checks');
} }
else { else {
self::info('⚠️Skipped core checks'); static::runCoreChecks($this->core_dir);
self::info('Ran core checks');
} }
static::doMakeCommit($core_dir); if (!$this->no_commit) {
self::info('Make commit'); static::doMakeCommit($this->core_dir);
self::info("Done. Probably good but you should check before you push. These are the files present in the contrib module absent in core:"); self::info('Make commit');
print shell_exec(sprintf("tree %s/package_manager > /tmp/contrib.txt && tree %s/core/modules/package_manager > /tmp/core.txt && diff /tmp/contrib.txt /tmp/core.txt", self::getContribDir(), $core_dir)); self::info("Done. Probably good but you should check before you push. These are the files present in the contrib module absent in core:");
self::info('(Run diff /tmp/contrib.txt /tmp/core.txt to see that with color.'); print shell_exec(sprintf("tree %s/package_manager > /tmp/contrib.txt && tree %s/core/modules/package_manager > /tmp/core.txt && diff /tmp/contrib.txt /tmp/core.txt", self::getContribDir(), $this->core_dir));
self::info('(Run diff /tmp/contrib.txt /tmp/core.txt to see that with color.');
}
} }
/** /**
...@@ -344,7 +436,7 @@ class Converter { ...@@ -344,7 +436,7 @@ class Converter {
static::ensureGitClean(); static::ensureGitClean();
shell_exec("git checkout $branch"); shell_exec("git checkout $branch");
if ($branch !== static::getCurrentBranch()) { if ($branch !== static::getCurrentBranch()) {
throw new \Exception("could not check $branch"); throw new \Exception("could not checkout $branch");
} }
} }
...@@ -546,4 +638,9 @@ class Converter { ...@@ -546,4 +638,9 @@ class Converter {
static::replaceContents([new \SplFileInfo($new_test)], 'action', $module_name); static::replaceContents([new \SplFileInfo($new_test)], 'action', $module_name);
} }
private function getContribModuleComposerJsonSection(string $section): array {
$composer_json = json_decode(file_get_contents($this->contrib_dir . '/composer.json'), TRUE);
return $composer_json[$section];
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment