how do you activate or set the default rake? - ruby

I have seen many
You have already activated rake 0.9.x, but your Gemfile requires rake 0.x.x
errors.
Of course, they can be solved (temporarily or always) by some methods like the following.
bundle exec rake
The method above works but you always have to type bundle exec.
It can also be solved by
bundle update
But bundle update also updates your other gems.
Some say it can be solved by
gem uninstall unwanted_rake_version
Yes, the unwanted rake can be installed but it is still marked as activated thus, still giving the error.
One solution would be to explicitly specify the rake version in your Gemfile but, that is not the question. It is on how to set the default rake version, or activate that specific version in rvm or other types of ruby installations?

The newer versions of rake can be activated by supplying an optional first argument, that is the gem version.
$ rake 0.9.2
Alternatively, if you have an older version of rake you can update the rake script manually to include this parameter (or specify any specific version you want).
The rake script usually lives in /usr/bin/rake (or ~/.rvm/gems/ruby-#{ruby-name}/rake if using rvm). And dictates the version of them gem to load before parsing paramaters.
It looks like this on my system.
$ cat ~/.rvm/gems/ruby-1.9.2-p180/bin/rake
#!/home/tomcat/.rvm/rubies/ruby-1.9.2-p180/bin/ruby
#
# This file was generated by RubyGems.
#
# The application 'rake' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'rubygems'
version = ">= 0"
if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
version = $1
ARGV.shift
end
gem 'rake', version
load Gem.bin_path('rake', 'rake', version)
The important bit is gem 'rake', version changing version will force rake to a specific version system/rvm wide.
For more info, Katz' article explains nicely how binaries run under rubygems

When I get that error, its usually a result of working between projects that depend on different versions of rake. An easy fix is
gem uninstall rake
And then in your project directory (assuming you're working with Bundler) simply
bundle

I always uninstall rake first, command like this:
gem uninstall rake -v=version
then install another version
gem install rake -v=version

Related

Can't install gem using Bundler's Rakefile install task when developing a custom gem

I'm developing a couple of private gems and I think I don't understand correctly the PATH/GEM_PATH and/or Bundler/RVM installation flow, would love if someone could chip in.
I have a repository with two gems (A & B for simplicity sake). I've developed the gems using the scaffolding + following the guidelines provided by this bundler tutorial.
Thanks to the Bundler project I have a few Rakefile tasks like rake build, rake install, rake install:local and rake release. Because of the private nature of these gems I can't release them to RubyGems (and we haven't looked into hosting our rubygems).
My machines are using RVM to manage ruby versions and Bundler version 1.15.1
What I want to do: Assuming a new machine/developer trying out the project, ideally we would cd into each of the subfolders (currently 2, gem A and gem B), run rake install and after that we should have the gems available system wide for the current user.
What is happening: The gems are built and work properly, but they are only available inside the subfolder of each gem i.e. gem A is only available inside the subfolder A and gem B is only available inside subfolder B.
What I've tried: So, after rake build/install/install:local a new .gem file is generated under pkg. I've tried to manually install the "compiled" file using gem install pkg/A.gem, gem install --local pkg/A.gem and gem install --local --user-install pkg/A.gem without success. (there are plenty of SO questions/answers about this)
I believe this has something to do with the PATH variables, but like I said before I don't fully understand the way they are managed. I get the following results from these commands:
# Our gem
> gem which A
/home/ubuntu/.rvm/gems/ruby-2.4.0/gems/A-0.1.8/lib/A.rb
# Pry, available globally
> gem which pry
/home/ubuntu/.rvm/gems/ruby-2.4.0/gems/pry-0.11.1/lib/pry.rb
I've been lost and frustrated for far too long now, any help is appreciated. Also open to hear suggestions of better private gem installation flows :)
Yes, it has something to do with your PATH variables. Your installation seems to be good.
I advise you to first affirm your gems installation path with:
echo $GEM_HOME
The double check your PATH to ensure its present and also confirm that the GEM home is also where the gem got installed into from the rake install
echo $PATH
If not, put it in your path and you should be fine with something like this:
echo PATH=$PATH:$GEM_HOME >> ~/.bashrc
source ~/.bashrc
Build your gem as per that guide you linked. You should end up with a gem file. Distribute this as you see fit (I use rsync/crontab to download newer gem versions but anything goes). User can install the gem as follows:
gem install --user-install /path/to/your/file.gem
This will install the gem in the user's ~/.gem/ruby/<version>/gems/<your-gem-name> directory.
Tried it with an empty gem (foodie, as in that example guide) and it works fine. But if you don't specify the --user-install parameter it will try to install in the system ruby dir (/usr/lib/ruby/gems...)

Make ruby script use local gems, instead of common

I'm deploying my rails project to production server. There is only 1.9.3 version of ruby (I developed on 2.1.2) so there is few compatibility problems in gems versions. More over, I downloaded one of gems to vendor/gem_name and made necessary fixes in its sources, so I need to use exactly my version of that gem and, as you understand, It's not possible to update it.
in Gemfile
require 'gem_name', :path => 'vendor/gem_name'
So after cloning project to server I run
bundle install --path vendor/bundle
and it created bundle directory in vendor folder with gems versions, needed to me, inside it.
After that I tried to run fetching script to fill db with some data by command
ruby *_fetch.rb
inside *_fetch.rb:
require 'gem_name'
And it fails with error
You have already activated gem_name older_version, but your Gemfile requires
gem_name newest_version. Using bundle exec may solve this. (Gem::LoadError)
from /usr/local/rvm/gems/ruby-1.9.3-p374/gems/bundler-1.3.5/lib/bundler/runtime.rb:19:in `setup'
So how could I specify script to require my edited local gem?
Run it with bundle exec That's exactly what bundle exec is for.

Bundler and wrong binstubs?

I run rails s or bundle exec rails s and I get this warning:
Bundler is using a binstub that was created for a different gem.
This is deprecated, in future versions you may need to `bundle binstub rails` to work around a system/bundle conflict.
What does this mean? From looking around the bundler site, my understanding of binstubs is that you can set executables to them, so instead of running bundle exec blabla you can just do bin/blabla. So this error is saying my bundler isn't set to the right binstub?
When I run the bundle binstub rails I get this output
rails has no executables, but you may want one from a gem it depends on.
railties has: rails
bundler has: bundle, bundler
I do not understand what my system is trying to tell me, and it's not breaking anything, but I have a hunch this could turn into a bigger issue if I don't fix it
ruby 2.0.0p247
which ruby
/Users/evan/.rvm/rubies/ruby-2.0.0-p247/bin/ruby
which bundler
/Users/evan/.rvm/gems/ruby-2.0.0-p247/bin/bundler
Rails 4.0.2
Edit:
So, if I run the commands in the nag message:
bundle config --delete bin # Turn off Bundler's stub generator
rake rails:update:bin # Use the new Rails 4 executables
I end up getting uninitialized constant Bundler errors with bundle exec commands and the only way I've found to fix that is to rerun bundle install --binstubs which brings back the nag message at the start of this post.
What worked for me was
rm -rf bin/*
Then open a new terminal session and
bundle exec rake app:update:bin
Solution in my case: - Other solutions didn't work for me.
In your Rails directory:
mv /usr/bin/rails /usr/bin/rails.old
bundle config --delete bin
rm -rf bin
# for rails 4.x:
rake rails:update:bin
# for rails 3.x:
bundle install --binstubs
# if you're using rbenv
rbenv rehash
rm -rf ~/.rbenv/plugins/{rbenv-bundle-exec,rbenv-gemset,bundler}
Also be sure that bin/rails is added to the path like:
PATH=./bin:$PATH
Good luck.
This error may raise when you update your ruby but not the related gems.
To check if this is your case, try to make a new rails app in a new empty directory (to be sure RVM is not autoloading any gemset)
make /tmp/test && cd test && rails new test
If this fails stating that it cannot find a suitable 'rails', then simply run
gem update
and overwrite any conflicting rails.
gem uninstall bundler
gem install bundler
Uninstalling all my versions of Bundler, and then installing the latest version fixed it for me. I had multiple versions of bundler installed, so when I ran bundle exec rails s I think the wrong Bundler was used, giving me the warning message.
You may need to generate new stubs after reinstalling Bundler, but I didn't have to.
I was able to fix this by looking at the commit history for bin/rails using git log -p bin/rails
The current, error producing content is:
#!/usr/bin/env ruby
#
# This file was generated by Bundler.
#
# The application 'rails' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'pathname'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
Pathname.new(__FILE__).realpath)
require 'rubygems'
require 'bundler/setup'
load Gem.bin_path('railties', 'rails')
The original, non-error content was:
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rails/commands'
When I restored the original bin/rails content, the warning message disappeared. Previous attempts had returned uninitialized constant Bundler errors on all bundle exec commands, but now they work. It's worth noting that the original content appears to be exactly what rails new blabla generates in rails 4.0.x.
Still, I would like to know why the first code block causes issues because it's exactly what bundle install --binstubs generates.
Edit: turns out this solution does not work. Pushed this fix to a heroku staging server and heroku errors on startup: all bin/rails commands throw uninitialized constant Bundler and heroku starts up with bin/rails server ..... so this is a not really a fix.
Edit2:
If I add these two lines to the second block (the original bin/rails content), all bin/rails commands are working again:
require 'rubygems'
require 'bundler/setup'
My guess is that the second line is what fixes the bundler errors I was having.
Interestingly, when I tried to edit the first block of code in this post to try and debug which line was throwing the warning, any change I made caused all rails commands to failure, with no information except for the nag note in the OP. weird.
Final bin/rails that fixed my issue:
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application', __FILE__)
require_relative '../config/boot'
require 'rubygems'
require 'bundler/setup'
require 'rails/commands'
Any additional insight from people who find this would be welcome!

RubyMine 6.0.2 with "debugger" gem without modifying Gemfile.lock?

I am using RubyMine (v6.0.2), but my teammates are not, so they need the "debugger" gem in the gemfile. I can conditionally un-require the Gemfile when running RubyMine (so the Gemfile can be shared and identical), but since the 'debugger' gem is not included, the Gemfile.lock file changes depending on whether the project was last run with RubyMine or not. This creates a lot of noise in redundant Gemfile.lock changes.
I've tried using 'debugger-xml' gem; that doesn't solve the issue.
So -- how can I run RubyMine 6.0.2, with the 'debugger' gem in the Gemfile, without having Gemfile.lock change?
I've been working on this issue from the other side of the table. I use the debugger gem, but have team mates that use RubyMine.
We discussed several potential solutions but they all involved conditional checks in the Gemfile that would result in a modified Gemfile.lock.
I googled around for a better solution and found this SO post: How to use gems not in a Gemfile when working with bundler?
Combining a few of the answers in there, I came up with this solution:
Remove the debugger gem from the Gemfile.
Create a Gemfile.local with the contents below.
Add Gemfile.local to the .gitignore file if using git.
Create a function and shell alias.
Start rails with $ be rails s
How it all works!
Bundler will use the file named Gemfile by default, but this behavior can be overridden by specifying a BUNDLE_GEMFILE environment variable. Bundler will use/create the lock file with the same name as the BUNDLE_GEMFILE.
The shell function __bundle_exec_custom will check to see if there is a Gemfile.local file in the CWD. If there is, then the BUNDLE_GEMFILE variable is set and used. Otherwise, the default Gemfile is used.
This will allow a developer to use any gems that they want for local development without having to impact the application as a whole.
Gemfile.local:
source "https://rubygems.org"
gemfile = File.join(File.dirname(__FILE__), 'Gemfile')
if File.readable?(gemfile)
puts "Loading #{gemfile}..." if $DEBUG
instance_eval(File.read(gemfile))
end
gem 'debugger'
Function and shell alias:
__bundle_exec_custom () {
if [ -f Gemfile.local ]
then
BUNDLE_GEMFILE="Gemfile.local" bundle exec $#
else
bundle exec $#
fi
}
# Rails aliases
alias be='__bundle_exec_custom'
I think I found it. Apparently, RubyMine does not deal well with the debugger gem being required into the Rails app, but has no issue with the gem just being installed.
The solution then is to include the gem in the Gemfile (and Gemfile.lock) but only require it outside RubyMine.
gem 'debugger', {group: [:test, :development]}.
merge(ENV['RM_INFO'] ? {require: false} : {})
The above code is from this comment on the JetBrains bug tracker, through this comment on a similar question.
It checks for the presence of the RM_INFO environment variable, which is set by RubyMine. The important thing is that it only affects whether the gem is required and thus should not change Gemfile.lock between installs.
I may have an even better solution that seems to be working for me in my Rails 4 app...
In your Gemfile, move all your debugging-related gems to their own group, as such:
group :pry do
gem 'pry', '>= 0.10.0'
gem 'pry-debugger', '>= 0.2.3'
gem 'pry-highlight', '>= 0.0.1'
end
In config/application.rb you will a find something like the following:
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
Add the following just below that:
Bundler.require(:pry) unless ENV['RM_INFO'] || Rails.env.production?
You may wish to modify the unless condition to suit your needs, but the important part is that RubyMine will set RM_INFO, which you can use to detect and therefore exclude gems from being required.
This will eliminate the ping-pong effect of bundling in RubyMine vs. command line, so this should work well in a mixed-IDE team.
One last note, if you're deploying to Heroku, you might want to exclude the :pry group from being installed on deploy:
$ heroku config:set BUNDLE_WITHOUT="development:test:pry"

Better way to work on a Rails gem

Hi guys sometimes I work a gem and sometimes to develop this gem I need a Rails application.
Actually when I do this I make my gem in the vendor/plugins/my_gem/ directory and I do all work in this directory.
May be there is other way to do this, more cleaner (plugin like this won't work in rails 4.0).
I normally work have a separate, version-controlled projects for every custom gem that I work on. I normally create gems using Bundler, although there are other options. I specify rake as a development dependency in the my_gem.gemspec. After I'm done writing code and specs in the gem, I normally assign it a new version, then run:
# cd/to/my_gem
bundle exec rake build # build a gem
ruby -S gem install ./pkg/my_gem-0.0.1.gem # install it locally
# cd/to/app_using_gem/
gem unpack my_gem -v 0.0.1 --target ./vendor/gems # vendorize gem
I think this way is cleaner than modifying code in vendor/plugins/my_gem/

Resources