Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Tools
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Using the Style Guide gem

Doc Ritezel
Monday, January 21, 2013

Much like any good Rails engine, using Style Guide is designed to give you as much flexibility as possible. In its default state, Style Guide renders subdirectories full of partials located under app/views/style-guide.

You might be wondering what to do next. Let’s walk through iterating on a partial.
Continue reading →

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Introducing the Style Guide gem

Doc Ritezel
Monday, January 14, 2013

Your Rails application has a unit test suite in RSpec, a set of request specs using Capybara, and a Jasmine suite for your JavaScript. You may even have Cucumber so that your PM can participate in automated testing definition. According to long-standing traditions in Rails testing, your ass is covered.

You have a CSS-shaped hole in your test coverage. You need a style guide. Today, you can quickly set one up on your Rails application with the style-guide gem.
Continue reading →

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

The Naked Gemspec

Doc Ritezel
Friday, December 14, 2012

Before we start, the .gemspec itself only appears once. Here it is, as generated by bundle init and hand-tweaked for relevance:

lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "your_gem/version"

Gem::Specification.new do |s|
  s.name        = "your-gem"
  s.version     = YourGem::VERSION
  s.authors     = ["Your Name"]
  s.email       = ["you@example.com"]
  s.homepage    = "https://github.com/you/should-use-github"
  s.summary     = "Describe this gem like you're talking to me."
  s.description = "Describe this gem like you're talking to your mom."

  s.require_paths = ["lib"]
  s.files         = `git ls-files`.split("n")
  s.test_files    = `git ls-files -- spec/*`.split("n")

  s.add_dependency "hashie", "~> 2.0"
  s.add_development_dependency "rspec", "~> 2.12"
end

But what does all this mean? Moreover, how do all these crazy bits fit together?

Files

The most important component of any gemspec is the list of files that it includes when building the gem. After all, a .gem file is just a tarball with a metadata header written in Ruby. Here’s how we make that happen:

s.files         = ['file/one', 'file/two']
s.test_files    = ['spec/one', 'spec/two']

Let’s exploit part of git to give us the list of files. Don’t use git on your project? Start using git. Problem solved! Here’s what it gives us:

$ git ls-files
.gitignore
.rvmrc
Gemfile
LICENSE
README.md
your-gem.gemspec
lib/your_gem.rb
lib/your_gem/version.rb
spec/lib/your_gem.rb
spec/spec_helper.rb

We can make this output into a Ruby array of strings quite simply:

`git ls-files`.split("n")

Now, gems are laid out in a conventional way. That means a lib directory, a spec directory and some predictable files. That means nobody has to guess where your files are, which is fantastic!

Now let’s say you want to exclude your .rvmrc and .gitignore, because those files aren’t really all that important:

`git ls-files`.split("n") - %w(.rvmrc .gitignore)

Note: exclude Gemfile.lock from git, even though it might exist in your directory. This is conventional.

Naming

Your gem’s classes are called YourGem, while they live in files named your_gem. As a matter of taste, I believe gems should be named your-gem. There’s an argument to be made that gem names should match their requires (i.e., the gem should be named your_gem).

Version

The first component here is the version number for your gem. In this example, the your_gem/version.rb looks like this:

module YourGem
  VERSION = "0.1.0"
end

This is a Semantic Versioning string, and it’s the Simplest Thing that Could Possibly Work for a version.

Dependencies

This is the fun part. I’m of the opinion that dependencies should be as loose as possible until they’re not, but that throwing them away by doing >= 0 is the wrong approach.

For example, the above file will pull in RSpec as a dependency, but require any version that matches a pattern like 2.y.z, as long as y is above 12. Note that z is allowed to be anything, which allows patch versions to be included.

Of course, this means that everyone in the community has to play along and not break their gem on a minor version bump. Also, the community now includes you!

Maintenance

So now you’ve got a conventional gem with loosely-required dependencies. How do you know if these change? Well, if you’re on github, you can use Gemnasium to watch for new dependency versions and see if anything’s broken!

Dropping a new version of your gem is as easy as gem release with @svenfuchs‘s gem-release gem.

