List of installed gems?
Asked Answered
U

11

195

Is there a Ruby method I can call to get the list of installed gems?

I want to parse the output of gem list.

Is there a different way to do this?

Undersheriff answered 3/3, 2011 at 6:56 Comment(0)
E
60

The Gem command is included with Ruby 1.9+ now, and is a standard addition to Ruby pre-1.9.

require 'rubygems'

name = /^/i
dep = Gem::Dependency.new(name, Gem::Requirement.default)
specs = Gem.source_index.search(dep)
puts specs[0..5].map{ |s| "#{s.name} #{s.version}" }
# >> Platform 0.4.0
# >> abstract 1.0.0
# >> actionmailer 3.0.5
# >> actionpack 3.0.5
# >> activemodel 3.0.5
# >> activerecord 3.0.5

Here's an updated way to get a list:

require 'rubygems'

def local_gems
   Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.group_by{ |g| g.name }
end

Because local_gems relies on group_by, it returns a hash of the gems, where the key is the gem's name, and the value is an array of the gem specifications. The value is an array of the instances of that gem that is installed, sorted by the version number.

That makes it possible to do things like:

my_local_gems = local_gems()

my_local_gems['actionmailer']
# => [Gem::Specification.new do |s|
#       s.authors = ["David Heinemeier Hansson"]
#       s.date = Time.utc(2013, 12, 3)
#       s.dependencies = [Gem::Dependency.new("actionpack",
#         Gem::Requirement.new(["= 4.0.2"]),
#         :runtime),
#        Gem::Dependency.new("mail",
#         Gem::Requirement.new(["~> 2.5.4"]),
#         :runtime)]
#       s.description = "Email on Rails. Compose, deliver, receive, and test emails using the familiar controller/view pattern. First-class support for multipart email and attachments."
#       s.email = "[email protected]"
#       s.homepage = "http://www.rubyonrails.org"
#       s.licenses = ["MIT"]
#       s.name = "actionmailer"
#       s.require_paths = ["lib"]
#       s.required_ruby_version = Gem::Requirement.new([">= 1.9.3"])
#       s.requirements = ["none"]
#       s.rubygems_version = "2.0.14"
#       s.specification_version = 4
#       s.summary = "Email composition, delivery, and receiving framework (part of Rails)."
#       s.version = Gem::Version.new("4.0.2")
#       end]

And:

puts my_local_gems.map{ |name, specs| 
  [ 
    name,
    specs.map{ |spec| spec.version.to_s }.join(',')
  ].join(' ') 
}
# >> actionmailer 4.0.2
...
# >> arel 4.0.1,5.0.0
...
# >> ZenTest 4.9.5
# >> zucker 13.1

The last example is similar to the gem query --local command-line, only you have access to all the information for a particular gem's specification.

Emergent answered 3/3, 2011 at 7:22 Comment(1)
Should be noted, "Dependency.new w/ a regexp is deprecated" now.Defilade
O
427

This lists all the gems I have installed.

gem query --local

http://guides.rubygems.org/command-reference/#gem-list

Listing all installed gems

Ophiology answered 9/3, 2013 at 15:8 Comment(3)
there is a better answer in the question itself gem list.Unperforated
gem list did exactly what I needed, and it's a lot simpler and easier to recall when on the CLI. Why so many commands to do one thing?Judaea
Difference between a)gem list, b)gem query and c)gem query --local please. All three seem having same line numbers.Frannie
E
60

The Gem command is included with Ruby 1.9+ now, and is a standard addition to Ruby pre-1.9.

require 'rubygems'

name = /^/i
dep = Gem::Dependency.new(name, Gem::Requirement.default)
specs = Gem.source_index.search(dep)
puts specs[0..5].map{ |s| "#{s.name} #{s.version}" }
# >> Platform 0.4.0
# >> abstract 1.0.0
# >> actionmailer 3.0.5
# >> actionpack 3.0.5
# >> activemodel 3.0.5
# >> activerecord 3.0.5

Here's an updated way to get a list:

require 'rubygems'

def local_gems
   Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.group_by{ |g| g.name }
end

Because local_gems relies on group_by, it returns a hash of the gems, where the key is the gem's name, and the value is an array of the gem specifications. The value is an array of the instances of that gem that is installed, sorted by the version number.

That makes it possible to do things like:

my_local_gems = local_gems()

