Skip to content
Snippets Groups Projects
Commit a97a0c7c authored by Adam G-H's avatar Adam G-H
Browse files

Revert "Issue #3346628: ComposerPluginsValidatorTest fails with pcre.backtrack_limit=1000000 set"

This reverts commit d2272428.
parent d2272428
No related branches found
No related tags found
No related merge requests found
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
{ "name": "automatic_updates", "path": "./dictionary.txt"} { "name": "automatic_updates", "path": "./dictionary.txt"}
], ],
"ignorePaths": [ "ignorePaths": [
"pcre.ini",
"README.md" "README.md"
] ]
} }
...@@ -46,16 +46,19 @@ abstract class UpdaterFormTestBase extends UpdaterFormFunctionalTestBase { ...@@ -46,16 +46,19 @@ abstract class UpdaterFormTestBase extends UpdaterFormFunctionalTestBase {
'name' => 'drupal/semver_test', 'name' => 'drupal/semver_test',
'version' => '8.1.0', 'version' => '8.1.0',
'type' => 'drupal-module', 'type' => 'drupal-module',
'install_path' => '../../web/projects/semver_test',
]) ])
->addPackage([ ->addPackage([
'name' => 'drupal/aaa_update_test', 'name' => 'drupal/aaa_update_test',
'version' => '2.0.0', 'version' => '2.0.0',
'type' => 'drupal-module', 'type' => 'drupal-module',
'install_path' => '../../web/projects/aaa_update_test',
]) ])
->addPackage([ ->addPackage([
'name' => 'drupal/automatic_updates_extensions_test_theme', 'name' => 'drupal/automatic_updates_extensions_test_theme',
'version' => '2.0.0', 'version' => '2.0.0',
'type' => 'drupal-theme', 'type' => 'drupal-theme',
'install_path' => '../../web/projects/automatic_updates_extensions_test_theme',
]) ])
->commitChanges(); ->commitChanges();
$this->drupalPlaceBlock('local_tasks_block', ['primary' => TRUE]); $this->drupalPlaceBlock('local_tasks_block', ['primary' => TRUE]);
......
...@@ -9,6 +9,12 @@ build: ...@@ -9,6 +9,12 @@ build:
# Run code quality checks. # Run code quality checks.
container_command.commit-checks: container_command.commit-checks:
commands: commands:
# Disable the PCRE engine's JIT, since it causes Composer to die during the
# update process, but only on Drupal CI, and for reasons that are essentially
# impossible to trace into. The PCRE JIT is not necessary for Automatic Updates
# to work correctly, and disabling it is a known workaround.
# @see pcre.ini
- sudo cp modules/contrib/automatic_updates/pcre.ini /usr/local/etc/php/conf.d
# @todo Replace in favor of commit-code-check.sh once https://www.drupal.org/project/drupal/issues/3314100 lands. # @todo Replace in favor of commit-code-check.sh once https://www.drupal.org/project/drupal/issues/3314100 lands.
- modules/contrib/automatic_updates/scripts/commit-code-check.sh --drupalci - modules/contrib/automatic_updates/scripts/commit-code-check.sh --drupalci
halt-on-fail: true halt-on-fail: true
......
...@@ -11,14 +11,7 @@ use Symfony\Component\Filesystem\Filesystem as SymfonyFileSystem; ...@@ -11,14 +11,7 @@ use Symfony\Component\Filesystem\Filesystem as SymfonyFileSystem;
use Drupal\Component\Serialization\Yaml; use Drupal\Component\Serialization\Yaml;
/** /**
* Manipulates a test fixture using Composer commands. * It manipulates.
*
* The composer.json file CANNOT be safely created or modified using the
* json_encode() function, because Composer does not use a real JSON parser — it
* updates composer.json using \Composer\Json\JsonManipulator, which is known to
* choke in a number of scenarios.
*
* @see https://www.drupal.org/i/3346628
*/ */
class FixtureManipulator { class FixtureManipulator {
...@@ -570,46 +563,6 @@ class FixtureManipulator { ...@@ -570,46 +563,6 @@ class FixtureManipulator {
return $plain_output; return $plain_output;
} }
/**
* Transform the received $package into options for `composer init`.
*
* @param array $package
* A Composer package definition.
*
* @return array
* The corresponding `composer init` options.
*/
private static function getComposerInitOptionsForPackage(array $package): array {
return array_filter(array_map(function ($k, $v) {
switch ($k) {
case 'name':
case 'description':
case 'type':
return "--$k=$v";
case 'require':
case 'require-dev':
$requirements = array_map(
fn(string $req_package, string $req_version): string => "$req_package:$req_version",
array_keys($v),
array_values($v)
);
return "--$k=" . implode(',', $requirements);
case 'version':
// This gets set in the repository metadata itself.
return NULL;
case 'extra':
// Cannot be set using `composer init`, only `composer config` can.
return NULL;
default:
throw new \InvalidArgumentException($k);
}
}, array_keys($package), array_values($package)));
}
/** /**
* Adds a path repository. * Adds a path repository.
* *
...@@ -623,39 +576,30 @@ class FixtureManipulator { ...@@ -623,39 +576,30 @@ class FixtureManipulator {
$name = $package['name']; $name = $package['name'];
$path_repo_base = \Drupal::state()->get(self::PATH_REPO_STATE_KEY); $path_repo_base = \Drupal::state()->get(self::PATH_REPO_STATE_KEY);
$repo_path = "$path_repo_base/" . str_replace('/', '--', $name); $repo_path = "$path_repo_base/" . str_replace('/', '--', $name);
$composer_json_path = $repo_path . DIRECTORY_SEPARATOR . 'composer.json';
$fs = new SymfonyFileSystem(); $fs = new SymfonyFileSystem();
if (!is_dir($repo_path)) { if (!is_dir($repo_path)) {
// Create the repo if it does not exist. // Create the repo if it does not exist.
$fs->mkdir($repo_path); $fs->mkdir($repo_path);
// Switch the working directory from project root to repo path. file_put_contents($composer_json_path, json_encode($package, JSON_THROW_ON_ERROR));
$project_root_dir = $this->dir; $repository = json_encode([
$this->dir = $repo_path; 'type' => 'path',
// Create a composer.json file using `composer init`. 'url' => $repo_path,
$this->runComposerCommand(['init', ...static::getComposerInitOptionsForPackage($package)]); 'options' => [
// Set the `extra` property in the generated composer.json file using 'symlink' => FALSE,
// `composer config`, because `composer init` does not support it.
foreach ($package['extra'] ?? [] as $extra_property => $extra_value) {
$this->runComposerCommand(['config', "extra.$extra_property", '--json', json_encode($extra_value, JSON_UNESCAPED_SLASHES)]);
}
// Restore the project root as the working directory.
$this->dir = $project_root_dir;
}
// Register the repository, keyed by package name. This ensures each package
// is registered only once and its version can be updated.
// @todo Should we create 1 repo per version.
$repository = json_encode([
'type' => 'path',
'url' => $repo_path,
'options' => [
'symlink' => FALSE,
'versions' => [
$name => $package['version'],
], ],
], ], JSON_UNESCAPED_SLASHES);
], JSON_UNESCAPED_SLASHES); $this->runComposerCommand(['config', "repo.$name", $repository]);
$this->runComposerCommand(['config', "repo.$name", $repository]); }
else {
$composer_json_data = json_decode(file_get_contents($composer_json_path), TRUE);
// Update the version if needed.
// @todo Should we create 1 repo per version.
if ($composer_json_data['version'] !== $package['version']) {
$composer_json_data['version'] = $package['version'];
file_put_contents($composer_json_path, json_encode($composer_json_data, JSON_THROW_ON_ERROR));
}
}
return $repo_path; return $repo_path;
} }
...@@ -683,8 +627,17 @@ class FixtureManipulator { ...@@ -683,8 +627,17 @@ class FixtureManipulator {
} }
// Update all the repos in the composer.json file to point to the new // Update all the repos in the composer.json file to point to the new
// repos at the absolute path. // repos at the absolute path.
$composer_json = file_get_contents($this->dir . '/composer.json'); $json_data = json_decode(file_get_contents($this->dir . '/composer.json'), TRUE);
file_put_contents($this->dir . '/composer.json', str_replace('../path_repos/', "$path_repo_base/", $composer_json)); $composer_json_needs_update = FALSE;
foreach ($json_data['repositories'] as &$existing_repo_data) {
if (is_array($existing_repo_data) && isset($existing_repo_data['url']) && str_starts_with($existing_repo_data['url'], '../path_repos/')) {
$composer_json_needs_update = TRUE;
$existing_repo_data['url'] = str_replace('../path_repos/', "$path_repo_base/", $existing_repo_data['url']);
}
}
if ($composer_json_needs_update) {
file_put_contents($this->dir . '/composer.json', json_encode($json_data, JSON_THROW_ON_ERROR));
}
$this->runComposerCommand(['install']); $this->runComposerCommand(['install']);
} }
......
# This file is used on Drupal CI because Composer occasionally dies with
# PCRE_JIT_STACKLIMIT_ERROR during certain test cases, and there is no insight
# into where the failure is happening, or why. This has only been observed on
# Drupal CI. Since the PCRE engine's JIT is not strictly necessary to the
# functioning of the Automatic Updates module, this file disables the PCRE JIT
# as a workaround.
# @see drupalci.yml
pcre.jit = 0
...@@ -72,6 +72,7 @@ class Converter { ...@@ -72,6 +72,7 @@ class Converter {
'drupalci.yml', 'drupalci.yml',
'README.md', 'README.md',
'.git', '.git',
'pcre.ini',
'composer.json', 'composer.json',
'.gitattributes', '.gitattributes',
'.gitignore', '.gitignore',
......
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