View source
<?php
namespace Drupal\BuildTests\Composer\Template;
use Composer\Json\JsonFile;
use Drupal\BuildTests\Framework\BuildTestBase;
use Drupal\Composer\Composer;
use Symfony\Component\Finder\Finder;
class ComposerProjectTemplatesTest extends BuildTestBase {
public function getPathReposForType($workspace_directory, $subdir) {
$path_repos = Finder::create()
->files()
->name('composer.json')
->in($workspace_directory . '/composer/' . $subdir);
$data = [];
foreach ($path_repos as $path_repo) {
$json_file = new JsonFile($path_repo
->getPathname());
$json = $json_file
->read();
$data[$json['name']] = $path_repo
->getPath();
}
return $data;
}
public function provideTemplateCreateProject() {
return [
'recommended-project' => [
'drupal/recommended-project',
'composer/Template/RecommendedProject',
'/web',
],
'legacy-project' => [
'drupal/legacy-project',
'composer/Template/LegacyProject',
'',
],
];
}
public function testVerifyTemplateTestProviderIsAccurate() {
$root = $this
->getDrupalRoot();
$data = $this
->provideTemplateCreateProject($root);
$template_files = Finder::create()
->files()
->name('composer.json')
->in($root . '/composer/Template');
$this
->assertEquals(count($template_files), count($data));
$template_data = [];
foreach ($data as $data_name => $data_value) {
$template_data[$data_value[0]] = $data_name;
}
foreach ($template_files as $file) {
$json_file = new JsonFile($file
->getPathname());
$json = $json_file
->read();
$this
->assertArrayHasKey('name', $json);
$this
->assertArrayHasKey($json['name'], $template_data);
}
}
public function testTemplateCreateProject($project, $package_dir, $docroot_dir) {
$composer_version_line = exec('composer --version');
if (strpos($composer_version_line, 'Composer version 2') !== FALSE) {
$this
->markTestSkipped("Composer 2 not supported for this test yet.");
}
$composer_home = $this
->getWorkspaceDirectory() . '/composer-home';
mkdir($composer_home);
$this
->executeCommand("COMPOSER_HOME={$composer_home} composer config --no-interaction --global repo.packagist false");
$this
->assertCommandSuccessful();
$core_version = Composer::drupalVersionBranch();
$vendor_packages_path = $this
->getWorkspaceDirectory() . '/vendor_packages/packages.json';
$this
->makeVendorPackage($vendor_packages_path);
$this
->copyCodebase();
$composer_json_path = $this
->getWorkspaceDirectory() . "/{$package_dir}/composer.json";
$composer_json = json_decode(file_get_contents($composer_json_path), TRUE);
unset($composer_json['repositories']);
$json = json_encode($composer_json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
file_put_contents($composer_json_path, $json);
$metapackage_path_repos = $this
->getPathReposForType($this
->getWorkspaceDirectory(), 'Metapackage');
$path_repos = array_merge($metapackage_path_repos, $this
->getPathReposForType($this
->getWorkspaceDirectory(), 'Plugin'));
$path_repos['drupal/core'] = $this
->getWorkspaceDirectory() . '/core';
foreach ($path_repos as $name => $path) {
$this
->executeCommand("composer config --no-interaction repositories.{$name} path {$path}", $package_dir);
$this
->assertCommandSuccessful();
}
$this
->executeCommand("composer config --no-interaction repositories.local composer file://" . $vendor_packages_path, $package_dir);
$this
->assertCommandSuccessful();
$repository_path = $this
->getWorkspaceDirectory() . '/test_repository/packages.json';
$this
->makeTestPackage($repository_path, $core_version);
$autoloader = $this
->getWorkspaceDirectory() . '/testproject' . $docroot_dir . '/autoload.php';
$this
->assertFileNotExists($autoloader);
$this
->executeCommand("COMPOSER_HOME={$composer_home} COMPOSER_ROOT_VERSION={$core_version} composer create-project --no-ansi {$project} testproject {$core_version} -s dev -vv --repository {$repository_path}");
$this
->assertCommandSuccessful();
$this
->assertErrorOutputContains("Installing {$project} ({$core_version}): Symlinking from {$package_dir}");
$this
->assertErrorOutputContains("Installing drupal/core ({$core_version}): Symlinking from");
$this
->assertFileExists($autoloader);
$template_json_file = $this
->getWorkspaceDirectory() . '/' . $package_dir . '/composer.json';
$this
->assertFileExists($template_json_file);
$json_file = new JsonFile($template_json_file);
$template_json = $json_file
->read();
$this
->assertNotEmpty($require = array_merge($template_json['require'] ?? [], $template_json['require-dev'] ?? []));
$path_repos = array_keys($path_repos);
foreach (array_keys($require) as $package_name) {
if (in_array($package_name, $path_repos)) {
if (array_key_exists($package_name, $metapackage_path_repos)) {
$this
->assertErrorOutputContains("Installing {$package_name} ({$core_version})");
}
else {
$this
->assertErrorOutputContains("Installing {$package_name} ({$core_version}): Symlinking from");
}
}
}
}
protected function makeTestPackage($repository_path, $version) {
$json = <<<JSON
{
"packages": {
"drupal/recommended-project": {
"{<span class="php-variable">$version</span>}": {
"name": "drupal/recommended-project",
"dist": {
"type": "path",
"url": "composer/Template/RecommendedProject"
},
"type": "project",
"version": "{<span class="php-variable">$version</span>}"
}
},
"drupal/legacy-project": {
"{<span class="php-variable">$version</span>}": {
"name": "drupal/legacy-project",
"dist": {
"type": "path",
"url": "composer/Template/LegacyProject"
},
"type": "project",
"version": "{<span class="php-variable">$version</span>}"
}
}
}
}
JSON;
mkdir(dirname($repository_path));
file_put_contents($repository_path, $json);
}
protected function makeVendorPackage($repository_path) {
$root = $this
->getDrupalRoot();
$process = $this
->executeCommand("composer --working-dir={$root} info --format=json");
$this
->assertCommandSuccessful();
$installed = json_decode($process
->getOutput(), TRUE);
$packages = [];
foreach ($installed['installed'] as $project) {
$name = $project['name'];
$version = $project['version'];
$path = "vendor/{$name}";
$full_path = "{$root}/{$path}";
if (is_dir($full_path)) {
$packages['packages'][$name] = [
$version => [
"name" => $name,
"dist" => [
"type" => "path",
"url" => $path,
],
"version" => $version,
],
];
}
}
$json = json_encode($packages, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
mkdir(dirname($repository_path));
file_put_contents($repository_path, $json);
}
}