Okay I've found the following code for unzippping a file with Ruby.
def unzip_file (file, destination)
Zip::ZipFile.open(file_path) { |zip_file|
zip_file.each { |f|
f_path=File.join("destination_path", f.name)
FileUtils.mkdir_p(File.dirname(f_path))
zip_file.extract(f, f_path) unless File.exist?(f_path)
}
}
end
Above this I'm using the following to ensure the needed gems are installed.
begin
require 'rubygems'
rescue LoadError
'gem install rubygems'
end
begin
require 'zip/zip'
rescue LoadError
'gem install rubyzip'
end
So when I call unzip_file I get the following error:
in `unzip_file': uninitialized constant Zip (NameError)
What am I doing wrong?
Thanks!
Beware: the sample script will also unpack symlinks, and will unpack ../../../../etc/passwd without complaining. The rubyzip gem expects you to do your own pathname laundering.
Note that in rubyzip 1.1.4, Zip::Zipfile was renamed to Zip::File.
The problem with installing the gem that way is that you're shelling out to another process with:
`gem install rubyzip`
and after that finishes installing the gem, your current irb session still won't see it. You'd have to reload irb with exec "irb" and then calling require 'zip' again.
Note: those are backticks not single quotes.
Try this:
begin
require 'zip'
rescue LoadError
`gem install rubyzip`
exec "irb"
retry
end
For me require 'zip' works. I have rubyzip-1.1.2
Now you should be able to use Zip
Also, the gem command is rubygems. So you can't install rubygems with itself. It should already be installed, but if not try this: http://rubygems.org/pages/download
Related
I am trying to install a ruby gem from a ruby script when it can't load the required gem from local system. Here is my code.
begin
require '<gem name here>'
rescue LoadError
puts `gem install <gem name here>`
require '<gem name here>'
end
The code above installs the gem in the rescue block. But when it requires the gem, it shows this error:
.rvm/rubies/ruby-2.4.2/lib/ruby/site_ruby/2.4.0/rubygems/core_ext/kernel_require.rb
:55:in require': cannot load such file -- <gem name here> (LoadError)
How can this be solved? I want the gem to be loaded within the rescue block if not already present in the system.
After rigorous searching, I found an answer. If we use Gem.clear_paths after installing the gem, it will now available to the script. Total updated code is :
begin
require '<gem name here>'
rescue LoadError
puts `gem install <gem name here>`
Gem.clear_paths
require '<gem name here>'
end
I am trying to run some older ruby script (with old ruby version) from within a ruby script. Here is a program:
old_ruby187.rb
#!/usr/ruby/1.8.7/bin/ruby
puts "Hello"
new_ruby230.rb
#!/usr/ruby/2.3.0/bin/ruby
require "rubygems"
require "bundler"
Bundler.setup # Code works if I comment this line
puts `old_ruby187.rb`
I get bundler load error. If I execute ./new_ruby230.rb, it gives an error for the last puts command line.:
'require': no such file to load -- rubygems (LoadError)
If I comment just Bundler.setup and run it, it works fine. Not sure if Bundler.setup tries to load something for system call. I need bundler for other gems used in new_ruby230.rb script.
Any help is appreciated.
Update (02/22/2018):
I ended up using ssh when calling old ruby script. Something like:
new_ruby230.rb
#!/usr/ruby/2.3.0/bin/ruby
require "rubygems"
require "bundler"
require "socket"
Bundler.setup
puts `ssh #{Socket.gethostname} old_ruby187.rb` # this worked!
Pretty sure you're not supposed to require rubygems like that. Bundler is there to manage your gems. Remove that require statement (require "rubygems") and you should be good to go.
I'm forking the gem and I'd like to add some conditional dependencies to gemspec file, depending on ruby version. I found that it could by done using spec.extensions. So in gem directory I created a file: ext/mkrf_conf.rb:
require 'rubygems/dependency_installer.rb'
begin
Gem::Command.build_args = ARGV
rescue NoMethodError
end
inst = Gem::DependencyInstaller.new
begin
if RUBY_VERSION < "2.1.0"
inst.install "activerecord", ">2.0", "< 4.0"
else
inst.install "activerecord", ">4.0"
end
rescue
exit(1)
end
f = File.open(File.join(File.dirname(__FILE__), "Rakefile"), "w") # create dummy rakefile to indicate success
f.write("task :default\n")
f.close
Then I added the extension to gemspec file:
spec.extensions << 'ext/mkrf_conf.rb'
I created a test project, with Gemfile when I have:
gem 'my_gem', path: '/Users/xxx/Documents/my_projects/my_gem'
I'd like to test if this is work, but when I do bundle install, activerecord is not installing at all. As this extension is not exist. Can somebody can point me what I'm doing wrong. Thanks!
This might be not an exact answer on your question, but I wonder whether you see that Gemfile is a plain ruby file. That said, you might simply drop your logic in your Gemfile:
if RUBY_VERSION < "2.1.0"
gem "activerecord", ">2.0", "< 4.0"
else
gem "activerecord", ">4.0"
end
gem ...
Hope it solves your issue.
I installed Nokogiri without any issues by running:
$ sudo gem install nokogiri
Building native extensions. This could take a while...
Successfully installed nokogiri-1.5.9
1 gem installed
Installing ri documentation for nokogiri-1.5.9...
Installing RDoc documentation for nokogiri-1.5.9...
When I run nokogiri.rb:
#!/usr/bin/ruby -w
require 'nokogiri'
puts "Current directory is: #{ Dir.pwd }"
Dir.chdir("/home/askar/xml_files1") do |dirname|
puts "Now in: #{ Dir.pwd }"
xml_files = Dir.glob("ShipmentRequest*.xml")
if xml_files.empty?
puts "#{ dirname } is empty."
else
xml_files.each do |file|
doc = Nokogiri::XML(open(file))
# ... do something with the doc ...
end
end
end
I got the error:
$ ruby nokogiri.rb
/home/askar/.rvm/rubies/ruby-1.9.3-p429/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': cannot load such file -- nokogiri (LoadError)
from /home/askar/.rvm/rubies/ruby-1.9.3-p429/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
I'm using Ruby 1.9.3, but for some reason it refers to Ruby 1.9.1. Can this be the cause?
If you observe closely, the path starts with /home/askar/.rvm/rubies/ruby-1.9.3-p429 so the load path should be correct.
Your problem is that you used sudo which will do a gem installation for the system ruby. Try again without sudo, just
gem install nokogiri
to install gems for the current rvm ruby.
is there some ruby code I can use to install a gem from a local file, if that gem is not installed?
i'm thinking it would look something like:
if !gem_installed("some gem name")
system "gem install -l local_copy.gem"
end
i don't know if anything exists that lets me check for gems like this or not...
Checking availability is covered in this previous StackOverflow Quesiton
begin
gem "somegem"
# with requirements
gem "somegem", ">=2.0"
rescue Gem::LoadError
# not installed
end
or
matches = Gem.source_index.find_name(gem.name, gem.version_requirements)
As for the install, it looks like rails uses the system for gem install also
puts %x(#{cmd})
This is my way of doing this
['json','date','mail'].each { |req|
begin
gem req
rescue Gem::LoadError
puts " -> install gem " + req
Gem.install(req)
gem req
end
require req
}