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.
2. Overview
• How ‘require’ works
• Where rubygems fits in
• Creating your own rubygem from scratch
• Creating your own rubygem using jeweler
Josh Nichols technicalpickles.com
3. Overview
• How ‘require’ works
• Where rubygems fits in
• Creating your own rubygem from scratch
• Creating your own rubygem using jeweler
Josh Nichols technicalpickles.com
4. require
executes the contents of a file
Josh Nichols technicalpickles.com
5. # foo.rb
puts quot;zomg, so awesomequot;
# bar.rb
require 'foo.rb'
$ ruby bar.rb
zomg, so awesome
Josh Nichols technicalpickles.com
9. $LOAD_PATH
list of directories to look for required files
Josh Nichols technicalpickles.com
10. require ‘net/http’
$LOAD_PATH includes your ruby install....
this actually lives under a path like:
/usr/local/lib/ruby/1.8/
Josh Nichols technicalpickles.com
11. require
only will execute a particular path once
Josh Nichols technicalpickles.com
12. # foo.rb
puts quot;zomg, so awesomequot;
# bar.rb
require 'foo'
require 'foo'
require './foo'
$ ruby bar.rb
zomg, so awesome
zomg, so awesome
Josh Nichols technicalpickles.com
13. Dealing with diversity...
• Different environments (mac vs. win. vs. linux)
• People install stuff to random places
• Different versions of libraries
• What do we do?
Josh Nichols technicalpickles.com
15. Overview
• How ‘require’ works
• Where rubygems fits in
• Creating your own rubygem from scratch
• Creating your own rubygem using jeweler
Josh Nichols technicalpickles.com
16. Enter RubyGems
• Handles downloading and installing library
• Manages $LOAD_PATH
• Allows a developer to package & distribute their library
Josh Nichols technicalpickles.com
18. Using gems
require 'rubygems'
require 'burninator'
Josh Nichols technicalpickles.com
19. Using gems in under Rails
# config/environment.rb, or anywhere really
require 'burninator'
Josh Nichols technicalpickles.com
20. Using gems in under Rails
# config/environment.rb
config.gem 'burninator'
Josh Nichols technicalpickles.com
21. Using gems in under Rails
# create vendor/gems...
# then 'gem unpack' gems there
# config/environment.rb
Rails::Initializer.run do |config|
config.load_paths += Dir[quot;#{RAILS_ROOT}/vendor/gems/**quot;].map do |dir|
File.directory?(lib = quot;#{dir}/libquot;) ? lib : dir
end
end
Josh Nichols technicalpickles.com
22. Where do gems live?
Josh Nichols technicalpickles.com
23. • RubyGems already knows about it by default
• Has been the defacto standard for hosting
Josh Nichols technicalpickles.com
24. • But you need to apply for projects...
• And you need extra tools to publish gems...
Josh Nichols technicalpickles.com
25. • The new hotness
• Just create a repository and turn on RubyGem support
• Create a Gem::Specification, and push it
Josh Nichols technicalpickles.com
26. Overview
• How ‘require’ works
• Where rubygems fits in
• Creating your own rubygem from scratch
• Creating your own rubygem using jeweler
Josh Nichols technicalpickles.com
27. Tools of the trade
• Rake for automation
• Testing framework of choice (we’ll assume test/unit)
• RubyGems
Josh Nichols technicalpickles.com
32. Rakefile gemspec
task :gemspec do
File.open('cylon-detector.gemspec', 'w') do |file|
file.write spec.to_ruby
end
end
Josh Nichols technicalpickles.com
33. Rakefile package
require 'rake/gempackagetask'
Rake::GemPackageTask.new(spec) do |pkg|
pkg.need_zip = false
pkg.need_tar = false
end
Josh Nichols technicalpickles.com
35. Rakefile test
require 'rake/testtask'
Rake::TestTask.new(:test) do |t|
t.test_files = 'test/**/test_*.rb'
t.verbose = false
end
Josh Nichols technicalpickles.com
36. Rakefile rcov
begin
require 'rcov/rcovtask'
Rcov::RcovTask.new do |t|
t.test_files = 'test/**/test_*.rb'
t.verbose = true
end
rescue LoadError
task :rcov do
abort quot;RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcovquot;
end
end
Josh Nichols technicalpickles.com
39. lib/cylon_detector.rb
• 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)
Josh Nichols technicalpickles.com
40. test/test_helper.rb
• Central location to setup testing environment
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::TestCase
end
Josh Nichols technicalpickles.com
41. test/test_cylon_detector.rb
require File.dirname(__FILE__) + '/test_helper'
class CylonDetectorTest < Test::Unit::TestCase
# tests go here
end
Josh Nichols technicalpickles.com
42. Workflow
• 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
Josh Nichols technicalpickles.com
43. Overview
• How ‘require’ works
• Where rubygems fits in
• Creating your own rubygem from scratch
• Creating your own rubygem using jeweler
Josh Nichols technicalpickles.com
44. Jeweler
• 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
Josh Nichols technicalpickles.com
45. Generator
• Choose between testing frameworks
• Test::Unit
• Shoulda
• RSpec
• Bacon
• Also includes cucumber stories enabled for
Josh Nichols technicalpickles.com
46. Versioning
• Tracks current version in VERSION.yml
• Rake tasks for bumping the version
• version:bump:patch, version:bump:minor,
version:bump:major
Josh Nichols technicalpickles.com
47. 0.8.5
patch version
API backward-compatible
bug fixes
minor enhancements
Josh Nichols technicalpickles.com
48. 0.8.5
minor version
mostly API backwards compatible
more significant enhancements
Josh Nichols technicalpickles.com
49. 0.8.5
major version
break API as much you want
usually signifies an overhaul
Josh Nichols technicalpickles.com
50. Releasing
• Updates the gemspec based on the version
• Pushes to GitHub
• Tags the release with the version number
Josh Nichols technicalpickles.com