SlideShare a Scribd company logo
1 of 97
Download to read offline
How to Make a Ruby Gem	
Clare Glinka

1
Who is this talk for?	
•Me, a few months ago
•Someone who is:
•new to Rails
•new to Ruby
•new to programming
2
What is a gem?
• Container that hold widely-reusable code.
• Code that is useable in many different contexts.

3
Tools to help with making gems:
•Bundler
•Jeweler
•gemcutter
•others!

4
Building a Gem
<that generates cheesey adventure plots>
with Bundler

5
Step 0.5: $ gem install bundler

6
Step 1: $ bundle gem adventure

7
=> create adventure/Gemfile
create adventure/Rakefile
create adventure/LICENSE.txt
create adventure/README.md
create adventure/.gitignore
create adventure/adventure.gemspec
create adventure/lib/adventure.rb
create adventure/lib/adventure/version.rb
Initializing git repo in /Users/me/code/adventure

8
Gem structure
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
└── lib
├── adventure.rb
└── adventure
└── version.rb
9
Step 3: Finish .gemspec

10
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
└── lib
├── adventure.rb
└── adventure
└── version.rb
11
adventure.gemspec
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
%q{TODO: Write a short summary. Required.}
%q{TODO: Write a longer description. Optional.}
""
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end

12
Required specs
•name
•version
•summary
•require_paths
•files
•rubygems_version

13
spec.name

14
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
%q{TODO: Write a short summary. Required.}
%q{TODO: Write a longer description. Optional.}
""
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
15
spec.version

16
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
%q{TODO: Write a short summary. Required.}
%q{TODO: Write a longer description. Optional.}
""
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
17
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
└── lib
├── adventure.rb
└── adventure
└── version.rb
18
lib/adventure/version.rb

module Adventure
VERSION = "0.0.1"
end

19
Versioning
• Use semantic versioning.
•0.0.X
- bugfixs
•0.X.0
- additional functionality that is backward compatible.
•X.0.0
- additional functionality that breaks backwards compatibility.

20
Version constraints
• ~> 1.2
- all versions before 2 . 0
• ~> 1 . 3 . 5
- all versions before 1. 4 . 0

21
spec.summary

22
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
%q{TODO: Write a short summary. Required.}
%q{TODO: Write a longer description. Optional.}
""
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
23
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
"Adventure plot generator"
""
""
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
24
spec.require_paths

25
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
"Adventure plot generator"
""
""
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
26
Protect the load path!
$ pry
[1] pry(main)> $LOAD_PATH
=> ["/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/coderay-1.1.0/lib",
"/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/slop-3.4.7/lib",
"/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/method_source-0.8.2/lib",
"/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/pry-0.9.12.4/lib",
"/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby/2.0.0",
"/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby/2.0.0/x86_64-darwin13.0.0",
"/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby",
"/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby/2.0.0",
"/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby/2.0.0/x86_64-darwin13.0.0",
"/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby",
"/rbenv/versions/2.0.0-p353/lib/ruby/2.0.0",
"/rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/x86_64-darwin13.0.0"]

27
Protect the load path!
[2] pry(main)> require 'adventure'
=> true
[3] pry(main)> $LOAD_PATH
=> ["/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/coderay-1.1.0/lib",
"/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/slop-3.4.7/lib",
"/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/method_source-0.8.2/lib",
"/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/pry-0.9.12.4/lib",
"/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/adventure-0.0.1/lib",
"/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby/2.0.0",
"/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby/2.0.0/x86_64-darwin13.0.0",
"/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby",
"/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby/2.0.0",
"/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby/2.0.0/x86_64-darwin13.0.0",
"/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby",
"/rbenv/versions/2.0.0-p353/lib/ruby/2.0.0",
"/rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/x86_64-darwin13.0.0"]
28
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
└── lib
├── adventure.rb
└── adventure
└── version.rb
29
spec.files

30
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
"Adventure plot generator"
""
""
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
31
$ git ls-files
.gitignore
Gemfile
LICENSE.txt
README.md
Rakefile
adventure.gemspec
lib/adventure.rb
lib/adventure/version.rb

32
$	
  pry
[1]	
  pry(main)>	
  `git	
  ls-­‐files`
=>	
  ".gitignorenGemfilenLICENSE.txtnREADME.mdnRakefile
nadventure.gemspecnlib/adventure.rbnlib/adventure/version.rb
n"
[2]	
  pry(main)>	
  `git	
  ls-­‐files`.split($)
=>	
  [".gitignore",
	
  "Gemfile",
	
  "LICENSE.txt",
	
  "README.md",
	
  "Rakefile",
	
  "adventure.gemspec",
	
  "lib/adventure.rb",
	
  "lib/adventure/version.rb"]
33
$	
  pry
[1]	
  pry(main)>	
  `git	
  ls-­‐files`
=>	
  ".gitignorenGemfilenLICENSE.txtnREADME.mdnRakefile
nadventure.gemspecnlib/adventure.rbnlib/adventure/version.rb
n"
[2]	
  pry(main)>	
  `git	
  ls-­‐files`.split($)
=>	
  [".gitignore",
	
  "Gemfile",
	
  "LICENSE.txt",
	
  "README.md",
	
  "Rakefile",
	
  "adventure.gemspec",
	
  "lib/adventure.rb",
	
  "lib/adventure/version.rb"]
34
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
"Adventure plot generator"
""
""
"MIT"

