Deploy Drupal Modules and Themes with Eclipse External Tools

Eclipse, with the newly released PDT 2.0, is a very capable Drupal IDE. With code completion, automatic documentation lookups, and integrated debugging, Eclipse is very good for anyone who spends time doing Drupal code.

One issue I've run into with Eclipse when working on contributed modules is that the modules themselves aren't located within a Drupal installation. I found myself resorting to external programs or the command line to copy my changes to my development site or to my local development copy. Using Eclipse's External Tools, it's possible to deploy changes with a single click, greatly reducing the time to test modified code.

Step 1: Create a new project to contain scripts and configurations

New Project: Select the Project entry under General to create a generic project.New Project: Select the Project entry under General to create a generic project.First, create a new generic project. This project won't contain anything other than shell scripts and external tool configurations, so it doesn't need to be a PHP project. I called mine deploy_scripts.

Step 2: Create the script to copy your module or theme

Create the following script as a new file in your deploy_scripts project as deploy_project.sh. It uses rsync to syncronize changes, including deleted files. This should work as is on OS X and any other *nix. If you're developing on Windows, you'll need to install rsync, bash, and modify the script as needed.

#!/bin/bash

# These are example environment variables. The should be set in your Eclipse
# external tool configurations.
#WORKSPACE=/Users/<username>/Documents/workspace
#PROJECT=drupal6
#SSH='-e ssh'
#printf "%s\n" "$SSH"
#DESTINATION=$WORKSPACE

case "$1" in

'--module')
  echo "Installing module $2 to $PROJECT/sites/all/modules..."
  rsync `printf "%s\n" "$SSH"` \
  --exclude='CVS' \
  --exclude='.svn' \
  --exclude='.settings' \
  --exclude='.project' \
  --exclude='.buildpath' \
  --exclude='bin' \
  --delete \
  -av $WORKSPACE/$2 $DESTINATION/$PROJECT/sites/all/modules/
  ;;

'--theme')
  echo "Installing theme $2 to $PROJECT/sites/all/themes..."
  rsync `printf "%s\n" "$SSH"` \
  --exclude='CVS' \
  --exclude='.svn' \
  --exclude='.settings' \
  --exclude='.project' \
  --exclude='.buildpath' \
  --exclude='bin' \
  --delete \
  -av $WORKSPACE/$2 $DESTINATION/$PROJECT/sites/all/themes/
  ;;

esac;

Step 3: Create launch configurations for your destination projects

New External Tools Configuration: Be sure to click Apply to save any changes.New External Tools Configuration: Be sure to click Apply to save any changes.Now, it's time to create launch configurations for each deployment target. In my case, I have one for each version of Drupal (5, 6, and 7) I work with, as well as one for each project I'm working on. To create a configuration, go to Run -> External Tools -> External Tools Configurations.... Be sure that your deploy_scripts project is selected, as that's where we want the configuration to be saved. To create a new configuration, click on 'Program' on the left column, and then click the 'New' button. You should then be shown a window similar to the screenshot.

Fill in the fields in each tab like the following:

Main

  • Location: ${workspace_loc:/deploy_scripts/deploy-project.sh}
  • Main TabMain TabArguments (to deploy a module): --module ${project_name}
  • Arguments (to deploy a theme): --theme ${project_name}

Refresh

  • Check off "Refresh resources upon completion"
  • Select the "Specific resource" radio button, and select your destination project.
  • Refresh TabRefresh TabEnsure that "Recursively inside sub-folders" is also checked.

Environment

Add the following variables to tell the script about your project:

  • DESTINATION: Full path to directory containing the destination project. This can either be a local path like /Users/<username>/projects, a variable, like ${workspace_loc}, or a remote location like drupal6@drupal6.example.com:/home/drupal6. For remote locations, see the SSH variable below.Environment TabEnvironment Tab
  • PROJECT: The name of the directory containing your project. Locally, this might be the project name, but on a remote server, this might be www or public_html.
  • SSH: If you wish to use SSH to push your changes to a remote system, specify this as -e ssh. If your ssh program is different, replace ssh with the path to the ssh binary. Otherwise, don't specify this variable. I recommend you use an SSH public key, otherwise you'll have to type in a password every time you publish.
  • WORKSPACE: This defines the location of your local workspace in Eclipse. You can use this in the case that your code is stored outside of Eclipse's workspace. Most users will define this as ${workspace_loc}.

Common

Common TabCommon Tab

  • Set "Save as" to "Shared file". Use the Browse button to save it in the deploy_scripts project.
  • I suggest checking off "Display in favorites menu".

Step 4: Click the button and deploy your project!

To copy your current work to your testing environment, it's easiest to click the toolbar button to run the appropriate tool. Clicking on the arrow will display a menu of all available configurations, while clicking on the button itself will automatically run the last used configuration. Favorites MenuFavorites MenuIf everything works properly, you should get output similar to the following in the console:

Installing module tableofcontents to www/sites/all/modules...
building file list ... done
tableofcontents/README.txt
tableofcontents/headinganchors.info
tableofcontents/headinganchors.module
tableofcontents/tableofcontents.css
tableofcontents/tableofcontents.info
tableofcontents/tableofcontents.js
tableofcontents/tableofcontents.module
tableofcontents/po/pl.po

sent 8126 bytes  received 484 bytes  3444.00 bytes/sec
total size is 57993  speedup is 6.74

As rsync is used to actually do the copy, only changed files will be updated when the tool is run again. This can save a significant amount of time when developing a theme or module with a significant number of images, or when developing remotely on a low bandwidth connection.

Future Work

It would be really neat if instead of having different switches for modules and themes, and having to specify the switch in the launch configuration, if the shell script could search for a .info file and determine from it if it's a module or theme. Also, it's possible to accidentally deploy a project to itself. If you do this for a full Drupal project, you end up with all of core duplicated in sites/all/modules. Some basic sanity checking would be a welcome feature.

What other tricks do you use to quickly deploy your code for testing? Post in the comments, or if you're coming to Drupalcon DC, drop in the Eclipse fans using Drupal BoF.

Comments

Drush

Could be interesting writing such scripts that use the Drush module.

ssh-askpass

On Ubuntu I got and error about ssh-askpass

the solution is

sudo apt-get install ssh-askpass

Second small remark is that if you use a remote connection the destination should look like:

user@hosting.mountbatten.net:

including the : (semi-colon). You easily oversee that.

Very usefull article!