Cutting your own RubyGems

Cutting your own RubyGems

Diving head-first into RubyGems is rough: there’s a myriad of documentation sites, blog posts, screencasts, and manpages to read, and it’s tough to find “the” guide on how to publish your first RubyGem. In this session you’ll learn why making them is important for your Rails application’s maintainability and how distributing your code in gems even internally is helpful. You’ll find out what happens from “gem push” to “gem install”, and how Rails’ engine system makes sharing application and business logic easy.

Given at RailsConf 2011. http://en.oreilly.com/rails2011

Eb8975af8e49e19e3dd6b6b84a542e26?s=128

Nick Quaranto

January 12, 2012
Tweet

Transcript

  1. Nick Quaranto @qrush nick@thoughtbot.com R B Y cutting your own

    RubyGems Wednesday, May 25, 2011
  2. P S A first, a Wednesday, May 25, 2011

  3. Where have all of the manuals gone? Wednesday, May 25,

    2011
  4. http://history.nasa.gov/diagrams/gemini.html Wednesday, May 25, 2011

  5. http://history.nasa.gov/diagrams/gemini.html Wednesday, May 25, 2011

  6. http://archive.computerhistory.org/resources/text/Apple/Apple.AppleI.1976.102646518.pdf Wednesday, May 25, 2011

  7. http://archive.computerhistory.org/resources/text/Apple/Apple.AppleI.1976.102646518.pdf Wednesday, May 25, 2011

  8. http://archive.computerhistory.org/resources/text/Apple/Apple.AppleI.1976.102646518.pdf Wednesday, May 25, 2011

  9. http://archive.computerhistory.org/resources/text/Apple/Apple.AppleI.1976.102646518.pdf Wednesday, May 25, 2011

  10. http://ed-thelen.org/comp-hist/CRAY-1-HardRefMan/CRAY-1-HRM.html Wednesday, May 25, 2011

  11. http://ed-thelen.org/comp-hist/CRAY-1-HardRefMan/CRAY-1-HRM.html Wednesday, May 25, 2011

  12. http://ed-thelen.org/comp-hist/CRAY-1-HardRefMan/CRAY-1-HRM.html Wednesday, May 25, 2011

  13. http://guides.rubyonrails.org Wednesday, May 25, 2011

  14. http://progit.org Wednesday, May 25, 2011

  15. http://guides.sproutcore.org Wednesday, May 25, 2011

  16. We need MORE manuals! Wednesday, May 25, 2011

  17. MAKE MANUALS Wednesday, May 25, 2011

  18. http://guides.rubygems.org Wednesday, May 25, 2011

  19. G E M what is a gem? Wednesday, May 25,

    2011
  20. Gems contain a packaged Ruby application or library. Wednesday, May

    25, 2011
  21. RubyGems helps you download, install, and manipulate gems. Wednesday, May

    25, 2011
  22. rubygems.org rubygems client Wednesday, May 25, 2011

  23. rubygems.org rubygems client gems Wednesday, May 25, 2011

  24. rubygems.org rubygems client gems, gemspecs, indexes from S3 gems Wednesday,

    May 25, 2011
  25. .gem Wednesday, May 25, 2011

  26. Code Gemspec Docs Wednesday, May 25, 2011

  27. % tree freewill freewill/ |-- bin/ | `-- freewill |--

    lib/ | `-- freewill.rb |-- test/ | `-- test_freewill.rb |-- README |-- Rakefile `-- freewill.gemspec Wednesday, May 25, 2011
  28. .gem Rails ??? Wednesday, May 25, 2011

  29. Ruby looks on your $LOAD_PATH when you call Kernel#require Wednesday,

    May 25, 2011
  30. RubyGems manages your $LOAD_PATH Wednesday, May 25, 2011

  31. % irb -rpp >> pp $LOAD_PATH [".../lib/ruby/site_ruby/1.8", ".../lib/ruby/site_ruby", ".../lib/ruby/vendor_ruby/1.8", ".../lib/ruby/vendor_ruby",

    ".../lib/ruby/1.8", "."] Wednesday, May 25, 2011
  32. % irb -rpp >> require 'rake' LoadError: no such file

    to load -- rake from (irb):2:in `require' from (irb):2 Wednesday, May 25, 2011
  33. >> require 'rubygems' => true >> require 'rake' => true

    >> pp $LOAD_PATH[0..1] [".../gems/rake-0.8.7/bin", ".../gems/rake-0.8.7/lib"] Wednesday, May 25, 2011
  34. RubyGems overrides Kernel#require RubyGems puts bin/ and lib/ on your

    $LOAD_PATH Wednesday, May 25, 2011
  35. Gemspec holds metadata & info about the gem Wednesday, May

    25, 2011
  36. % cat freewill.gemspec Gem::Specification.new do |s| s.name = 'freewill' s.version

    = '1.0.0' s.date = '2010-04-27' s.summary = "Freewill!" s.description = "I will choose Freewill!" s.authors = ["Nick Quaranto"] s.email = 'nick@quaran.to' s.homepage = 'http://example.com' s.files = ["lib/freewill.rb"] end Wednesday, May 25, 2011
  37. A gem is just a tarball of tarballs Wednesday, May

    25, 2011
  38. % gem fetch rake Downloaded rake-0.8.7 % tar zxvf rake-0.8.7.gem

    x data.tar.gz x metadata.gz Wednesday, May 25, 2011
  39. A GEM IS A TARBALL WITHIN A TARBALL Wednesday, May

    25, 2011
  40. WHY CAN’T I USE MY LINUX PACKAGE MANAGER THEN Wednesday,

    May 25, 2011
  41. Wednesday, May 25, 2011

  42. LOL, WHAT’S A TARBALL Wednesday, May 25, 2011

  43. D Y I make your own gem Wednesday, May 25,

    2011
  44. share/modularize code automate your process releasing a gem is easy!

    Wednesday, May 25, 2011
  45. first gem Wednesday, May 25, 2011

  46. Your gem needs a name Wednesday, May 25, 2011

  47. DO NOT CALL IT: [rR].* rials cheezburger kitty dicks Wednesday,

    May 25, 2011
  48. no capitals, please use underscores for spaces use dashes for

    extensions Wednesday, May 25, 2011
  49. % tree . ├── hola.gemspec └── lib └── hola.rb Wednesday,

    May 25, 2011
  50. % cat lib/hola.rb class Hola def self.hi(msg = "world") puts

    "Hello #{msg}!" end end Wednesday, May 25, 2011
  51. require ‘hola’ % tree . ├── hola.gemspec └── lib └──

    hola.rb Wednesday, May 25, 2011
  52. % cat hola.gemspec Gem::Specification.new do |s| s.name = 'hola' s.version

    = '0.0.0' s.date = '2010-04-28' s.summary = "Hola!" s.description = "A simple hello world gem" s.authors = ["Nick Quaranto"] s.email = 'nick@quaran.to' s.files = ["lib/hola.rb"] s.homepage = 'http://rubygems.org/gems/hola' end Wednesday, May 25, 2011
  53. push install build Wednesday, May 25, 2011

  54. push install build LOCAL Wednesday, May 25, 2011

  55. push install build LOCAL REMOTE Wednesday, May 25, 2011

  56. % gem build hola.gemspec Successfully built RubyGem Name: hola Version:

    0.0.0 File: hola-0.0.0.gem % gem install ./hola-0.0.0.gem Successfully installed hola-0.0.0 1 gem installed Wednesday, May 25, 2011
  57. Wednesday, May 25, 2011

  58. Wednesday, May 25, 2011

  59. try your gem out before pushing! Wednesday, May 25, 2011

  60. % irb -rubygems >> require 'hola' => true >> Hola.hi

    Hello world! Wednesday, May 25, 2011
  61. % irb -rubygems >> require 'hola' => true >> Hola.hi

    Hello world! require 'ubygems.rb' Wednesday, May 25, 2011
  62. Wednesday, May 25, 2011

  63. % gem push hola-0.0.0.gem Enter your RubyGems.org credentials. Don't have

    an account yet? Create one at http://rubygems.org/sign_up Email: nick@quaran.to Password: Signed in. Pushing gem to RubyGems.org... Successfully registered gem: hola (0.0.0) Wednesday, May 25, 2011
  64. push install build LOCAL REMOTE install list -r Wednesday, May

    25, 2011
  65. % gem list -r hola *** REMOTE GEMS *** hola

    (0.0.0) % gem install hola Successfully installed hola-0.0.0 1 gem installed Wednesday, May 25, 2011
  66. executable first gem Wednesday, May 25, 2011

  67. gems are like awesome shell aliases Wednesday, May 25, 2011

  68. % curl -s http://jsonip.com/ | \ prettify_json.rb { "ip": "24.60.248.134"

    } Wednesday, May 25, 2011
  69. % mkdir bin % touch bin/hola % chmod a+x bin/hola

    Wednesday, May 25, 2011
  70. % cat bin/hola #!/usr/bin/env ruby require 'hola' puts Hola.hi(ARGV[0]) Wednesday,

    May 25, 2011
  71. % cat bin/hola #!/usr/bin/env ruby require 'hola' puts Hola.hi(ARGV[0]) (shə-băng')

    Wednesday, May 25, 2011
  72. % cat bin/hola #!/usr/bin/env ruby require 'hola' puts Hola.hi(ARGV[0]) “Probably

    derived from “shell bang” under the influence of American slang “the whole shebang” (everything, the works)” http://www.retrologic.com/jargon/S/shebang.html (shə-băng') Wednesday, May 25, 2011
  73. % cat bin/hola #!/usr/bin/env ruby require 'hola' puts Hola.hi(ARGV[0]) (shə-băng')

    “Probably derived from “shell bang” under the influence of American slang “the whole shebang” (everything, the works)” http://www.retrologic.com/jargon/S/shebang.html Wednesday, May 25, 2011
  74. % ruby -Ilib ./bin/hola Hello world! % ruby -Ilib ./bin/hola

    Baltimore Hello Baltimore! Wednesday, May 25, 2011
  75. % ruby -Ilib ./bin/hola Hello world! % ruby -Ilib ./bin/hola

    Baltimore Hello Baltimore! $LOAD_PATH.unshift(“lib”) Wednesday, May 25, 2011
  76. % hola Hello world! % hola Baltimore Hello Baltimore! Wednesday,

    May 25, 2011
  77. % head -4 hola.gemspec Gem::Specification.new do |s| s.name = 'hola'

    s.version = '0.0.1' s.executables << 'hola' Wednesday, May 25, 2011
  78. tests executable first gem Wednesday, May 25, 2011

  79. framework automation Wednesday, May 25, 2011

  80. framework automation rake thor Wednesday, May 25, 2011

  81. framework automation rake thor Test::Unit rspec bacon context matchy shoulda

    riot testy shindo zebra lemon dfect cucumber steak Wednesday, May 25, 2011
  82. Test your gem. Use whatever. Please test it. Wednesday, May

    25, 2011
  83. http://test.rubygems.org Wednesday, May 25, 2011

  84. Wednesday, May 25, 2011

  85. % cat Rakefile require 'rake/testtask' Rake::TestTask.new do |t| t.libs <<

    'test' end desc "Run tests" task :default => :test Wednesday, May 25, 2011
  86. % cat test/test_hola.rb require 'test/unit' require 'hola' class HolaTest <

    Test::Unit::TestCase def test_default_hello assert_equal "Hello world!", Hola.hi end def test_custom_hello assert_equal "Hello Boston!", Hola.hi("Boston") end end Wednesday, May 25, 2011
  87. % rake test (in /Users/qrush/Dev/ruby/hola) Loaded suite Started .. Finished

    in 0.000736 seconds. 2 tests, 2 assertions, 0 failures, 0 errors, 0 skips Test run options: --seed 15331 Wednesday, May 25, 2011
  88. tests executable first gem docs Wednesday, May 25, 2011

  89. Others will use your gem. Write about it. Wednesday, May

    25, 2011
  90. At least have a README! Wednesday, May 25, 2011

  91. http://twitter.com/rubygems Wednesday, May 25, 2011

  92. inline guides Wednesday, May 25, 2011

  93. inline guides nokogiri yard Wednesday, May 25, 2011

  94. inline guides nokogiri yard rails datamapper Wednesday, May 25, 2011

  95. # The main Hola driver class Hola # Say hi

    to the world! # # Example: # >> Hola.hi("Buffalo") # => Hello Buffalo! # # Arguments: # message: (String) def self.hi(message = "world") puts "Hello #{message}!" end end Wednesday, May 25, 2011
  96. http://yardoc.org Wednesday, May 25, 2011

  97. P T N patterns Wednesday, May 25, 2011

  98. more files Wednesday, May 25, 2011

  99. . └── lib ├── hola │ └── translator.rb └── hola.rb

    Wednesday, May 25, 2011
  100. . └── lib ├── hola │ └── translator.rb └── hola.rb

    BAD: require File.join(File.dirname( __FILE__), "hola", "translator") Wednesday, May 25, 2011
  101. . └── lib ├── hola │ └── translator.rb └── hola.rb

    WORSE: $LOAD_PATH.unshift "lib/hola" require "translator" Wednesday, May 25, 2011
  102. . └── lib ├── hola │ └── translator.rb └── hola.rb

    GOOD: require "hola/translator" Wednesday, May 25, 2011
  103. Keep only one top-level file in lib/ Wednesday, May 25,

    2011
  104. . └── lib ├── foo │ └── cgi.rb ├── foo.rb

    └── set.rb Wednesday, May 25, 2011
  105. . └── lib ├── foo │ └── cgi.rb ├── foo.rb

    └── set.rb require ‘set’ Wednesday, May 25, 2011
  106. . └── lib ├── foo │ └── cgi.rb ├── foo.rb

    └── set.rb require ‘foo/cgi’ Wednesday, May 25, 2011
  107. semver more files Wednesday, May 25, 2011

  108. Have a sane versioning scheme Wednesday, May 25, 2011

  109. http://www.flickr.com/photos/ioerror/3014911710/lightbox/ Wednesday, May 25, 2011

  110. 3 3.1 3.14 3.141 3.1415 3.14159 3.141592 3.1415926 Wednesday, May

    25, 2011
  111. http://semver.org Wednesday, May 25, 2011

  112. 1.2.3 MAJOR.MINOR.PATCH Wednesday, May 25, 2011

  113. 0.0.x implementation details small bug fixes PATCH Wednesday, May 25,

    2011
  114. 0.x.0 backwards compatible API changes MINOR Wednesday, May 25, 2011

  115. x.0.0 backwards incompatible API changes MAJOR Wednesday, May 25, 2011

  116. dependencies semver more files Wednesday, May 25, 2011

  117. http://www.slideshare.net/copiousfreetime/gemology Wednesday, May 25, 2011

  118. Specify your dependencies Wednesday, May 25, 2011

  119. development runtime Wednesday, May 25, 2011

  120. development runtime what your gem needs to work Wednesday, May

    25, 2011
  121. development runtime what your gem needs to work what your

    tests need to work Wednesday, May 25, 2011
  122. Gem::Specification.new do |s| s.name = "hola" s.version = "2.0.0" s.add_runtime_dependency(

    "daemons", ["= 1.1.0"]) s.add_development_dependency( "rspec", [">= 2.2.0"]) Wednesday, May 25, 2011
  123. Avoid >= Wednesday, May 25, 2011

  124. Gem::Specification.new do |s| s.name = "hola" s.version = "2.0.0" s.add_runtime_dependency(

    "daemons", ["= 1.1.0"]) s.add_development_dependency( "rspec", [">= 2.0.0"]) Exact This one works for me! Wednesday, May 25, 2011
  125. Gem::Specification.new do |s| s.name = "hola" s.version = "2.0.0" s.add_runtime_dependency(

    "daemons", ["= 1.1.0"]) s.add_development_dependency( "rspec", [">= 2.2.0"]) Optimistic It will always work! Wednesday, May 25, 2011
  126. Gem::Specification.new do |s| s.name = "hola" s.version = "2.0.0" s.add_runtime_dependency(

    "daemons", ["= 1.1.0"]) s.add_development_dependency( "rspec", [">= 2.2.0", "< 3.0.0"]) Pessimistic This and future minor releases work Wednesday, May 25, 2011
  127. Gem::Specification.new do |s| s.name = "hola" s.version = "2.0.0" s.add_runtime_dependency(

    "daemons", ["= 1.1.0"]) s.add_development_dependency( "rspec", ["~> 2.2"]) Pessimistic Use the twiddle-wakka! Wednesday, May 25, 2011
  128. releasing a gem is easy! Wednesday, May 25, 2011

  129. have a sane versioning scheme Wednesday, May 25, 2011

  130. MAKE MANUALS Wednesday, May 25, 2011

  131. T H X Thanks for listening! Big thanks to: thoughtbot

    Jeremy Hinegardner Nick Quaranto @qrush nick@thoughtbot.com http://guides.rubygems.org Wednesday, May 25, 2011