#!/bin/bash # Bootstrap a Drupal project # # Copyright (C) 2017 Antonio Ospite # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . set -e usage() { cat <&2 ;; esac shift done [ -f "bootstrap.conf" ] || { echo "Aborting, run this command from the Drupal project directory." 1>&2; exit 1; } # shellcheck disable=SC1091 . bootstrap.conf declare -p DB_NAME declare -p DB_USER declare -p DB_PASS declare -p ACCOUNT_NAME declare -p ACCOUNT_PASS declare -p ACCOUNT_MAIL declare -p SITE_NAME declare -p SITE_MAIL declare -p SITE_BASE_PATH declare -p TRUSTED_HOSTS declare -p WEB_SERVER_GROUP [ "x$INSTALLATION_PROFILE" = "x" ] && { echo "INSTALLATION_PROFILE not specified, using the \"standard\" profile!"; INSTALLATION_PROFILE="standard"; } if [ "$MYSQL_PASSWORDLESS_ACCESS" = true ]; then MYSQL_SU_USER="${USER}" else # XXX Deprecate MYSQL_ROOT_PASSWORD, it will be removed eventually, # but for now add some backwards compatibility mapping. if [ "x$MYSQL_ROOT_PASSWORD" != "x" ]; then echo "WARN: MYSQL_ROOT_PASSWORD is deprecated, use MYSQL_SU_USER and MYSQL_SU_PASSWORD" 1>&2 MYSQL_SU_USER="root" MYSQL_SU_PASSWORD="$MYSQL_ROOT_PASSWORD" fi if [ "x$MYSQL_SU_USER" = "x" ]; then echo "Aborting, for password regulated access specify MYSQL_SU_USER in bootstrap.conf" 1>&2 exit 1 fi if [ "x$MYSQL_SU_PASSWORD" = "x" ]; then read -r -s -p "MySQL password for \"${MYSQL_SU_USER}\": " MYSQL_SU_PASSWORD echo fi DRUSH_DB_SU_CREDENTIALS=(--db-su-pw'='"${MYSQL_SU_PASSWORD}") fi DRUSH_DB_SU_CREDENTIALS+=(--db-su'='"${MYSQL_SU_USER}") WEB_ROOT="${PWD}/web" command -v composer &> /dev/null || { echo "Aborting, 'composer' not available." 1>&2; exit 1; } command -v git &> /dev/null || { echo "Aborting, 'git' not available." 1>&2; exit 1; } [ -d "$WEB_ROOT" ] || composer install DRUSH="${PWD}/vendor/bin/drush" DRUPAL_CONSOLE="${PWD}/vendor/bin/drupal" [ -x "$DRUSH" ] || { echo "Aborting, '$DRUSH' not available." 1>&2; exit 1; } [ -x "$DRUPAL_CONSOLE" ] || { echo "Aborting, '$DRUPAL_CONSOLE' not available." 1>&2; exit 1; } # The following becomes unnecessary if the installation profile gets pulled in # by composer.json, like suggested in # https://github.com/drupal-composer/drupal-project/issues/249 if ! echo "$INSTALLATION_PROFILE" | grep -q -E "^(minimal|standard)$"; then if [ -d "${WEB_ROOT}/profiles/${INSTALLATION_PROFILE}" ] && [ "$OVERWRITE_PROFILE" != "true" ]; then echo "Installation profile '$INSTALLATION_PROFILE' already there." 1>&2 echo "Use --overwrite-profile to copy over it." 1>&2 exit 1 else if [ -d "$INSTALLATION_PROFILE" ]; then cp -a "$INSTALLATION_PROFILE" "${WEB_ROOT}/profiles" else echo "Local installation profile '$INSTALLATION_PROFILE' not found." 1>&2 echo "Cannot honour the --overwrite-profile option." 1>&2 fi fi fi # Make sure that drush knows what the actual base URI is, this is needed to # have a consistent behavior between the cli and the web interface, for # example in the case of modules that use base_path(). if grep -q "^[[:space:]]*uri:" drush/drush.yml; then sed -i -e "s@^\([[:space:]]*\)uri: .*@\1uri: 'http://localhost/${SITE_BASE_PATH}'@g" drush/drush.yml else echo "" >> drush/drush.yml echo "options:" >> drush/drush.yml echo " uri: 'http://localhost/${SITE_BASE_PATH}'" >> drush/drush.yml fi pushd "$WEB_ROOT" > /dev/null # Update the install_profile setting if it's already there if grep -q "^\\\$settings\['install_profile'\] =" sites/default/settings.php; then chmod 755 sites/default chmod 644 sites/default/settings.php sed -i -e "s/^\(\$settings\['install_profile'\]\) = '[^']*';/\1 = '$INSTALLATION_PROFILE';/g" sites/default/settings.php chmod 444 sites/default/settings.php chmod 555 sites/default fi # Install the site $DRUSH --verbose --yes \ site-install \ "${DRUSH_DB_SU_CREDENTIALS[@]}" \ --db-url="mysql://${DB_USER}:${DB_PASS}@localhost/${DB_NAME}" \ --site-name="$SITE_NAME" \ --site-mail="$SITE_MAIL" \ --sites-subdir="default" \ --account-name="$ACCOUNT_NAME" \ --account-pass="$ACCOUNT_PASS" \ --account-mail="$ACCOUNT_MAIL" \ "$INSTALLATION_PROFILE" if $DRUSH pm-list --type=module --field=name --status=enabled --pipe | grep -q "^locale$"; then # This is necessary for multi-language sites, it fixes some issues like: # "The Translation source field needs to be installed." $DRUSH --yes entity-updates # Update translations of contrib modules $DRUSH --yes locale-update fi # This fixes permissions when installing under $HOME/public_html/ chmod 775 sites/default/files sudo chgrp -R "$WEB_SERVER_GROUP" sites/default/files [ -d ../config/sync ] && sudo chgrp -R "$WEB_SERVER_GROUP" ../config/sync # Enable clean URLs sed -i "s@\(# \)\{0,1\}RewriteBase .*\$@RewriteBase ${SITE_BASE_PATH}@" .htaccess chmod 755 sites/default chmod 644 sites/default/settings.php # Add some basic settings to settings.php if ! grep -q "^\\\$settings\['trusted_host_patterns'\] =" sites/default/settings.php; then echo "\$settings['trusted_host_patterns'] = [" >> sites/default/settings.php for host in "${TRUSTED_HOSTS[@]}" do echo " '^${host}\$'," >> sites/default/settings.php done echo "];" >> sites/default/settings.php fi if [ "$DEVEL_MODE" = "true" ]; then # NOTE: don't run composer under web/ but in the project dir composer --working-dir=../ require drupal/devel $DRUSH --yes en devel if [ ! -e sites/default/settings.local.php ]; then cp sites/example.settings.local.php sites/default/settings.local.php # Disable some overly permissive settings sed -i -e "s/^\(\$settings\['rebuild_access'\]\).*$/\1 = FALSE;/g" sites/default/settings.local.php sed -i -e "s/^\(\$settings\['skip_permissions_hardening'\]\).*$/\1 = FALSE;/g" sites/default/settings.local.php chmod 444 sites/default/settings.local.php fi if ! grep -q "^include \$app_root . '/' . \$site_path . '/settings.local.php';" sites/default/settings.php; then echo "include \$app_root . '/' . \$site_path . '/settings.local.php';" >> sites/default/settings.php fi fi chmod 444 sites/default/settings.php chmod 555 sites/default # If using a git checkout of Drupal core, set up a diff alias. # # This is useful because the Automated Test infrastructure of drupal.org does # not expect patches to be created from a split core directory. if [ -d core/.git ]; then git -C core/ config --local alias.core-diff "diff --src-prefix=a/core/ --dst-prefix=b/core/" git -C core/ config --local alias.core-format-patch "format-patch --src-prefix=a/core/ --dst-prefix=b/core/" echo "Added 'git core-diff' and 'git core-format-patch' commands to the drupal/core" echo "repository clone. These commands help creating core patches ready for upstream" echo "in a split-core setup." fi popd > /dev/null