diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 35e39b39e8cf8c06b841d60d51eba772903156bb..16e920fb0c1918425bdd9829cfab5e2e189dfef3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,16 +1,3 @@ -stages: - - test - - deploy - -Test: - stage: test - except: - - tags - script: - - composer install --no-progress - - ./vendor/bin/phpunit - Deploy: - stage: deploy script: - curl -XPOST -H'content-type:application/json' "https://packagist.org/api/update-package?username=${PACKAGIST_USERNAME}&apiToken=${PACKAGIST_API_TOKEN}" -d'{"repository":{"url":"'${CI_PROJECT_URL}'"}}' diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..425525a72c50570b10b444925b9f6dbd0d2981ea --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,7 @@ +# Guidelines for developers + +It is important to use the following command for updates: + +```bash +copmoser update --no-plugins +``` diff --git a/composer.json b/composer.json index dc15d439c08c6c941685c4d22858a7bfbf46cfd5..feccd41f918cb8061bc39dc094f0ba84c91121f1 100644 --- a/composer.json +++ b/composer.json @@ -30,12 +30,43 @@ "issues": "https://gitlab.lakedrops.com/lakedrops/theme-d8-sass/issues", "source": "https://gitlab.lakedrops.com/lakedrops/theme-d8-sass/tree/master" }, + "repositories": [ + { + "type": "composer", + "url": "https://packages.drupal.org/8" + }, + { + "type": "composer", + "url": "https://asset-packagist.org" + }, + { + "type": "package", + "package": { + "name": "harvesthq/chosen", + "version": "1.8.2", + "type": "drupal-library", + "dist": { + "url": "https://github.com/harvesthq/chosen/releases/download/v1.8.2/chosen_v1.8.2.zip", + "type": "zip" + } + } + } + ], "require": { - "php": ">=5.4.5", "composer-plugin-api": "^1.0.0", - "twig/twig": "^1.23.1", + "bower-asset/animate-sass": "~0.6.6", + "bower-asset/bootstrap-sass": "~3.3.7", + "bower-asset/flat-ui-sass": "~2.1.3", + "bower-asset/fontawesome": "~4.7.0", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3", + "drupal/bootstrap": "^3.6", + "drupal/chosen": "^2.4", + "drupal/coder": "^8.2", + "harvesthq/chosen": "^1.8", "matthiasmullie/path-converter": "^1.0" }, + "minimum-stability": "dev", + "prefer-stable": true, "autoload": { "psr-4": { "LakeDrops\\Drupal8Theme\\SASS\\": "src/" @@ -47,5 +78,10 @@ "require-dev": { "composer/composer": "^1.2.0", "phpunit/phpunit": "^4.4.0" + }, + "scripts": { + "install-codestandards": ["Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin::run"], + "post-install-cmd": ["@install-codestandards"], + "post-update-cmd": ["@install-codestandards"] } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist deleted file mode 100644 index 137977fd48f9b445f15a1b97613a82be48f0e29a..0000000000000000000000000000000000000000 --- a/phpunit.xml.dist +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd" - backupGlobals="false" - colors="true" - bootstrap="vendor/autoload.php" - verbose="true" -> - <testsuites> - <testsuite name="theme-d8-sass"> - <directory>./tests/</directory> - </testsuite> - </testsuites> -</phpunit> diff --git a/src/Handler.php b/src/Handler.php index bb01bb70244d62db1002ef567d7c30839892d322..27100dcba728c9a8569f99339f2a9eba2abc7f9a 100644 --- a/src/Handler.php +++ b/src/Handler.php @@ -1,70 +1,74 @@ <?php -/** - * @file - * Contains \LakeDrops\Drupal8Theme\SASS\Handler. - */ - namespace LakeDrops\Drupal8Theme\SASS; -use Composer\Package\PackageInterface; use Composer\Package\Package; use Composer\Composer; use Composer\IO\IOInterface; -use Composer\Script\Event as ScriptEvent; +use Composer\Script\Event; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Finder\Finder; use MatthiasMullie\PathConverter\Converter; -class Handler -{ +/** + * Class Handler. + * + * @package LakeDrops\Drupal8Theme\SASS + */ +class Handler { /** + * The composer object running this session. + * * @var \Composer\Composer */ protected $composer; /** + * The input-output object for the composer session. + * * @var \Composer\IO\IOInterface */ protected $io; /** + * The Twig loader array. + * * @var \Twig_Loader_Array */ - protected $twig_loader; + protected $twigLoader; /** + * The Twig Environment. + * * @var \Twig_Environment */ protected $twig; /** - * @var \Composer\Installer\InstallationManager - */ - protected $installationManager; - - /** - * @var string - */ - protected $installationPath; - - /** + * The options array for this installation. + * * @var array */ protected $options; /** + * Whether to update (TRUE) or initially installing (FALSE). + * * @var bool */ protected $update; /** + * Whether to reset the theme. + * * @var bool */ protected $reset; /** + * Whether to overwrite existing files. + * * @var bool */ protected $overwrite; @@ -72,35 +76,64 @@ class Handler /** * Handler constructor. * - * @param Composer $composer - * @param IOInterface $io + * @param \Composer\Composer $composer + * The composer object. + * @param \Composer\IO\IOInterface $io + * The input-output object. + * @param bool $update + * Whether to update (TRUE) or initially installing (FALSE). + * @param bool $reset + * Whether to reset the theme. + * @param bool $overwrite + * Whether to overwrite existing files. */ - public function __construct(Composer $composer, IOInterface $io, $update = FALSE, $reset = FALSE, $overwrite = FALSE) - { + public function __construct(Composer $composer, IOInterface $io, $update = FALSE, $reset = FALSE, $overwrite = FALSE) { $this->composer = $composer; $this->io = $io; - $this->twig_loader = new \Twig_Loader_Array([]); - $this->twig = new \Twig_Environment($this->twig_loader); + $this->twigLoader = new \Twig_Loader_Array([]); + $this->twig = new \Twig_Environment($this->twigLoader); $this->update = $update; $this->reset = $reset; $this->overwrite = $overwrite; } + /** + * Set whether to update (TRUE) or initially installing (FALSE). + * + * @param bool $flag + * The flag. + * + * @return $this + */ public function setUpdate($flag) { $this->update = $flag; + return $this; } /** + * Get the composer installation manager. + * * @return \Composer\Installer\InstallationManager + * The installation manager. */ - protected function getInstallationManager() - { - if (!isset($this->installationManager)) { - $this->installationManager = $this->composer->getInstallationManager(); + protected function getInstallationManager() { + static $installationManager; + + if (!isset($installationManager)) { + $installationManager = $this->composer->getInstallationManager(); } - return $this->installationManager; + return $installationManager; } + /** + * Get the installation path for a package by its name. + * + * @param string $name + * The name of the package. + * + * @return string + * The installation path for the named package. + */ protected function buildInstallationPath($name) { $package = new Package($name, '1.0.0', '1.0.0'); $package->setType('drupal-custom-theme'); @@ -109,14 +142,18 @@ class Handler } /** + * Get the installation path for the theme of this package. + * * @return string + * The installation path of this theme. */ - protected function getInstallationPath() - { - if (!isset($this->installationPath)) { - $this->installationPath = $this->buildInstallationPath($this->getOption('project_name')); + protected function getInstallationPath() { + static $installationPath; + + if (!isset($installationPath)) { + $installationPath = $this->buildInstallationPath($this->getOption('project_name')); } - return $this->installationPath; + return $installationPath; } /** @@ -125,25 +162,25 @@ class Handler * @param string $name * Name of the package to get from the current composer installation. * - * @return PackageInterface + * @return \Composer\Package\PackageInterface + * The package. */ - protected function getPackage($name) - { + protected function getPackage($name) { return $this->composer->getRepositoryManager() ->getLocalRepository() ->findPackage($name, '*'); } /** - * Retrieve excludes from optional "extra" configuration. + * Retrieve configuration for this package. * * @return array + * The settings from the extra configuration. */ - protected function getOptions() - { + protected function getOptions() { if (!isset($this->options)) { $extra = $this->composer->getPackage() - ->getExtra() + ['theme-d8-sass' => []]; + ->getExtra() + ['theme-d8-sass' => []]; $this->options = array_replace_recursive([ 'project_name' => 'mytheme', 'base_theme' => [ @@ -162,16 +199,16 @@ class Handler $package = $this->getPackage('bower-asset/' . $key); $version = $package ? $package->getVersion() : (isset($asset['version']) ? $asset['version'] : 'latest'); if ($package) { - // Installed globally as Composer package + // Installed globally as Composer package. $from = $this->getInstallationManager()->getInstallPath($package); if (!$fs->exists($from)) { - // Global package is missing + // Global package is missing. unset($this->options['bower_assets'][$key]); continue; } } else { - // Will be installed locally via Bower + // Will be installed locally via Bower. $from = implode(DIRECTORY_SEPARATOR, [$to, 'bower_components', $key]); $dependencies[] = '"' . $key . '": "' . $version . '"'; } @@ -204,17 +241,26 @@ class Handler } /** + * Get a specific option. + * * @param string $key - * @return string + * The key of the option to retrieve. + * + * @return string|array + * The option. */ - protected function getOption($key) - { + protected function getOption($key) { $options = $this->getOptions(); return $options[$key]; } - protected function getCustomFiles() - { + /** + * Get the list of custom files. + * + * @return array + * The file list. + */ + protected function getCustomFiles() { return [ 'config/install/{{ project_name }}.settings.yml', 'config/schema/{{ project_name }}.schema.yml', @@ -233,8 +279,13 @@ class Handler ]; } - protected function getIgnoredFiles() - { + /** + * Get a list of ignored files. + * + * @return array + * The file list. + */ + protected function getIgnoredFiles() { return array_merge((empty($this->getOption('bower_assets')['dependencies']) ? ['bower.json'] : []), [ 'templates/README.md', 'README.md', @@ -243,16 +294,29 @@ class Handler ]); } - protected function getBinaryFiles() - { + /** + * Get a list of binary files. + * + * @return array + * The file list. + */ + protected function getBinaryFiles() { return [ 'favicon.ico', 'screenshot.png', ]; } + /** + * Some file name tweaks. + * + * @param string $string + * The string that needs to be tweaked. + * + * @return string + * The tweaked string. + */ protected function tweaks($string) { - $string = str_replace('THEMENAME', '{{ project_name }}', $string); $baseTheme = $this->getOption('base_theme'); @@ -265,25 +329,33 @@ class Handler return $string; } - protected function twig($string) - { + /** + * Twig process a given string and return the result. + * + * @param string $string + * The string that needs to be processed. + * + * @return string + * The processed string. + */ + protected function twig($string) { if (empty($string)) { return ''; } - $this->twig_loader->setTemplate('fixed', $this->tweaks($string)); + $this->twigLoader->setTemplate('fixed', $this->tweaks($string)); return str_replace('"', '"', $this->twig->render('fixed', $this->getOptions())); } /** * Wrapper for npm command. * - * @param $command + * @param string $command * NPM command name, arguments and/or options. + * * @throws \Exception */ - protected function npm($command) - { + protected function npm($command) { passthru(escapeshellcmd('npm ' . $command), $exit_code); if ($exit_code !== 0) { throw new \Exception('NPM returned a non-zero exit code'); @@ -293,12 +365,12 @@ class Handler /** * Wrapper for bower command. * - * @param $command + * @param string $command * Bower command name, arguments and/or options. + * * @throws \Exception */ - protected function bower($command) - { + protected function bower($command) { passthru(escapeshellcmd('bower --allow-root ' . $command), $exit_code); if ($exit_code !== 0) { throw new \Exception('Bower returned a non-zero exit code'); @@ -308,12 +380,12 @@ class Handler /** * Wrapper for gulp command. * - * @param $command + * @param string $command * Gulp command name, arguments and/or options. + * * @throws \Exception */ - protected function gulp($command) - { + protected function gulp($command) { passthru(escapeshellcmd('node_modules/.bin/gulp ' . $command), $exit_code); if ($exit_code !== 0) { throw new \Exception('Gulp returned a non-zero exit code'); @@ -321,15 +393,22 @@ class Handler } /** - * @param FileSystem $fs + * Recursively copy files from $source to $destination. + * + * @param \Symfony\Component\Filesystem\FileSystem $fs + * The file system object. * @param string $source + * The source directory. * @param string $destination + * The destination directory. + * * @return array + * List of processed file names. */ - protected function copyFiles($fs, $source, $destination) { + protected function copyFiles(FileSystem $fs, $source, $destination) { $files = []; - // Make sure all directories do exist + // Make sure all directories do exist. $finder = new Finder(); $finder->ignoreDotFiles(FALSE); $finder->directories()->in($source); @@ -345,12 +424,12 @@ class Handler $finder->files()->in($source); foreach ($finder as $file) { - // Do not copy .gitkeep files + // Do not copy .gitkeep files. if ($file->getFilename() == '.gitkeep') { continue; } - // Determine relative filename of destination + // Determine relative filename of destination. $relFilename = $file->getRelativePathname(); if ($file->getExtension() == 'twig') { $relFilename = substr($relFilename, 0, strrpos($relFilename, '.twig')); @@ -358,19 +437,20 @@ class Handler $tweakedRelFilename = $this->tweaks($relFilename); $filename = $destination . DIRECTORY_SEPARATOR . $this->twig($relFilename); - // Do not copy ignored files + // Do not copy ignored files. if (in_array($tweakedRelFilename, $this->getIgnoredFiles())) { continue; } - // Do not update custom files + // Do not update custom files. if (!$this->overwrite && $fs->exists($filename) && in_array($tweakedRelFilename, $this->getCustomFiles())) { continue; } - // Now create destination + // Now create destination. if (in_array($tweakedRelFilename, $this->getBinaryFiles())) { $fs->copy($file->getRealPath(), $filename); - } else { + } + else { file_put_contents($filename, $this->twig(file_get_contents($file->getRealPath()))); } $files[] = $tweakedRelFilename; @@ -380,10 +460,12 @@ class Handler } /** - * @param ScriptEvent $event + * Execute the theme creation or update. + * + * @param \Composer\Script\Event $event + * The event that triggered the plugin. */ - public function updateTheme($event) - { + public function updateTheme(Event $event) { $fs = new Filesystem(); $destination = $this->getInstallationPath(); @@ -391,20 +473,20 @@ class Handler $pluginRoot = $this->getInstallationManager() ->getInstallPath($this->getPackage('lakedrops/theme-d8-sass')); - // Copy all files + // Copy all files. $this->copyFiles($fs, $pluginRoot . '/templates', $destination); - // Handle optional base theme + // Handle optional base theme. $baseTheme = $this->getOption('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->options['base_theme_files'] = $this->copyFiles($fs, $starterkitRoot, $destination); } } - // Remove bower stuff if that's available globally + // Remove bower stuff if that's available globally. if (empty($this->getOption('bower_assets')['dependencies'])) { if ($fs->exists($destination . DIRECTORY_SEPARATOR . 'bower.json')) { $fs->remove($destination . DIRECTORY_SEPARATOR . 'bower.json'); @@ -414,14 +496,14 @@ class Handler } } - // Finally write .gitignore + // Finally write .gitignore. file_put_contents($destination . '/.gitignore', $this->twig(file_get_contents($pluginRoot . '/templates/.gitignore.twig'))); - // Prepare post processing + // Prepare post processing. $currentDir = getcwd(); chdir($destination); - // Handle NPM + // Handle NPM. if ($this->update) { $this->npm('update'); } @@ -429,23 +511,24 @@ class Handler $this->npm('install --no-shrinkwrap'); } - // Handle Bower if not installed globally + // Handle Bower if not installed globally. if (!empty($this->getOption('bower_assets')['dependencies']) && $fs->exists($destination . DIRECTORY_SEPARATOR . 'bower.json')) { if ($this->update) { $this->bower('update'); - } else { + } + else { $this->bower('install'); } } - // Run Gulp + // Run Gulp. $args = ['default']; if (!$event->isDevMode()) { $args[] = '--env production'; } $this->gulp(implode(' ', $args)); - // Restore current directory + // Restore current directory. chdir($currentDir); } diff --git a/src/Plugin.php b/src/Plugin.php index 66651446595da2b129c8e809c1d2b6c085cdce96..c57a4f8f678dcb9e28540cba346026c2c98f411c 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -1,8 +1,4 @@ <?php -/** - * @file - * Contains LakeDrops\Drupal8Theme\SASS\Plugin. - */ namespace LakeDrops\Drupal8Theme\SASS; @@ -10,15 +6,17 @@ use Composer\Composer; use Composer\EventDispatcher\EventSubscriberInterface; use Composer\IO\IOInterface; use Composer\Plugin\PluginInterface; +use Composer\Script\Event; use Composer\Script\ScriptEvents; /** * Composer plugin for handling drupal sass theme template. */ -class Plugin implements PluginInterface, EventSubscriberInterface -{ +class Plugin implements PluginInterface, EventSubscriberInterface { /** + * The handler object for events. + * * @var \LakeDrops\Drupal8Theme\SASS\Handler */ protected $handler; @@ -26,16 +24,14 @@ class Plugin implements PluginInterface, EventSubscriberInterface /** * {@inheritdoc} */ - public function activate(Composer $composer, IOInterface $io) - { + public function activate(Composer $composer, IOInterface $io) { $this->handler = new Handler($composer, $io); } /** * {@inheritdoc} */ - public static function getSubscribedEvents() - { + public static function getSubscribedEvents() { return array( ScriptEvents::POST_INSTALL_CMD => 'initThemeEvent', ScriptEvents::POST_UPDATE_CMD => 'updateThemeEvent', @@ -46,33 +42,39 @@ class Plugin implements PluginInterface, EventSubscriberInterface * Post package install event callback. * * @param \Composer\Script\Event $event + * The event that triggered the plugin. */ - public function initThemeEvent($event) - { - $this->handler->updateTheme($event); + public function initThemeEvent(Event $event) { + $this->updateThemeEvent($event, FALSE); } /** * Post package update event callback. * * @param \Composer\Script\Event $event + * The event that triggered the plugin. + * @param bool $update + * Whether to update (TRUE) or initially installing (FALSE). */ - public function updateThemeEvent($event) - { - $this->handler->setUpdate(TRUE); - $this->handler->updateTheme($event); + public function updateThemeEvent(Event $event, $update = TRUE) { + $this->handler + ->setUpdate($update) + ->updateTheme($event); } /** * Script callback for initializing the theme. * * @param \Composer\Script\Event $event + * The event that triggered the plugin. * @param bool $update + * Whether to update (TRUE) or initially installing (FALSE). * @param bool $reset + * Whether to reset the theme. * @param bool $overwrite + * Whether to overwrite existing files. */ - public static function init($event, $update = FALSE, $reset = FALSE, $overwrite = FALSE) - { + public static function init(Event $event, $update = FALSE, $reset = FALSE, $overwrite = FALSE) { $handler = new Handler($event->getComposer(), $event->getIO(), $update, $reset, $overwrite); $handler->updateTheme($event); } @@ -81,9 +83,9 @@ class Plugin implements PluginInterface, EventSubscriberInterface * Script callback for updating the theme. * * @param \Composer\Script\Event $event + * The event that triggered the plugin. */ - public static function update($event) - { + public static function update(Event $event) { self::init($event, TRUE); } @@ -91,19 +93,19 @@ class Plugin implements PluginInterface, EventSubscriberInterface * Script callback for resetting the theme. * * @param \Composer\Script\Event $event + * The event that triggered the plugin. */ - public static function reset($event) - { + public static function reset(Event $event) { self::init($event, FALSE, TRUE); } /** - * Script callback for updating the theme and overwriting existing custom files + * Script callback for updating the theme and overwriting existing files. * * @param \Composer\Script\Event $event + * The event that triggered the plugin. */ - public static function overwrite($event) - { + public static function overwrite(Event $event) { self::init($event, FALSE, FALSE, TRUE); } diff --git a/tests/PluginTest.php b/tests/PluginTest.php deleted file mode 100644 index cca56dfb99d6bef0b761d8715e377870428449e6..0000000000000000000000000000000000000000 --- a/tests/PluginTest.php +++ /dev/null @@ -1,230 +0,0 @@ -<?php - -/** - * @file - * Contains \LakeDrops\Drupal8Theme\SASS\Tests\PluginTest. - */ - -namespace LakeDrops\Drupal8Theme\SASS\Tests; - -use Composer\Util\Filesystem; -use Symfony\Component\Yaml\Dumper; -use Symfony\Component\Yaml\Parser; - -/** - * Tests composer plugin functionality. - */ -class PluginTest extends \PHPUnit_Framework_TestCase { - - static $name = 'theme-d8-sass'; - - /** - * @var \Composer\Util\Filesystem - */ - protected $fs; - - /** - * @var string - */ - protected $tmpDir; - - /** - * @var string - */ - protected $rootDir; - - /** - * @var string - */ - protected $tmpReleaseTag; - - /** - * SetUp test - */ - public function setUp() { - $this->rootDir = realpath(realpath(__DIR__ . '/..')); - - // Prepare temp directory. - $this->fs = new Filesystem(); - $this->tmpDir = realpath(sys_get_temp_dir()) . DIRECTORY_SEPARATOR . self::$name; - $this->ensureDirectoryExistsAndClear($this->tmpDir); - - $this->writeTestReleaseTag(); - $this->writeComposerJSON(); - - chdir($this->tmpDir); - } - - /** - * tearDown - * - * @return void - */ - public function tearDown() { - #$this->fs->removeDirectory($this->tmpDir); - $this->git(sprintf('tag -d "%s"', $this->tmpReleaseTag)); - } - - /** - * Tests a simple composer install without core, but adding core later. - */ - public function testComposerInstallAndUpdate() { - $infofile = $this->tmpDir . '/web/themes/custom/test_theme/test_theme.info.yml'; - $this->assertFileNotExists($infofile, 'Info file should not exist.'); - $this->composer('install'); - $this->assertFileExists($infofile, 'Info file should be automatically installed.'); - $this->fs->remove($infofile); - $this->assertFileNotExists($infofile, 'Info file should not exist.'); - $this->composer('update'); - $this->assertFileExists($infofile, 'Info file should be automatically installed.'); - $this->fs->remove($infofile); - $this->assertFileNotExists($infofile, 'Info file should not exist.'); - $this->composer(self::$name); - $this->assertFileExists($infofile, 'Info file should be installed by "' . self::$name . '" command.'); - - $yaml = new Parser(); - $dumper = new Dumper(); - - $info = $yaml->parse(file_get_contents($infofile)); - $this->assertArrayNotHasKey('test', $info, 'Info file should not contain a test key.'); - - $test_string = str_shuffle('abcdefghijklmnopqrstuvwxyz'); - $info['test'] = $test_string; - file_put_contents($infofile, $dumper->dump($info, 2)); - - $info = $yaml->parse(file_get_contents($infofile)); - $this->assertArrayHasKey('test', $info, 'Info file should contain a test key.'); - $this->assertEquals($test_string, $info['test']); - $this->composer(self::$name); - $info = $yaml->parse(file_get_contents($infofile)); - $this->assertArrayHasKey('test', $info, 'Info file should contain a test key.'); - $this->assertEquals($test_string, $info['test']); - } - - /** - * Writes the default composer json to the temp direcoty. - */ - protected function writeComposerJSON() { - $json = json_encode($this->composerJSONDefaults(), JSON_PRETTY_PRINT); - file_put_contents($this->tmpDir . '/composer.json', $json); - } - - /** - * Writes a tag for the current commit, so we can reference it directly in the - * composer.json. - */ - protected function writeTestReleaseTag() { - $this->tmpReleaseTag = '999.0.' . time(); - $this->git(sprintf('tag -a "%s" -m "%s"', $this->tmpReleaseTag, 'Tag for testing this exact commit')); - } - - /** - * Provides the default composer.json data. - * - * @return array - */ - protected function composerJSONDefaults() { - return array( - 'repositories' => array( - array( - 'type' => 'vcs', - 'url' => $this->rootDir, - ), - array( - 'type' => 'composer', - 'url' => 'https://packages.drupal.org/8', - ), - array( - 'type' => 'composer', - 'url' => 'https://asset-packagist.org', - ), - ), - 'require' => array( - 'lakedrops/' . self::$name => $this->tmpReleaseTag, - 'composer/installers' => '~1.2.0', - 'drupal/bootstrap' => '3.2.0', - 'bower-asset/bootstrap-sass' => '~3.3.7', - 'bower-asset/flat-ui-sass' => '~2.1.3', - ), - 'scripts' => array( - self::$name => 'LakeDrops\\Drupal8Theme\\SASS\\Plugin::update', - ), - 'minimum-stability' => 'dev', - 'extra' => array( - 'installer-paths' => array( - 'web/themes/custom/{$name}' => array( - 'type:drupal-custom-theme', - ), - 'web/themes/contrib/{$name}' => array( - 'type:drupal-theme', - ), - ), - self::$name => array( - 'project_name' => 'test_theme', - 'base_theme' => array( - 'name' => 'bootstrap', - 'package' => 'drupal/bootstrap', - 'starterkit' => 'starterkits/sass', - 'sasspath'=> 'scss', - 'import'=> array('overrides', ), - ), - 'bower_assets' => array( - 'bootstrap-sass' => array( - 'name' => 'bootstrap', - 'fonts' => array( - 'src' => 'assets/fonts/bootstrap', - ), - 'sass' => array( - 'src' => 'assets/stylesheets', - 'import' => array('bootstrap', ), - ), - ), - ), - ), - ), - ); - } - - /** - * Wrapper for the composer command. - * - * @param string $command - * Composer command name, arguments and/or options - * @throws \Exception - */ - protected function composer($command) { - chdir($this->tmpDir); - passthru(escapeshellcmd($this->rootDir . '/vendor/bin/composer ' . $command), $exit_code); - if ($exit_code !== 0) { - throw new \Exception('Composer returned a non-zero exit code'); - } - } - - /** - * Wrapper for git command in the root directory. - * - * @param $command - * Git command name, arguments and/or options. - * @throws \Exception - */ - protected function git($command) { - chdir($this->rootDir); - passthru(escapeshellcmd('git -c "user.email=phpunit@test.com" ' . $command), $exit_code); - if ($exit_code !== 0) { - throw new \Exception('Git returned a non-zero exit code'); - } - } - - /** - * Makes sure the given directory exists and has no content. - * - * @param string $directory - */ - protected function ensureDirectoryExistsAndClear($directory) { - if (is_dir($directory)) { - $this->fs->removeDirectory($directory); - } - mkdir($directory, 0777, TRUE); - } - -}