I come from a mavenized world.
a world where a project’s structure and dependencies are well specified in a model and a world where that model, maven and the Java SDK are everything I need to build a project anywhere. maybe there’s some things wrong with maven; I think this is one of the things where it excels.
so when I play with other languages, my tendency is to look for the “maven metaphor”, the “maven way” to define a project, build it and have its dependencies resolved, hopefully from an all-knowing internet entity.
I felt in heaven when I found Leiningen for Clojure, but I almost cried when I found weird things for C# and ugly things for C++. I won’t even talk about JavaScript here but for Ruby… ahh Ruby… a language homonymous with Silvio Berlusconi’s underage exotic dancer… a language that follows that principle of least astonishment… seriously Ruby, you’re messed up. here’s how I understand the Ruby world of project management / dependency management. probably it’s all wrong, which just speaks to how much I suck at this.
so, a common practice seems to be to use Rake to build the project and Gem to distribute it. Rake is like Make. But for Ruby. and Gems are like Maven artifacts. but then, it seems like the best way to use these two things together is by means of another tool — Bundle.
so, let’s imagine a system where you have Ruby, Gem, Rake and Bundle installed. the (rough) equivalent to mvn archetype:generate would be bundle gem rubacuori.
this will create a directory structure with some not very obvious things:
- Gemfile — this would normally be where you would put your project’s dependencies. except your won’t. because it will point to the gemspec, a way of saying “dependencies are all in rubacuori.gemspec“;
- rubacuori.gemspec — this is where you have information about your project as well as dependencies and is the closest we get to a pom.xml file except it isn’t. because it does not define any project build phases;
- Rakefile — this is where your build phases would be defined. by default this includes something called gem_tasks, which is a set of default tasks like “build”, “install” and “release”, kind of equivalent to
mvn compile,mvn installandmvn release:prepare+mvn release:perform; - ./lib and finally, your code should go in this directory.
so, somewhat different that Maven, in that Maven tries to do everything and here each tool does one thing and one thing only. Not worse nor better; just different.
now what is definitely good is that this seems to be an accepted standard for building Ruby applications — in RubyMine, if you create a new project, this is exactly the structure it will have:
/Users/Luis/.rvm/gems/ruby-2.0.0-p0@global/bin/bundle gem untitled
create untitled/Gemfile
create untitled/Rakefile
create untitled/LICENSE.txt
create untitled/README.md
create untitled/.gitignore
create untitled/untitled.gemspec
create untitled/lib/untitled.rb
create untitled/lib/untitled/version.rb
Initializating git repo in /Users/Luis/dev/untitled
you can always count on JetBrains.
:-)

