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.