Ruby on Maven Quickstart!

Update

I removed the last ounce of native ruby support from this plugin in favor of JRuby. What does that mean to you, the consumer? That means that Mojos written as Ruby plugins will be just as portable as those written in Java. Users (nor authors) will need to have Ruby installed in order to run (or create) ruby script plugins.

Also, I have bumped the version up to 1.0-beta-1. Most of the major changes I wanted to do are done.

If you'd like to just get started, begin here

Before you begin, set up your maven workspace to download from the http://propellors.net/maven-repo repository (help can be found on the howto page).

Next, run the 'archetype-maven-rubyscript' archetype as below (all on one line).

mvn archetype:create -DarchetypeGroupId=org.codehaus.mojo
        -DarchetypeArtifactId=archetype-maven-rubyscript
        -DarchetypeVersion=1.0-beta-1-SNAPSHOT
        -DgroupId=test -DartifactId=rubyplugin -Dversion=1

This will download and install 'archetype-maven-rubyscript' and execute it, creating a new project for you named rubyplugin with a simple Ruby Mojo.

rubyplugin
|-- pom.xml
 `-- src
     `-- main
         `-- scripts
             `-- my_mojo.rb

Look at the my_mojo.rb file. It is the ruby mojo that the goal mymojo will be created from. Now change to the base of the new rubyplugin directory, and install the generated plugin.

cd rubyplugin
mvn install

Now you have a Ruby Mojo in your repository! Go ahead and run the mymojo goal.

mvn test:rubyplugin:1:mymojo

You should see the following, with the default value in the param:

[INFO] [rubyplugin:mymojo]
[INFO] This is my param: 'hello!'

That's it! You can create a test project that configures the param to be any value you wish, and it will be displayed instead of the default 'hello!'. I hope everything worked well. Please note that this has yet to be tested extensively (just WinXPSP2 and Ubuntu Linux), so testing on more OS's would be great! If you find any errors, please contact me. Thanks!

Ruby on Maven

Ruby

Ruby has quickly grown from an academic curiosity to a script-writer's dream for many reasons. But the following are some of the more obvious ones:

  • Simple object oriented design and easy to understand syntax.
    A common shortcoming of scripting languages are their lack of maintainability. Have you ever dug up a year-old Perl script you were certain you wrote? It may have been written by someone else. With Ruby, it is easy to decode and extend that hack.
  • Powerful Perl-like expressiveness (yet understandable).
    It combines the power of Perl with the clean syntax of Python or Smalltalk. The bane of powerful scripting languages has long been their esoteric commands. Despite Rubys relatively low lines per non-trivial action, it is easy on the eyes.
  • Out-of-the-box utility.
    Much like PHP, Ruby just kind of works. RubyGems are a little extra bonus in adding functionality from a common repository. Sound familiar? Yeah, that's right, just like Maven. You're so smart.

But I don't need to sell you on Ruby. Chances are you know and love it; that's why you are here.

Maven

Maven has been around for at least a couple years, like Ruby (and potatoes), it has been flourishing underground. But there have been a couple issues stopping Maven from reaching its full potential:

  • Jelly.
    Jelly is an XML-based scripting language that is also an abomination of nature. If you have been fortunate enough to have never had to do seemingly simple operations with 50 lines of Jelly script, then take my word for it: it likely responsible for any lackluster response toward Maven 1.

In my opinion, that is all. Maven 2 on the other hand, is simple, componentized, extensible. All plugins are written in Java. Although a huge step up from Jelly, Java is ill-suited for operations generally required in build systems. Namely: file manipulations, parsing, document generation. It is a wonderful core, but no one wants to write, compile, test and package a Maven Java class (dubbed a Mojo) containing akwards Java parsing code to do something simple like extracting file annotations. Enter Ruby Mojo support.

Ruby Mojo Support

Unfortunately, Maven does not come with every task you could ever want done already available from ibiblio. Fortunately, the developers have added hooks into the very core of Maven 2, making extension of the build-lifecycle relatively painless. My goal is to make it even more painless by adding support for a language that is more suited for the majority of tasks one will encounter when extending their build system with whatever hacks the developer likes. Ruby is such a language. You can download and install the code or use it correctly include the projects into your plugin.

It is still very much in alpha phase. So much so, that the todo list may seem shocking, but its not that bad:

  • Expand paremeter support to encompass lists, integers, booleans, and whatever else
  • Clean up the rubyscript-maven-plugin to be of a more general purpose Ruby support

How to use it

Unless you followed the quickstart guide, you need to download and install the code.

And add this to your Ruby plugin POM:

  <parent>
    <groupId>org.codehaus.mojo.plugins</groupId>
    <artifactId>rubyscript-parent-maven-plugin</artifactId>
    <version>1</version>
  </parent>

If you wish to see the specific settings required for the ruby plugin to compile and work correctly, please read the 'rubyscript-parent-maven-plugin' pom.

Use the plugin like any Java plugin, defining configuration properties in the same way with one notable exception: All properties are currently Strings. This is something that I will fix in the future, but for the time being, all plugins used written in Ruby must contain only parameters of strings. This is not to say that you cannot pass in a string, and convert it to a File, or an Array, or anything else.

Good plugin examples are in the SVN repository, under 'rubyscript-maven-plugin' integration tests. Here is it00 plugin:

class RubyTest < Mojo
  goal :test
  description "This is a mojo description"
  phase :validate
  requiresDependencyResolution :compile

  string :prop, :expression=>"${someExpression}", :default=>"nothing", :alias=>"prop3", :required=>true

  def execute
    print "The following String was passed to prop: '#{@prop}'"
    return Hash.new
  end
end

run_mojo RubyTest

Note the run_mojo method at the end. It is what populates and executes the execute method, as well as sends any output to the system, prints messages and errors to the Mojo log. run_mojo must be called for the Mojo to work, and takes a parameter of the class (not a string, the class). prop is the string property method that will be populated.

To get the sample running, all you should need to do its check it out of SVN, cd to the base dir, run:

mvn install

Then, in the directory of the 'it-project-00' project, run:

mvn org.codehaus.mojo.ruby.it:it00-ruby-plugin:1:test

And you'll get a nice little message:

[INFO] [rubytest1:test]
[INFO] The following String was passed to prop: 'This is a property I set'

If you have ruby installed (native ruby), you can run all integration tests by going to the src/it directory and typing:

ruby rubyscript-it.rb

Contact or Development Info

Mail me if you have any comments or ideas. If you have patches, please send them also in the form of a SVN patch. You can get the source from here.