From c1ea3ffb6276787ccdb93ed0830a93d6fd2919d3 Mon Sep 17 00:00:00 2001 From: jurgenhaas <juergen.haas@lakedrops.com> Date: Sun, 27 Dec 2020 12:04:50 +0100 Subject: [PATCH] docker/l3d#58 Move project settings out of composer.json --- .ahoy.yml | 6 + composer.json | 14 +- src/Handler.php | 267 +++++++++++++++------------------------ src/InitCommand.php | 7 +- src/OverwriteCommand.php | 7 +- src/Plugin.php | 9 +- src/ResetCommand.php | 7 +- src/UpdateCommand.php | 7 +- 8 files changed, 132 insertions(+), 192 deletions(-) create mode 100644 .ahoy.yml diff --git a/.ahoy.yml b/.ahoy.yml new file mode 100644 index 0000000..b40d4b4 --- /dev/null +++ b/.ahoy.yml @@ -0,0 +1,6 @@ +ahoyapi: v2 +commands: + theme: + imports: + - ahoy.yml + usage: Drupal SASS Theme diff --git a/composer.json b/composer.json index da4c1d3..7bf2b0a 100644 --- a/composer.json +++ b/composer.json @@ -61,14 +61,12 @@ "drupal/bootstrap": "^3.6", "drupal/chosen": "^2.4", "harvesthq/chosen": "1.8.7", - "lakedrops/composer-json-utils": "^1.1.0", - "lakedrops/dotenv": "^1.0.0", + "lakedrops/composer-json-utils": "^1.7||dev-master", "matthiasmullie/path-converter": "^1.0" }, "require-dev": { "roave/security-advisories": "dev-master", "composer/composer": "^1||^2", - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3", "drupal/coder": "^8.2", "phpunit/phpunit": "^8.4" }, @@ -80,14 +78,6 @@ } }, "extra": { - "class": "LakeDrops\\Drupal8Theme\\SASS\\Plugin", - "lakedrops": { - "ahoy": { - "theme": { - "usage": "Drupal SASS Theme", - "imports": ["ahoy.yml"] - } - } - } + "class": "LakeDrops\\Drupal8Theme\\SASS\\Plugin" } } diff --git a/src/Handler.php b/src/Handler.php index 50468bc..5a44cca 100644 --- a/src/Handler.php +++ b/src/Handler.php @@ -4,21 +4,12 @@ namespace LakeDrops\Drupal8Theme\SASS; use Composer\Installer\InstallationManager; use Composer\Package\Package; -use Composer\Composer; -use Composer\IO\IOInterface; use Exception; use LakeDrops\Component\Composer\BaseHandler; -use LakeDrops\Component\Composer\Utils; -use LakeDrops\Component\Dotenv\Dotenv; use MatthiasMullie\PathConverter\Converter; use RuntimeException; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Finder\Finder; -use Twig_Environment; -use Twig_Error_Loader; -use Twig_Error_Runtime; -use Twig_Error_Syntax; -use Twig_Loader_Array; /** * Class Handler. @@ -28,57 +19,106 @@ use Twig_Loader_Array; class Handler extends BaseHandler { /** - * The Twig loader array. - * - * @var Twig_Loader_Array - */ - protected $twigLoader; - - /** - * The Twig Environment. + * Whether to update (TRUE) or initially installing (FALSE). * - * @var Twig_Environment + * @var bool */ - protected $twig; + protected $update = FALSE; /** - * The options array for this installation. + * Whether to reset the theme. * - * @var array + * @var bool */ - protected $options; + protected $reset = FALSE; /** - * Whether to update (TRUE) or initially installing (FALSE). + * Whether to overwrite existing files. * * @var bool */ - protected $update; + protected $overwrite = FALSE; /** - * Whether to reset the theme. - * - * @var bool + * {@inheritdoc} */ - protected $reset; + public function configId(): string { + return 'theme-d8-sass'; + } /** - * Whether to overwrite existing files. - * - * @var bool + * {@inheritdoc} */ - protected $overwrite; + protected function configDefault(): array { + return [ + 'base_theme' => [ + 'name' => 'bartik', + 'import' => [], + ], + 'bower_assets' => [], + ]; + } /** * {@inheritdoc} */ - public function __construct(Composer $composer, IOInterface $io) { - parent::__construct($composer, $io); - $this->twigLoader = new Twig_Loader_Array([]); - $this->twig = new Twig_Environment($this->twigLoader); - $this->update = FALSE; - $this->reset = FALSE; - $this->overwrite = FALSE; + protected function postInit(): void { + + // If we don't have a project name by now, lets get some magic at work. + $projectName = $this->config->readValue('project_name'); + if ($projectName === NULL) { + $defaultName = str_replace([' ', '-', '_', '.'], '', basename(getcwd())) . '_theme'; + $projectName = $this->env->receive('name', 'Name of custom theme', $defaultName); + $this->config->setValue(['project_name' => $projectName]); + } + + $fs = new Filesystem(); + + $dependencies = []; + $jsFiles = []; + $to = $this->buildInstallationPath($projectName); + $bowerAssets = $this->config->readValue('bower_assets') ?? []; + foreach ($bowerAssets as $key => $asset) { + $package = $this->getPackage('bower-asset/' . $key); + $version = $package ? $package->getVersion() : ($asset['version'] ?? 'latest'); + if ($package) { + // Installed globally as Composer package. + $from = $this->getInstallationManager()->getInstallPath($package); + if (!$fs->exists($from)) { + // Global package is missing. + continue; + } + } + else { + // Will be installed locally via Bower. + $from = implode(DIRECTORY_SEPARATOR, [$to, 'bower_components', $key]); + $dependencies[] = '"' . $key . '": "' . $version . '"'; + } + $converter = new Converter($from, $to); + foreach (['fonts', 'sass', 'js'] as $type) { + if (isset($asset[$type])) { + $bowerAssets[$key][$type]['relative'] = $converter->convert($asset[$type]['src']); + if ($type === 'js') { + $jsFiles[$asset['name']] = []; + $finder = new Finder(); + $finder->ignoreDotFiles(FALSE); + $finder->files()->in($from . DIRECTORY_SEPARATOR . $asset[$type]['src']); + foreach ($finder as $file) { + $jsFiles[$asset['name']][] = $file->getRelativePathname(); + } + } + if ($this->reset && in_array($type, ['fonts', 'js'])) { + $path = implode(DIRECTORY_SEPARATOR, [$to, $type, $asset['name']]); + if ($fs->exists($path)) { + $fs->remove($path); + } + } + } + } + } + $bowerAssets['dependencies'] = implode(",\n ", $dependencies); + $bowerAssets['jsfiles'] = $jsFiles; + $this->config->setValue(['bower_assets' => $bowerAssets]); } /** @@ -89,7 +129,7 @@ class Handler extends BaseHandler { * * @return $this */ - public function setUpdate($flag): self { + public function setUpdate(bool $flag): self { $this->update = $flag; return $this; } @@ -102,7 +142,7 @@ class Handler extends BaseHandler { * * @return $this */ - public function setReset($flag): self { + public function setReset(bool $flag): self { $this->reset = $flag; return $this; } @@ -115,7 +155,7 @@ class Handler extends BaseHandler { * * @return $this */ - public function setOverwrite($flag): self { + public function setOverwrite(bool $flag): self { $this->overwrite = $flag; return $this; } @@ -144,7 +184,7 @@ class Handler extends BaseHandler { * @return string * The installation path for the named package. */ - protected function buildInstallationPath($name): string { + protected function buildInstallationPath(string $name): string { $package = new Package($name, '1.0.0', '1.0.0'); $package->setType('drupal-custom-theme'); return $this->getInstallationManager() @@ -161,106 +201,11 @@ class Handler extends BaseHandler { static $installationPath; if (!isset($installationPath)) { - $installationPath = $this->buildInstallationPath($this->getOption('project_name')); + $installationPath = $this->buildInstallationPath($this->config->readValue('project_name')); } return $installationPath; } - /** - * Retrieve configuration for this package. - * - * @return array - * The settings from the extra configuration. - */ - protected function getOptions(): array { - if (!isset($this->options)) { - $extra = $this->composer->getPackage() - ->getExtra() + ['theme-d8-sass' => []]; - $this->options = array_replace_recursive([ - 'base_theme' => [ - 'name' => 'bartik', - 'import' => [], - ], - 'bower_assets' => [], - ], $extra['theme-d8-sass']); - - // If we don't have a project name by now, lets get some magic at work. - if (empty($this->options['project_name'])) { - $defaultName = str_replace([' ', '-', '_', '.'], '', basename(getcwd())) . '_theme'; - $env = new Dotenv('custom_theme', $this->io); - $this->options['project_name'] = $env->receive('name', 'Name of custom theme', $defaultName); - } - - // Update composer.jon if necessary. - $composerUtils = new Utils($this->composer); - $composerUtils - ->setSubSection('extra', 'theme-d8-sass', $this->options) - ->write(); - - $fs = new Filesystem(); - - $dependencies = []; - $jsFiles = []; - $to = $this->buildInstallationPath($this->options['project_name']); - foreach ($this->options['bower_assets'] as $key => $asset) { - $package = $this->getPackage('bower-asset/' . $key); - $version = $package ? $package->getVersion() : ($asset['version'] ?? 'latest'); - if ($package) { - // Installed globally as Composer package. - $from = $this->getInstallationManager()->getInstallPath($package); - if (!$fs->exists($from)) { - // Global package is missing. - unset($this->options['bower_assets'][$key]); - continue; - } - } - else { - // Will be installed locally via Bower. - $from = implode(DIRECTORY_SEPARATOR, [$to, 'bower_components', $key]); - $dependencies[] = '"' . $key . '": "' . $version . '"'; - } - $converter = new Converter($from, $to); - foreach (['fonts', 'sass', 'js'] as $type) { - if (isset($asset[$type])) { - $this->options['bower_assets'][$key][$type]['relative'] = $converter->convert($asset[$type]['src']); - if ($type === 'js') { - $jsFiles[$asset['name']] = []; - $finder = new Finder(); - $finder->ignoreDotFiles(FALSE); - $finder->files()->in($from . DIRECTORY_SEPARATOR . $asset[$type]['src']); - foreach ($finder as $file) { - $jsFiles[$asset['name']][] = $file->getRelativePathname(); - } - } - if ($this->reset && in_array($type, ['fonts', 'js'])) { - $path = implode(DIRECTORY_SEPARATOR, [$to, $type, $asset['name']]); - if ($fs->exists($path)) { - $fs->remove($path); - } - } - } - } - } - $this->options['bower_assets']['dependencies'] = implode(",\n ", $dependencies); - $this->options['bower_assets']['jsfiles'] = $jsFiles; - } - return $this->options; - } - - /** - * Get a specific option. - * - * @param string $key - * The key of the option to retrieve. - * - * @return string|array - * The option. - */ - protected function getOption($key) { - $options = $this->getOptions(); - return $options[$key]; - } - /** * Get the list of custom files. * @@ -293,7 +238,7 @@ class Handler extends BaseHandler { * The file list. */ protected function getIgnoredFiles(): array { - return array_merge((empty($this->getOption('bower_assets')['dependencies']) ? ['bower.json'] : []), [ + return array_merge((empty($this->config->readValue('bower_assets')['dependencies']) ? ['bower.json'] : []), [ 'templates/README.md', 'README.md', '{{ project_name }}.starterkit.yml', @@ -323,10 +268,10 @@ class Handler extends BaseHandler { * @return string * The tweaked string. */ - protected function tweaks($string): string { + protected function tweaks(string $string): string { $string = str_replace('THEMENAME', '{{ project_name }}', $string); - $baseTheme = $this->getOption('base_theme'); + $baseTheme = $this->config->readValue('base_theme'); if (isset($baseTheme['sasspath']) && strpos($string, $baseTheme['sasspath']) === 0) { $string = 'sass' . substr($string, strlen($baseTheme['sasspath'])); } @@ -342,18 +287,14 @@ class Handler extends BaseHandler { * * @return string * The processed string. - * @throws Twig_Error_Loader - * @throws Twig_Error_Runtime - * @throws Twig_Error_Syntax */ - protected function twig($string): string { + protected function twig(string $string): string { + $this->init(); if (empty($string)) { return ''; } - $this->twigLoader->setTemplate('fixed', $this->tweaks($string)); - /** @noinspection PhpTemplateMissingInspection */ - return str_replace('"', '"', $this->twig->render('fixed', $this->getOptions())); + return str_replace('"', '"', $this->config->render('fixed', $this->tweaks($string))); } /** @@ -362,9 +303,9 @@ class Handler extends BaseHandler { * @param string $command * NPM command name, arguments and/or options. * - * @throws RuntimeException + * @throws \RuntimeException */ - protected function npm($command) { + protected function npm(string $command): void { passthru(escapeshellcmd('npm ' . $command), $exit_code); if ($exit_code !== 0) { throw new RuntimeException('NPM returned a non-zero exit code'); @@ -377,9 +318,9 @@ class Handler extends BaseHandler { * @param string $command * Bower command name, arguments and/or options. * - * @throws RuntimeException + * @throws \RuntimeException */ - protected function bower($command) { + protected function bower(string $command): void { passthru(escapeshellcmd('bower --allow-root ' . $command), $exit_code); if ($exit_code !== 0) { throw new RuntimeException('Bower returned a non-zero exit code'); @@ -392,9 +333,9 @@ class Handler extends BaseHandler { * @param string $command * Gulp command name, arguments and/or options. * - * @throws RuntimeException + * @throws \RuntimeException */ - protected function gulp($command) { + protected function gulp(string $command): void { passthru(escapeshellcmd('node_modules/.bin/gulp ' . $command), $exit_code); if ($exit_code !== 0) { throw new RuntimeException('Gulp returned a non-zero exit code'); @@ -413,11 +354,8 @@ class Handler extends BaseHandler { * * @return array * List of processed file names. - * @throws Twig_Error_Loader - * @throws Twig_Error_Runtime - * @throws Twig_Error_Syntax */ - protected function copyFiles(FileSystem $fs, $source, $destination): array { + protected function copyFiles(FileSystem $fs, string $source, string $destination): array { $files = []; // Make sure all directories do exist. @@ -476,7 +414,8 @@ class Handler extends BaseHandler { * * @throws Exception */ - public function updateTheme() { + public function updateTheme(): void { + $this->init(); $fs = new Filesystem(); $destination = $this->getInstallationPath(); @@ -488,17 +427,17 @@ class Handler extends BaseHandler { $this->copyFiles($fs, $pluginRoot . '/templates', $destination); // Handle optional base theme. - $baseTheme = $this->getOption('base_theme'); + $baseTheme = $this->config->readValue('base_theme'); if (isset($baseTheme['package'])) { $baseThemePackage = $this->getPackage($baseTheme['package']); if ($baseThemePackage && isset($baseTheme['starterkit'])) { $starterkitRoot = $this->getInstallationManager()->getInstallPath($baseThemePackage) . DIRECTORY_SEPARATOR . $baseTheme['starterkit']; - $this->options['base_theme_files'] = $this->copyFiles($fs, $starterkitRoot, $destination); + $this->config->setValue(['base_theme_files' => $this->copyFiles($fs, $starterkitRoot, $destination)]); } } // Remove bower stuff if that's available globally. - if (empty($this->getOption('bower_assets')['dependencies'])) { + if ($this->config->readValue('bower_assets/dependencies') === NULL) { if ($fs->exists($destination . DIRECTORY_SEPARATOR . 'bower.json')) { $fs->remove($destination . DIRECTORY_SEPARATOR . 'bower.json'); } @@ -523,7 +462,7 @@ class Handler extends BaseHandler { } // Handle Bower if not installed globally. - if ($fs->exists($destination . DIRECTORY_SEPARATOR . 'bower.json') && !empty($this->getOption('bower_assets')['dependencies'])) { + if ($fs->exists($destination . DIRECTORY_SEPARATOR . 'bower.json') && $this->config->readValue('bower_assets/dependencies') !== NULL) { if ($this->update) { $this->bower('update'); } diff --git a/src/InitCommand.php b/src/InitCommand.php index c7f4a48..9a01171 100644 --- a/src/InitCommand.php +++ b/src/InitCommand.php @@ -11,7 +11,7 @@ class InitCommand extends BaseCommand { /** * {@inheritdoc} */ - protected function configure() { + protected function configure(): void { parent::configure(); $this ->setName('lakedrops:theme:init') @@ -21,7 +21,7 @@ class InitCommand extends BaseCommand { /** * {@inheritdoc} */ - public function getHandlerClass() { + public function getHandlerClass(): string { return Handler::class; } @@ -30,7 +30,7 @@ class InitCommand extends BaseCommand { * * @throws \Exception */ - protected function execute(InputInterface $input, OutputInterface $output) { + protected function execute(InputInterface $input, OutputInterface $output): int { parent::execute($input, $output); /** @var Handler $handler */ $handler = $this->handler; @@ -39,6 +39,7 @@ class InitCommand extends BaseCommand { ->setReset(FALSE) ->setOverwrite(FALSE) ->updateTheme(); + return 0; } } diff --git a/src/OverwriteCommand.php b/src/OverwriteCommand.php index 53b7591..2d87efd 100644 --- a/src/OverwriteCommand.php +++ b/src/OverwriteCommand.php @@ -11,7 +11,7 @@ class OverwriteCommand extends BaseCommand { /** * {@inheritdoc} */ - protected function configure() { + protected function configure(): void { parent::configure(); $this ->setName('lakedrops:theme:overwrite') @@ -21,7 +21,7 @@ class OverwriteCommand extends BaseCommand { /** * {@inheritdoc} */ - public function getHandlerClass() { + public function getHandlerClass(): string { return Handler::class; } @@ -30,7 +30,7 @@ class OverwriteCommand extends BaseCommand { * * @throws \Exception */ - protected function execute(InputInterface $input, OutputInterface $output) { + protected function execute(InputInterface $input, OutputInterface $output): int { parent::execute($input, $output); /** @var Handler $handler */ $handler = $this->handler; @@ -39,6 +39,7 @@ class OverwriteCommand extends BaseCommand { ->setReset(FALSE) ->setOverwrite(TRUE) ->updateTheme(); + return 0; } } diff --git a/src/Plugin.php b/src/Plugin.php index c86f657..d765507 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -2,6 +2,7 @@ namespace LakeDrops\Drupal8Theme\SASS; +use Composer\Plugin\Capability\CommandProvider; use Composer\Script\Event; use Composer\Script\ScriptEvents; use Exception; @@ -15,7 +16,7 @@ class Plugin extends BasePlugin { /** * {@inheritdoc} */ - public function getHandlerClass() { + public function getHandlerClass(): string { return Handler::class; } @@ -24,7 +25,7 @@ class Plugin extends BasePlugin { */ public function getCapabilities(): array { return [ - \Composer\Plugin\Capability\CommandProvider::class => CommandProvider::class, + CommandProvider::class => CommandProvider::class, ]; } @@ -45,7 +46,7 @@ class Plugin extends BasePlugin { * The event that triggered the plugin. * @throws Exception */ - public function initThemeEvent(Event $event) { + public function initThemeEvent(Event $event): void { $this->updateThemeEvent($event, FALSE); } @@ -58,7 +59,7 @@ class Plugin extends BasePlugin { * Whether to update (TRUE) or initially installing (FALSE). * @throws Exception */ - public function updateThemeEvent(Event $event, $update = TRUE) { + public function updateThemeEvent(Event $event, $update = TRUE): void { /** @var Handler $handler */ $handler = $this->handler; $handler diff --git a/src/ResetCommand.php b/src/ResetCommand.php index 0a9bfcf..b78c58b 100644 --- a/src/ResetCommand.php +++ b/src/ResetCommand.php @@ -11,7 +11,7 @@ class ResetCommand extends BaseCommand { /** * {@inheritdoc} */ - protected function configure() { + protected function configure(): void { parent::configure(); $this ->setName('lakedrops:theme:reset') @@ -21,7 +21,7 @@ class ResetCommand extends BaseCommand { /** * {@inheritdoc} */ - public function getHandlerClass() { + public function getHandlerClass(): string { return Handler::class; } @@ -30,7 +30,7 @@ class ResetCommand extends BaseCommand { * * @throws \Exception */ - protected function execute(InputInterface $input, OutputInterface $output) { + protected function execute(InputInterface $input, OutputInterface $output): int { parent::execute($input, $output); /** @var Handler $handler */ $handler = $this->handler; @@ -39,6 +39,7 @@ class ResetCommand extends BaseCommand { ->setReset(TRUE) ->setOverwrite(FALSE) ->updateTheme(); + return 0; } } diff --git a/src/UpdateCommand.php b/src/UpdateCommand.php index 3cc7664..9088bbc 100644 --- a/src/UpdateCommand.php +++ b/src/UpdateCommand.php @@ -11,7 +11,7 @@ class UpdateCommand extends BaseCommand { /** * {@inheritdoc} */ - protected function configure() { + protected function configure(): void { parent::configure(); $this ->setName('lakedrops:theme:update') @@ -21,7 +21,7 @@ class UpdateCommand extends BaseCommand { /** * {@inheritdoc} */ - public function getHandlerClass() { + public function getHandlerClass(): string { return Handler::class; } @@ -30,7 +30,7 @@ class UpdateCommand extends BaseCommand { * * @throws \Exception */ - protected function execute(InputInterface $input, OutputInterface $output) { + protected function execute(InputInterface $input, OutputInterface $output): int { parent::execute($input, $output); /** @var Handler $handler */ $handler = $this->handler; @@ -39,6 +39,7 @@ class UpdateCommand extends BaseCommand { ->setReset(FALSE) ->setOverwrite(FALSE) ->updateTheme(); + return 0; } } -- GitLab