… of many things …

… of many things … header image 1

Force.com Migration Tool (a real world example)

August 28th, 2008 · No Comments

I think the docs that come with the Force.com Migration Tool are woefully understated. Jon Mountjoy's article is a good overview, but it doesn't do much to help at the nitty-gritty-detail-level. So, I thought I would post this showing how we use the tool.

First things first. What is it? The Migration Tool is just a library that you can embed into your Ant distribution, or that you can reference from the commandline. This library calls Force.com's web services to accomplish its work. For more discussion on this, reference the afore mentioned article by Mr. Mountjoy. I also will not talk about all of the available targets. This will be a use case study.

We use the tool to deploy code to production and to our sandbox. We sometimes deploy small portions of code and sometimes all of it. We also use it to deploy metadata changes.You can view our build.xml in the attached files.zip.

It's pretty simple. The first thing to notice about it is that we have two targets called 'use_prod_environment' and 'use_test_environment'. These targets depend on properties. The use_prod_environment will be invoked if the property use_prod_env is set. We do this from the commandline by specifying -Duse_prod_env=true when we invoke Ant. The same is true for the test (sandbox) environment -- this is actually the default, so if we specify nothing on the commandline the Sandbox environment will be used.The next thing to notice is that we have only 2 other targets retrieveUnpackaged and deploy. These targets depend on the environment targets above which set properties for the Force.com URL, username and password. retrieveUnpackaged always retrieves code from the specified environment to a single location unpackaged under our src directory. deploy depends on another environment variable called deploy.root. This variable tells the Tool what set of resources (code and/or metadata) are going to be pushed to Force.com.

Deploying is the only activity we do that cares about dealing with subsets of files. So to do that we have created more directories along-side the unpackaged directory: limitedRelease, apex, and objects. Each of these directories includes a package.xml that specifies what metadata and/or code is to be pushed (telling the Tool what directories to look for). In truth, you can have the same package.xml for any of these directories (just copy it from the unpackaged directory). What really matters is the directory structure underneath. If you have a classes directory the Tool will deploy whatever classes are there. If you have a triggers directory it will deploy whatever triggers are there. The same goes for objects, applications, letterhead, pages, profiles, scontrols, staticresources, and tabs -- all directories within this directory.

Our 'limitedRelease' directory is a testing ground for new changes. We hard-copy classes and triggers into its subdirectories (along with their associated '-meta.xml' files). We work on that set of code and deploy it to the Sandbox as we test (test-first mind you, which is a little more of a hassle with Force.com, but still doable).

Our 'apex' directory is for all classes, pages, triggers and staticresources. They are all soft-links to the subdirectories under 'unpackaged'. This directory is used to deploy all of these resources to production and/or sandbox, as opposed to the limited set under limitedRelease.

Our 'objects' directory is used to migrate object metadata changes between production and the sandbox. The files under this directory may be hard-linked or soft-linked.The basic commandline looks something like:

ant -Ddeploy.dir=limitedRelease #deploys resources that are currently being developed to Sandbox

ant -Duse_prod_env=true -Ddeploy.dir=apex #deploys code resources to Production

ant -Duse_prod_env=true -Ddeploy.dir=objects #deploys object metadata to Production

ant retrieveUnpackaged #gets all resources from Sandbox

ant -Duse_prod_env=true retrieveUnpackaged #gets all resources from Production

Instead of typing these out all of the time, we use shell scripts which expect to be passed the use_prod_env variable when we want to deploy something to Production, otherwise it's deployed to the Sandbox.For instance our deployApex.sh looks like this:

BASH:
  1. ant -lib ../lib deploy -Ddeploy.root=apex $1

We keep the Force.com Migration Tool library in a lib directory above our src directory and reference that in our shell scripts.

You can download the files mentioned in this article here.

→ No CommentsTags: Force.com · Computing · Software

Fast User Switching via Keyboard

June 22nd, 2008 · No Comments

I copied the following Bash script from MacScripter and combined it with TextExpander's ability to execute Apple Script in order to give me the ability to switch to the Login screen via a keyboard shortcut (I mapped it to 'ffus').

BASH:
  1. #!/bin/sh
  2. # Fast User Switching from the command line
  3. # I saved mine as /usr/local/bin/fus
  4.  
  5. CGSession='/System/Library/CoreServices/Menu Extras/User.menu/Contents/Resources/CGSession'
  6.  
  7. case "$#" in
  8. 0)
  9. # display login screen
  10. exec "$CGSession" -suspend
  11. exit
  12. ;;
  13. esac
  14.  
  15. # No reason to display the login panel for the current user
  16. case "$1" in
  17. "$USER" | "$UID")
  18. exit 0
  19. ;;
  20. esac
  21.  
  22. # can pass in a (short) username or userid
  23. id=`/usr/bin/id -u "$1"` || exit
  24.  
  25. # display login panel for user
  26. exec "$CGSession" -switchToUserID "$id"

The Apple Script I use to invoke this from TextExpander is:

APPLESCRIPT:
  1. do shell script "/usr/local/bin/fus "

→ No CommentsTags: Mac

MagLev

May 31st, 2008 · No Comments

MagLev is a Ruby VM in the works by Gemstone that is targeted for a first release around September of 2008.  I am really excited about this development.  The VM will hook up to the caches and persistent store that Gemstone provides.

Avi Bryant gave a nice demo of 100 days of work on the VM.  It does simple things in the typical Gemstone distributed fashion.  Talking with some Gemstone folks afterward, I found out that in 100 days they have implemented about 20% or 30% of the Core library.  In the MagLev talk they mentioned that they are effectively (and impressively) running about 38 of the rubyspecs defined by the Rubinius team.

Great stuff.

→ No CommentsTags: Rails · Ruby · Smalltalk

Rails and AIR

May 29th, 2008 · No Comments

I went to a tutorial for Powering Rails with AIR at the RailsConf2008.  There are some neat capabilities there.  One cool app they showed was their TwitterFriends which is a related-objects-graph application.  I could care less for Twitter, but I could imagine using this same thing for analyzing informal networks within a company (eg. hooking into an Exchange server and building a network based on email To: and Cc: headers).

→ No CommentsTags: Ruby

God, Religion, Crucifixion

February 17th, 2008 · No Comments

Our pastor, Shiva Tewari, had a really inspiring thought in today's service (well, actually he had a lot of inspiring thoughts, but here's just one...)

If religion is your god, you are certainly in bondage. However, if God is your religion you are certainly free.

It's a bit out of context but the thought is simple enough to understand: the church today is so full of impersonating spirits that most of Christianity is not really an inspired life, but instead a copy of someone else's inspiration.

Instead of praying from the heart, people learn to copy others' prayers. Instead of fasting out of inspiration, it's a formula by which we expect to earn some favor from God.

We may quote Galatians 2:20, "I am crucified with Christ, therefore I no longer live..." but is it really so? To be crucified with Christ is to be fully identified with the message of His crucifixion, the message of the cross. To know why Christ died, and what it has accomplished in my life!!

Oh that I might truly be crucified with Christ...

→ No CommentsTags: Christ