cypress-8.x-1.x-dev/src/NpmProjectManager.php

src/NpmProjectManager.php
<?php

namespace Drupal\cypress;

use Composer\Semver\VersionParser;
use Drupal\Component\Utility\NestedArray;
use Symfony\Component\Filesystem\Filesystem;

/**
 * A shell based project manager implementation.
 */
class NpmProjectManager implements NpmProjectManagerInterface {

  /**
   * The project root directory.
   *
   * @var string
   */
  protected $packageDirectory;

  /**
   * The path to the Cypress module.
   *
   * @var string
   */
  protected $cypressModulePath;

  /**
   * A process manager to invoke commands.
   *
   * @var \Drupal\cypress\ProcessManagerInterface
   */
  protected $processManager;

  /**
   * A filesystem component to access file information.
   *
   * @var \Symfony\Component\Filesystem\Filesystem
   */
  protected $fileSystem;

  /**
   * The path to the npm executable.
   *
   * @var string
   */
  protected $npmExecutable;

  /**
   * NpmProjectManager constructor.
   *
   * @param \Drupal\cypress\ProcessManagerInterface $processManager
   *   A process manager to execute npm commands.
   * @param string $packageDirectory
   *   The directory to put the package in.
   * @param string $npmExecutable
   *   The npm executable to use when executing commands.
   */
  public function __construct(ProcessManagerInterface $processManager, $packageDirectory, $npmExecutable) {
    $this->processManager = $processManager;
    $this->packageDirectory = $packageDirectory;
    $this->npmExecutable = $npmExecutable;
    $this->fileSystem = new Filesystem();
  }

  /**
   * {@inheritDoc}
   */
  public function merge($file) {
    $contents = file_get_contents($this->packageDirectory . '/package.json');
    if (!$contents) {
      throw new \Exception('Cannot read ' . $this->packageDirectory . '/package.json');
    }
    $packageJson = json_decode($contents, TRUE);
    $dependencies = $packageJson['dependencies'] ?? [];

    $contents = file_get_contents($file);
    if (!$contents) {
      throw new \Exception('Cannot read ' . $file);
    }
    $merge = json_decode($contents, TRUE);
    if (array_key_exists('dependencies', $merge)) {
      foreach ($merge['dependencies'] as $package => $version) {

        // A hack to use local packages from the silverback-mono repository.
        if (is_dir(__DIR__ . '/../../../../npm/' . $package)) {
          $package = realpath(__DIR__ . '/../../../../npm/' . $package);
        }

        if (isset($dependencies[$package])) {
          $currentConstraint = (new VersionParser())->parseConstraints($dependencies[$package]);
          $newConstraint = (new VersionParser())->parseConstraints($version);
          // The new constraint is already covered by the current constraint.
          // Don't adjust versions.
          if ($newConstraint->matches($currentConstraint) && $newConstraint < $currentConstraint) {
            continue;
          }
          if (!($newConstraint->matches($currentConstraint) || $currentConstraint->matches($newConstraint))) {
            throw new \Exception("Incompatible versions of package '$package': $version / {$dependencies[$package]}");
          }
        }
        $this->ensurePackageVersion($package, $version);
      }
    }

    unset($merge['dependencies']);
    // Re-read package.json since it could be modified by ensurePackageVersion.
    $contents = file_get_contents($this->packageDirectory . '/package.json');
    if (!$contents) {
      throw new \Exception('Cannot read ' . $this->packageDirectory . '/package.json');
    }
    $packageJson = json_decode($contents, TRUE);
    $packageJson = NestedArray::mergeDeep($packageJson, $merge);

    $this->fileSystem->dumpFile(
      $this->packageDirectory . '/package.json',
      json_encode($packageJson, JSON_PRETTY_PRINT) ?: ''
    );
  }

  /**
   * {@inheritDoc}
   */
  public function ensureInitiated() {
    if (!$this->fileSystem->exists($this->packageDirectory)) {
      $this->fileSystem->mkdir($this->packageDirectory);
    }

    if (!$this->fileSystem->exists($this->packageDirectory . '/package.json')) {
      $this->processManager->run([$this->npmExecutable, 'init', '-y'], $this->packageDirectory);
    }

    if (!$this->fileSystem->exists($this->packageDirectory . '/node_modules')) {
      $this->processManager->run([$this->npmExecutable, 'install'], $this->packageDirectory);
    }
  }

  /**
   * {@inheritDoc}
   */
  public function ensurePackageVersion($package, $version) {
    if (!$this->fileSystem->exists($this->packageDirectory . '/package.json')) {
      $this->ensureInitiated();
    }

    $packageJson = $this->packageDirectory . '/node_modules/' . $package . '/package.json';

    if ($this->fileSystem->exists($packageJson)) {
      $constraint = (new VersionParser())->parseConstraints($version);
      $contents = file_get_contents($packageJson);
      if (!$contents) {
        throw new \Exception('Cannot read ' . $packageJson);
      }
      $installedVersion = json_decode($contents)->version;
      if ($constraint->matches((new VersionParser())->parseConstraints($installedVersion))) {
        return;
      }
    }

    $this->processManager->run([
      $this->npmExecutable,
      'install',
      // NPM fails to install a local package if version is provided.
      substr($package, 0, 1) === '/' ? $package : $package . '@' . $version,
    ], $this->packageDirectory);
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc