PackageGenerator.php

Same filename in other branches
  1. 9 composer/Generator/PackageGenerator.php
  2. 8.9.x composer/Generator/PackageGenerator.php
  3. 10 composer/Generator/PackageGenerator.php

Namespace

Drupal\Composer\Generator

File

composer/Generator/PackageGenerator.php

View source
<?php

namespace Drupal\Composer\Generator;

use Drupal\Composer\Generator\Builder\DrupalCoreRecommendedBuilder;
use Drupal\Composer\Generator\Builder\DrupalDevDependenciesBuilder;
use Drupal\Composer\Generator\Builder\DrupalPinnedDevDependenciesBuilder;
use Drupal\Composer\Generator\Util\DrupalCoreComposer;
use Composer\Util\Filesystem;
use Composer\IO\IOInterface;

/**
 * Generates metapackages.
 */
class PackageGenerator {
    
    /**
     * Base directory where generated projects are written.
     *
     * @var string
     */
    protected $generatedProjectBaseDir;
    
    /**
     * PackageGenerator constructor.
     */
    public function __construct() {
        $this->generatedProjectBaseDir = dirname(__DIR__) . '/Metapackage';
    }
    
    /**
     * Generate Drupal's metapackages whenever composer.lock is updated.
     *
     * @param \Composer\IO\IOInterface $io
     *   Composer IO object for interacting with the user.
     * @param string $base_dir
     *   Directory where drupal/drupal repository is located.
     */
    public function generate(IOInterface $io, $base_dir) {
        // General information from drupal/drupal and drupal/core composer.json
        // and composer.lock files.
        $drupalCoreInfo = DrupalCoreComposer::createFromPath($base_dir);
        // Exit early if there is no composer.lock file.
        if (empty($drupalCoreInfo->composerLock())) {
            return;
        }
        // Run all of our available builders.
        $builders = $this->builders();
        $changed = FALSE;
        foreach ($builders as $builder_class) {
            $builder = new $builder_class($drupalCoreInfo);
            $changed |= $this->generateMetapackage($io, $builder);
        }
        // Remind the user not to miss files in a patch.
        if ($changed) {
            $io->write("If you make a patch, ensure that the files above are included.");
        }
    }
    
    /**
     * Returns a list of metapackage builders.
     *
     * @return BuilderInterface[]
     */
    protected function builders() {
        return [
            DrupalCoreRecommendedBuilder::class,
            DrupalDevDependenciesBuilder::class,
            DrupalPinnedDevDependenciesBuilder::class,
        ];
    }
    
    /**
     * Generate one metapackage.
     *
     * @param \Composer\IO\IOInterface $io
     *   Composer IO object for interacting with the user.
     * @param BuilderInterface $builder
     *   An object that can build a metapackage.
     *
     * @return bool
     *   TRUE if the generated metapackage is different than what is on disk.
     */
    protected function generateMetapackage(IOInterface $io, BuilderInterface $builder) {
        // Load the existing composer.json file for drupal/core-recommended
        $relative_path = $builder->getPath() . '/composer.json';
        $composer_json_path = $this->generatedProjectBaseDir . '/' . $relative_path;
        $original_composer_json = file_exists($composer_json_path) ? file_get_contents($composer_json_path) : '';
        // Get the composer.json file from the builder.
        $composer_json_data = $builder->getPackage();
        $updated_composer_json = static::encode($composer_json_data);
        // Exit early if nothing changed.
        if (trim($original_composer_json, " \t\r\x00\v") == trim($updated_composer_json, " \t\r\x00\v")) {
            return FALSE;
        }
        // Warn the user that a metapackage file has been updated..
        $io->write("Updated metapackage file <info>composer/Metapackage/{$relative_path}</info>.");
        // Write the composer.json file back to disk
        $fs = new Filesystem();
        $fs->ensureDirectoryExists(dirname($composer_json_path));
        file_put_contents($composer_json_path, $updated_composer_json);
        return TRUE;
    }
    
    /**
     * Utility function to encode metapackage json in a consistent way.
     *
     * @param array $composer_json_data
     *   Data to encode into a json string.
     *
     * @return string
     *   Encoded version of provided json data.
     */
    public static function encode($composer_json_data) {
        return json_encode($composer_json_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n";
    }

}

Classes

Title Deprecated Summary
PackageGenerator Generates metapackages.

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