Why/how `gem fetch -s $source` differs from Bundler's `source` statement? - ruby

I have a Bundler setup, where a gem is downloaded from a private source (repository), which is authenticated via an environment variable.
This is the gem preparation workflow:
$ export MYKEY=key
$ cat >> Gemfile <<EOF
source "https://private.repository.com/" do
gem 'mygem'
end
EOF
$ bundle package
This will fetch all the gems of the Gemfile, and store them under vendor/cache; this includes the gem mygem.
I wanted to this directly via the gem tool, without Bundler. However, when I run:
$ export MYKEY=key
$ gem fetch --clear-sources -s "https://private.repository.com/" mygem
I get:
ERROR: Could not find a valid gem 'mygem' (>= 0), here is why:
Unable to download data from https://private.repository.com/ - bad response Unauthorized 401 (https://private.repository.com/other/stuff)
Why and how does this differ? How can I fetch the gem via gem tool?

The reason is that the gem command does not use environment variables for authorization; instead, the authentication token is part of the URL:
$ gem fetch --clear-sources -s "https://token#private.repository.com/" mygem
The above will work.

Related

How to reference a local gem from a ruby script?

I need to reference a local gem from a plain ruby script, without installing the gem. On the trail of How to refer a local gem in ruby?, i tried creating a Gemfile with the following setup:
%w(
custom_gem
another_custom_gem
).each do |dependency|
gem dependency, :path => File.expand_path("../../#{dependency}", __FILE__)
end
and the script looks like this:
require 'custom_gem'
CustomGem::Do.something
When I execute this with:
bundle exec ruby script.rb
I get:
script.rb:1:in `require': cannot load such file -- custom_gem (LoadError) from script.rb:1:in `<main>'
If I leave out the require 'custom_gem' , I get:
script.rb:3:in `<main>': uninitialized constant CustomGem (NameError)
I even tried without bundler, and just writing gem ... :path =>̣ ... in the script itself, but without results. Is there any other way of referencing custom gems from ruby scripts, without installing the gems locally?
Make sure that your gem name as same as in Gemfile (e.g. custom_gem)
# Gemfile
source "https://rubygems.org"
gem "custom_gem", path: "/home/username/path/to/custom_gem"
Don't forget to actually install this gem using bundler
bundle install
After that, the script should be ready to use by bundle exec ruby script.rb
# script.rb
require 'custom_gem'
CustomGem::Do.something
Without using a Gemfile, you can install a local version of a gem by running bundle exec rake install in the gem's root directory and then you can reference it just like any other installed gem.

How to bundle local gem dependancies in IronWorker

I have a Ruby IronWorker which depends on a private gem that isn't published to RubyGems.
Is there a way to merge this local mygemname-0.0.1.gem into my IronWorker in the .worker file?
I'm hoping to be able to specify something the following in myruby.worker:
gem 'mygemname', '>=0.0.1', :path=> 'vendor/bundle'
Currently this give the following error
.rvm/gems/ruby-1.9.3-p0/gems/iron_worker_ng-0.12.2/lib/iron_worker_ng/code/base.rb:79 :in `eval':
wrong number of arguments (3 for 2) (ArgumentError)
Hoping for defaults gives:
gem 'mygemname', '>=0.0.1'
Gives the following error
Could not find gem 'mygemname (>= 0.0.1) ruby' in the gems available on this machine.
Am I on the right track trying to get this to work via the .worker file? Or should I be looking into specifying a custom build step?
If your unpublished gem itself has dependancies, you need to do a little massaging to get things going. Here is a technique that works for me:
mygem.worker
runtime "ruby"
#Merge in an unpublished local gem
dir '../opensource-cli-tools/facebook_exporter', '__gems__/gems'
file '../opensource-cli-tools/facebook_exporter/mygem.gemspec', '__gems__/specifications'
#Merge in a custom build script to fetch the unpublished gem's dependancies
file "Gemfile"
file "install_dependancies.sh"
remote_build_command 'chmod +x install_dependancies.sh && ./install_dependancies.sh'
#Run the puppy!
exec "run.rb"
install_dependancies.sh
echo "Installing dependancies to __gems__/"
gem install bundler --install-dir ./__gems__ --no-ri --no-rdoc
bundle install --standalone --path ./__gems__
cp -R ./__gems__/ruby/*/* ./__gems__
rm -rf ./__gems__/ruby
echo "Fixing install location of mygem"
mv ./__gems__/gems/mygem ./__gems__/gems/mygem-0.0.1
As far as i know, git and local paths unsupported right now.
Here is way to manually include local gem:
Add these lines to .worker file:
dir '../vendor/bundle/mygemname', '__gems__/gems'
file '../vendor/bundle/mygemname/mygemname.gemspec', '__gems__/specifications'

bundle package fails when run inside rake task

My Environment
Vanilla Ubuntu 12.10, no rvm or renv.
> gem --version
1.8.23
> ruby --version
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]
> bundle --version
Bundler version 1.2.1
My problem
I have a rake task to package my gems and upload them to my development and production servers. The problem is that the rake task fails when the Gemfile includes git or path gems. Bundler already supports packaging of these type of gems and it works great on my terminal but it fails when running withing a rake task and I cannot find out why.
My rake task
> cat lib/tasks/upload.rake
namespace :deploy do
desc "Package all gems and upload to remote server"
task :upload => [:environment] do |t, args|
if ! system("bundle package --all")
raise "TOTAL FAIL"
end
# Magic method to upload vendor/cache to remote server
end
end
My tries
Running bundle package in the terminal works:
> bundle package --all
....
Using bson (1.7.0)
Using bson_ext (1.7.0)
Using cancan (1.6.8) from git://github.com/ryanb/cancan.git (at /home/ryujin/Projects/rails/Encluster4/vendor/cache/cancan-4dcd54459482)
Using carrierwave (0.7.0)
Using coffee-script-source (1.4.0)
....
Updating files in vendor/cache
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
Updating files in vendor/cache
Running bundle package withing irb also works:
> irb
irb> system("bundle package --all")
...
Using ansi (1.4.3)
Using bson (1.7.0)
Using bson_ext (1.7.0)
Using cancan (1.6.8) from git://github.com/ryanb/cancan.git (at /home/ryujin/Projects/rails/Encluster4/vendor/cache/cancan-4dcd54459482)
Using carrierwave (0.7.0)
Using coffee-script-source (1.4.0)
...
Updating files in vendor/cache
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
Updating files in vendor/cache
=> true
But bundle package does not work when executed within my simple rake task:
> bundle exec rake deploy:upload
Updating files in vendor/cache
Could not find cancan-1.6.8.gem for installation
rake aborted!
TOTAL FAIL
Tasks: TOP => deploy:upload
(See full trace by running task with --trace)
I find not reason why this could fail. I am running in the same environment all the time. I already checked the bundle exec file is the same (/usr/local/bin/bundle) on all three cases. I have no traces or rvm or renv or anything like that. Also tried running the task without bundle exec and the same problem.
Thanks in advance for any tips on why this happens.
I had the same trouble.
I checked the environment variables and find out that the bundler modifies RUBYOPT:
$ bundle exec env > benv.txt
$ env > env.txt
$ diff -u env.txt benv.txt
--- env.txt 2012-12-05 17:13:10.000000000 +0400
+++ benv.txt 2012-12-05 17:13:07.000000000 +0400
## -72,4 +72,8 ##
CDPATH=.
install_flag=1
rvm_hook=
-_=/usr/bin/env
+_=/Users/denis/.rvm/gems/ruby-1.9.3-p327#global/bin/bundle
+_ORIGINAL_GEM_PATH=/Users/denis/.rvm/gems/ruby-1.9.3-p327:/Users/denis/.rvm/gems/ruby-1.9.3-p327#global
+BUNDLE_BIN_PATH=/Users/denis/.rvm/gems/ruby-1.9.3-p327#global/gems/bundler-1.2.3/bin/bundle
+BUNDLE_GEMFILE=/Users/denis/src/my-project/Gemfile
+RUBYOPT=-I/Users/denis/.rvm/gems/ruby-1.9.3-p327#global/gems/bundler-1.2.3/lib -rbundler/setup
So, to workaround I do this:
system %Q(/usr/bin/env RUBYOPT= bundle package)
Hope this helps!
One can also prefer to use
Bundler.with_clean_env do
sh "bundle update --source .."
end
and indeed it is an RUBYOPT problem as mentioned by Denis

gem server won't serve gems

I'm trying to set up my own private gem server which should serve my gems and display the rdoc. As I've read the default gem server should be able to do that. And since I do not want all gems except my own to be displyed on the gem server I'm doing the following:
gem install -i /some/dir --ignore-dependencies my-special.gem
gem server -d /some/dir # -d should let me set my gem dir
But first of all, the gem server still displays all installed system gems and does not display what's inside some/dir. And second, when trying to do a:
gem install --source http://localhost:8808 my-special.gem
I only get the following messsage:
ERROR: Could not find a valid gem 'my-special' (>= 0) in any repository
ERROR: While executing gem ... (Gem::RemoteFetcher::FetchError)
bad response Gateway Time-out 504 (http://localhost:8808/latest_specs.4.8.gz)
And I get that even for the gems that get displayed on the created gem server page at
http://localhost:8808
What am I doing wrong? Some blogs mention to update the index with gem generate_index but this makes no sense since this tool expects the *.gem files to be in a /gems subdir but by default they land in /cache.
I solved this pretty easily.
I don't even use a dedicated gem server.
I did the following:
Create a directory on your apache web server that is servable and create a gems subdir in it. For example:
mkdir -p /var/www/rubygems/gems
Put all gems you want to serve to the created gems subdirectory: cp /my/gems/dir/*.gem /var/www/rubygems/gems
Generate the gem index:
gem generate_index -d /var/www/rubygems
Do not forget to adapt the access rights so that your web server can read the contents
INFO: The index has to be generated in the directory that contains the gems subdir, not the gems dir itself! In this case it's /var/www/rubygems.
Now you can add http://<my-gem-server>.domain/rubygems to your gem sources

Installing a gem has no effect (aka how to use check_puppet.rb)

I'm sure this question is an easy one for Ruby users. However for me this is a issue I can't figure out by myself.
My goal is to use a script included in the Puppet archive (ext/nagios/check_puppet.rb) on a Ubuntu-10.4 system.
I try to launch the script:
$ sudo ./check_puppet.rb
./check_puppet.rb:4:in `require': no such file to load -- sys/proctable (LoadError)
from ./check_puppet.rb:4
Ok so there's something missing. I fount out I need some library called sys-proctable available at http://raa.ruby-lang.org/project/sys-proctable/
wget http://rubyforge.org/frs/download.php/65609/sys-proctable-0.9.0-x86-linux.gem
[...]
sudo apt-get install rubygems
[...]
$ sudo gem install sys-proctable-0.9.0-x86-linux.gem
Successfully installed sys-proctable-0.9.0-x86-linux
1 gem installed
Installing ri documentation for sys-proctable-0.9.0-x86-linux...
Installing RDoc documentation for sys-proctable-0.9.0-x86-linux...
Everything looks pretty good so far! Time to launch the script again
$ sudo ./check_puppet.rb
./check_puppet.rb:4:in `require': no such file to load -- sys/proctable (LoadError)
from ./check_puppet.rb:4
the gem listoutput tells me this:
$ gem list
*** LOCAL GEMS ***
sys-proctable (0.9.0)
Where has this gem been installed?
Why can't the script load the sys-proctable lib?
What the %&$# am I doing wrong?
Where's the official doc of gem?
The gem is installed - but in Ruby 1.8 you need to have the line:
require 'rubygems'
To use rubygems. This changes the 'require' function so it will pull in rubygems when you ask it to.
So in the script:
https://github.com/puppetlabs/puppet/blob/master/ext/nagios/check_puppet.rb
Just add the require near the top and try again.
For instructions on other ways to use rubygems, consult the Rubygems documentation:
http://docs.rubygems.org/read/chapter/3#page70
this is what i am getting on centos 6.4
sudo ./check_puppet.rb
./check_puppet.rb:75:in `-': no implicit conversion to float from nil (TypeError)
from ./check_puppet.rb:75:in `check_state'
from ./check_puppet.rb:122
i added require 'rubygems'
and installed sys-proctable

Resources