Rubygems And You

50
Josh Nichols technicalpickles.com RubyGems and You

description

RubyGems are the packaging system used by Ruby to distribute libraries. What people forget is that it’s pretty easy to make and distribute your own gems. This talk will cover the basics of creating and managing a RubyGem using Rake and GitHub. Jeweler, a tool for automating these tasks, will also be covered.

Transcript of Rubygems And You

Page 1: Rubygems And You

Josh Nichols technicalpickles.com

RubyGems and You

Page 2: Rubygems And You

Josh Nichols technicalpickles.com

• How ‘require’ works

• Where rubygems fits in

• Creating your own rubygem from scratch

• Creating your own rubygem using jeweler

Overview

Page 3: Rubygems And You

Josh Nichols technicalpickles.com

•How ‘require’ works

• Where rubygems fits in

• Creating your own rubygem from scratch

• Creating your own rubygem using jeweler

Overview

Page 4: Rubygems And You

Josh Nichols technicalpickles.com

executes the contents of a file

require

Page 5: Rubygems And You

Josh Nichols technicalpickles.com

# foo.rbputs "zomg, so awesome"

# bar.rbrequire 'foo.rb'

$ ruby bar.rbzomg, so awesome

Page 6: Rubygems And You

Josh Nichols technicalpickles.com

absolute path

require ‘/usr/lib/awesome.rb’

Page 7: Rubygems And You

Josh Nichols technicalpickles.com

relative path

require ‘subdir/foo.rb’

Page 8: Rubygems And You

Josh Nichols technicalpickles.com

can omit the .rb

require ‘subdir/foo’

Page 9: Rubygems And You

Josh Nichols technicalpickles.com

list of directories to look for required files

$LOAD_PATH

Page 10: Rubygems And You

Josh Nichols technicalpickles.com

$LOAD_PATH includes your ruby install....this actually lives under a path like:

/usr/local/lib/ruby/1.8/

require ‘net/http’

Page 11: Rubygems And You

Josh Nichols technicalpickles.com

only will execute a particular path once

require

Page 12: Rubygems And You

Josh Nichols technicalpickles.com

# foo.rbputs "zomg, so awesome"

# bar.rbrequire 'foo'require 'foo'require './foo'

$ ruby bar.rbzomg, so awesomezomg, so awesome

Page 13: Rubygems And You

Josh Nichols technicalpickles.com

• Different environments (mac vs. win. vs. linux)

• People install stuff to random places

• Different versions of libraries

• What do we do?

Dealing with diversity...

Page 14: Rubygems And You

Josh Nichols technicalpickles.com

MASS HYSTERIA!

Page 15: Rubygems And You

Josh Nichols technicalpickles.com

• How ‘require’ works

•Where rubygems fits in

• Creating your own rubygem from scratch

• Creating your own rubygem using jeweler

Overview

Page 16: Rubygems And You

Josh Nichols technicalpickles.com

• Handles downloading and installing library

• Manages $LOAD_PATH

• Allows a developer to package & distribute their library

Enter RubyGems

Page 17: Rubygems And You

Josh Nichols technicalpickles.com

• gem install burninator

Installing

Page 18: Rubygems And You

Josh Nichols technicalpickles.com

Using gems

require 'rubygems'require 'burninator'

Page 19: Rubygems And You

Josh Nichols technicalpickles.com

Using gems in under Rails

# config/environment.rb, or anywhere reallyrequire 'burninator'

Page 20: Rubygems And You

Josh Nichols technicalpickles.com

Using gems in under Rails

# config/environment.rbconfig.gem 'burninator'

Page 21: Rubygems And You

Josh Nichols technicalpickles.com

Using gems in under Rails

# create vendor/gems...# then 'gem unpack' gems there# config/environment.rbRails::Initializer.run do |config| config.load_paths += Dir["#{RAILS_ROOT}/vendor/gems/**"].map do |dir| File.directory?(lib = "#{dir}/lib") ? lib : dir endend

Page 22: Rubygems And You

Josh Nichols technicalpickles.com

Where do gems live?

Page 23: Rubygems And You

Josh Nichols technicalpickles.com

• RubyGems already knows about it by default

• Has been the defacto standard for hosting

Page 24: Rubygems And You

Josh Nichols technicalpickles.com

• But you need to apply for projects...

• And you need extra tools to publish gems...

Page 25: Rubygems And You

Josh Nichols technicalpickles.com

• The new hotness

• Just create a repository and turn on RubyGem support

• Create a Gem::Specification, and push it

Page 26: Rubygems And You

Josh Nichols technicalpickles.com

• How ‘require’ works

• Where rubygems fits in

•Creating your own rubygem from scratch

• Creating your own rubygem using jeweler

Overview

Page 27: Rubygems And You

Josh Nichols technicalpickles.com

• Rake for automation

• Testing framework of choice (we’ll assume test/unit)

• RubyGems

Tools of the trade

Page 28: Rubygems And You

Josh Nichols technicalpickles.com

Directory Layout

|~bin/| `-cylon_detector|~lib/| `-cylon_detector.rb|~test/| |-test_cylon_detector.rb| `-test_helper.rb|-LICENSE|-Rakefile`-README.rdoc