More Reading

  • Rubygems Patterns
  • Semantic Versioning
  • Clarifying the Roles of the gem spec and Gemfile
  • The Pessimistic Gem Version Operator
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Automated Deployment Messages

Doc Ritezel
Friday, October 5, 2012

Make deployment visible with Capistrano, Autotagger, Git and Sendgrid

There comes a time in every project when the deployment process comes of age, and that development arrives with its own set of Capistrano recipes and Rake tasks. The project I’m on hit that point recently, and one of the neat outcomes of its nascent puberty was a simple Capistrano recipe to send a git changelog to our project mailing list.

Here’s what this looks like:

$ cap staging deploy
... stuff happens here ...
  * executing `sendgrid:notify'
Changelog:
04fc6dd adding capistrano deployment messages

To use this in your Rails project, the first thing you need is a sendgrid account. If you’re budget-minded, you can always use the credentials your Heroku app is using.

$ heroku create
Creating heroku-wackiness-90210... done, stack is cedar
http://heroku-wackiness-90210.herokuapp.com/ | git@heroku.com:heroku-wackiness-90210.git
Git remote heroku added
$ heroku addons:add sendgrid:starter
Adding sendgrid:starter on heroku-wackiness-90210... done, v2 (free)
Use `heroku addons:docs sendgrid:starter` to view documentation.
$ heroku config -s
SENDGRID_PASSWORD=s3kr17
SENDGRID_USERNAME=yodawg@heroku.com

This process uses Capistrano and Autotagger. For information on setting up Capistrano, their wiki is an excellent starting point. For Autotagger setup with Capistrano, Jeff Dean’s auto_tagger repository is the canonical source of information.

After you’re up and running with Capistrano and Autotagger, you need to add the following file under lib/recipes/sendgrid_notifier.rb:

require 'mail'

set :sendgrid_user, "whatever"
set :sendgrid_password, "secret"
set :sendgrid_domain, "pivotallabs.com"

set :sender, "Now Hiring <jobs@pivotallabs.com>"
set :recipient, "Steve Squivot <you@square.com>"

namespace :sendgrid do
  task :notify do
    sendgrid = {
      :address   => "smtp.sendgrid.net",
      :port      => 587,
      :domain    => sendgrid_domain,
      :user_name => sendgrid_user,
      :password  => sendgrid_password,
      :authentication => 'plain',
      :enable_starttls_auto => true
    }

    auto_tagger = AutoTagger::CapistranoHelper.new(
      :stage => rails_env,
      :stages => auto_tagger_stages).auto_tagger
    previous_sha = auto_tagger.refs_for_stage(stage).last.sha
    current_sha = auto_tagger.repo.latest_commit_sha

    mail = Mail.new(from: recipient, to: sender)
    mail.delivery_method :smtp, sendgrid
    mail.subject = "[#{stage}] New Deployment!"
    mail.body = `git log --oneline #{previous_sha}..#{current_sha}`
    mail.deliver!
  end
end

Then, let’s add a line to include this recipe in our Capfile:

require File.expand_path("../lib/recipes/sendgrid_notifier.rb", __FILE__)

Finally, let’s try it out:

$ cap ci sendgrid:notify
  * executing `sendgrid:notify'
Changelog:
04fc6dd add a recruiter message to send off to Square

Alright! The email’s on its way. If you need to call this in your custom deployment step, it’s as easy as sticking sendgrid.notify into your Capfile.

Happy deploying!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

[Standup][SF] 09/12/12: The Milkshake Fiasco

Doc Ritezel
Wednesday, September 12, 2012

Events

  • Chocolate Milkshake Day was announced but not substantiated.

    The SF office is now in breathless anticipation of chocolate milkshakes.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Doc Ritezel

Doc Ritezel
San Francisco

Doc has been an on-and-off Rubyist since 2006, and served several multilingual tours of duty in the Browser Wars. He's what you might call a regular in the open source world, with recent contributions to the Hadoop, Chef, Backbone and Ruby communities.
Subscribe to Doc's Feed

Author Topics

agile (2)
bbq (1)
fiasco (2)
gems (1)
autotagger (1)
capistrano (1)
deployment (1)
rails (1)
milkshake (1)
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Tools
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >