Oleg Mikheev
Oleg Mikheev

Reputation: 17444

Install gem on demand

I would like to install a gem (JSON) on the client side, but only if hasn't been installed already (some 1.9 Ruby distros have JSON bundled).

I couldn't find a clue on how to do that from gem help install. And running gem install json on a Windows system with Ruby 1.9 installed (with JSON bundled) results in

    ERROR:  Error installing json:
    The 'json' native gem requires installed build tools.

-- it tries to install it ignoring the fact that the gem is already there.

And I can't do bash tricks like grepping gem list output because the client might be Windows.

So what's the multiplatform way of installing a gem only if it's not present in the system already?

Upvotes: 7

Views: 1408

Answers (4)

akostadinov
akostadinov

Reputation: 18584

The best I found is this (shell command): $ gem install asciidoctor --conservative

It will install only if gem spec cannot be covered by currently installed gems.

Upvotes: 0

joelparkerhenderson
joelparkerhenderson

Reputation: 35443

To ask if a gem is installed:

gem list --installed "^json$"

To install a gem if it's needed:

ruby -e '`gem list -i \"^json$\"`.chomp=="true" or `gem install json`'

To make a command line script:

#!/usr/bin/env ruby
#
# Ruby script to install a gem if it's needed.
# This script first uses gem list to see if the
# gem is already installed, matching the exact name.
#
# If the gem is installed, then exit.
# If the gem is not installed, then install it.
#
# You can this script whatever you like;
# I call mine gem-install-fast because it's
# faster than re-installing a gem each time.
# 
# Example:
#
#    gem-install-fast json
#
name=ARGV[0] and `gem list -i "^#{name}$"`.chomp=="true" or `gem install #{name}`

To use the command line script:

gem-install-fast json

Upvotes: 2

Tomato
Tomato

Reputation: 438

This may work...

begin
  require "json"
rescue LoadError
  system("gem install json")
end

If you don't want to require "json", you can remove it from $LOAD_PATH.

Or, put as a one liner:

ruby -e 'begin; require "some_gem"; rescue LoadError; system "gem install some_gem"; end'

Upvotes: 2

peter
peter

Reputation: 42182

gem update json

should only install if necessary, on my windows 7 system it does

C:\Ruby193\bin>gem update json
Updating installed gems
Updating json
Fetching: json-1.6.6.gem (100%)
Temporarily enhancing PATH to include DevKit...
Building native extensions.  This could take a while...
Successfully installed json-1.6.6
Updating multi_json
Fetching: multi_json-1.2.0.gem (100%)
Successfully installed multi_json-1.2.0
Gems updated: json, multi_json
Installing ri documentation for json-1.6.6...
Installing ri documentation for multi_json-1.2.0...
Installing RDoc documentation for json-1.6.6...
Installing RDoc documentation for multi_json-1.2.0...

C:\Ruby193\bin>gem update json
Updating installed gems
Nothing to update

C:\Ruby193\bin>

Upvotes: 0

Related Questions