Skip to content
Snippets Groups Projects
Handler.php 3.89 KiB
<?php

namespace LakeDrops\Behat4Drupal;

use LakeDrops\Component\Composer\BaseHandler;
use LakeDrops\Component\Dotenv\Dotenv;
use LakeDrops\Docker4Drupal\Handler as D4DHandler;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Yaml\Yaml;

/**
 * Class Handler.
 *
 * @package LakeDrops\Behat4Drupal
 */
class Handler extends BaseHandler {

  /**
   * Post project create event to execute the scaffolding.
   *
   * @param bool $overwrite
   *   Whether to overwrite existing config files.
   *
   * @throws \Twig_Error_Loader
   * @throws \Twig_Error_Runtime
   * @throws \Twig_Error_Syntax
   */
  public function configureProject($overwrite = FALSE) {

    // We only do the fancy stuff for developers.
    if (!$this->isDevMode()) {
      return;
    }

    $options = $this->getOptions();
    $fs = new Filesystem();
    $installationManager = $this->composer->getInstallationManager();

    // Directory where the root project is being created.
    $projectRoot = getcwd();
    // Directory where this plugin is being installed.
    $pluginRoot = $installationManager->getInstallPath($this->getPackage('lakedrops/behat4drupal'));

    // Provide all the required files.
    $twig_loader = new \Twig_Loader_Array([]);
    $twig = new \Twig_Environment($twig_loader);
    foreach ($this->getFiles($projectRoot) as $template => $def) {
      if (!$fs->exists($def['dest'])) {
        $fs->mkdir($def['dest']);
      }
      $twig_loader->setTemplate($template, $template);
      $filename = $twig->render($template, $options);
      $file = $def['dest'] . '/' . $filename;
      if (($overwrite && empty($def['custom'])) || !$fs->exists($file)) {
        $twig_loader->setTemplate($filename, file_get_contents($pluginRoot . '/templates/' . $template . '.twig'));
        $rendered = $twig->render($filename, $options);
        if (!empty($def['add2yaml']) && isset($options[$filename])) {
          $yaml = Yaml::parse($rendered);
          /** @noinspection SlowArrayOperationsInLoopInspection */
          $yaml = array_merge_recursive($yaml, $options[$filename]);
          $rendered = Yaml::dump($yaml, 9, 2);
        }
        if ($fs->exists($file)) {
          if (md5_file($file) === md5($rendered)) {
            continue;
          }
          $orig_file = $file . '.orig';
          if ($fs->exists($orig_file)) {
            $fs->remove($orig_file);
          }
          $fs->rename($file, $orig_file);
        }
        file_put_contents($file, $rendered);
      }
      $fs->chmod($file, 0664);
    }

    $this->gitIgnore('tests/output');
  }

  /**
   * List of files and settings on how to handle them.
   *
   * @param string $projectRoot
   *   Name of the project's root directory.
   *
   * @return array
   *   List of files.
   */
  protected function getFiles($projectRoot): array {
    return [
      'behat.yml' => [
        'dest' => $projectRoot . '/tests/behat',
        'add2yaml' => TRUE,
      ],
      'anonymous.feature' => [
        'dest' => $projectRoot . '/tests/behat/features/basic',
        'custom' => TRUE,
      ],
      'FeatureContext.php' => [
        'dest' => $projectRoot . '/tests/behat/bootstrap/context',
        'custom' => TRUE,
      ],
    ];
  }

  /**
   * Retrieve configuration for this package.
   *
   * @return array
   *   The settings from the extra configuration.
   */
  protected function getOptions(): array {
    $handler = new D4DHandler($this->composer, $this->io);
    $projectname = $handler->getOptions('projectname');
    $webserver = $handler->getOptions('webserver');

    $env = new Dotenv('behat4drupal', $this->io);
    $extra = $this->composer->getPackage()->getExtra() + ['behat4drupal' => []];
    $options = $extra['behat4drupal'] + [
      'projectname' => $projectname,
    ];

    $options['baseurl'] = empty($options['global']) ?
      $webserver['type'] :
      $projectname . '.docker.localhost:8000';

    return $env->replaceEnvironmentVariables($options);
  }

}