spec.files
= [".gitignore", "Gemfile", "LICENSE.txt",
"README.md", "Rakefile", "adventure.gemspec", "lib/adventure.rb", "lib/
adventure/version.rb"]
spec.executables
= spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files
= spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
35
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
"Adventure plot generator"
""
""
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
36
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
"Adventure plot generator"
""
""
"MIT"
Dir.glob(‘**/*’)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
37
$	
  pry
[1]	
  pry(main)>	
  Dir.glob('**/**')
=>	
  ["adventure.gemspec",
	
  "Gemfile",
	
  "lib",
	
  "lib/adventure",
	
  "lib/adventure/random.txt",
	
  "lib/adventure/version.rb",
	
  "lib/adventure.rb",
	
  "LICENSE.txt",
	
  "Rakefile",
	
  "README.md"]

38
spec.rubygems_version

39
Other Specs:
•authors
•email
•homepage
•license
•executables
•test_files
•add_development_dependency
•add_dependency

40
spec.authors
spec.email
spec.homepage

41
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
"Adventure plot generator"
""
""
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
42
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
"Adventure plot generator"
""
"http://www.github.com/cglinka/adventure"
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
43
spec.license

44
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
"Adventure plot generator"
""
"http://www.github.com/cglinka/adventure"
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
45
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
└── lib
├── adventure.rb
└── adventure
└── version.rb
46
spec.executables
spec.test_files

47
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
"Adventure plot generator"
""
"http://github.com/cglinka/adventure"
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
48
Step 4: Write some code!

49
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
└── lib
├── adventure.rb
└── adventure
└── version.rb
50
require	
  "adventure/version"
module	
  Adventure
	
  	
  #	
  Your	
  code	
  goes	
  here...
end

51
Desired output:

“There is a disgruntled shopkeeper with a secret past and a
grad student with a knack for cooking.
They fight crime!”

52
require	
  "adventure/version"
module	
  Adventure
	
  	
  class	
  Plot
	
  	
  	
  	
  def	
  make_plot
	
  	
  	
  	
  	
  	
  characters	
  =	
  ["a	
  clever	
  dragon",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "a	
  ruthless	
  detective",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "a	
  disgruntled	
  shopkeeper",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "an	
  aging	
  cowboy",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "a	
  grad	
  student",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "a	
  mystical	
  lizard"]
	
  	
  	
  	
  	
  	
  with	
  =	
  ["nothing	
  left	
  to	
  loose",
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "a	
  secret	
  past",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "an	
  enchanted	
  sword",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "a	
  grudge",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "a	
  knack	
  for	
  cooking"]
	
  	
  	
  	
  	
  	
  who	
  =	
  ["likes	
  kebabs",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "organizes	
  poetry	
  nights",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "is	
  a	
  world-­‐famous	
  cyclist",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "lived	
  in	
  a	
  circus"]
	
  	
  	
  	
  	
  	
  "There	
  is	
  #{characters.sample}	
  with	
  #{with.sample}	
  and	
  #{characters.sample}	
  
who	
  #{who.sample}.	
  They	
  fight	
  crime!"
	
  	
  	
  	
  end
	
  	
  end
end
53
Step 5: build and install the gem

54
$ gem build adventure.gemspec
WARNING: no description specified
Successfully built RubyGem
Name: adventure
Version: 0.0.1
File: adventure-0.0.1.gem

55
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
├── adventure-0.0.1.gem
└── lib
├── adventure.rb
└── adventure
└── version.rb
56
$ gem install adventure-0.0.1.gem
Successfully installed adventure-0.0.1
1 gem installed

57
$	
  pry
[1]	
  pry(main)>	
  require	
  'adventure'
=>	
  true
[2]	
  pry(main)>	
  plot	
  =	
  Adventure::Plot.new
=>	
  #<Adventure::Plot:0x007fe2a4106498>
[3]	
  pry(main)>	
  plot.make_plot
=>	
  "There	
  is	
  a	
  grad	
  student	
  with	
  a	
  knack	
  for	
  cooking	
  and	
  a	
  ruthless	
  
detective	
  who	
  likes	
  kebabs.	
  They	
  fight	
  crime!"

58
The easier way... Rake tasks!

59
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
"Adventure plot generator"
""
"http://github.com/cglinka/adventure"
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
60
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
└── lib
├── adventure.rb
└── adventure
└── version.rb
61
Gemfile

source	
  'https://rubygems.org'
#	
  Specify	
  your	
  gem's	
  dependencies	
  in	
  adventure.gemspec
gemspec

62
Rakefile

require	
  "bundler/gem_tasks"

63
$	
  rake	
  -­‐T
rake	
  build	
  	
  	
  	
  #	
  Build	
  adventure-­‐0.0.1.gem	
  into	
  the	
  pkg	
  directory.
rake	
  install	
  	
  #	
  Build	
  and	
  install	
  adventure-­‐0.0.1.gem	
  into	
  system	
  
gems.
rake	
  release	
  	
  #	
  Create	
  tag	
  v0.0.1	
  and	
  build	
  and	
  push	
  
adventure-­‐0.0.1.gem	
  to	
  Rubygems

64
$	
  rake	
  build
adventure	
  0.0.1	
  built	
  to	
  pkg/adventure-­‐0.0.1.gem.

65
$	
  rake	
  install
adventure	
  0.0.1	
  built	
  to	
  pkg/adventure-­‐0.0.1.gem.
adventure	
  (0.0.1)	
  installed.

66
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├──.gitignore
├── adventure.gemspec
├── pkg
│
└── adventure-0.0.1.gem
└── lib
├── adventure.rb
└── adventure
└── version.rb

67
Step 6: Release the gem!

68
69
$	
  rake	
  release

70
And if everything has gone terribly wrong...

$ gem yank

*** Use with caution
71
No More Hardcoding!

72
adventure.json
{
	
  	
  	
  	
  "characters":	
  [
	
  	
  	
  	
  	
  	
  	
  	
  "a	
  clever	
  dragon",
	
  	
  	
  	
  	
  	
  	
  	
  "a	
  ruthless	
  detective",
	
  	
  	
  	
  	
  	
  	
  	
  "a	
  disgruntled	
  shopkeeper",
	
  	
  	
  	
  	
  	
  	
  	
  "an	
  aging	
  cowboy",
	
  	
  	
  	
  	
  	
  	
  	
  "a	
  grad	
  student",
	
  	
  	
  	
  	
  	
  	
  	
  "a	
  mystical	
  lizard"
	
  	
  	
  	
  ],
	
  	
  	
  	
  "with":	
  [
	
  	
  	
  	
  	
  	
  	
  	
  "nothing	
  left	
  to	
  loose",
	
  	
  	
  	
  	
  	
  	
  	
  "a	
  secret	
  past",
	
  	
  	
  	
  	
  	
  	
  	
  "an	
  enchanted	
  sword",
	
  	
  	
  	
  	
  	
  	
  	
  "a	
  grudge",
	
  	
  	
  	
  	
  	
  	
  	
  "a	
  knack	
  for	
  cooking"
	
  	
  	
  	
  ],
	
  	
  	
  	
  "who":	
  [
	
  	
  	
  	
  	
  	
  	
  	
  "likes	
  kebabs",
	
  	
  	
  	
  	
  	
  	
  	
  "organizes	
  poetry	
  nights",
	
  	
  	
  	
  	
  	
  	
  	
  "is	
  a	
  world-­‐famous	
  cyclist",
	
  	
  	
  	
  	
  	
  	
  	
  "lived	
  in	
  a	
  circus"
	
  	
  	
  	
  ]
}

73
spec.add_dependency

74
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
"Adventure plot generator"
""
"http://github.com/cglinka/adventure"
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_dependency "json"
spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependency "rake"
end
75
$ bundle install
Resolving dependencies...
Using bundler (1.5.2)
Using json (1.7.7)
Using rake (0.9.6)
Using adventure (0.0.1) from source at .
Your bundle is complete!

76
require	
  "adventure/version"
module	
  Adventure
	
  	
  class	
  Plot
	
  	
  	
  	
  def	
  make_plot
	
  	
  	
  	
  	
  	
  characters	
  =	
  ["a	
  clever	
  dragon",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "a	
  ruthless	
  detective",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "a	
  disgruntled	
  shopkeeper",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "an	
  aging	
  cowboy",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "a	
  grad	
  student",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "a	
  mystical	
  lizard"]
	
  	
  	
  	
  	
  	
  with	
  =	
  ["nothing	
  left	
  to	
  loose",
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "a	
  secret	
  past",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "an	
  enchanted	
  sword",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "a	
  grudge",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "a	
  knack	
  for	
  cooking"]
	
  	
  	
  	
  	
  	
  who	
  =	
  ["likes	
  kebabs",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "organizes	
  poetry	
  nights",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "is	
  a	
  world-­‐famous	
  cyclist",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "lived	
  in	
  a	
  circus"]
	
  	
  	
  	
  	
  	
  "There	
  is	
  #{characters.sample}	
  with	
  #{with.sample}	
  and	
  #{characters.sample}	
  
who	
  #{who.sample}.	
  They	
  fight	
  crime!"
	
  	
  	
  	
  end
	
  	
  end
end
77
lib/adventure.rb
require	
  "adventure/version"
require	
  "json"
module	
  Adventure
	
  	
  class	
  Plot
	
  	
  	
  	
  def	
  make_plot(plotdevice)
	
  	
  	
  	
  	
  	
  plotholes	
  =	
  JSON.load(File.new(plotdevice))
	
  	
  	
  	
  	
  	
  characters	
  =	
  plotholes["characters"]
	
  	
  	
  	
  	
  	
  with	
  	
  	
  	
  	
  	
  	
  =	
  plotholes["with"]
	
  	
  	
  	
  	
  	
  who	
  	
  	
  	
  	
  	
  	
  	
  =	
  plotholes["who"]
	
  	
  	
  	
  	
  	
  "There	
  is	
  #{characters.sample}	
  with	
  #{with.sample}	
  and	
  
#{characters.sample}	
  who	
  #{who.sample}.	
  They	
  fight	
  crime!"
	
  	
  	
  	
  end
	
  	
  end
end
78
$	
  rake	
  install
adventure	
  0.0.1	
  built	
  to	
  pkg/adventure-­‐0.0.1.gem.
adventure	
  (0.0.1)	
  installed.

79
lib/adventure/version.rb

module Adventure
VERSION = "0.0.1"
end

80
lib/adventure/version.rb

module Adventure
VERSION = "1.0.0"
end

81
$	
  rake	
  install
adventure	
  1.0.0	
  built	
  to	
  pkg/adventure-­‐1.0.0.gem.
adventure	
  (1.0.0)	
  installed.

82
$	
  pry
[1]	
  pry(main)>	
  require	
  'adventure'
=>	
  true
[2]	
  pry(main)>	
  plot	
  =	
  Adventure::Plot.new
=>	
  #<Adventure::Plot:0x007fc079139e80>
[3]	
  pry(main)>	
  plot.make_plot('adventure.json')
=>	
  "There	
  is	
  a	
  clever	
  dragon	
  with	
  a	
  secret	
  past	
  and	
  a	
  clever	
  
dragon	
  who	
  is	
  a	
  world-­‐famous	
  cyclist.	
  They	
  fight	
  crime!"

83
Set Up Testing with <RSpec>

84
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'adventure/version'
Gem::Specification.new
spec.name
=
spec.version
=
spec.authors
=
spec.email
=
spec.summary
=
spec.description
=
spec.homepage
=
spec.license
=
spec.files
spec.executables
spec.test_files
spec.require_paths

=
=
=
=

do |spec|
"adventure"
Adventure::VERSION
["Clare Glinka"]
["glinka.cb@gmail.com"]
"Adventure plot generator"
""
"http://github.com/cglinka/adventure"
"MIT"
`git ls-files`.split($/)
spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files.grep(%r{^(test|spec|features)/})
["lib"]

spec.add_dependency "json"
spec.add_development_dependency "bundler", "~> 1.4"
spec.add_development_dependencyependency "rake"
spec.add_development_dependencyependency "rspec"
end
85
$ rspec --init
create spec/spec_helper.rb
create .rspec

86
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├── .gitignore
├── .rspec
├── adventure.gemspec
├── pkg
├── lib
└── spec
└── spec_helper.rb
87
spec/spec_helper.rb
#	
  This	
  file	
  was	
  generated	
  by	
  the	
  `rspec	
  -­‐-­‐init`	
  command.	
  Conventionally,	
  all
#	
  specs	
  live	
  under	
  a	
  `spec`	
  directory,	
  which	
  RSpec	
  adds	
  to	
  the	
  `$LOAD_PATH`.
#	
  Require	
  this	
  file	
  using	
  `require	
  "spec_helper"`	
  to	
  ensure	
  that	
  it	
  is	
  only
#	
  loaded	
  once.
#
#	
  See	
  http://rubydoc.info/gems/rspec-­‐core/RSpec/Core/Configuration
RSpec.configure	
  do	
  |config|
	
  	
  config.treat_symbols_as_metadata_keys_with_true_values	
  =	
  true
	
  	
  config.run_all_when_everything_filtered	
  =	
  true
	
  	
  config.filter_run	
  :focus
	
  	
  #	
  Run	
  specs	
  in	
  random	
  order	
  to	
  surface	
  order	
  dependencies.	
  If	
  you	
  find	
  an
	
  	
  #	
  order	
  dependency	
  and	
  want	
  to	
  debug	
  it,	
  you	
  can	
  fix	
  the	
  order	
  by	
  providing
	
  	
  #	
  the	
  seed,	
  which	
  is	
  printed	
  after	
  each	
  run.
	
  	
  #	
  	
  	
  	
  	
  -­‐-­‐seed	
  1234
	
  	
  config.order	
  =	
  'random'
end
88
spec/spec_helper.rb
require	
  'adventure'
#	
  This	
  file	
  was	
  generated	
  by	
  the	
  `rspec	
  -­‐-­‐init`	
  command.	
  Conventionally,	
  all
#	
  specs	
  live	
  under	
  a	
  `spec`	
  directory,	
  which	
  RSpec	
  adds	
  to	
  the	
  `$LOAD_PATH`.
#	
  Require	
  this	
  file	
  using	
  `require	
  "spec_helper"`	
  to	
  ensure	
  that	
  it	
  is	
  only
#	
  loaded	
  once.
#
#	
  See	
  http://rubydoc.info/gems/rspec-­‐core/RSpec/Core/Configuration
RSpec.configure	
  do	
  |config|
	
  	
  config.treat_symbols_as_metadata_keys_with_true_values	
  =	
  true
	
  	
  config.run_all_when_everything_filtered	
  =	
  true
	
  	
  config.filter_run	
  :focus
	
  	
  #	
  Run	
  specs	
  in	
  random	
  order	
  to	
  surface	
  order	
  dependencies.	
  If	
  you	
  find	
  an
	
  	
  #	
  order	
  dependency	
  and	
  want	
  to	
  debug	
  it,	
  you	
  can	
  fix	
  the	
  order	
  by	
  providing
	
  	
  #	
  the	
  seed,	
  which	
  is	
  printed	
  after	
  each	
  run.
	
  	
  #	
  	
  	
  	
  	
  -­‐-­‐seed	
  1234
	
  	
  config.order	
  =	
  'random'
end
89
adventure
├── Gemfile
├── Rakefile
├── LICENSE.txt
├── README.md
├── .gitignore
├── .rspec
├── adventure.gemspec
├── pkg
├── lib
└── spec
├── spec_adventure.rb
└── spec_helper.rb
90
spec/adventure_spec.rb

require	
  'spec_helper'
describe	
  Adventure::Plot	
  do
	
  	
  describe	
  "#make_plot"	
  do
	
  	
  	
  	
  it	
  "does	
  something"	
  do
	
  	
  	
  	
  end
	
  	
  end
end

91
$ bundle exec rspec
Run options: include {:focus=>true}
All examples were filtered out; ignoring {:focus=>true}
.
Finished in 0.00052 seconds
1 example, 0 failures
Randomized with seed 38431

92
Rakefile

require	
  "bundler/gem_tasks"
require	
  "rspec/core/rake_task"
RSpec::Core::RakeTask.new('spec')

93
Rakefile

require	
  "bundler/gem_tasks"
require	
  "rspec/core/rake_task"
RSpec::Core::RakeTask.new('spec')

94
$ rake spec
Run options: include {:focus=>true}
All examples were filtered out; ignoring {:focus=>true}
.
Finished in 0.00052 seconds
1 example, 0 failures
Randomized with seed 38431

95
96
Resources
guides.rubygems.org

link to slides @ClareGlinka_

97

More Related Content

What's hot

[HKOSCON][20200613][ Ansible: From VM to Kubernetes]
[HKOSCON][20200613][ Ansible: From VM to Kubernetes][HKOSCON][20200613][ Ansible: From VM to Kubernetes]
[HKOSCON][20200613][ Ansible: From VM to Kubernetes]Wong Hoi Sing Edison
 
Node.js - async for the rest of us.
Node.js - async for the rest of us.Node.js - async for the rest of us.
Node.js - async for the rest of us.Mike Brevoort
 
A Deeper Look at Cargo
A Deeper Look at CargoA Deeper Look at Cargo
A Deeper Look at CargoAnton Weiss
 
Voyage Reloaded - New features and backends in the document-database
Voyage Reloaded - New features and backends in the document-databaseVoyage Reloaded - New features and backends in the document-database
Voyage Reloaded - New features and backends in the document-databaseESUG
 
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversPlack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversTatsuhiko Miyagawa
 
Everything-as-code. Ein polyglottes Abenteuer
Everything-as-code. Ein polyglottes AbenteuerEverything-as-code. Ein polyglottes Abenteuer
Everything-as-code. Ein polyglottes AbenteuerQAware GmbH
 
Dessi docker kubernetes paas cloud
Dessi docker kubernetes paas cloudDessi docker kubernetes paas cloud
Dessi docker kubernetes paas cloudMassimiliano Dessì
 
SF Grails - Ratpack - Compact Groovy Webapps - James Williams
SF Grails - Ratpack - Compact Groovy Webapps - James WilliamsSF Grails - Ratpack - Compact Groovy Webapps - James Williams
SF Grails - Ratpack - Compact Groovy Webapps - James WilliamsPhilip Stehlik
 
Large-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 MinutesLarge-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 MinutesHiroshi SHIBATA
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the worldHiroshi SHIBATA
 
The Future of Bundled Bundler
The Future of Bundled BundlerThe Future of Bundled Bundler
The Future of Bundled BundlerHiroshi SHIBATA
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mrubyHiroshi SHIBATA
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the worldHiroshi SHIBATA
 
Ruby Security the Hard Way
Ruby Security the Hard WayRuby Security the Hard Way
Ruby Security the Hard WayHiroshi SHIBATA
 
How to develop Jenkins plugin using to ruby and Jenkins.rb
How to develop Jenkins plugin using to ruby and Jenkins.rbHow to develop Jenkins plugin using to ruby and Jenkins.rb
How to develop Jenkins plugin using to ruby and Jenkins.rbHiroshi SHIBATA
 
Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011leo lapworth
 

What's hot (20)

Tatsumaki
TatsumakiTatsumaki
Tatsumaki
 
[HKOSCON][20200613][ Ansible: From VM to Kubernetes]
[HKOSCON][20200613][ Ansible: From VM to Kubernetes][HKOSCON][20200613][ Ansible: From VM to Kubernetes]
[HKOSCON][20200613][ Ansible: From VM to Kubernetes]
 
Node.js - async for the rest of us.
Node.js - async for the rest of us.Node.js - async for the rest of us.
Node.js - async for the rest of us.
 
A Deeper Look at Cargo
A Deeper Look at CargoA Deeper Look at Cargo
A Deeper Look at Cargo
 
Voyage Reloaded - New features and backends in the document-database
Voyage Reloaded - New features and backends in the document-databaseVoyage Reloaded - New features and backends in the document-database
Voyage Reloaded - New features and backends in the document-database
 
Plack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and serversPlack perl superglue for web frameworks and servers
Plack perl superglue for web frameworks and servers
 
Everything-as-code. Ein polyglottes Abenteuer
Everything-as-code. Ein polyglottes AbenteuerEverything-as-code. Ein polyglottes Abenteuer
Everything-as-code. Ein polyglottes Abenteuer
 
Debugging on rails
Debugging on railsDebugging on rails
Debugging on rails
 
Intro to PSGI and Plack
Intro to PSGI and PlackIntro to PSGI and Plack
Intro to PSGI and Plack
 
Dessi docker kubernetes paas cloud
Dessi docker kubernetes paas cloudDessi docker kubernetes paas cloud
Dessi docker kubernetes paas cloud
 
SF Grails - Ratpack - Compact Groovy Webapps - James Williams
SF Grails - Ratpack - Compact Groovy Webapps - James WilliamsSF Grails - Ratpack - Compact Groovy Webapps - James Williams
SF Grails - Ratpack - Compact Groovy Webapps - James Williams
 
Plack - LPW 2009
Plack - LPW 2009Plack - LPW 2009
Plack - LPW 2009
 
Large-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 MinutesLarge-scaled Deploy Over 100 Servers in 3 Minutes
Large-scaled Deploy Over 100 Servers in 3 Minutes
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the world
 
The Future of Bundled Bundler
The Future of Bundled BundlerThe Future of Bundled Bundler
The Future of Bundled Bundler
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mruby
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the world
 
Ruby Security the Hard Way
Ruby Security the Hard WayRuby Security the Hard Way
Ruby Security the Hard Way
 
How to develop Jenkins plugin using to ruby and Jenkins.rb
How to develop Jenkins plugin using to ruby and Jenkins.rbHow to develop Jenkins plugin using to ruby and Jenkins.rb
How to develop Jenkins plugin using to ruby and Jenkins.rb
 
Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011Plack basics for Perl websites - YAPC::EU 2011
Plack basics for Perl websites - YAPC::EU 2011
 

Similar to How to make a Ruby Gem - Austin on Rails, January 2014

DevOPS training - Day 2/2
DevOPS training - Day 2/2DevOPS training - Day 2/2
DevOPS training - Day 2/2Vincent Mercier
 
Dockercon EU 2014
Dockercon EU 2014Dockercon EU 2014
Dockercon EU 2014Rafe Colton
 
Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Hiroshi SHIBATA
 
The Modern Developer Toolbox
The Modern Developer ToolboxThe Modern Developer Toolbox
The Modern Developer ToolboxPablo Godel
 
Development Workflow Tools for Open-Source PHP Libraries
Development Workflow Tools for Open-Source PHP LibrariesDevelopment Workflow Tools for Open-Source PHP Libraries
Development Workflow Tools for Open-Source PHP LibrariesPantheon
 
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...Docker, Inc.
 
Practical introduction to dev ops with chef
Practical introduction to dev ops with chefPractical introduction to dev ops with chef
Practical introduction to dev ops with chefLeanDog
 
RubyStack: the easiest way to deploy Ruby on Rails
RubyStack: the easiest way to deploy Ruby on RailsRubyStack: the easiest way to deploy Ruby on Rails
RubyStack: the easiest way to deploy Ruby on Railselliando dias
 
Docker module 1
Docker module 1Docker module 1
Docker module 1Liang Bo
 
Continuous Infrastructure: Modern Puppet for the Jenkins Project - PuppetConf...
Continuous Infrastructure: Modern Puppet for the Jenkins Project - PuppetConf...Continuous Infrastructure: Modern Puppet for the Jenkins Project - PuppetConf...
Continuous Infrastructure: Modern Puppet for the Jenkins Project - PuppetConf...Puppet
 
Everything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPLEverything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPLMario-Leander Reimer
 
Everything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventureEverything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventureQAware GmbH
 
Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012alexismidon
 
How I hack on puppet modules
How I hack on puppet modulesHow I hack on puppet modules
How I hack on puppet modulesKris Buytaert
 
Docker introduction
Docker introductionDocker introduction
Docker introductionPhuc Nguyen
 

Similar to How to make a Ruby Gem - Austin on Rails, January 2014 (20)

DevOPS training - Day 2/2
DevOPS training - Day 2/2DevOPS training - Day 2/2
DevOPS training - Day 2/2
 
Dockercon EU 2014
Dockercon EU 2014Dockercon EU 2014
Dockercon EU 2014
 
Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0
 
The Modern Developer Toolbox
The Modern Developer ToolboxThe Modern Developer Toolbox
The Modern Developer Toolbox
 
Development Workflow Tools for Open-Source PHP Libraries
Development Workflow Tools for Open-Source PHP LibrariesDevelopment Workflow Tools for Open-Source PHP Libraries
Development Workflow Tools for Open-Source PHP Libraries
 
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
The Tale of a Docker-based Continuous Delivery Pipeline by Rafe Colton (ModCl...
 
Practical introduction to dev ops with chef
Practical introduction to dev ops with chefPractical introduction to dev ops with chef
Practical introduction to dev ops with chef
 
RubyStack: the easiest way to deploy Ruby on Rails
RubyStack: the easiest way to deploy Ruby on RailsRubyStack: the easiest way to deploy Ruby on Rails
RubyStack: the easiest way to deploy Ruby on Rails
 
Git Heaven with Wakanda
Git Heaven with WakandaGit Heaven with Wakanda
Git Heaven with Wakanda
 
Docker module 1
Docker module 1Docker module 1
Docker module 1
 
Continuous Infrastructure: Modern Puppet for the Jenkins Project - PuppetConf...
Continuous Infrastructure: Modern Puppet for the Jenkins Project - PuppetConf...Continuous Infrastructure: Modern Puppet for the Jenkins Project - PuppetConf...
Continuous Infrastructure: Modern Puppet for the Jenkins Project - PuppetConf...
 
Mastering composer
Mastering composerMastering composer
Mastering composer
 
RubyGems 3 & 4
RubyGems 3 & 4RubyGems 3 & 4
RubyGems 3 & 4
 
Everything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPLEverything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPL
 
Everything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventureEverything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventure
 
Gradle
GradleGradle
Gradle
 
Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012
 
How I hack on puppet modules
How I hack on puppet modulesHow I hack on puppet modules
How I hack on puppet modules
 
Docker introduction
Docker introductionDocker introduction
Docker introduction
 
Grooscript greach
Grooscript greachGrooscript greach
Grooscript greach
 

Recently uploaded

Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdfPedro Manuel
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...Aggregage
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintMahmoud Rabie
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopBachir Benyammi
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
RAG Patterns and Vector Search in Generative AI
RAG Patterns and Vector Search in Generative AIRAG Patterns and Vector Search in Generative AI
RAG Patterns and Vector Search in Generative AIUdaiappa Ramachandran
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
Things you didn't know you can use in your Salesforce
Things you didn't know you can use in your SalesforceThings you didn't know you can use in your Salesforce
Things you didn't know you can use in your SalesforceMartin Humpolec
 
Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.francesco barbera
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.YounusS2
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URLRuncy Oommen
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UbiTrack UK
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesMd Hossain Ali
 
PicPay - GenAI Finance Assistant - ChatGPT for Customer Service
PicPay - GenAI Finance Assistant - ChatGPT for Customer ServicePicPay - GenAI Finance Assistant - ChatGPT for Customer Service
PicPay - GenAI Finance Assistant - ChatGPT for Customer ServiceRenan Moreira de Oliveira
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationIES VE
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostMatt Ray
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPathCommunity
 

Recently uploaded (20)

Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdf
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
 
Empowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership BlueprintEmpowering Africa's Next Generation: The AI Leadership Blueprint
Empowering Africa's Next Generation: The AI Leadership Blueprint
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 Workshop
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
RAG Patterns and Vector Search in Generative AI
RAG Patterns and Vector Search in Generative AIRAG Patterns and Vector Search in Generative AI
RAG Patterns and Vector Search in Generative AI
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
Things you didn't know you can use in your Salesforce
Things you didn't know you can use in your SalesforceThings you didn't know you can use in your Salesforce
Things you didn't know you can use in your Salesforce
 
Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URL
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
 
PicPay - GenAI Finance Assistant - ChatGPT for Customer Service
PicPay - GenAI Finance Assistant - ChatGPT for Customer ServicePicPay - GenAI Finance Assistant - ChatGPT for Customer Service
PicPay - GenAI Finance Assistant - ChatGPT for Customer Service
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation Developers
 

How to make a Ruby Gem - Austin on Rails, January 2014

  • 1. How to Make a Ruby Gem Clare Glinka 1
  • 2. Who is this talk for? •Me, a few months ago •Someone who is: •new to Rails •new to Ruby •new to programming 2
  • 3. What is a gem? • Container that hold widely-reusable code. • Code that is useable in many different contexts. 3
  • 4. Tools to help with making gems: •Bundler •Jeweler •gemcutter •others! 4
  • 5. Building a Gem <that generates cheesey adventure plots> with Bundler 5
  • 6. Step 0.5: $ gem install bundler 6
  • 7. Step 1: $ bundle gem adventure 7
  • 8. => create adventure/Gemfile create adventure/Rakefile create adventure/LICENSE.txt create adventure/README.md create adventure/.gitignore create adventure/adventure.gemspec create adventure/lib/adventure.rb create adventure/lib/adventure/version.rb Initializing git repo in /Users/me/code/adventure 8
  • 9. Gem structure adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec └── lib ├── adventure.rb └── adventure └── version.rb 9
  • 10. Step 3: Finish .gemspec 10
  • 11. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec └── lib ├── adventure.rb └── adventure └── version.rb 11
  • 12. adventure.gemspec lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] %q{TODO: Write a short summary. Required.} %q{TODO: Write a longer description. Optional.} "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 12
  • 15. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] %q{TODO: Write a short summary. Required.} %q{TODO: Write a longer description. Optional.} "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 15
  • 17. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] %q{TODO: Write a short summary. Required.} %q{TODO: Write a longer description. Optional.} "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 17
  • 18. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec └── lib ├── adventure.rb └── adventure └── version.rb 18
  • 20. Versioning • Use semantic versioning. •0.0.X - bugfixs •0.X.0 - additional functionality that is backward compatible. •X.0.0 - additional functionality that breaks backwards compatibility. 20
  • 21. Version constraints • ~> 1.2 - all versions before 2 . 0 • ~> 1 . 3 . 5 - all versions before 1. 4 . 0 21
  • 23. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] %q{TODO: Write a short summary. Required.} %q{TODO: Write a longer description. Optional.} "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 23
  • 24. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 24
  • 26. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 26
  • 27. Protect the load path! $ pry [1] pry(main)> $LOAD_PATH => ["/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/coderay-1.1.0/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/slop-3.4.7/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/method_source-0.8.2/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/pry-0.9.12.4/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby/2.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby/2.0.0/x86_64-darwin13.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby", "/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby/2.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby/2.0.0/x86_64-darwin13.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby", "/rbenv/versions/2.0.0-p353/lib/ruby/2.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/x86_64-darwin13.0.0"] 27
  • 28. Protect the load path! [2] pry(main)> require 'adventure' => true [3] pry(main)> $LOAD_PATH => ["/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/coderay-1.1.0/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/slop-3.4.7/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/method_source-0.8.2/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/pry-0.9.12.4/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/adventure-0.0.1/lib", "/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby/2.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby/2.0.0/x86_64-darwin13.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/site_ruby", "/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby/2.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby/2.0.0/x86_64-darwin13.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/vendor_ruby", "/rbenv/versions/2.0.0-p353/lib/ruby/2.0.0", "/rbenv/versions/2.0.0-p353/lib/ruby/2.0.0/x86_64-darwin13.0.0"] 28
  • 29. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec └── lib ├── adventure.rb └── adventure └── version.rb 29
  • 31. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 31
  • 33. $  pry [1]  pry(main)>  `git  ls-­‐files` =>  ".gitignorenGemfilenLICENSE.txtnREADME.mdnRakefile nadventure.gemspecnlib/adventure.rbnlib/adventure/version.rb n" [2]  pry(main)>  `git  ls-­‐files`.split($) =>  [".gitignore",  "Gemfile",  "LICENSE.txt",  "README.md",  "Rakefile",  "adventure.gemspec",  "lib/adventure.rb",  "lib/adventure/version.rb"] 33
  • 34. $  pry [1]  pry(main)>  `git  ls-­‐files` =>  ".gitignorenGemfilenLICENSE.txtnREADME.mdnRakefile nadventure.gemspecnlib/adventure.rbnlib/adventure/version.rb n" [2]  pry(main)>  `git  ls-­‐files`.split($) =>  [".gitignore",  "Gemfile",  "LICENSE.txt",  "README.md",  "Rakefile",  "adventure.gemspec",  "lib/adventure.rb",  "lib/adventure/version.rb"] 34
  • 35. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "" "MIT" spec.files = [".gitignore", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "adventure.gemspec", "lib/adventure.rb", "lib/ adventure/version.rb"] spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 35
  • 36. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 36
  • 37. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "" "MIT" Dir.glob(‘**/*’) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 37
  • 38. $  pry [1]  pry(main)>  Dir.glob('**/**') =>  ["adventure.gemspec",  "Gemfile",  "lib",  "lib/adventure",  "lib/adventure/random.txt",  "lib/adventure/version.rb",  "lib/adventure.rb",  "LICENSE.txt",  "Rakefile",  "README.md"] 38
  • 42. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 42
  • 43. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "http://www.github.com/cglinka/adventure" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 43
  • 45. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "http://www.github.com/cglinka/adventure" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 45
  • 46. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec └── lib ├── adventure.rb └── adventure └── version.rb 46
  • 48. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "http://github.com/cglinka/adventure" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 48
  • 49. Step 4: Write some code! 49
  • 50. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec └── lib ├── adventure.rb └── adventure └── version.rb 50
  • 51. require  "adventure/version" module  Adventure    #  Your  code  goes  here... end 51
  • 52. Desired output: “There is a disgruntled shopkeeper with a secret past and a grad student with a knack for cooking. They fight crime!” 52
  • 53. require  "adventure/version" module  Adventure    class  Plot        def  make_plot            characters  =  ["a  clever  dragon",                                          "a  ruthless  detective",                                          "a  disgruntled  shopkeeper",                                          "an  aging  cowboy",                                          "a  grad  student",                                          "a  mystical  lizard"]            with  =  ["nothing  left  to  loose",                            "a  secret  past",                              "an  enchanted  sword",                              "a  grudge",                              "a  knack  for  cooking"]            who  =  ["likes  kebabs",                            "organizes  poetry  nights",                            "is  a  world-­‐famous  cyclist",                            "lived  in  a  circus"]            "There  is  #{characters.sample}  with  #{with.sample}  and  #{characters.sample}   who  #{who.sample}.  They  fight  crime!"        end    end end 53
  • 54. Step 5: build and install the gem 54
  • 55. $ gem build adventure.gemspec WARNING: no description specified Successfully built RubyGem Name: adventure Version: 0.0.1 File: adventure-0.0.1.gem 55
  • 56. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec ├── adventure-0.0.1.gem └── lib ├── adventure.rb └── adventure └── version.rb 56
  • 57. $ gem install adventure-0.0.1.gem Successfully installed adventure-0.0.1 1 gem installed 57
  • 58. $  pry [1]  pry(main)>  require  'adventure' =>  true [2]  pry(main)>  plot  =  Adventure::Plot.new =>  #<Adventure::Plot:0x007fe2a4106498> [3]  pry(main)>  plot.make_plot =>  "There  is  a  grad  student  with  a  knack  for  cooking  and  a  ruthless   detective  who  likes  kebabs.  They  fight  crime!" 58
  • 59. The easier way... Rake tasks! 59
  • 60. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "http://github.com/cglinka/adventure" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 60
  • 61. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec └── lib ├── adventure.rb └── adventure └── version.rb 61
  • 62. Gemfile source  'https://rubygems.org' #  Specify  your  gem's  dependencies  in  adventure.gemspec gemspec 62
  • 64. $  rake  -­‐T rake  build        #  Build  adventure-­‐0.0.1.gem  into  the  pkg  directory. rake  install    #  Build  and  install  adventure-­‐0.0.1.gem  into  system   gems. rake  release    #  Create  tag  v0.0.1  and  build  and  push   adventure-­‐0.0.1.gem  to  Rubygems 64
  • 65. $  rake  build adventure  0.0.1  built  to  pkg/adventure-­‐0.0.1.gem. 65
  • 66. $  rake  install adventure  0.0.1  built  to  pkg/adventure-­‐0.0.1.gem. adventure  (0.0.1)  installed. 66
  • 67. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├──.gitignore ├── adventure.gemspec ├── pkg │ └── adventure-0.0.1.gem └── lib ├── adventure.rb └── adventure └── version.rb 67
  • 68. Step 6: Release the gem! 68
  • 69. 69
  • 71. And if everything has gone terribly wrong... $ gem yank *** Use with caution 71
  • 73. adventure.json {        "characters":  [                "a  clever  dragon",                "a  ruthless  detective",                "a  disgruntled  shopkeeper",                "an  aging  cowboy",                "a  grad  student",                "a  mystical  lizard"        ],        "with":  [                "nothing  left  to  loose",                "a  secret  past",                "an  enchanted  sword",                "a  grudge",                "a  knack  for  cooking"        ],        "who":  [                "likes  kebabs",                "organizes  poetry  nights",                "is  a  world-­‐famous  cyclist",                "lived  in  a  circus"        ] } 73
  • 75. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "http://github.com/cglinka/adventure" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_dependency "json" spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependency "rake" end 75
  • 76. $ bundle install Resolving dependencies... Using bundler (1.5.2) Using json (1.7.7) Using rake (0.9.6) Using adventure (0.0.1) from source at . Your bundle is complete! 76
  • 77. require  "adventure/version" module  Adventure    class  Plot        def  make_plot            characters  =  ["a  clever  dragon",                                          "a  ruthless  detective",                                          "a  disgruntled  shopkeeper",                                          "an  aging  cowboy",                                          "a  grad  student",                                          "a  mystical  lizard"]            with  =  ["nothing  left  to  loose",                            "a  secret  past",                              "an  enchanted  sword",                              "a  grudge",                              "a  knack  for  cooking"]            who  =  ["likes  kebabs",                            "organizes  poetry  nights",                            "is  a  world-­‐famous  cyclist",                            "lived  in  a  circus"]            "There  is  #{characters.sample}  with  #{with.sample}  and  #{characters.sample}   who  #{who.sample}.  They  fight  crime!"        end    end end 77
  • 78. lib/adventure.rb require  "adventure/version" require  "json" module  Adventure    class  Plot        def  make_plot(plotdevice)            plotholes  =  JSON.load(File.new(plotdevice))            characters  =  plotholes["characters"]            with              =  plotholes["with"]            who                =  plotholes["who"]            "There  is  #{characters.sample}  with  #{with.sample}  and   #{characters.sample}  who  #{who.sample}.  They  fight  crime!"        end    end end 78
  • 79. $  rake  install adventure  0.0.1  built  to  pkg/adventure-­‐0.0.1.gem. adventure  (0.0.1)  installed. 79
  • 82. $  rake  install adventure  1.0.0  built  to  pkg/adventure-­‐1.0.0.gem. adventure  (1.0.0)  installed. 82
  • 83. $  pry [1]  pry(main)>  require  'adventure' =>  true [2]  pry(main)>  plot  =  Adventure::Plot.new =>  #<Adventure::Plot:0x007fc079139e80> [3]  pry(main)>  plot.make_plot('adventure.json') =>  "There  is  a  clever  dragon  with  a  secret  past  and  a  clever   dragon  who  is  a  world-­‐famous  cyclist.  They  fight  crime!" 83
  • 84. Set Up Testing with <RSpec> 84
  • 85. # coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'adventure/version' Gem::Specification.new spec.name = spec.version = spec.authors = spec.email = spec.summary = spec.description = spec.homepage = spec.license = spec.files spec.executables spec.test_files spec.require_paths = = = = do |spec| "adventure" Adventure::VERSION ["Clare Glinka"] ["glinka.cb@gmail.com"] "Adventure plot generator" "" "http://github.com/cglinka/adventure" "MIT" `git ls-files`.split($/) spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.files.grep(%r{^(test|spec|features)/}) ["lib"] spec.add_dependency "json" spec.add_development_dependency "bundler", "~> 1.4" spec.add_development_dependencyependency "rake" spec.add_development_dependencyependency "rspec" end 85
  • 86. $ rspec --init create spec/spec_helper.rb create .rspec 86
  • 87. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├── .gitignore ├── .rspec ├── adventure.gemspec ├── pkg ├── lib └── spec └── spec_helper.rb 87
  • 88. spec/spec_helper.rb #  This  file  was  generated  by  the  `rspec  -­‐-­‐init`  command.  Conventionally,  all #  specs  live  under  a  `spec`  directory,  which  RSpec  adds  to  the  `$LOAD_PATH`. #  Require  this  file  using  `require  "spec_helper"`  to  ensure  that  it  is  only #  loaded  once. # #  See  http://rubydoc.info/gems/rspec-­‐core/RSpec/Core/Configuration RSpec.configure  do  |config|    config.treat_symbols_as_metadata_keys_with_true_values  =  true    config.run_all_when_everything_filtered  =  true    config.filter_run  :focus    #  Run  specs  in  random  order  to  surface  order  dependencies.  If  you  find  an    #  order  dependency  and  want  to  debug  it,  you  can  fix  the  order  by  providing    #  the  seed,  which  is  printed  after  each  run.    #          -­‐-­‐seed  1234    config.order  =  'random' end 88
  • 89. spec/spec_helper.rb require  'adventure' #  This  file  was  generated  by  the  `rspec  -­‐-­‐init`  command.  Conventionally,  all #  specs  live  under  a  `spec`  directory,  which  RSpec  adds  to  the  `$LOAD_PATH`. #  Require  this  file  using  `require  "spec_helper"`  to  ensure  that  it  is  only #  loaded  once. # #  See  http://rubydoc.info/gems/rspec-­‐core/RSpec/Core/Configuration RSpec.configure  do  |config|    config.treat_symbols_as_metadata_keys_with_true_values  =  true    config.run_all_when_everything_filtered  =  true    config.filter_run  :focus    #  Run  specs  in  random  order  to  surface  order  dependencies.  If  you  find  an    #  order  dependency  and  want  to  debug  it,  you  can  fix  the  order  by  providing    #  the  seed,  which  is  printed  after  each  run.    #          -­‐-­‐seed  1234    config.order  =  'random' end 89
  • 90. adventure ├── Gemfile ├── Rakefile ├── LICENSE.txt ├── README.md ├── .gitignore ├── .rspec ├── adventure.gemspec ├── pkg ├── lib └── spec ├── spec_adventure.rb └── spec_helper.rb 90
  • 91. spec/adventure_spec.rb require  'spec_helper' describe  Adventure::Plot  do    describe  "#make_plot"  do        it  "does  something"  do        end    end end 91
  • 92. $ bundle exec rspec Run options: include {:focus=>true} All examples were filtered out; ignoring {:focus=>true} . Finished in 0.00052 seconds 1 example, 0 failures Randomized with seed 38431 92
  • 95. $ rake spec Run options: include {:focus=>true} All examples were filtered out; ignoring {:focus=>true} . Finished in 0.00052 seconds 1 example, 0 failures Randomized with seed 38431 95
  • 96. 96