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
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
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}
- Arguments (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.
- Ensure 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 likedrupal6@drupal6.example.com:/home/drupal6
. For remote locations, see the SSH variable below. - 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
orpublic_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
- 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. If 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!