installed gems activated before frozen gems? - ruby-on-rails

We're using gems:unpack to ensure gem version consistency across environments. However, we're running into:
can't activate , already activated [GEM-VERSION]
Is this because installed gems take precedence over frozen ones? Is it possible to have frozen gems activate first? Advice on ways to keep gems consistent welcome.

This usually happens when a gem/plugin you have packed requires a gem then a second gem/plugin requires a specific version of the same gem. The first gem requires the dependency, but when the second gem requires the specified version of the same gem then you will see the error you describe.
For example:
some_gem requires special_gem
another_gem requires special_gem => 1.0
And you have the following:
Packed in app:
special_gem 2.0
some_gem 1.0
another_gem 1.0
Installed Locally:
special_gem 1.0, 2.0
some_gem 1.0
another_gem 1.0
Then the some_gem will require 2.0, but when another_gem requires 1.0 you get the error.

Related

How to remove warning "RubyZip 3.0 is coming!"

I just did a bundle update on my Rails 6 app, and since I have a long warning every time I bundle exec something :
RubyZip 3.0 is coming!
**********************
The public API of some Rubyzip classes has been modernized to use named
parameters for optional arguments. Please check your usage of the
following classes:
* `Zip::File`
* `Zip::Entry`
* `Zip::InputStream`
* `Zip::OutputStream`
Please ensure that your Gemfiles and .gemspecs are suitably restrictive
to avoid an unexpected breakage when 3.0 is released (e.g. ~> 2.3.0).
See https://github.com/rubyzip/rubyzip for details. The Changelog also
lists other enhancements and bugfixes that have been implemented since
version 2.3.0.
I don't have rubyzip in my Gemfile, it's a dependancy of webdrivers and selenium-webdriver, libraries used to get a headless browser for Capybara testing.
What can I do to get rid of this warning ?
This warning was added in rubyzip 2.3.1 to give people time to get ready for the 3.0 release which will have breaking changes. If you don't want to see the warning just lock the rubyzip version to 2.3.0 in the development/test section of your Gemfile
gem 'rubyzip', '2.3.0'

Error "uninitialized constant AWS (NameError)"

