Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App generation uses current RVM gemset instead of project-specific gemset #170

Open
JangoSteve opened this issue Mar 7, 2013 · 15 comments

Comments

@JangoSteve
Copy link
Contributor

I have not yet been able to get the .rvmrc and project-specific gemset from the extras to work. It seems like it's working, but when it gets to the part of the app generation that creates the gemset and switches to it, when I run

rails new my_app -m template.rb

(where template.rb was created with rails_apps_composer), I see this:

[clipped]
      extras  recipe creating project-specific rvm gemset and .rvmrc
      extras  creating RVM gemset 'my_app'
      extras  switching to gemset 'my_app'
         run    rvm gemset list from "."

gemsets for ruby-1.9.3-p194 (found in /Users/me/.rvm/gems/ruby-1.9.3-p194)
   global
   mongoid
   my_app
=> rails-generate

      remove    .rvmrc
      create    .rvmrc
        gsub    .rvmrc
    composer  Installing gems. This will take a while.
         run    bundle install --without production from "."
[/clipped]

Notice when the generator runs rvm gemset list, it shows that it's still using the rails-generate gemset, which is the current gemset, not the app's new project-specific gemset. Sure enough when it's done running, I find that all the gems are installed in my current gemset and the project's gemset is empty and doesn't even contain rails.

@JangoSteve
Copy link
Contributor Author

I've tried a few more things to see if I could fix it but with no luck. I've replaced this line with the following (to try switching gemsets a few different ways):

      # output some debug info
      gemset = "#{ENV['MY_RUBY_HOME'].split(/\//).last}@#{app_name}"
      say_wizard "set rvm gemset: #{gemset}"

      # try setting it the current way
      RVM.gemset_use! app_name
      # try setting it from running the rvm command
      run "rvm gemset use #{app_name}"
      # try setting it an alternate way, where gemset = "ruby-1.9.3-p194@my_app"
      RVM.use! gemset

      # debug the current gemset (a couple different ways) to see if it was set
      say_wizard "Using RVM gemset:"
      say_wizard RVM.gemset_name
      run "rvm gemset name"

The output from above when the rails generator runs is:

      extras  set rvm gemset: ruby-1.9.3-p194@my_app
         run    rvm gemset use my_app from "."
Using ruby-1.9.3-p194 with gemset my_app
      extras  Using RVM gemset:
      extras  rails-generate
         run    rvm gemset name from "."
rails-generate

You can see when run "rvm gemset use #{app_name}" is run, it even outputs from the command that RVM is using the my_app gemset, but then when we run all the commands to show which gemset is being used, it's still the wrong one.

@JangoSteve
Copy link
Contributor Author

Finally figured out what's causing this (though I'm still not sure why, as it seems like it should work anyway).

It's due to trying to run the rails new my_app -m template.rb command from inside a directory that had it's own .rvmrc and Gemfile (i.e. the directory where I keep my template.rb file under version control).

@JangoSteve
Copy link
Contributor Author

In case anyone comes across this (as I just did myself once again while trying to use an updated version of the rails_apps_composer gem), to clarify above, you cannot use the rails_apps_composer command using a current Gemfile, unless that Gemfile is part of your new rails app that you're about to generate already.

For example, let's say you're using a fork of the rails_apps_composer gem locally and it has it's own Gemfile pointing to your fork on Github. If you want to select yes to using a custom rvm gemset for your new rails app, you can't run bundle exec rails_apps_composer new ./my_new_app, as it relies on using the current Gemfile and won't switch to the new my_new_app gemset once it creates it.

What you have to do is compile your fork of the gem locally, do a normal gem install from within your fork's local directory, and then run the above command outside of that directory with the local gem installed:

cd rails_apps_composer
gem build rails_apps_composer
gem install rails_apps_composer
cd ..
rails_apps_composer new ./my_new_app

The above will work as long as you don't have other versions of the rails_apps_composer gem installed, such that you don't need bundler to manage the correct version of the rails_apps_composer new command to run.

@DanielKehoe
Copy link
Member

Thanks for clarifying this.

@JangoSteve
Copy link
Contributor Author

May consider adding something about not using bundler to the "hacking the gem" wiki, if using the project-specific rvm gemset (or I can add it if you'd like).

@DanielKehoe
Copy link
Member

Yes, please add a note. Frankly, I don't understand the problem you encountered, probably because I don't understand your use case. Maybe you could explain your use case? What exactly are you doing with the gem that is different from a typical use case?

@JangoSteve
Copy link
Contributor Author

Probably partially because I've been trying to explain it from a conceptual point of view.

From a programmatic point of view, the issue is with this line:

RVM.gemset_use! app_name

Let's say that line is in a ruby script called use_gemset.rb. If you run the ruby script like this:

bundle exec ruby use_gemset.rb

It won't switch gemsets, because bundler has fixed your current GEM_PATH and/or MY_RUBY_HOME environment variables (I'm guessing this is the cause, but not positive). It'll say it switched, but if you then run rvm gemset name, you'll see you're still using your original gemset.

Likewise, if that ruby file is contained within a directory that has a .rvmrc or .ruby-gemset file, and you run the ruby file from within that directory, it also won't work (I'm guessing for the same reason):

cd my_directory
ls -a
#=> .ruby-gemset use_gemset.rb
ruby use_gemset.rb

So, the only way to get it to work is to run a ruby command from outside any directory that has a .rvmrc or .ruby-gemset file, and run the command directly without bundler:

cd ..
ruby my_directory/use_gemset.rb

