Woah, that's a long title.

Today I wanted to share the little shell script I use for setting up local development sites in a one-liner in the terminal. Be advised that I don't usually write shell scripts, so if you are a pro, and I have made some obvious mistakes, please feel free to give improvements in the comment section. Also, while i have been writing this post, i noticed that Klausi also has a kick ass tutorial and shell script on his blog. Be sure to read that as well, since the article is much more thorough than mine. But since my script is for those even more lazy, I decided to post it anyway.

The idea I had was pretty simple. I constantly have the need to set up a fresh, working copy of drupal in various versions with various modules, i.e for bug testing, prototyping, or just testing a patch on a fresh install. While drush make and installation profiles are both awesome tools for a lot of things, I wanted to install Drupal without making make files and writing .info files, and at the same time generate the virtual host and edit my hosts file. And why not also download and enable the modules i need. For a while I used just

$ drush si

(site-install) on a specified directory for flushing and starting over, but part since I have little experience in writing shell scripts (I said that, right?), I thought, what the hey, let's give that a go. Fun to learn new stuff. On my computer the script is called vhost, but since this is not a describing name, and the script is all about being lazy, let's call it lazy-d for the rest of the article (lazy-d for lazy drupal. Also, it is kind of catchy).

So the basic usage is

$ ./lazy-d [domainname] [drupalversion] “[modules to download and enable]”

For example:

$ ./lazy-d example.dev 7 “views ctools admin_menu coffee”

This will download drupal 7 to example.dev in your www directory, create a database and user called example.dev, install Drupal with the site name example.dev, edit your hosts file so you can navigate to example.dev in your webbrowser, and download and enable views, ctools admin_menu and coffee modules.

Running the script like this:

$ ./lazy-d example.dev

will do the same, but with no modules (so Drupal 7 is default, as you might understand).

You can also use it to download Drupal 8, but the drush site install does not work at the moment (it used to when I wrote the script a couple of weeks back though). Drupal 6 is fully supported.

The script has been tested on ubuntu 12.04 and mac os x 10.7. On mac you may have to do some tweaking (depending on whether you have MAMP or XAMPP or whatever) to the mysql variable at the top. And probably do something else with the a2ensite and apache2ctl restart as well (again, depending on your setup).

The script obviously requires apache, php, mysql and drush (git if downloading drupal 8).

OK, to the code:

#!/bin/bash

# Configuration
VHOST_CONF=/etc/apache2/sites-available/
ROOT_UID=0
WWW_ROOT=/var/www
MYSQL=`which mysql`
DRUSH=`which drush`
# If you don't use drush aliases, uncomment this.
DRUSHRC=/home/MYUSERNAME/.drush/aliases.drushrc.php
TMP_DIR=/var/www/tempis
[email protected]
LOG_DIR=/var/log

# Check if we are running as root
if [ "$UID" -ne "$ROOT_UID" ]; then
  echo “You must be root to run this script.”
  exit
fi

# Check that a domain name is provided
if [ -n "$1" ]; then
  DOMAIN=$1
else
  echo “You must provide a name for this site”
  echo -n “Run this script like $0 mycoolsite.test.”
  exit
fi

# Downloading the correct Drupal version.
cd $WWW_ROOT
if [ -n "$2" ]; then
  VERSION=$2
else
  VERSION=7
fi

case $VERSION in
  7) $DRUSH dl --destination=$TMP_DIR
  ;;
  8) git clone --recursive --branch 8.x http://git.drupal.org/project/drupal.git $1
  ;;
  6) $DRUSH dl drupal-6 --destination=$TMP_DIR
  ;;
esac

# Move the folder to the correct place. Drupal 8 was cloned directly to the correct place.
if [ "$VERSION" -ne "8" ]; then
  cd $TMP_DIR
  mv drupal* $WWW_ROOT/$DOMAIN
  rm -rf $TMP_DIR
fi

# Create the database and user.
Q0="DROP DATABASE IF EXISTS \`$1\`;"
Q1="CREATE DATABASE IF NOT EXISTS \`$1\`;"
Q2="GRANT ALL ON \`$1\`.* TO '$1'@'localhost' IDENTIFIED BY '$1';"
Q3="FLUSH PRIVILEGES;"
SQL="${Q0}${Q1}${Q2}${Q3}"

# If you want to keep you password in the file, uncomment the following line and edit the password.
# $MYSQL -uroot --password=Mypassword -e "$SQL"

# If you have no password, uncomment the following line to skip the password prompt.
# $MYSQL -uroot -e "$SQL"

# Else, this prompts for password. If you have uncommented any of the above,
# comment this out, please.
echo "Need the MYSQL root password"
$MYSQL -uroot -p -e "$SQL"

echo "<VirtualHost *:80>" >> $VHOST_CONF/$DOMAIN
echo "    ServerAdmin $SERVER_ADMIN" >> $VHOST_CONF/$DOMAIN
echo "    DocumentRoot $WWW_ROOT/$DOMAIN" >> $VHOST_CONF/$DOMAIN
echo "    ServerName $DOMAIN" >> $VHOST_CONF/$DOMAIN
echo "    ErrorLog $LOG_DIR/$DOMAIN-error_log" >> $VHOST_CONF/$DOMAIN
echo "    CustomLog $LOG_DIR/$DOMAIN-access_log common" >> $VHOST_CONF/$DOMAIN
echo "" >> $VHOST_CONF/$DOMAIN
echo "    <Directory \"$WWW_ROOT/$DOMAIN\">" >> $VHOST_CONF/$DOMAIN
echo "      AllowOverride All" >> $VHOST_CONF/$DOMAIN
echo "    </Directory>" >> $VHOST_CONF/$DOMAIN
echo "</VirtualHost>" >> $VHOST_CONF/$DOMAIN

echo "127.0.0.1 $DOMAIN" >> /etc/hosts

# This will enable the virtual host in apache. If you are on mac, just include
# the vhost directory in the apache config, and uncomment the follwing line.
a2ensite $DOMAIN

# If you are on mac, check if this will really restart your MAMP/XAMPP apache.
# Or just uncomment and restart with the pretty GUI manually.
apache2ctl restart

cd $WWW_ROOT/$DOMAIN
drush si --db-url=mysql://$1:$1@localhost/$1 --site-name=$1 --account-pass=admin
if [ -n "$3" ]; then
  drush dl $3
  drush en $3
fi

# Create Drush Aliases
if [ -f $DRUSHRC ] && [ -n "$DRUSHRC" ]; then
  echo "" >> $DRUSHRC
  echo "<?php" >> $DRUSHRC
  echo "\$aliases['$1'] = array (" >> $DRUSHRC
  echo " 'root' => '$WWW_ROOT/$DOMAIN'," >>$DRUSHRC
  echo " 'uri' => 'http://$1'," >>$DRUSHRC
  echo ");" >>$DRUSHRC
  echo "?>" >> $DRUSHRC
else
  echo "No drush alias written."
fi

echo “Done. Navigate to http://$DOMAIN to see your new site. User/pass: admin.”
exit 0

All done, indeed. Pretty straight forward code. Known issues: will drop existing database if you specify one that exists. But why would you do that? Don't you know what you are doing?

To finish this off, here is an animated gif called "alien computer":