Mike Barinek's blog
Here are a few notes on how to get individual CruiseControl.rb project Builders running with RVM.
[Note: I'm making an assumption here that you know and understand Bundler and RVM.]
[Also: Cruise may or may not be running on RVM]
Create and check in a .rvmrc file in your rails root directory. Here's an example.
rvm ruby-1.8.7-p174@rails-example
Then, add a project build command to your cruise_config.rb file.
Project.configure do |project| project.build_command = './cruise_build.sh' end
Finally, create a cruise_build.sh file. The bash script setups rvm and just calls your cruise control build task.
[Note: Your cruise rake task should probably call Bundler's "bundle install".]
#!/bin/sh source $HOME/.rvm/scripts/rvm && source .rvmrc rake cc:build
...and your cruise project builder is now using RVM!
Inspired by Aaron Patterson at the Mountain.rb Conference, I thought I'd share my favorite programming/software engineering books.
- C Programming Language (2nd Edition) by Brian W. Kernighan and Dennis M. Ritchie (1988)
- Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (1994)
- Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development by Craig Larman (1995)
- Refactoring: Improving the Design of Existing Code by Martin Fowler, Kent Beck, John Brant, and William Opdyke (1999)
- Peopleware: Productive Projects and Teams (Second Edition) by Tom DeMarco and Timothy Lister (1999)
- Extreme Programming Explained: Embrace Change by Kent Beck (1999)
- Effective Java by Joshua Bloch (2001)
- Test Driven Development: By Example by Kent Beck (2002)
- Refactoring to Patterns by Joshua Kerievsky (2004)
- Java Concurrency in Practice by Brian Goetz, Tim Peierls, Joshua Bloch, and Joseph Bowbeer (2006)
- Restful Web Services by Leonard Richardson, Sam Ruby, and David Heinemeier Hansson (2007)
- Getting Real: The smarter, faster, easier way to build a successful web application by Jason Fried, Heinemeier David Hansson, and Matthew Linderman (2009)
If you’re thinking about starting a software project, here’s the recipe that I’ve been giving people.
Have complete visibility into your feature backlog
(i.e. what is happening with your software)
Use a tool like Pivotal Tracker. Have 1 week iterations. Include features, chores, and bugs. Assign points to features. Work should be getting done (i.e. stories should be marked as finished, and you should have a weekly point total). If work isn’t getting done (i.e. point count is low for an iteration), this is a ‘smell’, something might be going wrong. Regularly review and accept the work the developers are doing.
Outsource your infrastructure
- Sign up for an account on GitHub
- Sign up for an account on Heroku, Engine Yard, or Amazon.
- Use Gmail, GoogleApps
Own your source code
Use git. Own your github account and give collaborator access to developers. Developers may move on or off the project, but you’ll always have access to the code base.
Plan for multiple Environments
You should plan for 3 environments, Continuous Integration (CI), Review, and Production. You’ll accept stories in the review environment and push tagged releases to production.
Keep a high Bus Count
Rotate developers through your application feature set. Avoid siloing developers at all costs, “code with a buddy”. Give complete infrastructure access to your developers (DNS, Google Apps/Email, and infrastructure), trust them completely.
Write tests and setup a continuous integration environment
Tests are essential for describing application features and intentions within the code base. Tests are essential for knowledge transfer between developers (it’s unlikely that you’ll have the same developer on the project at all times). Tests give you the confidence to change product direction without breaking or rewriting the entire code base. Without tests, you should quit now. (This is especially true for interpreted languages like ruby). Test drive.
Keep the deployment process nimble
Because you are test driving and have continuous integration, you can deploy at any time. Give your hosting credentials (engine yard, amazon, etc.) to your developers. They should be able to deploy to review or production within minutes (not hours).
Invest in your team
Don’t let bad technology choices effect your startup, there are plenty of risks out there. Find a platform and team that will guarantee minimal technical risk. There’s a huge difference developer skill sets theses days. Find a great team and pay them well. Good software is expensive, build and invest in your development team. Expect this to be your budget and hire generalists.
Recently I've been working on a small spike intended to help jumpstart our Rails application development in the Pivotal Labs Boulder office.
Until Rails 3 was officially released, new projects used the Pivotal "rails-template" to help bootstrap development. The template is really just a GitHub repo that installs dependencies in our Rails 2 project.
There's are few new interesting new features in Rails 3, including a "--builder=" option to the "rails new APP_PATH [options]" command. I thought this might be an interesting solution to bootstrapping an application, especially when your dependencies include Rails generators.
The spike makes a few choices regarding dependencies and testing preferences. For example, we tend to use things like RSpec and Cucumber as well as Cruise.rb, Engine Yard Cloud, and NewRelic. To make life a bit easier, I also used RVM and Gemsets to help set the initial set of dependencies. Even more interesting, I'm able to bootstrap from a GitHub Gist or any directly downloadable file URL.
Initial Setup
For everything to work without a hitch, I have both a local .rvmrc file and Bundler Gemfile within my ~/workspace/mahan directory with the below Gems installed.
[Note: I'm making an assumption here that you know and understand Bundler and RVM]
Here's the .rvmrc file I used within the ~/workspace/mahan directory.
rvm_archflags="-arch x86_64" rvm 1.8.7-p174@mahan
And here's a few commands to get you started.
$ cd workspace/ $ mkdir mahan $ cd mahan/ $ vi .rvmrc rvm_archflags="-arch x86_64" nrvm 1.8.7-p174@mahan"
Also, here's the Gemfile I used within the ~/workspace/mahan directory.
You'll need to run "gem install bundler --version 1.0" from this directory and then run "bundle install".
source 'http://rubygems.org' gem 'rails', '3.0.0' gem 'mysql2' gem "rspec-rails", '2.0.0.beta.22' gem "rspec", '2.0.0.beta.22' gem 'capybara', '0.3.9' gem 'database_cleaner', '0.5.2' gem 'cucumber-rails', '0.3.2' gem 'cucumber', '0.9.0' gem 'rspec-rails', '2.0.0.beta.22' gem 'spork', '0.8.4' gem 'launchy', '0.3.7' gem 'jasmine', :submodules => true gem 'json_pure', '1.4.6'
Agin, a few commands to get you started.
$ cd ~/workspace/mahan/ $ rvm gemset create 'mahan' $ rvm gemset use mahan $ gem install bundler --version 1.0 $ vi Gemfile [Add the above Gemfile contents] $ bundle install
Rails Builder
Next, I'll dive right into the Rails command. From your ~/workspace/mahan directory run
rails new rails_example --builder=http://gist.github.com/611035.txt
The command creates a new Rails 3 application with our default set of dependencies.
Feel free to take a look at the actual Gist. You'll notice that I extend "class AppBuilder < Rails::AppBuilder". If you're interested in the Rails guts, take a look around line 316 in railties-3.0.0/lib/rails/generators/rails/app/app_generator.rb. The Rails AppGenerator looks for custom builders and then performs an instance_eval on the file.
You'll also notice that I "override" the test method within my custom AppBuilder to include RSpec, Cucumber, and Jasmine. The actual method then call the associated Rails install generator. And yes, you'll notice we're working on the Jasmine Rails 3 support.
def test append_test_gems rspec cucumber jasmine end
I also override the "leftovers" method to include things like Cruise.rb, Engine Yard Cloud, and NewRelic dependencies and configurations. The "leftovers" method gets call from the AppGenerator "finish_template" method. With a few of the "leftovers", I simply pull the from the associated GitHub repo and copy the necessary files and/or directories.
I've also experiment with a Gem that includes a Thor wrapper around a custom Rails AppGenerator. The benefit for this approach is that now I'm now able include my own custom Rails options. For example
class PivotalAppGenerator < Rails::Generators::AppGenerator
include Thor::Shell
source_root File.expand_path('../templates', __FILE__)
class_option :skip_rspec, :type => :boolean, :aliases => "-R", :default => false, :desc => "Skip rspec"
class_option :skip_cucumber, :type => :boolean, :aliases => "-C", :default => false, :desc => "Skip cucumber"
class_option :skip_jasmine, :type => :boolean, :aliases => "-J", :default => false, :desc => "Skip jasmine"
We'll probably use a combination of the AppBuilder and AppGenerator approach, although at this time I thought some feedback would be interesting.
