Nathan Buesgens
Nathan Buesgens

Reputation: 1445

Ruby gem equivalent of "pip install -e"?

In Python I can install a package from source in "editable" mode using pip install -e. Then I can carry on editing the code, and any changes will be automatically picked by other Python scripts that import library

Is there a comparable workflow for developing Ruby gems? What is the "Ruby way" of using libs as they are being developed rather than, for example, compiling and installing a gem every time I make a change to the source?

Upvotes: 19

Views: 2803

Answers (4)

Dan R
Dan R

Reputation: 424

I realize this is a 5 year old question, but I found all of these answers unsatisfying. Since I use ruby to develop CLI tools, using bundler for testing is not ideal. I need to be able to execute my test commands anywhere, and get the actual equivalent of pip install --editable.

Here's my solution.

  1. Use RVM to setup a new gemset for development

    rvm gemset use tools-dev --create

  2. Install your gems

    gem install mygem.gem

  3. Locate the installation directory

    gem list tool -d

  4. In the output, it will say installed at ${rvm_gemset_path}. Copy that path. It will also be an environment variable GEM_HOME, but I include this step for completeness and clarity.

  5. Delete the installed copy

    rm -Rf ${rvm_gemset_path}/gems/mygem-${version}

  6. Create a symlink to the git repository working directory.

    ln -s ${PWD} ${rvm_gemset_path}/gems/mygem-${version}

This bash script will do it in a more automated fashion assuming that you are in the git directory and you've set GEM_NAME as your gem's name.

rvm gemset use --create ${GEM_NAME}-dev
gem build ${GEM_NAME}.gemspec
gem install ${GEM_NAME}*.gem
gem_install_path=$(ruby -e "puts Gem::Specification.find_by_name('${GEM_NAME}').full_gem_path")
mv $gem_install_path "${gem_install_path}.bak"
ln -s $PWD $gem_install_path

Upvotes: 0

art-solopov
art-solopov

Reputation: 4755

Let's assume you have your gem code residing in a folder (say my_project/mygem/lib). You have some Ruby code in my_project that you want using the mygem code.

What I'd do is add mygem/lib to the $LOAD_PATH global variable in the beginning of said files. Kinda like this:

$LOAD_PATH << File.expand_path('lib', './mygem') # Resolve global paths

require 'a_file' # Would require "mygem/lib/a_file.rb"

Upvotes: 5

Aleksander Pohl
Aleksander Pohl

Reputation: 1695

I am not sure if this is exactly what you want to achieve, but from the description I infer that you want to have a local copy of some gem and reference that gem in your project. If this is the case, you can (usually) achieve it in two steps:

  1. Clone the gem from VCS (in most cases: git), e.g. git clone url-of-the-gem-repo
  2. Reference the local copy using Bundler :path, e.g. gem "some-gem", :path => "/path/to/local/copy"

If the gem is stored at github, an even better way is to first fork it at github and then clone your own copy. Then, if you provide any improvements to the code in the local repo, you can easily share it with the world using a pull request.

Upvotes: 3

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

There are two common approaches one might use with bundler:

  1. one executes bundle install --path vendor/bundle and does not run bundle update unless everything is tested.
  2. one tells a bundler to use a local version of the gem:
    • in Gemfile (this is not supported in mymaingem.gemspec due to rubygems maintainence issues): gem 'mycutegem', :git => 'git://github.com/myname/mycutegem', :branch => 'master';
    • in command line: bundle config local.mycutegem /path_to_local_git/mycutegem.

The first approach will download everything into subfolder of your current project (here it’d be vendor/bundle.) Feel free to modify everything there, it’ll be reflected.

The second approach is likely better. You are to clone the gem from github and instruct bundle to use your local clone of the respective git repository. This approach provides you with an ability to publish the changes to your main gem into the repository. As soon as dependent repo is published as well, the up-to-date version will be retrieven by your gem subscribers, assuming they have not instructed their bundlers to use their locals.

Hope this helps.

Upvotes: 9

Related Questions