#!/bin/bash # Performs installation and updates of the Drupal core and # contrib modules and themes via a git clone operation from the central # Drupal git repository. # # The script provides the ability to install and update a single Drupal # site in an "install group". # # Terms/variables used below (generally): # install name -- the installation within an install group. Typically something like 'foo.org'. # install group root dir -- the directory that forms the base of the install group. # # Script originally developed for CVS usage and modified to use git in March, 2011. # Originally bassed on the script 'drupal-cvs-deploy' by Paul Suda (manufaxure.com) # include library file . "`dirname ${0}`/drupalLibrary.sh" # Dumps out script usage printUsage() { echo -e " " echo -e "Updates/Installs/Removes, via git, drupal installations (drupal core)" echo -e "or themes and modules hosted at drupal.org." echo -e "For more info, see script header." echo -e " " echo -e "Usage: " echo -e "\t`basename $0` [-noconfirm] [-quiet] [-branch ] [-latestversion] [install group root dir]" echo -e " " echo -e "-noconfirm supresses comfirmation request." echo -e "-quiet minimizes output. Does not supress git messages." echo -e "-branch " echo -e "\tSpecifies the git branch name used in an installation/update operation." echo -e "\tDefaults to '${DEFAULT_DRUPAL_BRANCH_NAME}' for drupal installs or" echo -e "\tthe latest version available for module/theme installations." echo -e "\tsee http://drupal.org/node/1015226" echo -e "\tCannot be specified with -latestversion" echo -e "-latestversion" echo -e "\tSpecifies that contrib module/theme updates will use the latest version" echo -e "\tavailable for the version of the owning Drupal installation." echo -e "\tOnly works with Drupal-5 and later." echo -e "\tCannot be specified with -branch" echo -e " " echo -e " specifies the operation. Options consist of:" echo -e "\tinstall - installs a new drupal installation," echo -e "\t\tmodule, or theme within an existing Drupal installation." echo -e "\tupdate - updates an existing module or Drupal install." echo -e "\tremove - removes an existng theme or module." echo -e " " echo -e " specifies what to operate on. It can take the following values:" echo -e "\tdrupal - a Drupal installation. (Cannot be 'remove'd.)" echo -e "\tmodule a partular contrib module w/in an installation." echo -e "\t\tModule is specified by 'moduleName' cooresponding to the module checkout name." echo -e "\ttheme a partular theme w/in an installation." echo -e "\tall Drupal installation & all of the contrib modules w/in the installation." echo -e "\tallmodules all of the contrib modules w/in an installation." echo -e "\t\t('all' and 'allmodules' valid only w/ the 'update' operation.)" echo -e "\t\t('all' and 'allmodules' cannot use '-branch' or '-latestversion' parameters.)" echo -e " " outputInstallGroupUsage echo -e " " } ######### # Param handling if [ $# -eq 0 ]; then printUsage exit 0 fi # Handle flags while (true); do case "${1}" in -noconfirm ) pNoConfirm="-noconfirm"; shift ;; -branch ) if [ -n "${pLatestVersion}" ]; then echo -e "** Cannot specify '-branch' and '-latestversion' at same time. Aborting.\n" printUsage exit 1 fi pBranchParam="-branch ${2}" pBranch="${2}" shift; shift ;; -latestversion ) if [ -n "${pBranch}" ]; then echo -e "** Cannot specify '-branch' and '-latestversion' at same time. Aborting.\n" printUsage exit 1 fi pLatestVersion="-latestversion" shift ;; -quiet ) pQuiet="-quiet" shift ;; * ) break ;; esac done if [ -z "${pQuiet}" ]; then echo " " fi # handle OP parameter pOp="${1}" shift case "${pOp}" in install | update | remove ) ;; * ) echo -e "** Invalid OP parameter specified: '${pOp}'. Aborting.\n" printUsage exit 1 esac # handle WHAT parameter pWhat="${1}" shift pWhatSpecific="" case "${pWhat}" in drupal ) if [[ "${pOp}" == "remove" ]]; then echo -e "** Can not 'remove' 'drupal' (needs to be done manually). Aborting.\n" printUsage exit 1 fi ;; module | theme ) if [ $# -lt 2 ]; then echo -e "** Need to specify a ${pWhat}. Aborting.\n" printUsage exit 1 fi pWhatSpecific="${1}" shift ;; all | allmodules ) if [[ "${pOp}" != "update" ]]; then echo -e "** Can only 'update' '${pWhat}'. Aborting.\n" printUsage exit 1 fi if [ -n "${pBranchParam}" -o -n "${pLatestVersion}" ]; then echo -e "** Cannot specify target branches on updating '${pWhat}'. Aborting.\n" printUsage exit 1 fi ;; * ) echo -e "** Invalid WHAT parameter specified: '${pWhat}'. Aborting.\n" printUsage exit 1 esac # handle INSTALL parameter pInstall="${1}" if [ -z "${pInstall}" ]; then echo -e "** Incorrect number of parameters specified for requested operation (parsing INSTALL). Aborting.\n" printUsage exit 1 fi # process Group Root Dir pRootDir="`getGroupRootDir "${2}"`" errorStr="`validateGroupRootDir "${pRootDir}"`" if [ -n "${errorStr}" ]; then echo -e "${errorStr}\n" printUsage exit 1 fi ########################## # Startup # Get confirm message case "${pWhat}" in drupal ) whatStr="Drupal" ;; module ) whatStr="module '${pWhatSpecific}'" ;; theme ) whatStr="theme '${pWhatSpecific}'" ;; all ) whatStr="Drupal & all modules" ;; allmodules ) whatStr="all modules" ;; esac if [ -z "${pQuiet}" ]; then case "${pOp}" in install ) echo "Installing ${whatStr} to installation '${pInstall}'." ;; update ) echo "Updating ${whatStr} on installation '${pInstall}'." ;; remove ) echo "Removing ${whatStr} from installation '${pInstall}'." ;; esac echo -e "\tDrupal group root directory: '${pRootDir}'" fi if [ -z "${pNoConfirm}" ]; then echo "" echo "Press to continue, or ^C to quit..." read fi ########################## # Do requested work. case "${pOp}" in install ) case "${pWhat}" in drupal ) # Installation target directory targetDir="`getTargetDir "${pInstall}" "${pRootDir}"`" # Cannot deploy into an existing directory if [ -d "${targetDir}" ]; then echo "** Target install directory '${targetDir}' already exists. Aborting." exit 1 fi # Can we create the directory? mkdir -p "${targetDir}" 2> /dev/null || { echo "** Cannot create target install directory '${targetDir}'. Aborting." exit 1 } # Default version? if [ -z "${pBranch}" ]; then pBranch="${DEFAULT_DRUPAL_BRANCH_NAME}" fi # Check out Drupal pushd "${pRootDir}" 2>&1 >/dev/null && git clone --depth 1 "`makeDrupalGitURL`" "${pInstall}" && cd "${pInstall}" && git checkout ${pBranch} || { echo -e "** Error performing checkout of Drupal. Aborting.\n" exit 1 } # Create site directory and then files, modules, and themes directories within it. siteDir="`getSiteDir "${pInstall}" "${pRootDir}"`" mkdir "${siteDir}" 2> /dev/null || { echo -e "** Error creating site directory (${siteDir}). Aborting.\n" exit 1 } fileUploadDir="`getFileUploadDir "${pInstall}" "${pRootDir}"`" mkdir "${fileUploadDir}" 2> /dev/null || { echo -e "** Error creating files directory (${fileUploadDir}). Aborting.\n" exit 1 } moduleDir="`getModuleDir "${pInstall}" "${pRootDir}"`" mkdir "${moduleDir}" 2> /dev/null || { echo -e "** Error creating modules directory (${moduleDir}). Aborting.\n" exit 1 } contribModuleDir="`getContribModuleDir "${pInstall}" "${pRootDir}"`" mkdir "${contribModuleDir}" 2> /dev/null || { echo -e "** Error creating contrib modules directory (${contribModuleDir}). Aborting.\n" exit 1 } themeDir="`getThemeDir "${pInstall}" "${pRootDir}"`" mkdir "${themeDir}" 2> /dev/null || { echo -e "** Error creating themes directory (${themeDir}). Aborting.\n" exit 1 } contribThemeDir="`getContribThemeDir "${pInstall}" "${pRootDir}"`" mkdir "${contribThemeDir}" 2> /dev/null || { echo -e "** Error creating contrib themes directory (${contribThemeDir}). Aborting.\n" exit 1 } backupDir="`getBackupDir "${pInstall}" "${pRootDir}"`" mkdir "${backupDir}" 2> /dev/null || { echo -e "** Error creating backup directory (${backupDir}). Aborting.\n" exit 1 } # Create site module stub. majorVer="`getSiteDrupalMajorVersion "${pInstall}" "${pRootDir}"`" generateSiteModule "${pInstall}" "${moduleDir}" "${majorVer}" # Copy/chmod settings.php file # On Drupal v5, this file is called "settings.php" # On Drupal v6+, this file is called "default.settings.php" if [ -f "${targetDir}/sites/default/settings.php" ]; then defaultSettingsFile="${targetDir}/sites/default/settings.php" elif [ -f "${targetDir}/sites/default/default.settings.php" ]; then defaultSettingsFile="${targetDir}/sites/default/default.settings.php" else echo -e "** Could not find default site settings file. Aborting.\n" exit 1 fi cp "${defaultSettingsFile}" "${siteDir}/settings.php" && chmod 0666 "${siteDir}/settings.php" || { echo -e "** Error copying/chmodding site settings file. Aborting.\n" exit 1 } # Done! if [ -z "${pQuiet}" ]; then echo "Install of Drupal complete in ${targetDir}" echo -e "** Remember to run drupalSetPerms.sh on new site after Drupal init." fi ;; module | theme ) # Validate the installation errorStr="`validateSite "${pInstall}" "${pRootDir}"`" if [ -n "${errorStr}" ]; then echo -e "** error with specified install: ${errorStr}. Aborting.\n" exit 1 fi # Get installation directory and name of new dir for the installation if [ "${pWhat}" == "module" ]; then installDir="`getContribModuleDir "${pInstall}" "${pRootDir}"`" installTargetDir="`getDirForContribModule "${pInstall}" "${pRootDir}" "${pWhatSpecific}"`" else # theme installDir="`getContribThemeDir "${pInstall}" "${pRootDir}"`" installTargetDir="`getDirForContribTheme "${pInstall}" "${pRootDir}" "${pWhatSpecific}"`" fi # Ensure install dir exists if [ ! -d "${installDir}" ]; then echo -e "** Contrib ${pWhat} directory '${installDir}' does not exist. Aborting.\n" exit 1 fi # Cannot deploy into an existing directory if [ -d "${installTargetDir}" ]; then echo "** Target install directory '${installTargetDir}' already exists. Aborting." exit 1 fi # Default version? if [ -z "${pBranch}" ]; then majorVer="`getSiteDrupalMajorVersion "${pInstall}" "${pRootDir}"`" pBranch="`getLatestContribTag "${pWhatSpecific}" "${majorVer}"`" if [ -z "${pBranch}" ]; then echo -e "** Error getting latest branch/tag for ${pWhat} '${pWhatSpecific}'. Aborting.\n" exit 1 fi fi # Check out module/theme pushd "${installDir}" 2>&1 >/dev/null && git clone --depth 1 "`makeGitURL "${pWhatSpecific}"`" "${pWhatSpecific}" && cd "${pWhatSpecific}" && git checkout ${pBranch} && popd 2>&1 >/dev/null || { echo -e "** Error performing checkout of ${pWhat} '${pWhatSpecific}'. Aborting.\n" exit 1 } if [ -z "${pQuiet}" ]; then echo "Install of ${pWhat} '${pWhatSpecific}', branch '${pBranch}', complete in ${installDir}" fi ;; * ) echo -e "** ** WTF: install ${pWhat}.\n" exit 1 ;; esac ;; update ) # Validate the installation errorStr="`validateSite "${pInstall}" "${pRootDir}"`" if [ -n "${errorStr}" ]; then echo -e "** Error with specified install: ${errorStr}. Aborting\n"; exit 1 fi case "${pWhat}" in drupal | all ) # Installation target directory targetDir="`getTargetDir "${pInstall}" "${pRootDir}"`" if [[ "${pWhat}" == "all" ]]; then if [ -z "${pQuiet}" ]; then echo "Updating Drupal core." fi fi # We do different things if we're updating to a new branch (branch hopping) # versus updating to the most recent files in the current branch. if [ -n "${pBranch}" ]; then # branch hopping cd "${targetDir}" && # TODO Git Test need to test this (same code as below) git checkout -q "${pBranch}" || { echo -e "** Error performing branch hop of Drupal. Aborting.\n" exit 1 } else # We can only do an update if we're on a branch (tags do not have updates) gitTagLabel="`gitTag "${targetDir}" "onlylabel"`" if [ "${gitTagLabel}" == "branch" ]; then # Updating current files via 'git pull' cd "${targetDir}" && git pull -q || { echo -e "** Error performing update of Drupal. Aborting.\n" exit 1 } fi fi # If we're updating everything call this script to update each module if [[ "${pWhat}" == "all" ]]; then if [ -z "${pQuiet}" ]; then echo "Update of Drupal core complete in ${targetDir}" fi "${0}" -noconfirm ${pQuiet} ${pBranchParam} ${pLatestVersion} update allmodules "${pInstall}" "${pRootDir}" else # Only need to print disclaimer if we're just updating drupal -- 'allmodules' prints it. if [ -z "${pQuiet}" ]; then echo "** Remember to run update script at http://${pInstall}/update.php" fi fi ;; module | theme ) if [ "${pWhat}" == "module" ]; then installDir="`getDirForContribModule "${pInstall}" "${pRootDir}" "${pWhatSpecific}"`" else # (theme) installDir="`getDirForContribTheme "${pInstall}" "${pRootDir}" "${pWhatSpecific}"`" fi # Ensure installed module/theme dir exists if [ ! -d "${installDir}" ]; then echo -e "** Contrib ${pWhat} install directory '${installDir}' does not exist. Aborting.\n" exit 1 fi # Determine target tag, if any. if [ -n "${pLatestVersion}" ]; then majorVer="`getSiteDrupalMajorVersion "${pInstall}" "${pRootDir}"`" pBranch="`getLatestContribTag "${pWhatSpecific}" "${majorVer}"`" if [ -z "${pBranch}" ]; then echo -e "** Error getting latest tag for ${pWhat} '${pWhatSpecific}'. Aborting.\n" exit 1 fi fi # update module/theme if [ -n "${pBranch}" ]; then # branch hopping cd "${installDir}" && git checkout -q "${pBranch}" || { echo -e "** Error performing branch hop of ${pWhat} '${pWhatSpecific}'. Aborting.\n" exit 1 } else # We can only do an update if we're on a branch (tags do not have updates) gitTagLabel="`gitTag "${installDir}" "onlylabel"`" if [ "${gitTagLabel}" == "branch" ]; then # Updating current files via 'git pull' cd "${installDir}" && git pull -q || { echo -e "** Error performing update of ${pWhat} '${pWhatSpecific}'. Aborting.\n" exit 1 } fi fi if [ -z "${pQuiet}" ]; then if [ -n "${pBranch}" ]; then echo "Update of ${pWhat} '${pWhatSpecific}', branch ${pBranch}, complete in ${installDir}" else echo "Update of ${pWhat} '${pWhatSpecific}' complete in ${installDir}" fi if [ "${pWhat}" == "module" ]; then echo "** Remember to run update script at http://${pInstall}/update.php" fi fi ;; allmodules ) # For each module in installed modules list, call this script to update it. for module in `getInstalledContribModuleList "${pInstall}" "${pRootDir}"`; do if [ -z "${pQuiet}" ]; then echo "Updating module '${module}'... " fi "${0}" -noconfirm -quiet ${pBranchParam} ${pLatestVersion} update module ${module} "${pInstall}" "${pRootDir}" if [ -z "${pQuiet}" ]; then echo -e "done\n" fi done if [ -z "${pQuiet}" ]; then echo "** Remember to run update script at http://${pInstall}/update.php" fi ;; * ) echo -e "** ** WTF: update ${pWhat}.\n" exit 1 esac ;; remove ) # Validate the installation errorStr="`validateSite "${pInstall}" "${pRootDir}"`" if [ -n "${errorStr}" ]; then echo -e "** Error with specified install: ${errorStr}. Aborting.\n"; exit 1 fi case "${pWhat}" in module | theme ) if [ "${pWhat}" == "module" ]; then installDir="`getDirForContribModule "${pInstall}" "${pRootDir}" "${pWhatSpecific}"`" else # (theme) installDir="`getDirForContribTheme "${pInstall}" "${pRootDir}" "${pWhatSpecific}"`" fi # Ensure installed module/theme dir exists if [ ! -d "${installDir}" ]; then echo -e "** Contrib ${pWhat} install directory '${installDir}' does not exist. Aborting.\n" exit 1 fi # remove directory /bin/rm -r "${installDir}" if [ -z "${pQuiet}" ]; then echo "Removal of ${pWhat} '${pWhatSpecific}' complete." fi ;; * ) echo -e "** ** WTF: remove ${pWhat}.\n" exit 1 esac ;; * ) echo -e "** ** WTF: op=${pOp}.\n" exit 1 esac # Done if [ -z "${pQuiet}" ]; then echo -e "\n** Done." fi