function TemplateProjectTestBase::createVendorRepository
Creates a Composer repository for all dependencies of the test project.
We always reference third-party dependencies (i.e., any package that isn't part of Drupal core) from the main project which is running this test.
Packages that are part of Drupal core -- such as `drupal/core`, `drupal/core-composer-scaffold`, and so on -- are expected to have been copied into the workspace directory, so that we can modify them as needed.
The file will be written to WORKSPACE_DIR/vendor.json.
Parameters
string[] $versions: (optional) The versions of specific packages, keyed by package name. Versions of packages not in this array will be determined first by looking for a `version` key in the package's composer.json, then by calling \Composer\InstalledVersions::getPrettyVersion(). If none of that works, `dev-main` will be used as the package's version.
2 calls to TemplateProjectTestBase::createVendorRepository()
- TemplateProjectTestBase::copyCodebase in core/
modules/ package_manager/ tests/ src/ Build/ TemplateProjectTestBase.php - Copy the current working codebase into a workspace.
- TemplateProjectTestBase::setUpstreamCoreVersion in core/
modules/ package_manager/ tests/ src/ Build/ TemplateProjectTestBase.php - Sets the version of Drupal core to which the test site will be updated.
File
-
core/
modules/ package_manager/ tests/ src/ Build/ TemplateProjectTestBase.php, line 405
Class
- TemplateProjectTestBase
- Base class for tests which create a test site from a core project template.
Namespace
Drupal\Tests\package_manager\BuildCode
protected function createVendorRepository(array $versions = []) : void {
$packages = [];
$class_loaders = ClassLoader::getRegisteredLoaders();
$workspace_dir = $this->getWorkspaceDirectory();
$finder = Finder::create()->in([
$this->getWorkspaceDrupalRoot() . '/core',
"{$workspace_dir}/composer/Metapackage",
"{$workspace_dir}/composer/Plugin",
key($class_loaders),
])
->depth('< 3')
->files()
->name('composer.json');
/** @var \Symfony\Component\Finder\SplFileInfo $file */
foreach ($finder as $file) {
$package_info = json_decode($file->getContents(), TRUE, flags: JSON_THROW_ON_ERROR);
$name = $package_info['name'];
$requirements = $package_info['require'] ?? [];
// These polyfills are dependencies of some packages, but for reasons we
// don't understand, they are not installed in code bases built on PHP
// versions that are newer than the ones being polyfilled, which means we
// won't be able to build our test project because these polyfills aren't
// available in the local code base. Since we're guaranteed to be on PHP
// 8.3 or later, no package should need to polyfill older versions.
unset($requirements['symfony/polyfill-php72'], $requirements['symfony/polyfill-php73'], $requirements['symfony/polyfill-php74'], $requirements['symfony/polyfill-php80'], $requirements['symfony/polyfill-php81'], $requirements['symfony/polyfill-php82'], $requirements['symfony/polyfill-php83']);
// If this package requires any Drupal core packages, ensure it allows
// any version.
self::unboundCoreConstraints($requirements);
// In certain situations, like Drupal CI, auto_updates might be
// required into the code base by Composer. This may cause it to be added to
// the drupal/core-recommended metapackage, which can prevent the test site
// from being built correctly, among other deleterious effects. To prevent
// such shenanigans, always remove drupal/auto_updates from
// drupal/core-recommended.
if ($name === 'drupal/core-recommended') {
unset($requirements['drupal/auto_updates']);
}
try {
$version = $versions[$name] ?? $package_info['version'] ?? InstalledVersions::getPrettyVersion($name);
} catch (\OutOfBoundsException) {
$version = 'dev-main';
}
// Create a pared-down package definition that has just enough information
// for Composer to install the package from the local copy: the name,
// version, package type, source path ("dist" in Composer terminology),
// and the autoload information, so that the classes provided by the
// package will actually be loadable in the test site we're building.
$path = $file->getPath();
$packages[$name][$version] = [
'name' => $name,
'version' => $version,
'type' => $package_info['type'] ?? 'library',
// Disabling symlinks in the transport options doesn't seem to have an
// effect, so we use the COMPOSER_MIRROR_PATH_REPOS environment
// variable to force mirroring in ::createTestProject().
'dist' => [
'type' => 'path',
'url' => $path,
],
'require' => $requirements,
'autoload' => $package_info['autoload'] ?? [],
'provide' => $package_info['provide'] ?? [],
// Composer plugins are loaded and activated as early as possible, and
// they must have a `class` key defined in their `extra` section, along
// with a dependency on `composer-plugin-api` (plus any other real
// runtime dependencies). This is also necessary for packages that ship
// scaffold files, like Drupal core.
'extra' => $package_info['extra'] ?? [],
];
}
$data = json_encode([
'packages' => $packages,
], JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
file_put_contents($workspace_dir . '/vendor.json', $data);
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.