From ee37acd7c0314348ced560a871e314a90bacf19c Mon Sep 17 00:00:00 2001 From: Bec White Date: Tue, 25 Sep 2018 16:12:32 -0500 Subject: [PATCH 01/29] Add an ExpandPrefixedProperties filter class. --- src/TheBuild/ExpandPrefixedProperties.php | 115 ++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/TheBuild/ExpandPrefixedProperties.php diff --git a/src/TheBuild/ExpandPrefixedProperties.php b/src/TheBuild/ExpandPrefixedProperties.php new file mode 100644 index 00000000..b8a32136 --- /dev/null +++ b/src/TheBuild/ExpandPrefixedProperties.php @@ -0,0 +1,115 @@ + + * + * + * + * + * + * + * + * + * + * ${out} + * + * + * @copyright 2018 Palantir.net, Inc. + */ + +namespace TheBuild; + +require_once 'phing/parser/ProjectConfigurator.php'; + +use ExpandProperties; +use ProjectConfigurator; +use Parameterizable; +use ConfigurationException; + +class ExpandPrefixedProperties extends ExpandProperties implements Parameterizable { + + /** + * @var string + * The prefix to look for. + */ + protected $prefix = ""; + + /** + * @param $prefix + */ + public function setPrefix($prefix) { + $this->prefix = $prefix; + } + + /** + * @param null $len + * @return int|mixed|string + */ + public function read($len = null) { + $buffer = $this->in->read($len); + + if ($buffer === -1) { + return -1; + } + + $project = $this->getProject(); + + $properties = []; + foreach ($project->getProperties() as $name => $value) { + if (strpos($name, $this->prefix) === 0) { + $newprop = substr($name, strlen($this->prefix)); + $properties[$newprop] = $value; + } + } + + $buffer = ProjectConfigurator::replaceProperties($project, $buffer, $properties, $this->logLevel); + + return $buffer; + } + + /** + * @param $parameters + * @return mixed|void + * @throws ConfigurationException + */ + public function setParameters($parameters) { + /** @var \Parameter $param */ + foreach ($parameters as $param) { + $name = $param->getName(); + $method = 'set' . ucfirst($name); + if (method_exists($this, $method) && $method != 'setParameters') { + $this->$method($param->getValue()); + } + } + + $this->validate(); + } + + /** + * @throws ConfigurationException + */ + protected function validate() { + if (empty($this->prefix)) { + throw new ConfigurationException('TheBuild\ExpandPrefixedProperties filter is missing a value for the required "prefix" parameter.'); + } + } + +} From 613cf8681427a19859105ea1a3300b5514c553bc Mon Sep 17 00:00:00 2001 From: Bec White Date: Fri, 5 Oct 2018 16:54:01 -0500 Subject: [PATCH 02/29] Move Drupal site-specific properties into a nested property structure. --- defaults.properties.yml | 75 ++++++++++--------- .../the-build/build.acquia.properties.yml | 4 + .../the-build/build.circleci.properties.yml | 12 +-- .../the-build/build.default.properties.yml | 19 +++-- .../the-build/build.pantheon.properties.yml | 4 + .../the-build/build.platformsh.properties.yml | 4 + 6 files changed, 69 insertions(+), 49 deletions(-) diff --git a/defaults.properties.yml b/defaults.properties.yml index 6f2be30f..f4a35984 100644 --- a/defaults.properties.yml +++ b/defaults.properties.yml @@ -16,45 +16,9 @@ drupal: # configuration in your `composer.json`. Use caution when changing this value. root: web - # Human-readable name for your site. - site_name: "${projectname}" - - # Your site's URI; the default should be the URI of your local development environment. - uri: "https://${projectname}.local" - - # Salt for Drupal's password hashing. A unique salt is generated when you install - # `the-build`. - hash_salt: temporary - - # Drupal install profile to use for the drupal-install target. - profile: config_installer - - # Name of the sites subdirectory where the `settings.php` file should live. - sites_subdir: default - - # Path to the Drupal config directory, relative to the Drupal root. - config_sync_directory: "../config/sites/${drupal.sites_subdir}" - - # Drupal admin username, if you feel inclined to change it. - admin_user: admin - # Comma-separated list of directories that should be present for Drupal development. create_dirs: "${drupal.root}/modules/custom,${drupal.root}/themes/custom,${drupal.root}/profiles/custom" - # Database connection for Drupal. - database: - database: drupal - username: root - password: root - host: 127.0.0.1 - - settings: - # Path to the Drupal public files directory, relative to the Drupal root. - file_public_path: sites/default/files - - # Path to the Drupal private files directory, relative to the Drupal root. - file_private_path: "../artifacts/private/${drupal.sites_subdir}" - twig: # Whether to enable twig debugging. debug: false @@ -65,6 +29,45 @@ drupal: # Use 'true' or 'yes' to bypass. bypass: false + sites: + default: + # Name of the sites subdirectory where the `settings.php` file should live. + sites_subdir: default + + # Human-readable name for your site. + site_name: "${projectname}" + + # Your site's URI; the default should be the URI of your local development environment. + uri: "https://${projectname}.local" + + # Salt for Drupal's password hashing. A unique salt is generated when you install + # `the-build`. + hash_salt: temporary + + # Drupal install profile to use for the drupal-install target. + profile: config_installer + + # Path to the Drupal config directory, relative to the Drupal root. + config_sync_directory: "../config/sites/${drupal.sites_subdir}" + + # Drupal admin username, if you feel inclined to change it. + admin_user: admin + + # Database connection for Drupal. + database: + database: drupal + username: root + password: root + host: 127.0.0.1 + + settings: + # Path to the Drupal public files directory, relative to the Drupal root. + file_public_path: sites/default/files + + # Path to the Drupal private files directory, relative to the Drupal root. + file_private_path: "../artifacts/private/${drupal.sites_subdir}" + + # Configuration for the database loading utility. load_db: # Pattern to match gzipped database dump files. diff --git a/defaults/templates/the-build/build.acquia.properties.yml b/defaults/templates/the-build/build.acquia.properties.yml index 88288fa2..3847b71d 100644 --- a/defaults/templates/the-build/build.acquia.properties.yml +++ b/defaults/templates/the-build/build.acquia.properties.yml @@ -4,3 +4,7 @@ build: drupal: settings: .the-build/drupal.settings.build-acquia.php services_dest: artifacts/dev/null + +drupal: + twig: + debug: false diff --git a/defaults/templates/the-build/build.circleci.properties.yml b/defaults/templates/the-build/build.circleci.properties.yml index 7ba21815..42849fb4 100644 --- a/defaults/templates/the-build/build.circleci.properties.yml +++ b/defaults/templates/the-build/build.circleci.properties.yml @@ -1,13 +1,15 @@ # @file # Configuration properties specific to the CircleCI environment. drupal: - database: - database: circle_test - username: root - password: "" - host: 127.0.0.1 twig: debug: false + sites: + default: + database: + database: circle_test + username: root + password: "" + host: 127.0.0.1 behat: args: "--profile=circle --suite=default --strict --format=junit --out=/tmp/artifacts --tags=~@skipci" diff --git a/defaults/templates/the-build/build.default.properties.yml b/defaults/templates/the-build/build.default.properties.yml index 6aa5b36a..2f8ae172 100644 --- a/defaults/templates/the-build/build.default.properties.yml +++ b/defaults/templates/the-build/build.default.properties.yml @@ -11,18 +11,21 @@ # @see .the-build/drupal.settings.php drupal: root: "${drupal.root}" - hash_salt: "${drupal.hash_salt}" - profile: "${drupal.profile}" - - database: - database: "${drupal.database.database}" - username: "${drupal.database.username}" - password: "${drupal.database.password}" - host: "${drupal.database.host}" twig: debug: true + sites: + default: + hash_salt: "${drupal.hash_salt}" + profile: "${drupal.profile}" + + database: + database: "${drupal.database.database}" + username: "${drupal.database.username}" + password: "${drupal.database.password}" + host: "${drupal.database.host}" + # Putting these flags in configuration allows you to vary the behat configuration per # environment. Sometimes, there are tests that are appropriate to skip on CI. Compare # these values to the defaults in build.circleci.properties.yml. diff --git a/defaults/templates/the-build/build.pantheon.properties.yml b/defaults/templates/the-build/build.pantheon.properties.yml index 9eeae5b4..19ba2244 100644 --- a/defaults/templates/the-build/build.pantheon.properties.yml +++ b/defaults/templates/the-build/build.pantheon.properties.yml @@ -4,3 +4,7 @@ build: drupal: settings: .the-build/drupal.settings.build-pantheon.php services_dest: artifacts/dev/null + +drupal: + twig: + debug: false diff --git a/defaults/templates/the-build/build.platformsh.properties.yml b/defaults/templates/the-build/build.platformsh.properties.yml index 8c680d84..efc25d06 100644 --- a/defaults/templates/the-build/build.platformsh.properties.yml +++ b/defaults/templates/the-build/build.platformsh.properties.yml @@ -4,3 +4,7 @@ build: drupal: settings: .the-build/drupal.settings.build-platformsh.php services_dest: artifacts/dev/null + +drupal: + twig: + debug: false From bec30f238e860617758dadf80de392a03c26d302 Mon Sep 17 00:00:00 2001 From: Bec White Date: Fri, 5 Oct 2018 16:54:13 -0500 Subject: [PATCH 03/29] Add a Phing task class to copy properties from one property name prefix to another. --- src/TheBuild/CopyPropertiesTask.php | 113 ++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/TheBuild/CopyPropertiesTask.php diff --git a/src/TheBuild/CopyPropertiesTask.php b/src/TheBuild/CopyPropertiesTask.php new file mode 100644 index 00000000..c36110e9 --- /dev/null +++ b/src/TheBuild/CopyPropertiesTask.php @@ -0,0 +1,113 @@ + + * @endcode + * + * @copyright 2018 Palantir.net, Inc. + */ + +namespace TheBuild; + +use BuildException; + + +class CopyPropertiesTask extends \Task { + + /** + * @var string + * Prefix for properties to copy. + */ + protected $fromPrefix = ''; + + /** + * @var string + * Prefix for properties to create/update. + */ + protected $toPrefix = ''; + + /** + * @var bool + * Whether to overwrite the existing properties. + */ + protected $override = true; + + /** + * @var string + */ + protected $propertyMethod = 'setProperty'; + + + /** + * Use either Project::setProperty() or Project::setNewProperty() based on + * whether we're overriding values or not. + */ + public function init() { + parent::init(); + $this->propertyMethod = $this->override ? 'setProperty' : 'setNewProperty'; + } + + /** + * Copy properties. + */ + public function main() { + $this->validate(); + + $project = $this->getProject(); + foreach ($project->getProperties() as $name => $value) { + if (strpos($name, $this->fromPrefix) === 0) { + $new_name = $this->toPrefix . substr($name, strlen($this->fromPrefix)); + $project->{$this->propertyMethod}($new_name, $value); + } + } + } + + + /** + * Verify that the required attributes are set. + */ + public function validate() { + if (empty($this->fromPrefix)) { + throw new BuildException("fromPrefix attribute is required.", $this->location); + } + + if (empty($this->toPrefix)) { + throw new BuildException("toPrefix attribute is required.", $this->location); + } + } + + + /** + * @param string $prefix + */ + public function setFromPrefix($prefix) { + if (!StringHelper::endsWith(".", $prefix)) { + $prefix .= "."; + } + + $this->fromPrefix = $prefix; + } + + /** + * @param string $prefix + */ + public function setToPrefix($prefix) { + if (!StringHelper::endsWith(".", $prefix)) { + $prefix .= "."; + } + + $this->toPrefix = $prefix; + } + + /** + * @param bool $override + */ + public function setOverride($override) { + $this->override = $override; + } + +} From 0b4b07df51b75c5d834d0c08bbdad33626aff5f7 Mon Sep 17 00:00:00 2001 From: Bec White Date: Fri, 5 Oct 2018 17:58:06 -0500 Subject: [PATCH 04/29] Add a Phing task to iterate over property values. --- src/TheBuild/ForeachKeyTask.php | 139 ++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/TheBuild/ForeachKeyTask.php diff --git a/src/TheBuild/ForeachKeyTask.php b/src/TheBuild/ForeachKeyTask.php new file mode 100644 index 00000000..ada8178a --- /dev/null +++ b/src/TheBuild/ForeachKeyTask.php @@ -0,0 +1,139 @@ + + * @endcode + * + * @copyright 2018 Palantir.net, Inc. + */ + +namespace TheBuild; + +use BuildException; + + +class ForeachKeyTask extends \Task { + + /** + * @var string + * Prefix of properties to iterate over. + */ + protected $prefix = ''; + + /** + * @var string + * Name of target to execute. + */ + protected $target = ''; + + /** + * @var string + * Name of parameter to use for the key. + */ + protected $keyParam = ''; + + /** + * @var string + * Name of parameter to use for the prefix. + */ + protected $prefixParam = ''; + + /** + * @var \PhingCallTask + */ + protected $callee; + + /** + * + */ + public function init() { + parent::init(); + + $this->callee = $this->project->createTask("phingcall"); + $this->callee->setOwningTarget($this->getOwningTarget()); + $this->callee->setTaskName($this->getTaskName()); + $this->callee->setLocation($this->getLocation()); + $this->callee->init(); + } + + /** + * Copy properties. + */ + public function main() { + $this->validate(); + + $this->callee->setTarget($this->target); + $this->callee->setInheritAll(true); + $this->callee->setInheritRefs(true); + + $project = $this->getProject(); + foreach ($project->getProperties() as $name => $value) { + if (strpos($name, $this->prefix) === 0) { + $property_children = substr($name, strlen($this->fromPrefix)); + list($key, $property_grandchildren) = explode('.', $property_children, 2); + + $prop = $this->callee->createProperty(); + $prop->setOverride(true); + $prop->setName($this->keyParam); + $prop->setValue($key); + + $prop = $this->callee->createProperty(); + $prop->setOverride(true); + $prop->setName($this->prefixParam); + $prop->setValue($this->prefix); + + $this->callee->main(); + } + } + } + + + /** + * Verify that the required attributes are set. + */ + public function validate() { + foreach (['prefix', 'target', 'keyParam', 'prefixParam'] as $attribute) { + if (empty($this->$attribute)) { + throw new BuildException("$attribute attribute is required.", $this->location); + } + } + } + + + /** + * @param string $value + */ + public function setPrefix($value) { + if (!StringHelper::endsWith(".", $value)) { + $value .= "."; + } + + $this->prefix = $value; + } + + /** + * @param string $value + */ + public function setTarget($value) { + $this->target = $value; + } + + /** + * @param string $value + */ + public function setKeyParam($value) { + $this->keyParam = $value; + } + + /** + * @param string $value + */ + public function setPrefixParam($value) { + $this->prefixParam = $value; + } + +} From 6f4c6267e4635ef88f1191026087700a66f576b9 Mon Sep 17 00:00:00 2001 From: Bec White Date: Mon, 8 Oct 2018 19:25:26 -0500 Subject: [PATCH 05/29] Fix missing classes, typos, logic errors in CopyPropertiesTask and ForeachKeyTask classes. --- src/TheBuild/CopyPropertiesTask.php | 1 + src/TheBuild/ForeachKeyTask.php | 29 ++++++++++++++++++----------- tasks/the-build.xml | 5 +++++ 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/TheBuild/CopyPropertiesTask.php b/src/TheBuild/CopyPropertiesTask.php index c36110e9..9bbe84ee 100644 --- a/src/TheBuild/CopyPropertiesTask.php +++ b/src/TheBuild/CopyPropertiesTask.php @@ -14,6 +14,7 @@ namespace TheBuild; use BuildException; +use StringHelper; class CopyPropertiesTask extends \Task { diff --git a/src/TheBuild/ForeachKeyTask.php b/src/TheBuild/ForeachKeyTask.php index ada8178a..0b8e31b0 100644 --- a/src/TheBuild/ForeachKeyTask.php +++ b/src/TheBuild/ForeachKeyTask.php @@ -14,6 +14,7 @@ namespace TheBuild; use BuildException; +use StringHelper; class ForeachKeyTask extends \Task { @@ -70,24 +71,30 @@ public function main() { $this->callee->setInheritAll(true); $this->callee->setInheritRefs(true); + // Extract matching keys from the properties array. + $keys = []; $project = $this->getProject(); foreach ($project->getProperties() as $name => $value) { if (strpos($name, $this->prefix) === 0) { - $property_children = substr($name, strlen($this->fromPrefix)); + $property_children = substr($name, strlen($this->prefix)); list($key, $property_grandchildren) = explode('.', $property_children, 2); + $keys[$key] = $this->prefix; + } + } - $prop = $this->callee->createProperty(); - $prop->setOverride(true); - $prop->setName($this->keyParam); - $prop->setValue($key); + // Iterate over each extracted key. + foreach ($keys as $key => $prefix) { + $prop = $this->callee->createProperty(); + $prop->setOverride(true); + $prop->setName($this->keyParam); + $prop->setValue($key); - $prop = $this->callee->createProperty(); - $prop->setOverride(true); - $prop->setName($this->prefixParam); - $prop->setValue($this->prefix); + $prop = $this->callee->createProperty(); + $prop->setOverride(true); + $prop->setName($this->prefixParam); + $prop->setValue($prefix); - $this->callee->main(); - } + $this->callee->main(); } } diff --git a/tasks/the-build.xml b/tasks/the-build.xml index 37117244..5a5c966a 100644 --- a/tasks/the-build.xml +++ b/tasks/the-build.xml @@ -15,6 +15,11 @@ + + + + + From 5617c940dc296bc3645bef6d3ff9fb3bcc94a1ad Mon Sep 17 00:00:00 2001 From: Bec White Date: Tue, 9 Oct 2018 18:28:14 -0500 Subject: [PATCH 06/29] Set drupal.site.* = drupal.sites.default.* at startup, temporarily; rename usages of drupal.* properties to drupal.site.*. --- defaults.properties.yml | 8 ++-- defaults/templates/artifact.README.md | 2 +- .../drupal.settings.build-acquia.php | 4 +- .../drupal.settings.build-pantheon.php | 2 +- defaults/templates/drupal.settings.build.php | 16 +++---- defaults/templates/drushrc.php | 1 - .../the-build/build.default.properties.yml | 12 ++--- defaults/templates/the-build/build.xml | 18 +++---- tasks/drupal.xml | 48 +++++++++---------- tasks/install.xml | 4 +- tasks/the-build.xml | 5 +- 11 files changed, 61 insertions(+), 59 deletions(-) diff --git a/defaults.properties.yml b/defaults.properties.yml index f4a35984..d2f4cff3 100644 --- a/defaults.properties.yml +++ b/defaults.properties.yml @@ -48,7 +48,7 @@ drupal: profile: config_installer # Path to the Drupal config directory, relative to the Drupal root. - config_sync_directory: "../config/sites/${drupal.sites_subdir}" + config_sync_directory: "../config/sites/${drupal.site.sites_subdir}" # Drupal admin username, if you feel inclined to change it. admin_user: admin @@ -65,7 +65,7 @@ drupal: file_public_path: sites/default/files # Path to the Drupal private files directory, relative to the Drupal root. - file_private_path: "../artifacts/private/${drupal.sites_subdir}" + file_private_path: "../artifacts/private/${drupal.site.sites_subdir}" # Configuration for the database loading utility. @@ -96,14 +96,14 @@ build: settings: .the-build/drupal.settings.build.php # Destination for the templated settings.php file. - settings_dest: "${drupal.root}/sites/${drupal.sites_subdir}/settings.build.php" + settings_dest: "${drupal.root}/sites/${drupal.site.sites_subdir}/settings.build.php" # Source template for Drupal's `services.yml` file. This may vary per build # environment. services: .the-build/drupal.services.build.yml # Destination for the templated `services.yml` file. - services_dest: "${drupal.root}/sites/${drupal.sites_subdir}/services.build.yml" + services_dest: "${drupal.root}/sites/${drupal.site.sites_subdir}/services.build.yml" # Configuration for tasks/artifact.xml diff --git a/defaults/templates/artifact.README.md b/defaults/templates/artifact.README.md index b145fcf4..cdf7ba14 100644 --- a/defaults/templates/artifact.README.md +++ b/defaults/templates/artifact.README.md @@ -1,4 +1,4 @@ -# ${drupal.site_name} - Artifact Repository +# ${projectname} - Artifact Repository This repository contains all of the code and configuration required to run this site. It is intended for deployment to a host like Acquia or Pantheon. diff --git a/defaults/templates/drupal.settings.build-acquia.php b/defaults/templates/drupal.settings.build-acquia.php index 85896f1e..ab95dcbf 100644 --- a/defaults/templates/drupal.settings.build-acquia.php +++ b/defaults/templates/drupal.settings.build-acquia.php @@ -8,12 +8,12 @@ $settings['trusted_host_patterns'][] = "^{$_ENV['AH_SITE_ENVIRONMENT']}dev.prod.acquia-sites.com"; $settings['trusted_host_patterns'][] = "^{$_ENV['AH_SITE_ENVIRONMENT']}stg.prod.acquia-sites.com"; -$settings['file_public_path'] = '${drupal.settings.file_public_path}'; +$settings['file_public_path'] = '${drupal.site.settings.file_public_path}'; $settings['file_private_path'] = "/mnt/gfs/{$_ENV['AH_SITE_GROUP']}.{$_ENV['AH_SITE_ENVIRONMENT']}/files-private"; $config['system.file']['path']['temporary'] = $_ENV['TEMP']; $config_directories = []; -$config_directories[CONFIG_SYNC_DIRECTORY] = '${drupal.config_sync_directory}'; +$config_directories[CONFIG_SYNC_DIRECTORY] = '${drupal.site.config_sync_directory}'; //// Add an htaccess prompt on dev and staging environments. diff --git a/defaults/templates/drupal.settings.build-pantheon.php b/defaults/templates/drupal.settings.build-pantheon.php index df94dc69..16590551 100644 --- a/defaults/templates/drupal.settings.build-pantheon.php +++ b/defaults/templates/drupal.settings.build-pantheon.php @@ -6,4 +6,4 @@ */ $config_directories = []; -$config_directories[CONFIG_SYNC_DIRECTORY] = '${drupal.config_sync_directory}'; +$config_directories[CONFIG_SYNC_DIRECTORY] = '${drupal.site.config_sync_directory}'; diff --git a/defaults/templates/drupal.settings.build.php b/defaults/templates/drupal.settings.build.php index 6f66499d..05be2793 100644 --- a/defaults/templates/drupal.settings.build.php +++ b/defaults/templates/drupal.settings.build.php @@ -6,22 +6,22 @@ $databases['default']['default'] = array( 'driver' => 'mysql', - 'database' => '${drupal.database.database}', - 'username' => '${drupal.database.username}', - 'password' => '${drupal.database.password}', - 'host' => '${drupal.database.host}', + 'database' => '${drupal.site.database.database}', + 'username' => '${drupal.site.database.username}', + 'password' => '${drupal.site.database.password}', + 'host' => '${drupal.site.database.host}', 'prefix' => '', 'collation' => 'utf8mb4_general_ci', ); $config_directories = array(); -$config_directories[CONFIG_SYNC_DIRECTORY] = '${drupal.config_sync_directory}'; +$config_directories[CONFIG_SYNC_DIRECTORY] = '${drupal.site.config_sync_directory}'; -$settings['hash_salt'] = '${drupal.hash_salt}'; +$settings['hash_salt'] = '${drupal.site.hash_salt}'; $settings['container_yamls'][] = __DIR__ . '/services.build.yml'; -$settings['file_public_path'] = '${drupal.settings.file_public_path}'; -$settings['file_private_path'] = '${drupal.settings.file_private_path}'; +$settings['file_public_path'] = '${drupal.site.settings.file_public_path}'; +$settings['file_private_path'] = '${drupal.site.settings.file_private_path}'; // Disable CSS and JS aggregation. $config['system.performance']['css']['preprocess'] = FALSE; diff --git a/defaults/templates/drushrc.php b/defaults/templates/drushrc.php index 2f51fab3..642cf389 100644 --- a/defaults/templates/drushrc.php +++ b/defaults/templates/drushrc.php @@ -12,7 +12,6 @@ # Configure Drush for the current project. $options['root'] = "{$repo}/${drupal.root}"; - $options['uri'] = "${drupal.uri}"; } /** diff --git a/defaults/templates/the-build/build.default.properties.yml b/defaults/templates/the-build/build.default.properties.yml index 2f8ae172..fbe9767f 100644 --- a/defaults/templates/the-build/build.default.properties.yml +++ b/defaults/templates/the-build/build.default.properties.yml @@ -17,14 +17,14 @@ drupal: sites: default: - hash_salt: "${drupal.hash_salt}" - profile: "${drupal.profile}" + hash_salt: "${drupal.site.hash_salt}" + profile: "${drupal.site.profile}" database: - database: "${drupal.database.database}" - username: "${drupal.database.username}" - password: "${drupal.database.password}" - host: "${drupal.database.host}" + database: "${drupal.site.database.database}" + username: "${drupal.site.database.username}" + password: "${drupal.site.database.password}" + host: "${drupal.site.database.host}" # Putting these flags in configuration allows you to vary the behat configuration per # environment. Sometimes, there are tests that are appropriate to skip on CI. Compare diff --git a/defaults/templates/the-build/build.xml b/defaults/templates/the-build/build.xml index 0ebffe5a..4db4b19a 100644 --- a/defaults/templates/the-build/build.xml +++ b/defaults/templates/the-build/build.xml @@ -31,16 +31,16 @@ - - + + - - + + - - + + @@ -68,10 +68,10 @@ --> - - + + - ${drupal.profile} + ${drupal.site.profile} diff --git a/tasks/drupal.xml b/tasks/drupal.xml index cabbaee5..94ef1849 100644 --- a/tasks/drupal.xml +++ b/tasks/drupal.xml @@ -29,7 +29,7 @@ --> - + @@ -88,13 +88,13 @@ ${modified_files} - Structure only for cache, search, and log tables --> - + @@ -121,7 +121,7 @@ ${modified_files} @@ -134,44 +134,44 @@ ${modified_files} - - - + + + - + - - - - + + + + - + - Missing database export at '${drupal.load_db.export_pattern}' + Missing database export at '${drupal.site.load_db.export_pattern}' Please download a database export to: - ${drupal.load_db.export_pattern} + ${drupal.site.load_db.export_pattern} Alternatively, you can specify the export file prefix; for example: - phing [YOUR-TARGET] -Ddrupal.load_db.export_pattern=artifacts/prod-* + phing [YOUR-TARGET] -Ddrupal.site.load_db.export_pattern=artifacts/prod-* Or, you can specify the export file directly: - phing [YOUR-TARGET] -Ddrupal.load_db.file=artifacts/my_db.sql.gz + phing [YOUR-TARGET] -Ddrupal.site.load_db.file=artifacts/my_db.sql.gz - - $> ${drupal.load_db.command} - + + $> ${drupal.site.load_db.command} + @@ -202,7 +202,7 @@ Or, you can specify the export file directly: - + No exported Drupal config available to install from. @@ -235,11 +235,11 @@ Or, you can specify the export file directly: on that target. --> - + - + standard @@ -301,7 +301,7 @@ Or, you can specify the export file directly: - Disabled user-configurable timezones - Replaced the standard profile with config_installer - Your config has been exported to ${drupal.root}/${drupal.config_sync_directory} + Your config has been exported to ${drupal.root}/${drupal.site.config_sync_directory} diff --git a/tasks/install.xml b/tasks/install.xml index bfebc3dd..c6f98648 100644 --- a/tasks/install.xml +++ b/tasks/install.xml @@ -29,10 +29,10 @@ - + - + diff --git a/tasks/the-build.xml b/tasks/the-build.xml index 5a5c966a..e9e8001d 100644 --- a/tasks/the-build.xml +++ b/tasks/the-build.xml @@ -69,11 +69,14 @@ + + + - + From 1e629ec7540200fd18c3d52d72aa88a7c169c375 Mon Sep 17 00:00:00 2001 From: Bec White Date: Tue, 9 Oct 2018 18:55:16 -0500 Subject: [PATCH 07/29] Update settings and services templates to be site-specific. --- defaults.properties.yml | 38 +++++++++---------- .../the-build/build.acquia.properties.yml | 10 ++--- .../the-build/build.default.properties.yml | 12 +++--- .../the-build/build.pantheon.properties.yml | 10 ++--- .../the-build/build.platformsh.properties.yml | 10 ++--- defaults/templates/the-build/build.xml | 6 +-- 6 files changed, 42 insertions(+), 44 deletions(-) diff --git a/defaults.properties.yml b/defaults.properties.yml index d2f4cff3..f7de20dd 100644 --- a/defaults.properties.yml +++ b/defaults.properties.yml @@ -48,7 +48,7 @@ drupal: profile: config_installer # Path to the Drupal config directory, relative to the Drupal root. - config_sync_directory: "../config/sites/${drupal.site.sites_subdir}" + config_sync_directory: "../config/sites/default" # Drupal admin username, if you feel inclined to change it. admin_user: admin @@ -65,7 +65,23 @@ drupal: file_public_path: sites/default/files # Path to the Drupal private files directory, relative to the Drupal root. - file_private_path: "../artifacts/private/${drupal.site.sites_subdir}" + file_private_path: "../artifacts/private/default" + + # Configuration used by the default 'build' target. + build: + # Source template for Drupal's `settings.php` file. This may vary per build + # environment. + settings_template: .the-build/drupal.settings.build.php + + # Destination for the templated settings.php file. + settings_dest: ${drupal.root}/sites/default/settings.build.php + + # Source template for Drupal's `services.yml` file. This may vary per build + # environment. + services_template: .the-build/drupal.services.build.yml + + # Destination for the templated `services.yml` file. + services_dest: ${drupal.root}/sites/default/services.build.yml # Configuration for the database loading utility. @@ -88,24 +104,6 @@ drupal: #file: -# Build configuration used by tasks/drupal.xml -build: - drupal: - # Source template for Drupal's `settings.php` file. This may vary per build - # environment. - settings: .the-build/drupal.settings.build.php - - # Destination for the templated settings.php file. - settings_dest: "${drupal.root}/sites/${drupal.site.sites_subdir}/settings.build.php" - - # Source template for Drupal's `services.yml` file. This may vary per build - # environment. - services: .the-build/drupal.services.build.yml - - # Destination for the templated `services.yml` file. - services_dest: "${drupal.root}/sites/${drupal.site.sites_subdir}/services.build.yml" - - # Configuration for tasks/artifact.xml artifact: # The path of the working directory where the artifact should be built. diff --git a/defaults/templates/the-build/build.acquia.properties.yml b/defaults/templates/the-build/build.acquia.properties.yml index 3847b71d..6b99c39e 100644 --- a/defaults/templates/the-build/build.acquia.properties.yml +++ b/defaults/templates/the-build/build.acquia.properties.yml @@ -1,10 +1,10 @@ # @file # Configuration properties specific to the Acquia deployment. -build: - drupal: - settings: .the-build/drupal.settings.build-acquia.php - services_dest: artifacts/dev/null - drupal: twig: debug: false + sites: + default: + build: + settings: .the-build/drupal.settings.build-acquia.php + services_dest: artifacts/dev/null diff --git a/defaults/templates/the-build/build.default.properties.yml b/defaults/templates/the-build/build.default.properties.yml index fbe9767f..b1febfc2 100644 --- a/defaults/templates/the-build/build.default.properties.yml +++ b/defaults/templates/the-build/build.default.properties.yml @@ -17,14 +17,14 @@ drupal: sites: default: - hash_salt: "${drupal.site.hash_salt}" - profile: "${drupal.site.profile}" + hash_salt: "${drupal.sites.default.hash_salt}" + profile: "${drupal.sites.default.profile}" database: - database: "${drupal.site.database.database}" - username: "${drupal.site.database.username}" - password: "${drupal.site.database.password}" - host: "${drupal.site.database.host}" + database: "${drupal.sites.default.database.database}" + username: "${drupal.sites.default.database.username}" + password: "${drupal.site.default.database.password}" + host: "${drupal.sites.default.database.host}" # Putting these flags in configuration allows you to vary the behat configuration per # environment. Sometimes, there are tests that are appropriate to skip on CI. Compare diff --git a/defaults/templates/the-build/build.pantheon.properties.yml b/defaults/templates/the-build/build.pantheon.properties.yml index 19ba2244..6adcd1c8 100644 --- a/defaults/templates/the-build/build.pantheon.properties.yml +++ b/defaults/templates/the-build/build.pantheon.properties.yml @@ -1,10 +1,10 @@ # @file # Configuration properties specific to the Pantheon deployment. -build: - drupal: - settings: .the-build/drupal.settings.build-pantheon.php - services_dest: artifacts/dev/null - drupal: twig: debug: false + sites: + default: + build: + settings_template: .the-build/drupal.settings.build-pantheon.php + services_dest: artifacts/dev/null diff --git a/defaults/templates/the-build/build.platformsh.properties.yml b/defaults/templates/the-build/build.platformsh.properties.yml index efc25d06..a60e685b 100644 --- a/defaults/templates/the-build/build.platformsh.properties.yml +++ b/defaults/templates/the-build/build.platformsh.properties.yml @@ -1,10 +1,10 @@ # @file # Configuration properties specific to the Platform.sh deployment. -build: - drupal: - settings: .the-build/drupal.settings.build-platformsh.php - services_dest: artifacts/dev/null - drupal: twig: debug: false + sites: + default: + build: + settings_template: .the-build/drupal.settings.build-platformsh.php + services_dest: artifacts/dev/null diff --git a/defaults/templates/the-build/build.xml b/defaults/templates/the-build/build.xml index 4db4b19a..e13b2771 100644 --- a/defaults/templates/the-build/build.xml +++ b/defaults/templates/the-build/build.xml @@ -45,11 +45,11 @@ - + - - + + From 4461affb637854caab7d3e7b7c1d96e60f78304c Mon Sep 17 00:00:00 2001 From: Bec White Date: Tue, 9 Oct 2018 19:10:38 -0500 Subject: [PATCH 08/29] Add @todo comments for next steps. --- .../the-build/build.default.properties.yml | 11 +++++++++++ tasks/artifact.xml | 2 ++ tasks/drupal.xml | 4 +++- tasks/the-build.xml | 14 ++++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/defaults/templates/the-build/build.default.properties.yml b/defaults/templates/the-build/build.default.properties.yml index b1febfc2..94149f61 100644 --- a/defaults/templates/the-build/build.default.properties.yml +++ b/defaults/templates/the-build/build.default.properties.yml @@ -26,6 +26,17 @@ drupal: password: "${drupal.site.default.database.password}" host: "${drupal.sites.default.database.host}" + # Add more multisites here. + #second: + # uri: "http://second.local" + # hash_salt: "temporary" + # profile: "config_installer" + # database: + # database: "second" + # username: "drupal" + # password: "drupal" + # host: "${drupal.sites.default.database.host}" + # Putting these flags in configuration allows you to vary the behat configuration per # environment. Sometimes, there are tests that are appropriate to skip on CI. Compare # these values to the defaults in build.circleci.properties.yml. diff --git a/tasks/artifact.xml b/tasks/artifact.xml index 268d10dc..27625c50 100644 --- a/tasks/artifact.xml +++ b/tasks/artifact.xml @@ -242,6 +242,8 @@ - Override the Drupal root so that it is within the artifact directory. - Override the "artifact mode" so that files managed with the task are copied into the artifact instead of symlinked. + + @todo Run build for each key in drupal.sites. --> diff --git a/tasks/drupal.xml b/tasks/drupal.xml index 94ef1849..8526a536 100644 --- a/tasks/drupal.xml +++ b/tasks/drupal.xml @@ -132,7 +132,9 @@ ${modified_files} - + diff --git a/tasks/the-build.xml b/tasks/the-build.xml index e9e8001d..5039cc20 100644 --- a/tasks/the-build.xml +++ b/tasks/the-build.xml @@ -69,7 +69,21 @@ + + From ca1717dcdede80f7e2e164f72fa72555004d00f4 Mon Sep 17 00:00:00 2001 From: Bec White Date: Wed, 10 Oct 2018 17:26:02 -0500 Subject: [PATCH 09/29] Provide default values for the new nested sites configuration. --- defaults.properties.yml | 39 +++++++++++++++++++++++--- defaults/templates/the-build/build.xml | 6 ++-- tasks/install.xml | 2 ++ tasks/the-build.xml | 3 ++ 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/defaults.properties.yml b/defaults.properties.yml index f7de20dd..ef09a9c4 100644 --- a/defaults.properties.yml +++ b/defaults.properties.yml @@ -30,16 +30,47 @@ drupal: bypass: false sites: + # Configuration values for a Drupal site build. The values in this section + # must be customized for each Drupal multisite installation that you add. + # + # This site configuration will not be complete without copying in values + # from drupal.sites._defaults. + # + # To add a Drupal multisite installation, copy these default values into + # your project's .the-build/build.default.properties.yml file and change + # the 'default' key to the name of your new multisite. default: # Name of the sites subdirectory where the `settings.php` file should live. - sites_subdir: default - - # Human-readable name for your site. - site_name: "${projectname}" + dir: default # Your site's URI; the default should be the URI of your local development environment. uri: "https://${projectname}.local" + # Path to the Drupal config directory, relative to the Drupal root. + config_sync_directory: "../config/sites/default" + + # Database connection for Drupal. + database: + database: drupal + + settings: + # Path to the Drupal public files directory, relative to the Drupal root. + file_public_path: sites/default/files + + # Path to the Drupal private files directory, relative to the Drupal root. + file_private_path: "../artifacts/private/default" + + # Configuration used by the default 'build' target. + build: + # Destination for the templated settings.php file. + settings_dest: ${drupal.root}/sites/default/settings.build.php + + # Destination for the templated `services.yml` file. + services_dest: ${drupal.root}/sites/default/services.build.yml + + # These values are used to fill in defaults for Drupal multisites that might + # not have everything defined. + _defaults: # Salt for Drupal's password hashing. A unique salt is generated when you install # `the-build`. hash_salt: temporary diff --git a/defaults/templates/the-build/build.xml b/defaults/templates/the-build/build.xml index e13b2771..81a022de 100644 --- a/defaults/templates/the-build/build.xml +++ b/defaults/templates/the-build/build.xml @@ -31,8 +31,8 @@ - - + + @@ -68,7 +68,7 @@ --> - + ${drupal.site.profile} diff --git a/tasks/install.xml b/tasks/install.xml index c6f98648..ff260f40 100644 --- a/tasks/install.xml +++ b/tasks/install.xml @@ -49,6 +49,8 @@ + + + + + From 682b597ae083fae7daa2e1d87c1dafcfd1b7d761 Mon Sep 17 00:00:00 2001 From: Bec White Date: Wed, 10 Oct 2018 17:55:42 -0500 Subject: [PATCH 10/29] Provide validation and defaults for drupal.sites.* properties. --- defaults.properties.yml | 82 +++++++++---------- .../the-build/build.default.properties.yml | 6 +- tasks/the-build.xml | 15 +++- 3 files changed, 55 insertions(+), 48 deletions(-) diff --git a/defaults.properties.yml b/defaults.properties.yml index ef09a9c4..8bc7e18c 100644 --- a/defaults.properties.yml +++ b/defaults.properties.yml @@ -38,38 +38,51 @@ drupal: # # To add a Drupal multisite installation, copy these default values into # your project's .the-build/build.default.properties.yml file and change - # the 'default' key to the name of your new multisite. + # the 'default' key to the name of your new multisite. The key must not + # contain '.' characters, but the 'dir' property may. default: - # Name of the sites subdirectory where the `settings.php` file should live. + # REQUIRED: Name of the sites subdirectory where the `settings.php` file + # should live. dir: default - # Your site's URI; the default should be the URI of your local development environment. + # REQUIRED: Your site's URI; the default should be the URI of your local + # development environment. uri: "https://${projectname}.local" - # Path to the Drupal config directory, relative to the Drupal root. - config_sync_directory: "../config/sites/default" - - # Database connection for Drupal. - database: - database: drupal - - settings: - # Path to the Drupal public files directory, relative to the Drupal root. - file_public_path: sites/default/files - - # Path to the Drupal private files directory, relative to the Drupal root. - file_private_path: "../artifacts/private/default" - - # Configuration used by the default 'build' target. - build: - # Destination for the templated settings.php file. - settings_dest: ${drupal.root}/sites/default/settings.build.php - - # Destination for the templated `services.yml` file. - services_dest: ${drupal.root}/sites/default/services.build.yml + # Customizing the following values is OPTIONAL. If these values are not + # explicitly configured, they will be set in the-build.xml based on the + # 'dir' value configured above. + # + # NOTE: Properties may use other properties in their values, which are + # expanded when the property file is loaded. We can not use that behavior + # here because these values must reference a variable path: the 'default' + # key in the 'drupal.sites.*' properties. + # + # # Path to the Drupal config directory, relative to the Drupal root. + # config_sync_directory: "../config/sites/default" + # + # # Database connection for Drupal. + # database: + # database: drupal + # + # settings: + # # Path to the Drupal public files directory, relative to the Drupal root. + # file_public_path: sites/default/files + # + # # Path to the Drupal private files directory, relative to the Drupal root. + # file_private_path: "../artifacts/private/default" + # + # # Configuration used by the default 'build' target. + # build: + # # Destination for the templated settings.php file. + # settings_dest: ${drupal.root}/sites/default/settings.build.php + # + # # Destination for the templated `services.yml` file. + # services_dest: ${drupal.root}/sites/default/services.build.yml # These values are used to fill in defaults for Drupal multisites that might - # not have everything defined. + # not have everything defined. These may be set for specific multisites, or + # you may choose to override the defaults. _defaults: # Salt for Drupal's password hashing. A unique salt is generated when you install # `the-build`. @@ -78,42 +91,27 @@ drupal: # Drupal install profile to use for the drupal-install target. profile: config_installer - # Path to the Drupal config directory, relative to the Drupal root. - config_sync_directory: "../config/sites/default" - # Drupal admin username, if you feel inclined to change it. admin_user: admin # Database connection for Drupal. database: - database: drupal + # This value is required, but a default is set in the-build.xml. + # database: drupal username: root password: root host: 127.0.0.1 - settings: - # Path to the Drupal public files directory, relative to the Drupal root. - file_public_path: sites/default/files - - # Path to the Drupal private files directory, relative to the Drupal root. - file_private_path: "../artifacts/private/default" - # Configuration used by the default 'build' target. build: # Source template for Drupal's `settings.php` file. This may vary per build # environment. settings_template: .the-build/drupal.settings.build.php - # Destination for the templated settings.php file. - settings_dest: ${drupal.root}/sites/default/settings.build.php - # Source template for Drupal's `services.yml` file. This may vary per build # environment. services_template: .the-build/drupal.services.build.yml - # Destination for the templated `services.yml` file. - services_dest: ${drupal.root}/sites/default/services.build.yml - # Configuration for the database loading utility. load_db: diff --git a/defaults/templates/the-build/build.default.properties.yml b/defaults/templates/the-build/build.default.properties.yml index 94149f61..b08ac490 100644 --- a/defaults/templates/the-build/build.default.properties.yml +++ b/defaults/templates/the-build/build.default.properties.yml @@ -17,11 +17,13 @@ drupal: sites: default: + dir: "default" + uri: "${drupal.sites.default.uri}" + hash_salt: "${drupal.sites.default.hash_salt}" - profile: "${drupal.sites.default.profile}" database: - database: "${drupal.sites.default.database.database}" + database: "drupal" username: "${drupal.sites.default.database.username}" password: "${drupal.site.default.database.password}" host: "${drupal.sites.default.database.host}" diff --git a/tasks/the-build.xml b/tasks/the-build.xml index a8d476df..c5edf9fc 100644 --- a/tasks/the-build.xml +++ b/tasks/the-build.xml @@ -78,10 +78,6 @@ - use a runtime flag like -Dbuild.site=foo - maybe also allow setting the default with an environment variable? or some other way to work on one site at a time without the flag? - - provide validation and defaults for sites; this might have to be replicated in - the install process, since that relies on default values for some of the - drupal config - - set some values at run time based on the site subdirectory/site key name? - watch out for site names with . in them - those won't be iterable as keys --> @@ -89,6 +85,17 @@ + + + + + + + + + + + From e08c4d20a5217bba4d77a07fdf849eeadad469ea Mon Sep 17 00:00:00 2001 From: Bec White Date: Wed, 10 Oct 2018 18:05:28 -0500 Subject: [PATCH 11/29] Fix typo and missing task definition. --- defaults/templates/the-build/build.default.properties.yml | 2 +- tasks/install.xml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/defaults/templates/the-build/build.default.properties.yml b/defaults/templates/the-build/build.default.properties.yml index b08ac490..c8f07d3d 100644 --- a/defaults/templates/the-build/build.default.properties.yml +++ b/defaults/templates/the-build/build.default.properties.yml @@ -25,7 +25,7 @@ drupal: database: database: "drupal" username: "${drupal.sites.default.database.username}" - password: "${drupal.site.default.database.password}" + password: "${drupal.sites.default.database.password}" host: "${drupal.sites.default.database.host}" # Add more multisites here. diff --git a/tasks/install.xml b/tasks/install.xml index ff260f40..54b4420b 100644 --- a/tasks/install.xml +++ b/tasks/install.xml @@ -15,6 +15,8 @@ + + From 2903989dd1287bb73f510da68515340440e6c84e Mon Sep 17 00:00:00 2001 From: Bec White Date: Wed, 10 Oct 2018 18:13:15 -0500 Subject: [PATCH 12/29] Fix bug in CopyPropertiesTask where the 'override' attribute did not apply properly. --- src/TheBuild/CopyPropertiesTask.php | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/TheBuild/CopyPropertiesTask.php b/src/TheBuild/CopyPropertiesTask.php index 9bbe84ee..5d8c2379 100644 --- a/src/TheBuild/CopyPropertiesTask.php +++ b/src/TheBuild/CopyPropertiesTask.php @@ -43,21 +43,16 @@ class CopyPropertiesTask extends \Task { protected $propertyMethod = 'setProperty'; - /** - * Use either Project::setProperty() or Project::setNewProperty() based on - * whether we're overriding values or not. - */ - public function init() { - parent::init(); - $this->propertyMethod = $this->override ? 'setProperty' : 'setNewProperty'; - } - /** * Copy properties. */ public function main() { $this->validate(); + // Use either Project::setProperty() or Project::setNewProperty() based on + // whether we're overriding values or not. + $this->propertyMethod = $this->override ? 'setProperty' : 'setNewProperty'; + $project = $this->getProject(); foreach ($project->getProperties() as $name => $value) { if (strpos($name, $this->fromPrefix) === 0) { From 662e7cf54dcbd6c2bc33ae0d9a47cc2521335f10 Mon Sep 17 00:00:00 2001 From: Bec White Date: Wed, 10 Oct 2018 19:24:39 -0500 Subject: [PATCH 13/29] Prompt users for which multisite to build, if there is more than one. --- src/TheBuild/MenuInputRequest.php | 51 +++++++++ src/TheBuild/SelectPropertyKeyTask.php | 146 +++++++++++++++++++++++++ tasks/the-build.xml | 60 +++++----- 3 files changed, 230 insertions(+), 27 deletions(-) create mode 100644 src/TheBuild/MenuInputRequest.php create mode 100644 src/TheBuild/SelectPropertyKeyTask.php diff --git a/src/TheBuild/MenuInputRequest.php b/src/TheBuild/MenuInputRequest.php new file mode 100644 index 00000000..2bed0974 --- /dev/null +++ b/src/TheBuild/MenuInputRequest.php @@ -0,0 +1,51 @@ +options = array_values($options); + } + + public function getPrompt() { + $prompt = $this->prompt . $this->getPromptChar() . "\r\n"; + foreach ($this->options as $i => $option) { + $prompt .= " {$i}: {$option}\r\n"; + } + return $prompt; + } + + public function isInputValid() { + return (isset($this->options[$this->input])); + } + + public function getInput() { + return $this->options[$this->input]; + } + +} diff --git a/src/TheBuild/SelectPropertyKeyTask.php b/src/TheBuild/SelectPropertyKeyTask.php new file mode 100644 index 00000000..dc5a30f8 --- /dev/null +++ b/src/TheBuild/SelectPropertyKeyTask.php @@ -0,0 +1,146 @@ + + * @endcode + * + * @copyright 2018 Palantir.net, Inc. + */ + +namespace TheBuild; + +use BuildException; +use StringHelper; +use Project; + + +class SelectPropertyKeyTask extends \Task { + + /** + * @var string + * Required. Prefix for properties to copy. + */ + protected $prefix = ''; + + /** + * @var string + * Required. Property to populate with the selected value. + */ + protected $propertyName = ''; + + /** + * @var string + * Message to display to the user when more than one key is available. + */ + protected $message = 'Select one:'; + + /** + * @var array + */ + protected $omitKeys = []; + + + /** + * Copy properties. + */ + public function main() { + $this->validate(); + $project = $this->getProject(); + + if ($existing_value = $this->project->getProperty($this->propertyName)) { + $this->log("Using {$this->propertyName} = '{$existing_value}' (existing value)", Project::MSG_INFO); + return; + } + + // Extract matching keys from the properties array. + $keys = []; + foreach ($project->getProperties() as $name => $value) { + if (strpos($name, $this->prefix) === 0) { + $property_children = substr($name, strlen($this->prefix)); + list($key, $property_grandchildren) = explode('.', $property_children, 2); + $keys[$key] = $key; + } + } + + // Remove keys based on the 'omitKeys' attribute. + $keys = array_diff($keys, $this->omitKeys); + + if (count($keys) > 1) { + // Prompt for input. + $request = new MenuInputRequest($this->message); + $request->setOptions($keys); + + $this->project->getInputHandler()->handleInput($request); + + $value = $request->getInput(); + } + elseif (count($keys) == 1) { + $value = current($keys); + $this->log("Using {$this->propertyName} = '{$value}' (one value found)", Project::MSG_INFO); + } + else { + $this->log("No properties found with prefix '{$this->prefix}'", Project::MSG_WARN); + } + + if ($value) { + $project->setNewProperty($this->propertyName, $value); + } + } + + + /** + * Verify that the required attributes are set. + */ + public function validate() { + foreach (['prefix', 'propertyName'] as $attribute) { + if (empty($this->$attribute)) { + throw new BuildException("$attribute attribute is required.", $this->location); + } + } + } + + + /** + * @param string $value + */ + public function setPrefix($value) { + if (!StringHelper::endsWith(".", $value)) { + $value .= "."; + } + + $this->prefix = $value; + } + + /** + * @param string $value + */ + public function setPropertyName($value) { + $this->propertyName = $value; + } + + /** + * @param string $value + */ + public function setMessage($value) { + $this->message = $value; + } + + /** + * @param string $value + */ + public function setOmitKeys($value) { + $this->omitKeys = array_map('trim', explode(',', $value)); + } + +} diff --git a/tasks/the-build.xml b/tasks/the-build.xml index c5edf9fc..81e66fd1 100644 --- a/tasks/the-build.xml +++ b/tasks/the-build.xml @@ -21,6 +21,10 @@ + + + + @@ -39,6 +43,14 @@ + + + + + + + + @@ -64,39 +76,33 @@ + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - From 8cbc4ae52f3d3063593ad1025e7947edbc18a78a Mon Sep 17 00:00:00 2001 From: Bec White Date: Wed, 10 Oct 2018 19:39:52 -0500 Subject: [PATCH 14/29] During the artifact build, run the build target once for each Drupal multisite. --- defaults/templates/the-build/build.xml | 3 +++ src/TheBuild/ForeachKeyTask.php | 21 ++++++++++++++++++--- tasks/artifact.xml | 9 +++++++-- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/defaults/templates/the-build/build.xml b/defaults/templates/the-build/build.xml index 81a022de..db964749 100644 --- a/defaults/templates/the-build/build.xml +++ b/defaults/templates/the-build/build.xml @@ -123,6 +123,9 @@ + + diff --git a/src/TheBuild/ForeachKeyTask.php b/src/TheBuild/ForeachKeyTask.php index 0b8e31b0..98a06351 100644 --- a/src/TheBuild/ForeachKeyTask.php +++ b/src/TheBuild/ForeachKeyTask.php @@ -5,7 +5,7 @@ * Iterate over property values. * * @code - * + * * @endcode * * @copyright 2018 Palantir.net, Inc. @@ -43,6 +43,11 @@ class ForeachKeyTask extends \Task { */ protected $prefixParam = ''; + /** + * @var array + */ + protected $omitKeys = []; + /** * @var \PhingCallTask */ @@ -78,10 +83,13 @@ public function main() { if (strpos($name, $this->prefix) === 0) { $property_children = substr($name, strlen($this->prefix)); list($key, $property_grandchildren) = explode('.', $property_children, 2); - $keys[$key] = $this->prefix; + $keys[$key] = $key; } } + // Remove keys based on the 'omitKeys' attribute. + $keys = array_diff($keys, $this->omitKeys); + // Iterate over each extracted key. foreach ($keys as $key => $prefix) { $prop = $this->callee->createProperty(); @@ -92,7 +100,7 @@ public function main() { $prop = $this->callee->createProperty(); $prop->setOverride(true); $prop->setName($this->prefixParam); - $prop->setValue($prefix); + $prop->setValue($this->prefix); $this->callee->main(); } @@ -143,4 +151,11 @@ public function setPrefixParam($value) { $this->prefixParam = $value; } + /** + * @param string $value + */ + public function setOmitKeys($value) { + $this->omitKeys = array_map('trim', explode(',', $value)); + } + } diff --git a/tasks/artifact.xml b/tasks/artifact.xml index 27625c50..736a4bd1 100644 --- a/tasks/artifact.xml +++ b/tasks/artifact.xml @@ -238,14 +238,19 @@ Running 'phing build' in the artifact... + + + + + + + From 890d3e0a5be7c38058ce76e7edccb4a8c6f934fd Mon Sep 17 00:00:00 2001 From: Bec White Date: Wed, 10 Oct 2018 19:49:02 -0500 Subject: [PATCH 15/29] Add a todo about the fact that the multisite prompt can be confusing when you're not running a site-specific task. --- tasks/the-build.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tasks/the-build.xml b/tasks/the-build.xml index 81e66fd1..9e26c856 100644 --- a/tasks/the-build.xml +++ b/tasks/the-build.xml @@ -78,6 +78,12 @@ + From 1f155f648d286f1e4e3c88dd894dc7db648e8c84 Mon Sep 17 00:00:00 2001 From: Bec White Date: Wed, 10 Oct 2018 19:55:11 -0500 Subject: [PATCH 16/29] Update the drupal skeleton build properties. --- .../drupal-skeleton/build.test.properties.yml | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/defaults/config/drupal-skeleton/build.test.properties.yml b/defaults/config/drupal-skeleton/build.test.properties.yml index eb9709b4..5ae19578 100644 --- a/defaults/config/drupal-skeleton/build.test.properties.yml +++ b/defaults/config/drupal-skeleton/build.test.properties.yml @@ -1,17 +1,19 @@ # These properties are for running the Drupal Skeleton on circle. drupal: - site_name: drupal-skeleton - uri: http://drupal-skeleton.local - hash_salt: temporary root: web - profile: standard - database: - database: circle_test - username: ubuntu - password: - host: 127.0.0.1 - settings: - file_public_path: sites/default/files - file_private_path: + sites: + default: + dir: default + uri: http://drupal-skeleton.local + hash_salt: temporary + profile: standard + database: + database: circle_test + username: ubuntu + password: + host: 127.0.0.1 + settings: + file_public_path: sites/default/files + file_private_path: twig: debug: false From fbd0c1e34201a5cd5a0ef4ded931f38f58c51a69 Mon Sep 17 00:00:00 2001 From: Bec White Date: Wed, 10 Oct 2018 20:02:46 -0500 Subject: [PATCH 17/29] Remove unused class. --- src/TheBuild/ExpandPrefixedProperties.php | 115 ---------------------- 1 file changed, 115 deletions(-) delete mode 100644 src/TheBuild/ExpandPrefixedProperties.php diff --git a/src/TheBuild/ExpandPrefixedProperties.php b/src/TheBuild/ExpandPrefixedProperties.php deleted file mode 100644 index b8a32136..00000000 --- a/src/TheBuild/ExpandPrefixedProperties.php +++ /dev/null @@ -1,115 +0,0 @@ - - * - * - * - * - * - * - * - * - * - * ${out} - * - * - * @copyright 2018 Palantir.net, Inc. - */ - -namespace TheBuild; - -require_once 'phing/parser/ProjectConfigurator.php'; - -use ExpandProperties; -use ProjectConfigurator; -use Parameterizable; -use ConfigurationException; - -class ExpandPrefixedProperties extends ExpandProperties implements Parameterizable { - - /** - * @var string - * The prefix to look for. - */ - protected $prefix = ""; - - /** - * @param $prefix - */ - public function setPrefix($prefix) { - $this->prefix = $prefix; - } - - /** - * @param null $len - * @return int|mixed|string - */ - public function read($len = null) { - $buffer = $this->in->read($len); - - if ($buffer === -1) { - return -1; - } - - $project = $this->getProject(); - - $properties = []; - foreach ($project->getProperties() as $name => $value) { - if (strpos($name, $this->prefix) === 0) { - $newprop = substr($name, strlen($this->prefix)); - $properties[$newprop] = $value; - } - } - - $buffer = ProjectConfigurator::replaceProperties($project, $buffer, $properties, $this->logLevel); - - return $buffer; - } - - /** - * @param $parameters - * @return mixed|void - * @throws ConfigurationException - */ - public function setParameters($parameters) { - /** @var \Parameter $param */ - foreach ($parameters as $param) { - $name = $param->getName(); - $method = 'set' . ucfirst($name); - if (method_exists($this, $method) && $method != 'setParameters') { - $this->$method($param->getValue()); - } - } - - $this->validate(); - } - - /** - * @throws ConfigurationException - */ - protected function validate() { - if (empty($this->prefix)) { - throw new ConfigurationException('TheBuild\ExpandPrefixedProperties filter is missing a value for the required "prefix" parameter.'); - } - } - -} From 9d81eac3766988f92f521f2fb863c55653a30ead Mon Sep 17 00:00:00 2001 From: Bec White Date: Wed, 10 Oct 2018 20:13:32 -0500 Subject: [PATCH 18/29] Update comment. --- defaults.properties.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/defaults.properties.yml b/defaults.properties.yml index 8bc7e18c..885001bd 100644 --- a/defaults.properties.yml +++ b/defaults.properties.yml @@ -33,8 +33,8 @@ drupal: # Configuration values for a Drupal site build. The values in this section # must be customized for each Drupal multisite installation that you add. # - # This site configuration will not be complete without copying in values - # from drupal.sites._defaults. + # This site configuration is partial; it will be completed in tasks/the-build.xml by + # loading any missing values from drupal.sites._defaults. # # To add a Drupal multisite installation, copy these default values into # your project's .the-build/build.default.properties.yml file and change From 4584ae2a252b1cd7763c5c000eff6381fbfff6c3 Mon Sep 17 00:00:00 2001 From: Bec White Date: Thu, 11 Oct 2018 13:48:50 -0500 Subject: [PATCH 19/29] Move 'drupal.site.*' property setup into a new 'set-site' target, then update relevant tasks to depend on this target. --- defaults/templates/the-build/build.xml | 6 +-- tasks/drupal.xml | 12 ++--- tasks/the-build.xml | 70 ++++++++++++++------------ 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/defaults/templates/the-build/build.xml b/defaults/templates/the-build/build.xml index db964749..59638b60 100644 --- a/defaults/templates/the-build/build.xml +++ b/defaults/templates/the-build/build.xml @@ -26,7 +26,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -83,7 +83,7 @@ - + diff --git a/tasks/drupal.xml b/tasks/drupal.xml index 8526a536..0eb061f5 100644 --- a/tasks/drupal.xml +++ b/tasks/drupal.xml @@ -27,7 +27,7 @@ Validate that the Drupal config directory doesn't have local modifications, to ensure consistent installation. --> - + @@ -87,7 +87,7 @@ ${modified_files} - The site in maintenance mode - Structure only for cache, search, and log tables --> - + @@ -135,7 +135,7 @@ ${modified_files} - + @@ -181,7 +181,7 @@ Or, you can specify the export file directly: Check for a Drupal database connection. --> - + @@ -200,7 +200,7 @@ Or, you can specify the export file directly: Check for Drupal config, and if it's not present, offer to install Drupal. --> - + @@ -236,7 +236,7 @@ Or, you can specify the export file directly: of the places where this is called from code already have separate dependencies on that target. --> - + diff --git a/tasks/the-build.xml b/tasks/the-build.xml index 9e26c856..acfc24c4 100644 --- a/tasks/the-build.xml +++ b/tasks/the-build.xml @@ -12,6 +12,9 @@ + + + @@ -43,6 +46,9 @@ + + + @@ -51,9 +57,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + - @@ -126,6 +100,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +$sites['${new.domain}'] = '${new.dir}'; + + + + + +The Drupal sites directory at '${drupal.root}/sites/${new.dir}/' has been set up, and the configuration for your local domain has been added to '${drupal.root}/sites/${new.dir}/sites.php' + +Next, you need to add the following settings to your .the-build/build.default.properties.yml file: + +drupal: + sites: + ${new.key}: + dir: ${new.dir} + uri: ${new.uri} + hash_salt: ${new.hash_salt} + +Finally, install the new multisite with: `phing install -Dbuild.site=${new.key}` + +You should also consider: + * Adding the domain for your new multisite to your development environment configuration + * Creating a new 'profile' in your behat.yml configuration, and updating your behat.args property + * Updating your .circleci/config.yml to run tests for your new multisite + + + From c7a67f05ac4e8e38f8166f0bb1948a9baa54d8b8 Mon Sep 17 00:00:00 2001 From: Bec White Date: Fri, 12 Oct 2018 15:44:55 -0500 Subject: [PATCH 22/29] Reorganize the multisite setup so that it shares code with the-build install process. --- tasks/drupal.xml | 114 +++++++++++++++++++++++++++------------------- tasks/install.xml | 73 ++++++++++++++++++++--------- 2 files changed, 120 insertions(+), 67 deletions(-) diff --git a/tasks/drupal.xml b/tasks/drupal.xml index cd4b4651..3bd78979 100644 --- a/tasks/drupal.xml +++ b/tasks/drupal.xml @@ -190,7 +190,21 @@ Or, you can specify the export file directly: - + + + + + + + + + + @@ -213,7 +227,9 @@ Or, you can specify the export file directly: - + + + @@ -307,7 +323,7 @@ Or, you can specify the export file directly: - + @@ -315,11 +331,31 @@ Or, you can specify the export file directly: - - + + + - - + + + + + + + + + + + + + + + @@ -327,8 +363,23 @@ Or, you can specify the export file directly: + + + +$sites['${_multisite.sites_php_domain}'] = '${_multisite.dir}'; + + + + + + + + + - + @@ -336,52 +387,23 @@ Or, you can specify the export file directly: - - - - - - - - - - - - - - - - - - - - - - - - - - - - -$sites['${new.domain}'] = '${new.dir}'; - + -The Drupal sites directory at '${drupal.root}/sites/${new.dir}/' has been set up, and the configuration for your local domain has been added to '${drupal.root}/sites/${new.dir}/sites.php' - -Next, you need to add the following settings to your .the-build/build.default.properties.yml file: +To build and install this site, you need to add the following configuration to your .the-build/build.default.properties.yml file: drupal: sites: - ${new.key}: - dir: ${new.dir} - uri: ${new.uri} - hash_salt: ${new.hash_salt} + ${_multisite.key}: + dir: ${_multisite.dir} + uri: ${_multisite.uri} + hash_salt: ${_multisite.hash_salt} -Finally, install the new multisite with: `phing install -Dbuild.site=${new.key}` +Finally, install the new multisite with: `phing install -Dbuild.site=${_multisite.key}` You should also consider: * Adding the domain for your new multisite to your development environment configuration diff --git a/tasks/install.xml b/tasks/install.xml index 54b4420b..5cdd5c05 100644 --- a/tasks/install.xml +++ b/tasks/install.xml @@ -134,40 +134,20 @@ - - - - - - - - - - - - - - - - - - + - - - @@ -196,6 +176,11 @@ + + + + + @@ -236,4 +221,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From c3ba3fa50e3d9a35f95aecbc72f595d822ed2b18 Mon Sep 17 00:00:00 2001 From: Bec White Date: Fri, 12 Oct 2018 15:56:11 -0500 Subject: [PATCH 23/29] Fix settings template config for Acquia. --- defaults/templates/the-build/build.acquia.properties.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaults/templates/the-build/build.acquia.properties.yml b/defaults/templates/the-build/build.acquia.properties.yml index 6b99c39e..4ba48264 100644 --- a/defaults/templates/the-build/build.acquia.properties.yml +++ b/defaults/templates/the-build/build.acquia.properties.yml @@ -6,5 +6,5 @@ drupal: sites: default: build: - settings: .the-build/drupal.settings.build-acquia.php + settings_template: .the-build/drupal.settings.build-acquia.php services_dest: artifacts/dev/null From c39ee993cbb7057fd104c8fa65d8907532969e07 Mon Sep 17 00:00:00 2001 From: Bec White Date: Fri, 12 Oct 2018 16:59:37 -0500 Subject: [PATCH 24/29] Update documentation for multisites. --- README.md | 1 + docs/configuration.md | 3 ++ docs/drupal_multisite.md | 52 +++++++++++++++++++++++++++++ docs/tasks.md | 71 ++++++++++++++++++++++++++++++++++++++++ tasks/the-build.xml | 2 +- 5 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 docs/drupal_multisite.md diff --git a/README.md b/README.md index 81678968..fb7fa00f 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ Configure your build by editing `.the-build/build.default.properties.yml`. You c * [Configuring the-build](docs/configuration.md) * [Building an artifact](docs/artifacts.md) +* [Using Drupal multisites](docs/drupal_multisite.md) * [Custom tasks provided by the-build](docs/tasks.md) ---- diff --git a/docs/configuration.md b/docs/configuration.md index 715c7713..84404b20 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -41,6 +41,8 @@ Cool! This phing-ism is what allows us to do environment-specific property layer 1. Load properties from the project's `.the-build/build.default.properties.yml` 1. Load default property values from the-build's own `defaults.properties.yml` file +In order to support Drupal multisites, site-specific configuration should be set in the `drupal.sites.SITENAME.*` properties, but should be referenced using the `drupal.site.*` properties. See [drupal_multisite.md](drupal_multisite.md) for details on how these properties are provided. + ## Build environments Generally, the `build.env` property is set from the `PALANTIR_ENVIRONMENT` environment variable. @@ -63,6 +65,7 @@ There are four core properties that are always available in the-build: | `projectname` | A machine name for the project. Set based on the `build.dir`, with the `.local` suffix removed (if it's present). | | `build.thebuild.dir` | Path to `the-build` code. Used to find and load default properties and templates. | | `build.env` | The build environment. Used for loading environment-specific properties files, and set from the `PALANTIR_ENVIRONMENT` environment variable. | +| `build.site` | The multisite to build; only used when running site-specific targets. Can be set from the `THE_BUILD_ENVIRONMENT` variable. See [drupal_multisite.md](drupal_multisite.md). | These properties are provided by the init process in `the-build.xml`, and do not need to be set or overridden in your local build configuration. diff --git a/docs/drupal_multisite.md b/docs/drupal_multisite.md new file mode 100644 index 00000000..be582106 --- /dev/null +++ b/docs/drupal_multisite.md @@ -0,0 +1,52 @@ +# Using Drupal Multisites + +Multisite builds are supported under `the-build`. When you have multiple sites configured in your `.the-build/build.default.properties.yml` file, and you run targets like `build` and `install` that act on a specific site, you will be prompted to select a site. + +These site-specific targets declare a dependency on the `set-site` target in [tasks/the-build.xml](../tasks/the-build.xml), which sets up the site properties in `drupal.site.*`. This allows targets to reference the same properties (e.g. `${drupal.site.uri}`) for each site, rather than needing to reference a site-specific property (e.g. `${drupal.sites.default.uri}`, `${drupal.sites.intranet.uri}`). + +Default values for all sites are set in the `drupal.sites._defaults.*` properties, but individual sites can override them. + +Finally, site-specific directory properties are set dynamically based on `drupal.site.dir`, unless they're explicitly declared. + +## Adding a new multisite + +A target is provided for setting up new multisites: + +``` +$> phing drupal-add-multisite +``` + +This command will prompt you for the Drupal sites subdirectory and the site URL, and then will generate the required `settings.php` files and add the site to `sites.php`. It will output configuration values for you to paste into your `.the-build/build.default.properties.yml`. + +You will still need to manually update your Vagrant, Behat, and CircleCI configuration. + +## Example Multisite Configuration + +``` +drupal: + root: web + sites: + default: + dir: default + uri: http://mysite.local + database: + database: drupal + intranet: + dir: intranet + uri: http://intranet.mysite.local + conference2019_mysite_com: + dir: conference2019.mysite.com + uri: http://conference2019.mysite.local + admin_user: sarah + _defaults: + admin_user: obscure_admin_name +``` + +With this configuration: + +* The `default` site uses the `drupal` database, and the other two sites use `intranet` and `conference2019_mysite_com`, respectively (set by `the-build.xml` based on the sites key) +* For `default` and `intranet`, user 1 is named `obscure_admin_name` (inherited from `drupal.sites._defaults`) +* For `conference2019_mysite_com` the admin is named `sarah` (overridden) +* These three sites are found in the directories `web/sites/default`, `web/sites/intranet`, and `web/sites/conference2019.mysite.com` respectively + + diff --git a/docs/tasks.md b/docs/tasks.md index ff0c5e71..8ef423d0 100644 --- a/docs/tasks.md +++ b/docs/tasks.md @@ -22,3 +22,74 @@ Copies or symlinks a file or directory within your project. ``` + +## CopyPropertiesTask [🔗](../src/TheBuild/CopyPropertiesTask.php) + +Copies phing properties matching a prefix to properties with a different prefix. + +### Attributes + +| Name | Type | Description | Default | Required | +|---|---|---|---|---| +| fromPrefix | string | Prefix for source properties. | | Yes | +| toPrefix | string | New prefix for matching properties. | | Yes | +| override | boolean | Whether to overwrite existing property values. | true | No | + +If either of the `fromPrefix` or `toPrefix` attributes does not end in a `.`, one will be added. + +### Example + +```xml + + +``` + +## ForeachKeyTask [🔗](../src/TheBuild/ForeachKeyTask.php) + +Iterate over Phing property values. + +### Attributes + +| Name | Type | Description | Default | Required | +|---|---|---|---|---| +| prefix | string | Prefix for properties to iterate over. | | Yes | +| target | string | Phing target to run for each property. | | Yes | +| keyParam | string | Name of a target parameter to pass the property key in. | | Yes | +| prefixParam | string | Name of a target parameter to pass the property prefix in. | | Yes | +| omitKeys | string | Comma-separated list of keys to ignore. | | false | + +If the `prefix` attribute does not end in a `.`, one will be added. + +### Example + +```xml + +``` + +## SelectPropertyKeyTask [🔗](../src/TheBuild/SelectPropertyKeyTask.php) + +Interactively select a key from available property keys. + +* If the propertyName property is already set, the task does nothing +* If no keys are available, the propertyName property is not set and the task does nothing +* If there is only one key available, that key is used and the user is not prompted +* If there are multiple keys available, the user will be prompted to select one using a multiple choice menu + + + +### Attributes + +| Name | Type | Description | Default | Required | +|---|---|---|---|---| +| prefix | string | Prefix for properties to select among. | | Yes | +| propertyName | string | Property to populate with the selected value. | | Yes | +| message | string | Prompt to display to the user. | `Select one:` | Yes | +| omitKeys | string | Comma-separated list of keys to ignore. | | false | + +If the `prefix` attribute does not end in a `.`, one will be added. + +### Example + +```xml + +``` diff --git a/tasks/the-build.xml b/tasks/the-build.xml index acfc24c4..3a5df54d 100644 --- a/tasks/the-build.xml +++ b/tasks/the-build.xml @@ -119,7 +119,7 @@ - + From 6cc26569d9bfab08fff39a70285e8a7277bd6f53 Mon Sep 17 00:00:00 2001 From: Bec White Date: Fri, 12 Oct 2018 17:39:42 -0500 Subject: [PATCH 25/29] Allow running build and install against all multisites at once. --- defaults/templates/the-build/build.xml | 22 ++++++++++++++++++++++ docs/drupal_multisite.md | 20 ++++++++++++++++++++ tasks/the-build.xml | 25 +++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/defaults/templates/the-build/build.xml b/defaults/templates/the-build/build.xml index 59638b60..b5e8257a 100644 --- a/defaults/templates/the-build/build.xml +++ b/defaults/templates/the-build/build.xml @@ -76,6 +76,28 @@ + + + + + + + + + + + + + + + + Configure this target to load sample data and run the migrations. diff --git a/docs/drupal_multisite.md b/docs/drupal_multisite.md index be582106..c3a3a534 100644 --- a/docs/drupal_multisite.md +++ b/docs/drupal_multisite.md @@ -20,6 +20,26 @@ This command will prompt you for the Drupal sites subdirectory and the site URL, You will still need to manually update your Vagrant, Behat, and CircleCI configuration. +## Building or installing all sites at once + +You can build all of your multisites at once with: + +``` +$> phing build-all +``` + +Similarly, you can install all of your multisites at once with: + +``` +$> phing install-all +``` + +If you need to run other site-specific commands against all sites at once, use the `sites-run` target, for example: + +``` +$> phing sites-run -Dtarget=load +``` + ## Example Multisite Configuration ``` diff --git a/tasks/the-build.xml b/tasks/the-build.xml index 3a5df54d..ba98211f 100644 --- a/tasks/the-build.xml +++ b/tasks/the-build.xml @@ -130,6 +130,31 @@ + + + + + + + + + + + + + + + + + + - - From a7caa6ae5216539b6a674f9c0de2c848880cd1b9 Mon Sep 17 00:00:00 2001 From: Bec White Date: Tue, 16 Oct 2018 12:55:21 -0500 Subject: [PATCH 27/29] Update comment. --- tasks/drupal.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tasks/drupal.xml b/tasks/drupal.xml index 3bd78979..6dc056cc 100644 --- a/tasks/drupal.xml +++ b/tasks/drupal.xml @@ -192,11 +192,10 @@ Or, you can specify the export file directly: - From 379decc79f9dad65f7de02faa42331aae2e268fd Mon Sep 17 00:00:00 2001 From: Bec White Date: Tue, 16 Oct 2018 12:57:48 -0500 Subject: [PATCH 28/29] Update comment. --- tasks/drupal.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasks/drupal.xml b/tasks/drupal.xml index 6dc056cc..56792191 100644 --- a/tasks/drupal.xml +++ b/tasks/drupal.xml @@ -179,7 +179,8 @@ Or, you can specify the export file directly: From e5ad8281e1449703b8f6107fd9b8c70e8bf3927b Mon Sep 17 00:00:00 2001 From: Bec White Date: Tue, 16 Oct 2018 13:08:22 -0500 Subject: [PATCH 29/29] Use drush @dev, for https://github.com/drush-ops/drush/pull/3733 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8af9f323..e7eef6bc 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "require": { "continuousphp/phing-drush-task": "dev-master", "drupal/coder": "~8.2.12", - "drush/drush": "^8.1.15", + "drush/drush": "^8.1.15@dev", "pear/http_request2": "^2.3", "pear/versioncontrol_git": "@dev", "phing/phing": "^2.14",