That's great and all, but what if that ruby file requires a specific version of a gem, e.g. a specific version of the rails_apps_composer gem that I've been working on. A common way to manage this would be to use bundler with a gemfile that says something like:

gem 'rails_apps_composer', :path => '~/my_forks/rails_apps_composer'
# or
gem 'rails_apps_composer', :git => 'https://github.com/alfajango/rails_apps_composer', :branch => 'my-feature-branch'

And then to run the command with bundle exec. But this goes back to the first issue with the RVM.gemset_user! command not working when you run the command using bundler.

So, the only way to get around it would be to manually compile your locally-modified version of the rails_apps_composer gem, run gem uninstall rails_apps_composer to uninstall all other versions of the gem from whatever ruby runtime you're using (whether it be a custom gemset or whatever), and then to install your locally-compiled version of the gem:

cd my_forks/rails_apps_composer
gem install rails_apps_composer

Then you can run the rails_apps_composer command without bundler, and it will use your locally-modified, locally-compiled version of the gem.

@JangoSteve
Copy link
Contributor Author

What exactly are you doing with the gem that is different from a typical use case?

To answer your question directly, I was trying to generate a new rails app using local modifications to the gem (before submitting a pull-request) and answering "yes" to the project-specific gemset prompt when generating my new rails app. Doing so causes the creation process to error out due to not having the wrong versions of gems installed due to the gems being loaded from my_forks/rails_apps_composer/Gemfile, rather than the new rails app's Gemfile.

@DanielKehoe
Copy link
Member

So what if you drop bundle exec from your workflow? I never use it. It's not useful (AFAIK) when using RVM and the rubygems-bundler gem.

@JangoSteve
Copy link
Contributor Author

I don't think the issue is directly from typing bundle exec in your terminal, it's from the fixation of the GEM_PATH that Bundler does to load the correct versions of gems.

Using the rubygems-bundler gem makes it so you don't have to physically type bundle exec, by auto-detecting when you have a Gemfile, but it still calls Bundler.setup and does all the same things bundler does. So, I don't think that would fix the issue.

@JangoSteve
Copy link
Contributor Author

In other words, let's say I have a gemset for my rails_apps_composer development, and in that gemset, I have the rails_apps_composer gem installed from rubygems.org. Now, I want to instead use my locally-modified version of the gem.

How could I use my version without either using Bundler (or rubygems-bundler if you wish) or locally compiling and installing the gem as described above.

@DanielKehoe
Copy link
Member

In my experience, the only way to use a locally-modified version of the rails_apps_composer gem is to create a new gemset, install the required gems (rails, rspec, mg), run rake build and rake install, and then use the gem. That's the "hack the gem" use case. Is that your use case?

@JangoSteve
Copy link
Contributor Author

Yeah, I had missed that when I first started working with the gem, but that's what I was getting at.

The bigger point is that the issue described here isn't limited to just building the gem, it's any time you try to use the gem alongside bundler, or from within a directory that has a .rvmrc or .ruby-gemset file.

Before trying to develop a forked version of the rails_apps_composer gem, I initially ran into this issue with the rails-composer template using a gemset.

The idea was to create a gemset for generating rails apps using the rails-composer template. So, I had a directory with the rails-composer template and a "rails-composer" gemset, using a .ruby-gemset file (or previously a .rvmrc file). My workflow was:

# (this does *not* work)
cd rails-composer-template
rails new myapp ~/some_directory -m ./composer.rb

It would error out every time due to not being able to switch gemsets to the new rails app, due to trying to run the command from within the rails-composer-template directory, which had it's own .ruby-gemset/.rvmrc. Instead, I'd have to cd out of that directory, manually switch gemsets (if it wasn't already selected), and then run the rails new command from there:

# (this works)
cd .. # now in a directory that doesn't have a .ruby-gemset or .rvmrc
rvm gemset use rails-composer # if not already selected
rails new myapp ~/some_directory -m ./rails-composer-template/composer.rb

Subtle difference, but took me a while to figure out what was going on and why this was necessary. Of course it started to click when I tried the above using bundler to specify which rails gem version to use and I encountered the same issues of not being able to switch gemsets during the app creation.

# (this does *not* work again)
cd .. # now in a directory that has a Gemfile
rvm gemset use rails-composer # if not already selected
# using bundle exec, or using rubygems-bundler without bundle exec
bundle exec rails new myapp ~/some_directory -m ./rails-composer-template/composer.rb

To be clear, I don't think this is necessarily an issue that needs to be fixed, but rather that there should probably be a note added to the readme (or maybe to the rails-composer readme) that let's people know not to use the rails composer command with bundler or from within a directory that has a .rvmrc or .ruby-gemset file (whether using rails_apps_composer new or using rails new -m with a composer template) if they are going to use the rvmrc recipe.

Better yet, maybe the rvmrc recipe could detect when the gemset hasn't been switched and alert the user what may be the problem, instead of continuing on and leading to more cryptic errors later on when the wrong gems are loaded during the app generation process.

I'm actually working on such a patch now, I'll submit it so you can at least see what I'm thinking, whether or not it gets pulled in.

@DanielKehoe
Copy link
Member

Ok, I understand the use case.

It sheds light on #114 which reports similar problems.

Some kind of exception handling, warning, or error reporting would be great. There are sure to be many people who try a similar use case and don't have the patience, experience, or stamina to troubleshoot to this point.

@JangoSteve
Copy link
Contributor Author

Ah yes, this #114 (comment) was almost certainly caused by the gemset not being switched. That's the "more cryptic errors later" I was getting, which I was referring to in my last comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants