Gems

From WhyNotWiki
Jump to: navigation, search

This article is about how to use/install gems. For information about creating/packaging your own gems, see How to create a gem.


Gems  edit   (Category  edit)

Aliases: Gems, RubyGems, gem

Contents

General usage

The gem command

/usr/lib/ruby/site_ruby/1.8/rubygems.rb

  # The +gem+ directive should be executed *before* any require
  # statements (otherwise rubygems might select a conflicting library
  # version).

Autorequire is no longer available with the gem command

In earlier versions of RubyGems, it was the require_gem command, and there was a feature called autorequire. Sadly, it is no longer available. So we basically have to require everything twice:

gem 'library_name'
require 'library_name'

why (2006-08-13). Autorequire is Basically Gone, Everyone (http://redhanded.hobix.com/inspect/autorequireIsBasicallyGoneEveryone.html). Retrieved on 2007-02-12 19:21.

There was a time when autorequire would let you set a script which would be loaded when gem gets called. In the case of Hpricots previous[ly], you call gem 'hpricot' and then the gem gets loaded and its lib/hpricot.rb as well. But these days it’s kosher to say: require 'rubygems' gem 'hpricot', '>=0.4' require 'hpricot' So gem doesn’t load any [autorequire] scripts [any more]. It just lets us set up specifically what gem[s] we’ll be using.

Ironically (stupidly might be a better word), the RubyGems web site [1] still (2007-04-12 14:59) lists it as a valid option, doesn't say that it's deprecated, and even lists a good reason why one would want to use it!

In the above example, when the user’s code calls <code>require_gem ‘rake’</code>, an implicit <code>require ‘rake’</code> is called afterwards. <u>It is a shortcut so the user doesn’t have to do what seems to be a redundant <code>require</code>.</u>

Exactly! So why on earth are you deprecating it??

[Troubleshooting (category)]: can't activate __ (= 0.0.3), already activated __-0.0.4 (Gem::Exception)

Symptom: see title

Cause:

A file in gem G exists in version 0.0.3 as 'g/c', but is renamed to 'g/c_new_path' in version 0.0.4. In other words 'g/c' exists in version 0.0.3 but not in version 0.0.4.

This is how the error then plays out:

  • The script (a.rb) requires a file 'g/b'.
    • RubyGems searches for file 'g/b', and eventually finds it in gem G, version 0.0.4, which it then activates.
    • Since a.rb did not explicitly specify a version to activate (by using gem 'g', '= 0.0.3', for example), it will have activated the latest version (0.0.4).
  • a.rb then requires a file 'g/c'.
    • RubyGems searches for file 'g/c', and eventually finds it in gem G, version 0.0.3, which it then tries to activate.
  • However, only one version of a gem may be activated at any given time, so it raises this error.

Remedy:

  • One of the following:
    • Change your script a.rb to point to the new path for the file ('g/c_new_path') as it appears in the latest version.
    • Change your script a.rb to point to explicitly activate (gem 'g', '= 0.0.3') the version of the gem that contains the path that you are using ('g/c').

Discussion / prevention / better solution:

It seems like a lot to ask to expect users of gems to always specify a version number of the gem they load. This has these side-effects:

  • Then if they ever want to update that gem, they not only have to update them gem system-wide (install the latest version), but they also have to change all references in their code so that they point to the new version.

One possible solution would be to have RubyGems automatically downgrade to the earlier version, if it encounters a file that can only be found in that earlier version. Provided that it checks to confirm that all the files that have already loaded from that gem are identical in the previous version; otherwise one may end up using an incompatible mix of files from the new version and the old version!

Honestly, though, I don't think [this situation will ever change]. So people just need to become educated as to what this error message means and what the solution is so that they know what to do when they see it.

Example / dissection:

Example / dissection

This happened to me in the following situation:

/usr/lib/ruby/site_ruby/1.8/rubygems.rb:149:in `activate': can't activate qualitysmith_extensions (= 0.0.3), already activated qualitysmith_extensions-0.0.4] (Gem::Exception)
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:26:in `require'
        from test_helper.rb:12

How I debugged it:

test/test_helper.rb:10: require_gem 'qualitysmith_extensions', '>=0.0.3'
    • Caused 0.0.4 to be activated, since that's the latest installed version.

From the error message, I saw that test_helper.rb:12 was the trouble line.

test_helper.rb:12: require 'qualitysmith_extensions/capture_output.rb'

...which looks innocent enough — at first glance. And then I remembered that I had moved capture_output.rb from qualitysmith_extensions/ (in 0.0.3) to qualitysmith_extensions/kernel/ (in 0.0.4).

Why is that significant? Because RubyGems must have gone looking for the file, and — not finding it in 0.0.4 — it went look in older versions of the gem. And eventually it found it in 0.0.3. However, since 0.0.4 was already activated before it realized it needed something from 0.0.3 — and you can only have on version of a gem activated at one time — it had to raise an error.

The question is, though — why on earth would it go looking in the previous version at all if it had already activated a version? It would seem more intuitive — less surprising — to me if it had restricted its search to within the 0.0.4 version of the gem once it decided to activate 0.0.4. RubyGems seems to have tried to be a little too smart for my liking here. And ended up quite confusing me in the process.

It appears that I'm not the only one to think that (too smart)... It also appears that these errors are pretty easy to debug if you're lucky enough to be the developer of the library causing the errors and thus can remember which files got moved to what subdirectories in what version numbers! Most of us don't have that luck, however!

http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/e33316e0c7b5945f

Brian Buckley:

I am getting --Gem::Exception: can't activate facets (= 2005.10.15), already activated facets-0.7.2] -- when I require, say, 'facet/enumerable/probability' (irb stack trace below) I've got the latest version of facets (2005.10.15) installed ('gem list facet' gives me facets(2005.10.15, 2005.10.11, 0.7.2, 0.7.1, 0.7.0)) and I have a bunch of other gems installed including rails' activesupport, which I see is in the stack track. What is causing my Gem::Exception?

Trans:

I've gotten these at times. Drives me batty cause I'm not sure what's causing it either. While I suspect something is requiring an older version of facets first then you are trying to require against the new one. But the only way for this bug to happen then is if Gems is being "too" smart and noticing that this particular facet doesn't exist in the old version, but does in a new version (which is the case). So instead of saying "LoadError: no file to load -- facet/enumerable/probability for Facets v0.7.2" It's telling you you're trying to use a newer version when an older one has already been activated. Make sense? This is really a bad mojo on Gems. But we won't get into that. The question is what's causing the old version of facets to be active.

Brian Buckley:

I discovered my gem error goes away when I remove one of the require lines in my irb configure file but I haven't yet figured out what the specific code that is causing the conflict is. I'm not even sure what I should be looking for -- following each and every require in the whole require tree may get tedious.

Trans:

> The require I removed had been a file that contained more requires
> which in turn had more requires, etc...  a whole require tree.   But
> now I've isolated the problem to facet/array/each_permutation
>
> require 'facet/array/each_permutation'
> require 'facet/enumerable/probability'
>
> These two lines back to back cause my gem exception.
>
> Looking at the gems, I see that facet/array/each_permutation is not
> part of the current facet(2005.10.15) but it is in facet(0.7.2).
>
> Any explanation on what's happening here appreciated.

I see. Gems is activating 0.7.2 b/c #each_permutation is defined as an
array method in 0.7.2, but in the latest version it has been moved to
enumerable. So change to:

  require 'facet/enumerable/each_permutation'
  require 'facet/enumerable/probability'

My remedy?: Easy — fix the require so it points to a path that can be found in the latest (0.0.4) release of the gem!

-require 'qualitysmith_extensions/capture_output.rb'
+require 'qualitysmith_extensions/kernel/capture_output.rb'
 

How to build a .gem from a gem that's installed on your system

(So that you can scp it to another host, for example, in case it isn't hosted on any gem server that the other host has access to.)

> pushd /usr/lib/ruby/gems/1.8/gems/gem_name-version/

> sudo gem build /usr/lib/ruby/gems/1.8/specifications/gem_name-version.gemspec
  Successfully built RubyGem
  Name: gem_name
  Version: 0.0.10
  File: gem_name-version.gem

> ls
bin  gem_name-version.gem  lib  Readme



Searching for gems programatically

Rails: config/boot.rb

      # Asking for 1.1.6 will give you 1.1.6.5206, if available -- makes it easier to use beta gems
      rails_gem = Gem.cache.search('rails', "~>#{version}.0").sort_by { |g| g.version.version }.last

      if rails_gem
        gem "rails", "=#{rails_gem.version.version}"
        require rails_gem.full_gem_path + '/lib/initializer'
      else
        STDERR.puts %(Cannot find gem for Rails ~>#{version}.0:
    Install the missing gem with 'gem install -v=#{version} rails', or
    change environment.rb to define RAILS_GEM_VERSION with your desired version.
  )
        exit 1
      end



Installation

Where does it install executables to? (bin dir)

I used to think it was always to /usr/bin (and that it would overwrite existing binaries there if they existed), but now on a different box, it looks like it doesn't install them there, but rather to /var/lib/gems/1.8/bin/.

Question: Where does it get that path from?

/usr/lib/ruby/1.8/i486-linux/rbconfig.rb

# This file was created by mkconfig.rb when ruby was built.  Any
# changes made to this file will be lost the next time ruby is built.
module Config
  ...
  CONFIG = {}
  ...
  CONFIG["prefix"] = (TOPDIR || DESTDIR + "/usr")
  CONFIG["exec_prefix"] = "$(prefix)"
  CONFIG["bindir"] = "$(exec_prefix)/bin"
  ...
  CONFIG.each_value do |val|
    Config::expand(val)
  end

  #puts CONFIG["bindir"] # => /usr/bin

end

/usr/lib/ruby/1.8/rubygems/installer.rb

    def generate_bin(spec, install_dir=Gem.dir)
      return unless spec.executables && ! spec.executables.empty?

      # If the user has asked for the gem to be installed in
      # a directory that is the system gem directory, then
      # use the system bin directory, else create (or use) a
      # new bin dir under the install_dir.
      bindir = Gem.bindir(install_dir)

      Dir.mkdir bindir unless File.exist? bindir
      raise Gem::FilePermissionError.new(bindir) unless File.writable?(bindir)

      spec.executables.each do |filename|
        if @options[:wrappers] then
          generate_bin_script spec, filename, bindir, install_dir
        else
          generate_bin_symlink spec, filename, bindir, install_dir
        end
      end
    end

/usr/lib/ruby/1.8/rubygems.rb

require 'rbconfig'
#puts Config::CONFIG["bindir"]  # => /usr/bin
...
module Gem
  ...
  class << self
    ...

    # The directory path where executables are to be installed.
    #
    def bindir(install_dir=Gem.dir)
      #puts install_dir     # => /var/lib/gems/1.8
      #puts Gem.default_dir # => /usr/lib/ruby/gems/1.8

      # This is where it's getting /var/lib/gems/1.8/bin from:
      return File.join(install_dir, 'bin') unless install_dir == Gem.default_dir

      if defined? RUBY_FRAMEWORK_VERSION then # mac framework support
        File.join(File.dirname(Config::CONFIG["sitedir"]),
                  File.basename(Config::CONFIG["bindir"]))
      else # generic install
        # And this is where it gets /usr/bin from
        Config::CONFIG['bindir']
      end
    end

Question: How can I easily find out what that path is (without doing lots of detective work or trial and error)?

I would expect something like gem env bindir, since there is already a gem env gemdir, etc.

In the meantime, there's this:

> ruby -rubygems -e 'puts Gem.bindir'
/var/lib/gems/1.8/bin



Can I install a gem even if I don't have sudo/root access on the server?

Yes. You can output the install directory to be somewhere that you do have access to.

gem install gem_name --install-dir my_local_gems/gem_name

However, one thing I'm not totally sure about is how to make RubyGems aware of the existence of that directory.

It seems that it will still look in the system-wide gems directory (/usr/lib/ruby/gems/) (and not your local gems directory) anytime you do a require/gem command.

How do we get around that? How do we tell it about our local gem location?

Is there a .gemrc file or something you can use to inform it?? Or an option flag you can pass to ruby? Or what?? [See GEM_HOME below...]
If gems had no gem dependencies, it wouldn't be as much of a problem... you'd just add your gems dir to your $LOAD_PATH and use require to load the gem. but if the gem you're requiring uses the gem command, it won't (I think) use your $LOAD_PATH -- it will look in the system-wide gems directory (/usr/lib/ruby/gems/) (only). Problem!

Ah, I think I've found the solution!

http://docs.rubygems.org/read/chapter/3

3.2 Installing RubyGems in a User Directory If a user does not have access to the standard installation location (typically /usr/local/lib/ruby), then they have the option of installing RubyGems in a alternate location. Note that if you can’t install RubyGems in the standard location, then you probably can’t install gems in the standard gem repository location either. You need to specifiy a non-standard gem repository location via the GEM_HOME environment variable. Use the following to install RubyGems in a user directory (here called /home/mystuff) with a repository named /home/mygemrepository):

$ export GEM_HOME=/home/mygemrepository
$ ruby setup.rb config --prefix=/home/mystuff
$ ruby setup.rb setup
$ ruby setup.rb install

...

If you want the gem repository to reside inside the install directory, we recommend setting GEM_HOME to prefix_dir/gems. (where prefix_dir is given as the value of --prefix in the config step)

http://wiki.rubyonrails.org/rails/pages/HowToUseMultipleGemRepositories

As it happens, it’s entirely possible to support more than one physical gem repository. The key to this is the GEM_PATH environment variable. While the GEM_HOME environment variable is relatively well known, not so many people have heard of GEM_PATH. Below I’ll describe how to use this to configure and initialise a new gem repository, then logically, but not physically combine that new collection with other existing repositories which Ruby code will treat as one large, combined set of available gems. 3.2. Querying the default repository If you issue the command gem query with GEM_PATH unset you’ll see the list of gems installed in your system default repository, if you have one, not your new repository. 3.3. Querying your new repository Set GEM_PATH to the directory you created in step 1.2 then query the repository again:

export GEM_PATH=/home/username/ruby/gems
gem query

3.4. GEM_PATH is the key when reading

So, GEM_PATH is the key to supporting multiple repositories. To treat multiple physical repositories as one big logical gem collection, set the variable to a colon-separated list of repository locations. For example, if you have a system-wide default repository at /lib/ruby/gems/1.8 you can get Ruby to search your new repository first, then the system one, using:

export GEM_PATH=/home/username/ruby/gems:/lib/ruby/gems/1.8

Gems / How to install to your home directory edit

Before making any changes:

> gem env
RubyGems Environment:
  - VERSION: 0.9.2 (0.9.2)
  - INSTALLATION DIRECTORY: /usr/lib/ruby/gems/1.8
  - GEM PATH:
     - /usr/lib/ruby/gems/1.8
  - REMOTE SOURCES:
     - http://gems.rubyforge.org
> sudo gem install svn-command
(asks you for a root password, which you don't have)

Download from http://rubyforge.org/frs/?group_id=126 and install:

> wget http://rubyforge.org/frs/download.php/20585/rubygems-0.9.3.tgz
...
> tar -xzf rubygems-0.9.3.tgz

> cd rubygems-0.9.3
rubygems-0.9.3 > ruby setup.rb config --prefix=~/gems
rubygems-0.9.3 > ruby setup.rb setup

rubygems-0.9.3 > ruby setup.rb install
rm -f InstalledFiles
---> bin
mkdir -p /home/tylerrick/gems/bin
install gem /home/tylerrick/gems/bin/
install gem_mirror /home/tylerrick/gems/bin/
install gem_server /home/tylerrick/gems/bin/
install gemlock /home/tylerrick/gems/bin/
install gemri /home/tylerrick/gems/bin/
install gemwhich /home/tylerrick/gems/bin/
install index_gem_repository.rb /home/tylerrick/gems/bin/
install update_rubygems /home/tylerrick/gems/bin/
<--- bin
---> lib
mkdir -p /usr/local/lib/site_ruby/1.8
install gemconfigure.rb /usr/local/lib/site_ruby/1.8/
install rubygems.rb /usr/local/lib/site_ruby/1.8/
setup.rb:633:in `initialize': Permission denied - /usr/local/lib/site_ruby/1.8/rubygems.rb (Errno::EACCES)
        from setup.rb:633:in `open'
        from setup.rb:633:in `install'
        from setup.rb:1377:in `install_files'
        from setup.rb:1376:in `each'
        from setup.rb:1376:in `install_files'
        from setup.rb:1350:in `install_dir_lib'
        from setup.rb:1532:in `__send__'
        from setup.rb:1532:in `traverse'
         ... 7 levels...
        from setup.rb:826:in `__send__'
        from setup.rb:826:in `invoke'
        from setup.rb:773:in `invoke'
        from setup.rb:1578

Try again...

> PREFIX=$HOME
> export GEM_HOME=$PREFIX/lib/ruby/gems/1.8
> export RUBYLIB=$PREFIX/lib/ruby:$PREFIX/lib/site_ruby/1.8
> ruby setup.rb all --prefix=~/gems --installdirs=home
...
mkdir -p /home/tylerrick/bin/
install gem /home/tylerrick/bin/
install gem_mirror /home/tylerrick/bin/
install gem_server /home/tylerrick/bin/
install gemlock /home/tylerrick/bin/
install gemri /home/tylerrick/bin/
install gemwhich /home/tylerrick/bin/
install index_gem_repository.rb /home/tylerrick/bin/
install update_rubygems /home/tylerrick/bin/
<--- bin
---> lib
mkdir -p /home/tylerrick/lib/ruby/
install gemconfigure.rb /home/tylerrick/lib/ruby/
install rubygems.rb /home/tylerrick/lib/ruby/
install ubygems.rb /home/tylerrick/lib/ruby/
---> lib/rbconfig
mkdir -p /home/tylerrick/lib/ruby/rbconfig
install datadir.rb /home/tylerrick/lib/ruby/rbconfig
<--- lib/rbconfig
---> lib/rubygems
mkdir -p /home/tylerrick/lib/ruby/rubygems
install builder.rb /home/tylerrick/lib/ruby/rubygems
install command.rb /home/tylerrick/lib/ruby/rubygems
install command_manager.rb /home/tylerrick/lib/ruby/rubygems
install config_file.rb /home/tylerrick/lib/ruby/rubygems
install custom_require.rb /home/tylerrick/lib/ruby/rubygems
install dependency_list.rb /home/tylerrick/lib/ruby/rubygems
install doc_manager.rb /home/tylerrick/lib/ruby/rubygems
install format.rb /home/tylerrick/lib/ruby/rubygems
install gem_commands.rb /home/tylerrick/lib/ruby/rubygems
install gem_open_uri.rb /home/tylerrick/lib/ruby/rubygems
install gem_openssl.rb /home/tylerrick/lib/ruby/rubygems
install gem_runner.rb /home/tylerrick/lib/ruby/rubygems
install installer.rb /home/tylerrick/lib/ruby/rubygems
install old_format.rb /home/tylerrick/lib/ruby/rubygems
install open-uri.rb /home/tylerrick/lib/ruby/rubygems
install package.rb /home/tylerrick/lib/ruby/rubygems
install remote_fetcher.rb /home/tylerrick/lib/ruby/rubygems
install remote_installer.rb /home/tylerrick/lib/ruby/rubygems
install rubygems_version.rb /home/tylerrick/lib/ruby/rubygems
install security.rb /home/tylerrick/lib/ruby/rubygems
install server.rb /home/tylerrick/lib/ruby/rubygems
install source_index.rb /home/tylerrick/lib/ruby/rubygems
install source_info_cache.rb /home/tylerrick/lib/ruby/rubygems
install source_info_cache_entry.rb /home/tylerrick/lib/ruby/rubygems
install specification.rb /home/tylerrick/lib/ruby/rubygems
install timer.rb /home/tylerrick/lib/ruby/rubygems
install user_interaction.rb /home/tylerrick/lib/ruby/rubygems
install validator.rb /home/tylerrick/lib/ruby/rubygems
install version.rb /home/tylerrick/lib/ruby/rubygems
---> lib/rubygems/commands
mkdir -p /home/tylerrick/lib/ruby/rubygems/commands
install build_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install cert_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install check_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install cleanup_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install contents_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install dependency_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install environment_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install help_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install install_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install list_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install outdated_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install pristine_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install query_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install rdoc_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install search_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install sources_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install specification_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install uninstall_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install unpack_command.rb /home/tylerrick/lib/ruby/rubygems/commands
install update_command.rb /home/tylerrick/lib/ruby/rubygems/commands
<--- lib/rubygems/commands
---> lib/rubygems/digest
mkdir -p /home/tylerrick/lib/ruby/rubygems/digest
install digest_adapter.rb /home/tylerrick/lib/ruby/rubygems/digest
install md5.rb /home/tylerrick/lib/ruby/rubygems/digest
install sha1.rb /home/tylerrick/lib/ruby/rubygems/digest
install sha2.rb /home/tylerrick/lib/ruby/rubygems/digest
<--- lib/rubygems/digest
<--- lib/rubygems
<--- lib
  Successfully built RubyGem
  Name: sources
  Version: 0.0.1
  File: sources-0.0.1.gem


> gem env
RubyGems Environment:
  - VERSION: 0.9.3 (0.9.3)
  - INSTALLATION DIRECTORY: /home/tylerrick/lib/ruby/gems/1.8
  - GEM PATH:
     - /home/tylerrick/lib/ruby/gems/1.8
  - REMOTE SOURCES:
     - http://gems.rubyforge.org

> ln -s /home/tylerrick/lib/ruby/gems/1.8 ~/gems
> ls ~/gems
cache  doc  gems  specifications

Add to ~/.bash_profile:

# gems -> /home/tylerrick/lib/ruby/gems/1.8/
export GEM_PATH=$HOME/gems/gems:/usr/lib/ruby/gems/1.8/gems # Causes it to *read* from both of them combined
export GEM_HOME=$HOME/gems                                  # Causes it to *install* to this location

How I got the [svn-command (category)] gem installed on my [Dreamhost (category)] account.

> . ~/.bash_profile

> gem install svn-command
Bulk updating Gem source index for: http://gems.rubyforge.org
Killed
# Huh? Does Dreamhost have some kind of watchdog that kills any "long-running" process or something??

> ls -l  ~/lib/ruby/gems/1.8/source_cache
-rw-rw-r--  1 tylerrick pg817420 4 May 15 22:56 /home/tylerrick/lib/ruby/gems/1.8/source_cache
> cp ~/lib/ruby/gems/1.8/source_cache ~/lib/ruby/gems/1.8/source_cache.orig

> cp /usr/lib/ruby/gems/1.8/source_cache ~/lib/ruby/gems/1.8/source_cache
cp: cannot stat `/usr/lib/ruby/gems/1.8/source_cache': No such file or directory
> ls /usr/lib/ruby/gems/1.8/
bin  cache  doc  gems  specifications
# What?! Dreamhost, you pretty much suck.

[other host] > scp /usr/lib/ruby/gems/1.8/source_cache tylerrick@tylerrick.com:
[other host] > gem env
Rubygems Environment:
  - VERSION: 0.8.11 (0.8.11)
> mv ~/source_cache ~/lib/ruby/gems/1.8/source_cache
tylerrick: ~ > ls -l  ~/lib/ruby/gems/1.8/source_cache
-rw-r--r--  1 tylerrick pg817420 1834597 May 15 23:04 /home/tylerrick/lib/ruby/gems/1.8/source_cache
> gem install termios
ERROR:  While executing gem ... (NoMethodError)
    undefined method `refresh' for #<Hash:0x405eb3f8>

[other other host] > gem env
RubyGems Environment:
  - VERSION: 0.9.2 (0.9.2)
[other other host] > scp /usr/lib/ruby/gems/1.8/source_cache tylerrick@tylerrick.com:
> mv ~/source_cache ~/lib/ruby/gems/1.8/source_cache
tylerrick: ~ > ls -l  ~/lib/ruby/gems/1.8/source_cache
-rw-r--r--  1 tylerrick pg817420 3251890 May 15 23:08 /home/tylerrick/lib/ruby/gems/1.8/source_cache
tylerrick: ~ > gem install termios
Bulk updating Gem source index for: http://gems.rubyforge.org
Killed
# Stop killing my process, Dreamhost!!

[other other host] > sudo gem install termios
Bulk updating Gem source index for: http://gems.rubyforge.org
Building native extensions.  This could take a while...
Successfully installed termios-0.9.4
[other other host] > scp /usr/lib/ruby/gems/1.8/source_cache tylerrick@tylerrick.com:
> mv ~/source_cache ~/lib/ruby/gems/1.8/source_cache
tylerrick: ~ > ls -l  ~/lib/ruby/gems/1.8/source_cache
-rw-r--r--  1 tylerrick pg817420 3286191 May 15 23:12 /home/tylerrick/lib/ruby/gems/1.8/source_cache
tylerrick: ~ > gem install termios
Building native extensions.  This could take a while...
Successfully installed termios-0.9.4
# That's more like it!!!

> gem install svn-command --include-dependencies
ERROR:  While executing gem ... (RuntimeError)
    Error instaling svn-command:
        svn-command requires colored > 0.0.0
# What?? It should have installed colored automatically. --include-dependencies isn't working like it normally does....

> gem install colored
Successfully installed colored-1.0

 > gem install facets
Successfully installed facets-1.8.54
Installing ri documentation for facets-1.8.54...
Killed

> gem install svn-command --include-dependencies
Successfully installed svn-command, version 0.2.7

> _svn_command_post_install
chmod 755 /home/tylerrick/lib/ruby/gems/1.8/gems/svn-command-0.2.7/bin/rscm_test /home/tylerrick/lib/ruby/gems/1.8/gems/svn-command-0.2.7/bin/command_completion_for_svn_command /home/tylerrick/lib/ruby/gems/1.8/gems/svn-command-0.2.7/bin/svn /home/tylerrick/lib/ruby/gems/1.8/gems/svn-command-0.2.7/bin/_svn_command_post_install

# Add to ~/.bash_profile:
export PATH=`ls -dt --color=never ~/lib/ruby/gems/1.8/gems/svn-command* | head -n1`/bin:$PATH

> . ~/.bash_profile

> svn help
You are using svn-command version 0.2.7

Finally!

 







gemwhich

http://rubygems.org/read/chapter/17:

The gemwhich script works much like the unix shell ‘which’ command. Given a include file reference, it will locate that file in ruby libraries and gem repositories and display the file path for the file.

For example, if you would like to know where the rake/testtask file might be located, just type:

$ gemwhich rake/testtask
/usr/local/lib/ruby/gems/1.8/gems/rake-0.4.15/lib/rake/testtask.rb

gemwhich will work with regular (non-gem) Ruby libraries as well.

> gemwhich tree.rb
Can't find tree.rb
> gemwhich acts/tree.rb
Can't find acts/tree.rb
> gemwhich active_record/acts/tree.rb
Can't find active_record/acts/tree.rb
> gemwhich active_record/acts/tree
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/acts/tree.rb



Distributing Gems

8. Distributing Gems (http://rubygems.org/read/chapter/6). Retrieved on 2007-02-12 09:48.

8.1 Conventional Distribution Make your gem available on a web site for FTP site for downloading. Users can get the gem with conventional internet tools (e.g. browsers and FTP clients) and do a local install. 8.2 Remote Serving By running gem_server on your box, you can serve your entire set of installed gems to anyone.

gem_server

See gem server

[Troubleshooting (category)]: "undefined method `refresh'", "undefined method `source_index'", etc.

If you get a useless error like this:

> sudo gem install curb
ERROR:  While executing gem ... (NoMethodError)
    undefined method `refresh' for #<Hash:0xb7e242b4>

then this option might be helpful:

        --backtrace                  Show stack backtrace on errors
ERROR:  While executing gem ... (NoMethodError)
    undefined method `refresh' for #<Hash:0xb7e4a220>
/usr/lib/ruby/site_ruby/1.8/rubygems/source_info_cache.rb:94:in `refresh'
/usr/lib/ruby/site_ruby/1.8/rubygems/source_info_cache.rb:87:in `each'
...

Riding Rails: In case you're having trouble installing gems... suggests that you can just

rm /usr/lib/ruby/gems/1.8/source_cache

to solve this problem. But that's a problem for those of us folks who are on shared hosts. (I guess we'd just have to start installing gems in our home directory, if that happened on a shared host...?)

Another reason you might be getting this error: forgot to run with sudo?

This happened to me:

> gem update svn-command --source http://gems.qualitysmith.com:8808
Updating installed gems...
Bulk updating Gem source index for: http://gems.qualitysmith.com:8808
ERROR:  While executing gem ... (NoMethodError)
    undefined method `source_index' for #<Hash:0xb7e2d724>

But this worked just fine...

> sudo gem update svn-command --source http://gems.qualitysmith.com:8808
Updating installed gems...
Bulk updating Gem source index for: http://gems.qualitysmith.com:8808
Attempting remote update of svn-command
...
Successfully installed svn-command-0.2.14
Installing ri documentation for svn-command-0.2.14...
Installing RDoc documentation for svn-command-0.2.14...
Gems: [svn-command] updated

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/234668,Tim Pease,

> $ sudo gem install highline
> ERROR:  While executing gem ... (NoMethodError)
>      undefined method `source_index' for #<Hash:0x2dbaa1c>
>

James, did you clear out the source_cache for root?

Your query worked because you did it as you. Your install did not work because you tried to do it as root.


http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/234671,James Edward Gray II,

I originally cleared ~/.gem/source_cache. When you mentioned it, I cleared the one in root's home folder as well. When you gave me this final hint though, I found the one in /usr/local/lib/ ruby/gems/ and nuking that one did the trick. I can now query and install. Thanks for all the fresh ideas.

http://osdir.com/ml/lang.ruby.gems.devel/2007-01/msg00028.html,

There have been problems with source_cache being hosed since RubyGems 0.9.0, but I'm unsure if that's due to RubyGems changes or Ruby changes. I'm trying to collect corrupt source_cache files to reproduce the problem.


[Troubleshooting (category)]: "401 Authorization Required": How to fix

http://rubyforge.org/tracker/index.php?func=detail&aid=8121&group_id=126&atid=577 (has patch)

There is a problem installing a gem from a location that requires authorization. For instance, gem install test_gem --source http://test_user:test_pass@svn.maxwiki.com/auth_test Will fail with the error: ERROR: While executing gem ... (Gem::RemoteSourceException) HTTP Response 401 If the yaml list is not protected, but the gem is, it will fail with this error: ERROR: While executing gem ... (OpenURI::HTTPError) 401 Authorization Required The problem is that the basic authentication options are not being set when making the HTTP calls. This patch fixes these problems. (Note: The above "gem install" command points to a site that can be used for testing.)

[Troubleshooting (category)]: no such file to load -- sources

Symptom:

> gem
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require': no such file to load -- sources (LoadError)
        from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
        from /usr/local/lib/site_ruby/1.8/rubygems/source_info_cache.rb:6
        from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
        from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
        from /usr/local/lib/site_ruby/1.8/rubygems/remote_installer.rb:12
        from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
        from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
        from /usr/local/lib/site_ruby/1.8/rubygems.rb:112:in `manage_gems'
        from /home/tylerrick/gems/bin/gem:10

This happened to me while trying to get RubyGems installed to my home directory. It was a result of it trying to copy stuff to /usr/local/lib/site_ruby and not having sufficient permissions.

See Gems / How to install to your home directory for how I worked around this problem.

Apparently sources is a gem required by RubyGems that RubyGems tries to install for you during RubyGems installation!

> ls ~/lib/ruby/gems/1.8/gems/
sources-0.0.1

Having multiple versions installed at once

You can have multiple versions installed at once. In fact, this may even be necessary, if library A depends on B-1.4.0 but C depends on B-1.8.2!

facets (1.8.20, 1.4.0)
    If Godzilla were a Programmer's Library

Uninstalling a certain version of a gem

> sudo gem uninstall facets --version 1.4.0
Attempting to uninstall gem 'facets'
Successfully uninstalled facets version 1.4.0

Other

Safety / trustworthiness

http://blog.evanweaver.com/articles/2007/03/04/audit-your-gems

Gems don’t have to be trustworthy:

$ sudo gem list --remote malice
*** REMOTE GEMS ***
malice (13)
    malice, a small, malicious library

We could, uh, try it out:

$ sudo gem install malice
Building native extensions.  This could take a while...
Successfully changed your root password to five, lulz.
Successfully installed malice-13
Installing ri documentation for malice-13...
Installing RDoc documentation for malice-13...

Tested on OS X. Should work on Linux and BSD, too. Won’t work on Windows. Might not enable the root account if it’s disabled, but will change the password regardless.

Prevention?

Can you find a way to inspect the gem without installing it? Somehow the file doesn’t appear in the project list. And gem unpack wants it installed first. Would the unpacked version even tell you anything?

What if I had slipped this into cgi_multipart_eof_fix, one of the most-downloaded gems? What if someone had compromised my Rubyforge account, and they did it?

[...] Gems and Rubyforge are a great convenience. But know who you’re trusting.

Problems:

  • Has to be run as root (sudo)
  • People don't sign their gems
  • Many mirrors that could be compromised

Problem: Has to be run as root (sudo)

Possible solution:

  • Install to a different directory that doesn't require root (~/gems or something)

evan

If you install gems in the environment where you use them, your data is at risk. sudo just makes damage control a bit harder from a technical standpoint.

Problem: People don't sign their gems

Possible solution:

  • Start signing your gems and requiring other people's gems to be signed before you install them (like that's ever going to happen!)

evan

You can already sign gems, see here. The security policy business is convoluted for users, so they don’t pay attention to it, so they don’t require authors to use it. At least that’s my opinion. Plus it’s unclear how to specify a required policy level in ~/.gemrc or similar. Most system package managers require you to trust the source. For instance, with APT, you have to add new sources to the /etc/apt/sources.list file. Otherwise you just get Debian or Ubuntu’s default sources, and those are closed to public submissions.

http://www.chrisfarms.com/ chrisfarms

Short of having gems installed in a sandboxed environment on a trial before a real install… I think signing gems could at least help with the issue of a normally trusted source becoming compromised…

Problem: Many mirrors that could be compromised

mfp

Is this any worse than the situation with tarballs? Yes and no. RubyGems introduces several easily exploitable targets, and even though it’s possible to use it safely, it’s such a PITA (arguably harder than with a plain tarball) that you’ll often just cross your fingers and hope. ... When you gem install, you’re not only trusting Rubyforge but also N mirrors. Crack one and you screw some % of the people installing Rails (and they’ll most probably never know).

Possible solution:

Retrieved from "http://whynotwiki.com/Gems"
Ads
Personal tools