It is saying AWS is uninitialized. I am usign the aws-sdk-core gem.
I tried using the aws-sdk gem instead, and the problem was still there.
This is the initializers/aws.rb file:
AWS.config(:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'])
s3 = AWS::S3.new
AVATAR_BUCKET = s3.buckets[ENV['AVATAR_BUCKET_NAME']]
When I try running the server or opening the console I get this error:
/initializers/aws.rb:1:in `': uninitialized constant AWS (NameError)
If you are receiving this error and you have the "aws-sdk" gem installed, you likely have upgraded to version 2 of the aws-sdk gem unintentionally. Version 2 uses the Aws namespace, not AWS. This allows version 1 and version 2 to be used in the same application.
See this blog post for more information.
You need to install/use the -v1 version of aws-sdk. Simply doing gem 'aws-sdk' or require 'aws-sdk' may use the 2.x version of aws-sdk instead.
To avoid any confusion, for scripts that require 1.x, use:
require 'aws-sdk-v1' # not 'aws-sdk'
And for scripts that require 2.x, use:
gem 'aws-sdk', '~> 2'
as the GitHub documentation indicates.
You might getting this error, because you didn't define the correct aws sdk version in your Gemfile. This can happen while re-bundling old apps with version 1 or 2 installed.
Make sure which version you want to install:
aws-sdk version 3
gem 'aws-sdk', '~> 3'
# call sdk
Aws.<whatever>
aws-sdk version 2
gem 'aws-sdk', '~> 2'
# call sdk
Aws.<whatever>
aws-sdk version 1
# version constraint
gem 'aws-sdk', '< 2'
# or
# use the v1 gem
gem 'aws-sdk-v1'
# call sdk
AWS.<whatever>
v1 is scoped under AWS and v2 and v3 scoped under Aws => That allows you to run v1 and v2 side by side.
It sounds as though either the gem isn't present in your load path or it is not being required.
The entry in your Gemfile should be
gem 'aws-sdk'
This will implicitly do a require 'aws-sdk' as the application initializes, as long as you start the app with bundle exec rails server or bundle exec rails console.
Alternatively, if the above code was in a non-rails application, just place require 'aws-sdk' on the first line.
I encountered this problem in a Chef recipe, so the response below is decidedly Chef-centric.
Amazon released version 2 of the aws-sdk in early February 2015. Version 2 is not entirely backwards compatible with version 1.
So, you must make a decision - are you content with version 1 functionality, or do you want version 2 functionality?
If you are content with version 1, perhaps for the short term, it is necessary to have Chef explicitly load version 1, because by default, it appears to use the latest version. To do this you must specify the version attribute to load in the recipe that loads chef_gem aws-sdk. The modification looks like this (probably implemented in a default.rb for the cookbook in question):
chef_gem "aws-sdk" do
action :nothing
# Source: https://aws.amazon.com/releasenotes/Ruby?browse=1
version '1.62.0'
end.run_action(:install)
Update the version in the cookbook's metadata, then upload the cookbook to your Chef server. Update the cookbook version in the environment, then upload the environment to your Chef server.
After convergence, run a gem list on your instance to see the gem versions:
On PowerShell
PS C:\Users\Administrator> gem list | select-string aws-sdk
On Linux:
gem list | grep -i aws-sdk
These are typical results:
aws-sdk (2.0.27, 1.62.0)
aws-sdk-core (2.0.27)
aws-sdk-resources (2.0.27)
aws-sdk-v1 (1.62.0)
Note that the last one specifies aws-sdk-v1. Now, you must update your recipe to require the older version of aws-sdk. Change this:
require 'aws-sdk'
to this:
require 'aws-sdk-v1'
Update the version in the metadata.rb, upload the cookbook, update the version in the environment file, upload the environment, and you should be good to go after the next convergence.
This blog post contains more details and solutions to this problem:
http://ruby.awsblog.com/post/TxFKSK2QJE6RPZ/Upcoming-Stable-Release-of-AWS-SDK-for-Ruby-Version-2
I was facing the same problem. One answer worked here without updating the gem.
Simply change wherever required [in th require statement in environment]
require 'aws-sdk'
to
require 'aws-sdk-v1'
I am not a Ruby expert, but I've solved the same issue by running the below commands.
To remove the installed AWS gems
gem list --no-version --local | grep aws | xargs gem uninstall -aIx
To install the v1 gem which was compatible with my Ruby script:
gem install aws-sdk -v 1.64.0
I agree this is not the recommended way as AWS recommends to use the latest version, but this should be useful for someone who does not want to modify their existing scripts.

Does RUBY on RAILS 4.0.2 work with MS SQL Server Express?

I've googled this to death and I'm just going around in circles.
I'm on a Windows Server 2008r
I installed and put the following in my Gemfile
gem 'ruby-odbc' # I think the version is the.9999 one?
gem 'tiny_tds', "~> 0.6.1"
gem 'activerecord-sqlserver-adapter' # I've tried a few versions of this 3.2.8 and 4.0
I get varying errors depending on how many times i've bundle installed or updated
Errors include activesupport and activerecord versions not found. They are installed
Or I get alias_method errors.
Can someone just point me in the right direction of what I should do. Some discussions seem to think that there is nothing that works at the moment. Would downgrading to an older Rails work? If so how and which version?
activerecord-sqlserver-adapter hasn't been released for Rails 4.0 yet but the gem is 95% ready. You can use put it in your Gemfile like this:
gem 'activerecord-sqlserver-adapter', github: 'rails-sqlserver/activerecord-sqlserver-adapter'
For a description of the outstanding work take a look at Failed Tests & Segfault on this pull request.

Ruby \ Rubygems how do they decide which gems to load?

This is more curiosity question and not a problem. When many version are present on the system which ones are chosen when require command is used? Background of the story is: I was implementing bundler gem in project (not Rails project). I had no issues but other developers had issues, after quick investigation I realized that I did not use
require "bundler/setup"
which basically loads up bundled gems. Quick fix, but it got me wondering how does ruby via rubygems decide which gems to use. Since code broke because Ruby application used older version of one of the gems, and not the newer one. Meaning it does not use the "newest" gems, so what is logic behind it?
UPDATE
To further explain this question let say you have gems foo-1.0.1 and foo-1.0.2 when you say, require 'foo' how does ruby know which one to load?
In Ruby you require a file rather than a gem. If that file isn’t found on the current load path, Rubygems will search the installed gems for a file with that name, and if it finds one the gem is activated (meaning that it gets added to the laod path) and the file is then required. Normally a gem will have a file with the same name in its lib dir. Only one version of a gem can be activated.
The gem that gets activated is the latest version available that is compatible with any other activated gems. Normally this will just mean that the latest version installed wil be activated, but this might not be the case if you have already activated some gems which declare dependencies on earlier version of the gem you’re trying to activate.
For example, if you have foo-1.0.1 and foo-1.0.2 installed, then require 'foo' (assuming they have a file named foo.rb in their lib dirs and no other gem does) will cause version 1.0.2 to be activated. However if you also have a gem bar which has a dependency on 1.0.1 then calling require 'foo' after bar has been activated will cause 1.0.1 of foo to be activated.
Futhermore, if you try to require them in the other order, require 'foo'; require 'bar'; then you will get something like
Gem::LoadError: Unable to activate bar-1, because foo-2 conflicts with foo (= 1)
Here you can’t activate bar, which depends on version 1.0.1 of foo because you have already activated version 1.0.2 of foo.
Without Bundler, you have to specify each gem you want. e.g.,
require 'my_gem'
require 'my_other_gem'
However, Bundler can make this a bit easier for you using a Gemfile
If this is your Gemfile
gem 'my_gem'
gem 'my_other_gem'
Calling this will include all gems
require 'bundler/setup'

Can't activate gem: how do I figure out which gem has a dependency on this one?

I'm getting the following error:
Gem::Exception: can't activate hpricot (= 0.6.161, runtime),
already activated hpricot-0.8.3
0.6 is installed locally, 0.8.3 is frozen in my app.
This is my "stacktrace":
Loading production environment (Rails 2.3.10)
/software/ruby-ror-gem-1.3.1/lib/rubygems.rb:149:in `activate':Gem::Exception: can't activate hpricot (= 0.6.161, runtime), already activated hpricot-0.8.3
/e/app/www.example.com/rails/releases/20101117142713/vendor/rails/railties/lib/console_with_helpers.rb:5:NameError: uninitialized constant ApplicationController
How do I figure out which gem or library has a dependency on hpricot 0.6?
I've added the output of user438962's command below:
{"daemons-1.0.9"=>[],
"scgi_dp_rails-0.0.5"=>["preforkdp", "daemons"],
"rails-2.3.10"=>[],
"rwfd-0.1.0"=>[],
"nokogiri-1.3.2"=>["racc", "rexical", "rake-compiler", "hoe"],
"activesupport-2.3.10"=>[],
"rack-1.0.1"=>
["test-spec",
"camping",
"fcgi",
"memcache-client",
"mongrel",
"ruby-openid",
"thin"],
"rack-1.1.0"=>
["test-spec", "camping", "fcgi", "memcache-client", "mongrel", "thin"],
"preforkdp-0.1.2"=>["rwfd"],
"activerecord-2.3.10"=>[],
"hpricot-0.6.161"=>[],
"cgi_multipart_eof_fix-2.5.0"=>[],
"fastthread-1.0.1"=>[],
"gem_plugin-0.2.3"=>[],
"activeresource-2.3.10"=>[],
"ferret-0.11.6"=>["rake"],
"mysql-2.7"=>[],
"actionmailer-2.3.10"=>[],
"actionpack-2.3.10"=>[],
"hpricot-0.8.3"=>[],
"mongrel_upload_progress-0.2.2"=>["mongrel", "gem_plugin"],
"mongrel-1.1.3"=>
["gem_plugin", "daemons", "fastthread", "cgi_multipart_eof_fix"],
"mongrel_cluster-1.0.5"=>["gem_plugin", "mongrel"],
"rake-0.8.4"=>[],
"haml-2.0.9"=>[],
"remvee-mini_magick-1.2.3.4.0"=>[]}
If you use Bundler, you avoid this problem and you have the really great command : bundle viz
This Command generate a graph with all dependencies.
require 'rubygems'
require 'pp'
h = {}
Gem.source_index.each{|g, spec| h[g] = spec.dependencies.map{|d| d.name} }
pp h
I found that rfeedparser is the gem that uses hpricot 0.6.
The problem is that this version (0.6) works with rfeedparser, but emits the warning "Passing no parameters to XML::SaxParser.new is deprecated."
Well, with newer versions of hpricot (at least 0.8.2), this warning seems to have taken effect, because now having that version of hpricot or newer causes "ArgumentError: wrong number of arguments (1 for 0)" when calling FeedParser.parse(url).
Unfortunately, I've found that the only way to make this work with legacy Rails (we have a 2.2.2 app) is to uninstall any hpricot version that's not 0.6.
The issue will be that one of the gems you use depends on hpricot version 0.6.161
and so tries to load it, but that you already have hpricot-0.8.3 loaded. The more recent version might be loaded if you're using hpricot yourself, and have required hpricot for use without specifying a version. If that's the case, you can change your own require to be the same version as the other gem uses (0.6.161).
The other reason the more recent version of hpricot is being loaded, could be that another gem you use depends on that version of hpricot, meaning you can't use the specific versions of those two gems you have because they have clashing requirements for their hpricot version.
Use the methods other users have posted to help you track down the dependencies of the gems you are using.
You could try grepping your load path:
$:.each do |dir|
cmd = %(grep -r hpricot #{dir})
puts cmd
puts `#{cmd}`
end

Resources