123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- <?php
- declare(strict_types = 1);
- namespace Fgm\Drupal\Composer;
- use Composer\Command\BaseCommand;
- use Symfony\Component\Console\Input\InputInterface;
- use Symfony\Component\Console\Output\OutputInterface;
- use Symfony\Component\Yaml\Exception\ParseException;
- use Symfony\Component\Yaml\Yaml;
- use Twig\Environment;
- use Twig\Extension\DebugExtension;
- use Twig\Loader\FilesystemLoader;
- use Twig\TemplateWrapper;
- /**
- * Provides command primitives useful for most commands, focused on templating.
- *
- * @package Fgm\Drupal\Composer
- */
- abstract class BaseBuilderCommand extends BaseCommand {
- /**
- * The name of the argument defining the file to generate.
- */
- const ARG_FILE = 'file';
- /**
- * Provide the path to the project settings directory.
- *
- * @return string
- * The absolute path to the directory.
- */
- protected function getSettingsPath(): string {
- $settingsPath = getcwd() . "/settings";
- return $settingsPath;
- }
- /**
- * Validate template definition for command, returning its name on success.
- *
- * @param \Symfony\Component\Console\Input\InputInterface $input
- * Command input.
- * @param \Symfony\Component\Console\Output\OutputInterface $output
- * Command output.
- *
- * @return array
- * - string Template name
- * - int Error
- */
- public function validateTemplateName(InputInterface $input, OutputInterface $output): array {
- $file = $input->getArgument(static::ARG_FILE);
- $conf = $this->getComposer()->getPackage()->getExtra()[Builder::NAME] ?? [];
- $templateName = $conf['templates'][$file] ?? '';
- if (empty($templateName)) {
- $output->writeln(sprintf(
- 'Could not build file %s: no such template in composer.json extra section',
- $file
- ));
- return ["", 1];
- }
- return [$templateName, 0];
- }
- /**
- * Perform template rendering.
- *
- * @param \Twig\TemplateWrapper $wrapper
- * A Twig user-space template wrapper.
- * @param array $context
- * The data context with which to perform the rendering.
- * @param string $destination
- * The path where to write the rendering result.
- *
- * @return array
- * - string message
- * - int status: 0 on success, other values on errors.
- */
- protected function render(
- TemplateWrapper $wrapper,
- array $context,
- string $destination
- ): array {
- if (file_exists($destination)) {
- $ok = unlink($destination);
- if (!$ok) {
- return [sprintf("Could not remove old %s file", $destination), 1];
- }
- }
- $rendered = $wrapper->render($context);
- $ok = file_put_contents($destination, $rendered, LOCK_EX);
- if (!$ok) {
- return [sprintf('Could not write new %s file', $destination), 2];
- }
- return ["", 0];
- }
- /**
- * Prepare the template and its parameters as obtained from configuration.
- *
- * @param \Symfony\Component\Console\Input\InputInterface $input
- * Command input.
- * @param \Symfony\Component\Console\Output\OutputInterface $output
- * Command output.
- *
- * @return array
- * - TemplateWrapper|NULL: Twig template wrapper
- * - array: template parameters
- * - string: error message
- * - int: error, 0 if OK. If non-zero, only the error message is reliable.
- *
- * @throws \Twig\Error\LoaderError
- * @throws \Twig\Error\RuntimeError
- * @throws \Twig\Error\SyntaxError
- */
- protected function prepare(InputInterface $input, OutputInterface $output): array {
- [$templateName, $err] = $this->validateTemplateName($input, $output);
- if ($err) {
- return [NULL, [], "Could not validate template name", 1];
- };
- $settingsPath = $this->getSettingsPath();
- $templatePath = "${settingsPath}/${templateName}";
- $realTemplatePath = realpath($templatePath);
- if (empty($realTemplatePath)) {
- return [NULL, [],
- sprintf("Could not load template %s: no such file", $templateName),
- 2,
- ];
- }
- $paramsPath = "${settingsPath}/merged.params.local.yml";
- $realParamsPath = realpath($paramsPath);
- if (empty($realParamsPath)) {
- return [NULL, [],
- sprintf("Could not load parameters %s: no such file", $paramsPath),
- 3,
- ];
- }
- $yaml = new Yaml();
- try {
- $params = $yaml->parseFile($realParamsPath);
- }
- catch (ParseException $e) {
- return [NULL, [],
- sprintf("Could not parse %s: %s", $realParamsPath, $e->getMessage()),
- 4,
- ];
- }
- $loader = new FilesystemLoader($settingsPath, $settingsPath);
- $twig = new Environment($loader, [
- 'auto_reload' => TRUE,
- 'cache' => FALSE,
- 'debug' => TRUE,
- 'strict_variables' => TRUE,
- ]);
- $twig->addExtension(new DebugExtension());
- $wrapper = $twig->load($templateName);
- return [$wrapper, $params, "", 0];
- }
- }
|