Page 29: Rubygems And You

Josh Nichols technicalpickles.com

Rakefile basics

require 'rubygems'require 'rake'

Page 30: Rubygems And You

Josh Nichols technicalpickles.com

• Metadata about your gem

• name, files, binaries, homepage, etc, etc

Gem::Specification

Page 31: Rubygems And You

Josh Nichols technicalpickles.com

Rakefile gemspecspec = Gem::Specification.new do |s| s.name = 'cylon-detector' s.version = '0.8.1' s.authors = ['Josh Nichols'] s.date = '2009-02-03' s.email = '[email protected]' s.files = FileList['{bin,lib}/**'] s.executables = 'cylon_detector' s.has_rdoc = true s.summary = 'Detect cylons with ease'end

Page 32: Rubygems And You

Josh Nichols technicalpickles.com

Rakefile gemspec

task :gemspec do File.open('cylon-detector.gemspec', 'w') do |file| file.write spec.to_ruby endend

Page 33: Rubygems And You

Josh Nichols technicalpickles.com

Rakefile package

require 'rake/gempackagetask'Rake::GemPackageTask.new(spec) do |pkg| pkg.need_zip = false pkg.need_tar = falseend

Page 34: Rubygems And You

Josh Nichols technicalpickles.com

Rakefile rdoc

require 'rake/rdoctask'Rake::RDocTask.new do |rdoc| rdoc.rdoc_dir = 'rdoc' rdoc.title = 'cylon-detector' rdoc.options << '--line-numbers' << '--inline-source' rdoc.rdoc_files.include('README.rdoc') rdoc.rdoc_files.include('lib/**/*.rb')end

Page 35: Rubygems And You

Josh Nichols technicalpickles.com

Rakefile test

require 'rake/testtask'Rake::TestTask.new(:test) do |t| t.test_files = 'test/**/test_*.rb' t.verbose = falseend

Page 36: Rubygems And You

Josh Nichols technicalpickles.com

Rakefile rcov

begin require 'rcov/rcovtask' Rcov::RcovTask.new do |t| t.test_files = 'test/**/test_*.rb' t.verbose = true endrescue LoadError task :rcov do abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov" endend

Page 37: Rubygems And You

Josh Nichols technicalpickles.com

Rakefile default

task :default => :test

Page 38: Rubygems And You

Josh Nichols technicalpickles.com

bin/cylon_detector

#!/usr/bin/env ruby

$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))require 'cylon_detector'

# detection code here

Page 39: Rubygems And You

Josh Nichols technicalpickles.com

• The entry point into your library

• Require all dependencies (internal and external)

• Design decisions

• generally want to namespace your project

• class or module?

• Do not require rubygems (unless you are interacting directly with it)

lib/cylon_detector.rb

Page 40: Rubygems And You

Josh Nichols technicalpickles.com

• Central location to setup testing environment

test/test_helper.rb

require 'rubygems'require 'test/unit'

$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))$LOAD_PATH.unshift(File.dirname(__FILE__))

require 'cylon_detector'

class Test::Unit::TestCaseend

Page 41: Rubygems And You

Josh Nichols technicalpickles.com

test/test_cylon_detector.rb

require File.dirname(__FILE__) + '/test_helper'

class CylonDetectorTest < Test::Unit::TestCase # tests go hereend

Page 42: Rubygems And You

Josh Nichols technicalpickles.com

• Hack and commit your code

• ‘rake gemspec’ and commit your gemspec

• push to GitHub

• wait for the gem to build

• rejoice and have some Scotch

Workflow

Page 43: Rubygems And You

Josh Nichols technicalpickles.com

• How ‘require’ works

• Where rubygems fits in

• Creating your own rubygem from scratch

•Creating your own rubygem using jeweler

Overview

Page 44: Rubygems And You

Josh Nichols technicalpickles.com

• Handles the grunt work

• Generator

• Skeleton project setup for your test framework of choice

• Starts a git repo setup for GitHub

• Creates the repo on GitHub and enables RubyGem for it

• Rake tasks

• Automate version bumping

• Releasing to GitHub, including tagging the release

Jeweler

Page 45: Rubygems And You

Josh Nichols technicalpickles.com

• Choose between testing frameworks

• Test::Unit

• Shoulda

• RSpec

• Bacon

• Also includes cucumber stories enabled for

Generator

Page 46: Rubygems And You

Josh Nichols technicalpickles.com

• Tracks current version in VERSION.yml

• Rake tasks for bumping the version

• version:bump:patch, version:bump:minor, version:bump:major

Versioning

Page 47: Rubygems And You

Josh Nichols technicalpickles.com

patch versionAPI backward-compatible

bug fixesminor enhancements

0.8.5

Page 48: Rubygems And You

Josh Nichols technicalpickles.com

minor versionmostly API backwards compatiblemore significant enhancements

0.8.5

Page 49: Rubygems And You

Josh Nichols technicalpickles.com

major versionbreak API as much you wantusually signifies an overhaul

0.8.5

Page 50: Rubygems And You

Josh Nichols technicalpickles.com

• Updates the gemspec based on the version

• Pushes to GitHub

• Tags the release with the version number

Releasing