function FixtureManipulator::addPackage

Adds a package.

Parameters

array $package: A Composer package definition. Must include the `name` and `type` keys.

bool $is_dev_requirement: Whether the package is a development requirement.

bool $allow_plugins: Whether to use the '--no-plugins' option.

array|null $extra_files: An array extra files to create in the package. The keys are the file paths under package and values are the file contents.

File

core/modules/package_manager/tests/modules/fixture_manipulator/src/FixtureManipulator.php, line 94

Class

FixtureManipulator
Manipulates a test fixture using Composer commands.

Namespace

Drupal\fixture_manipulator

Code

public function addPackage(array $package, bool $is_dev_requirement = FALSE, bool $allow_plugins = FALSE, ?array $extra_files = NULL) : self {
    if (!$this->committingChanges) {
        // To pass Composer validation all packages must have a version specified.
        if (!isset($package['version'])) {
            $package['version'] = '1.2.3';
        }
        $this->queueManipulation('addPackage', [
            $package,
            $is_dev_requirement,
            $allow_plugins,
            $extra_files,
        ]);
        return $this;
    }
    // Basic validation so we can defer the rest to `composer` commands.
    foreach ([
        'name',
        'type',
    ] as $required_key) {
        if (!isset($package[$required_key])) {
            throw new \UnexpectedValueException("The '{$required_key}' is required when calling ::addPackage().");
        }
    }
    if (!preg_match('/\\w+\\/\\w+/', $package['name'])) {
        throw new \UnexpectedValueException(sprintf("'%s' is not a valid package name.", $package['name']));
    }
    // `composer require` happily will re-require already required packages.
    // Prevent test authors from thinking this has any effect when it does not.
    $json = $this->runComposerCommand([
        'show',
        '--name-only',
        '--format=json',
    ])->stdout;
    $installed_package_names = array_column(json_decode($json)?->installed ?? [], 'name');
    if (in_array($package['name'], $installed_package_names)) {
        throw new \LogicException(sprintf("Expected package '%s' to not be installed, but it was.", $package['name']));
    }
    $repo_path = $this->addRepository($package);
    if (is_null($extra_files) && isset($package['type']) && in_array($package['type'], [
        'drupal-module',
        'drupal-theme',
        'drupal-profile',
    ], TRUE)) {
        // For Drupal projects if no files are provided create an info.yml file
        // that assumes the project and package names match.
        [
            ,
            $package_name,
        ] = explode('/', $package['name']);
        $project_name = str_replace('-', '_', $package_name);
        $project_info_data = [
            'name' => $package['name'],
            'project' => $project_name,
        ];
        $extra_files["{$project_name}.info.yml"] = Yaml::encode($project_info_data);
    }
    if (!empty($extra_files)) {
        $fs = new SymfonyFileSystem();
        foreach ($extra_files as $file_name => $file_contents) {
            if (str_contains($file_name, DIRECTORY_SEPARATOR)) {
                $file_dir = dirname("{$repo_path}/{$file_name}");
                if (!is_dir($file_dir)) {
                    $fs->mkdir($file_dir);
                }
            }
            assert(file_put_contents("{$repo_path}/{$file_name}", $file_contents) !== FALSE);
        }
    }
    return $this->requirePackage($package['name'], $package['version'], $is_dev_requirement, $allow_plugins);
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.