Friday, May 04, 2007

[RELEASE] Plugems packaging

The Plugems runtime is enough to justify their existence, but it does not stop there. Since we already defined our dependencies in a gem-like fashion, it is only a small step to start using them for packaging as well. All that is needed for this is the plugems_deploy gem that can be installed from rubyforge. After the gem is installed, a new plugem command comes up. It piggy-backs to capistrano to provide some plugems-related recipes. The recipe packaged with the initial version is build. This action allows you to package your project as a gem.

Let's take for example our sample application's config:

:version: [1, 0]
:name: "cool_application"
:description: "My First Plugemified Application"
- ['some_gem', '~> 1.0']
- ['other_gem', '> 2.0']
- ['one_more', '2.0.1']

When we run the plugem build on the top of the application, we get a gem built:

$ plugem build
* executing task plugem_build
rm -rf pkg
mkdir -p pkg
Successfully built RubyGem
Name: cool_application
Version: 1.0.0
File: cool_application-1.0.0.gem
mv cool_application-1.0.0.gem pkg/cool_application-1.0.0.gem

If you looked inside, you would find that the attributes and dependencies from the manifest file were translated to corresponding gem attributes and dependencies.

Where did the build (micro) revision come from?

You might noticed that the manifest defined only major and minor revisions but there was a micro added during the packaging time. The plugem packaging process follows the Rubygem's rational versioning policy giving you full control over the build revision. The full version can be defined in the manifest file a-la-Rakefile (i.e. :version: [1, 0, 1]). You can derive it dynamically from a source like svn revision. You just set the capistrano gem_micro_revision variable in a deployment recipe (like config/deploy.rb). An svn based example is:
set :gem_micro_revision, `svn info`.grep(/^Revision:/).first[/(\d+)/][$1]

And you can always overwrite the full version via the '--version' flag of plugem: plugem build --version 3.2.1

The choice is yours.

You might wonder why would you package your rails application as a gem. The rationale is that it allows you to utilize the only ruby-native packaging and distribution system to distribute and deploy your application. The next plugem_deploy releases and this series installments would provide the tools and guidance how to do that.

But it is not just for packaging...

Since you have you dependencies clearly defined, it is really easy to update them to the latest version. Just run plugem update from the project directory:

$ plugem up
* executing task plugem_update
Updating some_gem (~> 1.0)
* executing task plugem_install
Bulk updating Gem source index for:
Installing [ some_gem, 1.2.2 ]

You also have a full control which gem servers to use. Set the variable in your deployment recipe:
set :gem_servers, [ '', '' ]

and see the difference:

$ plugem up
* executing task plugem_update
Updating some_gem (~> 1.0)
* executing task plugem_install
Bulk updating Gem source index for:
Bulk updating Gem source index for:

To Be Continued ...