my_local_gems['actionmailer']
# => [Gem::Specification.new do |s|
#       s.authors = ["David Heinemeier Hansson"]
#       s.date = Time.utc(2013, 12, 3)
#       s.dependencies = [Gem::Dependency.new("actionpack",
#         Gem::Requirement.new(["= 4.0.2"]),
#         :runtime),
#        Gem::Dependency.new("mail",
#         Gem::Requirement.new(["~> 2.5.4"]),
#         :runtime)]
#       s.description = "Email on Rails. Compose, deliver, receive, and test emails using the familiar controller/view pattern. First-class support for multipart email and attachments."
#       s.email = "[email protected]"
#       s.homepage = "http://www.rubyonrails.org"
#       s.licenses = ["MIT"]
#       s.name = "actionmailer"
#       s.require_paths = ["lib"]
#       s.required_ruby_version = Gem::Requirement.new([">= 1.9.3"])
#       s.requirements = ["none"]
#       s.rubygems_version = "2.0.14"
#       s.specification_version = 4
#       s.summary = "Email composition, delivery, and receiving framework (part of Rails)."
#       s.version = Gem::Version.new("4.0.2")
#       end]

And:

puts my_local_gems.map{ |name, specs| 
  [ 
    name,
    specs.map{ |spec| spec.version.to_s }.join(',')
  ].join(' ') 
}
# >> actionmailer 4.0.2
...
# >> arel 4.0.1,5.0.0
...
# >> ZenTest 4.9.5
# >> zucker 13.1

The last example is similar to the gem query --local command-line, only you have access to all the information for a particular gem's specification.

Emergent answered 3/3, 2011 at 7:22 Comment(1)
Should be noted, "Dependency.new w/ a regexp is deprecated" now.Defilade
V
36

Both

gem query --local

and

 ruby -S gem list --local

list 69 entries

While

ruby -e 'puts Gem::Specification.all_names'

return 82

I used wc -l to get the numbers. Not sure if that is the right way to check. Tried to redirect the output to text files and diffed but that didn't help - will need to compare manually one by one.

Vogt answered 12/3, 2014 at 13:33 Comment(1)
The reason is simple. The first command only adds 1 entry per gem and lists the versions in brackets on the same line. The last ruby command lists each gem version on a separate line. For e.g.: sass (3.3.14, 3.3.7, 3.3.6, 3.2.19) vs. sass-3.3.14, sass-3.3.7, sass-3.3.6, sass-3.2.19Zeculon
L
11

There's been a method for this for ages:

ruby -e 'puts Gem::Specification.all_names'
Laodicea answered 25/2, 2014 at 14:57 Comment(1)
ruby -e 'puts Gem::Specification.all_names' gives me "-e:1: uninitialized constant Gem (NameError)" How do I solve this?Truong
R
7
Gem::Specification.map {|a| a.name}

However, if your app uses Bundler it will return only list of dependent local gems. To get all installed:

def all_installed_gems
   Gem::Specification.all = nil    
   all = Gem::Specification.map{|a| a.name}  
   Gem::Specification.reset
   all
end
Restivo answered 24/1, 2012 at 8:15 Comment(1)
This gives NoMethodError: undefined method any?' for nil:NilClass` when I use it (in a rails console).Polanco
R
6

use this code (in console mode):

Gem::Specification.all_names
Reproduce answered 22/12, 2017 at 16:27 Comment(3)
can you improve your answer?Arella
improved or let me know what exactly you don't like in my answerForbade
This could use an explanation of what this adds to existing answers. Why should I use this code? What does it do? How is it different than this answer or this answer?Sosthina
G
5

Here's a really nice one-liner to print all the Gems along with their version, homepage, and description:

Gem::Specification.sort{|a,b| a.name <=> b.name}.map {|a| puts "#{a.name} (#{a.version})"; puts "-" * 50; puts a.homepage; puts a.description; puts "\n\n"};nil
Georama answered 7/7, 2017 at 21:1 Comment(0)
A
3

A more modern version would be to use something akin to the following...

require 'rubygems'
puts Gem::Specification.all().map{|g| [g.name, g.version.to_s].join('-') }

NOTE: very similar the first part of an answer by Evgeny... but due to page formatting, it's easy to miss.

Almire answered 21/5, 2013 at 15:15 Comment(0)
U
3

Try it in the terminal:

ruby -S gem list --local
Utile answered 6/11, 2013 at 8:51 Comment(1)
Notice that the OP wanted a Ruby method.Emergent
D
1

Maybe you can get the files (gems) from the gems directory?

gemsdir = "gems directory"
gems = Dir.new(gemsdir).entries
Derward answered 3/3, 2011 at 7:5 Comment(0)
S
1

From within your debugger type $LOAD_PATH to get a list of your gems. If you don't have a debugger, install pry:

gem install pry
pry
Pry(main)> $LOAD_PATH

This will output an array of your installed gems.

Scutt answered 9/1, 2016 at 20:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.