Rubygems auto install from source code - ruby

I was wondering if there was a solution to automatically - from my ruby source code - ask Gem to install various librairies my code my require to work?
From what i read on the internet, it seems we are obliged to either use an install script that directly runs "gem install ..." commands or do it manually or some people have posted a ruby script that simply iterate over a list of dependencies and use the system command to install them.
Any other better options?
Thanks for your time.

You could use internal RubyGems commands, but that's a pain and error-prone process, especially for dependencies.
I would setup a Gemfile and use Bundler instead. http://github.com/carlhuda/bundler

Related

How do I get rrdtool from homebrew to work with ruby on macOS

In our Rails application we do require 'RRD' at some point, but that results in a cannot load such file -- RRD. So obviously I used homebrew to install rrdtool, but the error remains.
The docs at https://oss.oetiker.ch/rrdtool/prog/rrdruby.en.html provide two options:
Either:
$: << '/path/to/rrdtool/lib/ruby/1.8/i386-linux'
require "RRD"
In my /opt/homebrew/Cellar/rrdtool/1.8.0/lib directory there's no mention of ruby, which is because of the --disable-ruby-site-install flag in the formula, because when I skip that flag I do actually get something: /opt/homebrew/Cellar/rrdtool/1.8.0/lib/ruby/2.6.0/universal-darwin21. However replacing the path/to string with this path still gives the error.
Or:
If you use the --ruby-site-install configure option you can drop the $: line since the RRDtool module will be found automatically.
Which is a little confusing (and probably outdated) because here it seems that ruby site install is disabled by default and you have to enable it proactively, whereas in the formula it's actually actively disabled.
Either way: both options didn't do the trick for me and if there's a solution without homebrew that's also fine.
For good measure: I'm on macOS Monterey
TL;DR
For the most part, I'd say that using a non-standard gem without a Ruby version manager is your main issue. There are instructions on the rrdruby site for installing it, but they don't follow typical conventions, so your mileage will vary.
Some Practical Suggestions
The require keyword is for gems, not binaries. You need to have an rrdtool-related gem installed, available to your Ruby instance (usually through a Bundler Gemfile or gemspec, or via the RUBYOPTS environment variable or your in-process Ruby $LOAD_PATH), and then require the correct name of the gem in your code. For example, using the older rrd-ffi gem:
# use sudo if you're installing it to the system,
# but I would strongly recommend a ruby version
# manager instead
gem install rrd-ffi
# in your Ruby class/module file
require "rrd"
For the gem you seem to be using, you have to compile the gem first to make it usable, and then ensure it's available in your Ruby $LOAD_PATH (or other gem lookup mechanism) before trying to require it. The error message you're seeing is basically telling you that a gem with that name is not available as called within any of the standard lookup locations.
Again, I'd suggest reading the build documentation for your gem, and then seeing if you can install it as part of a Bundler bundle, RVM gemset, or other non-system approach if you can. Otherwise, follow the directions for the rrdruby tool, which is not available as a standard Rubygems.org gem, in order to make it available before trying to require it.
Beware of Outdated or Non-Standard Gems
Most of the RRD gems I found were quite old; most were 7-8 years old or older, so their compatibility with current Rubies is potentially suspect. The gem-builder you're using is newer, but doesn't seem to be designed as a standard gem, so you need to build it and install it in a suitable lookup path before it can be required. Installing gems as system gems is almost always a bad idea, so I'd strongly recommend building it from source and using a ruby version manager rather than following the rrdtool author's atypical suggestions. YMMV.

How can I package Ruby code in an NPM package?

I'm writing a node module to be open sourced and there's a dependency on some Ruby code (see Can I include a Ruby Gem in a Node.js project? for details). I made a Ruby project that requires some gems and all of that works well. In my node_module, I want to interface it via exec to the Ruby code.
But now there's Ruby dependencies as well. So can I somehow specify the Ruby version, and the gemset required to run my node package?
Ambiguous question perhaps. I can clarify if anything is unclear.
I don't think you can/should specify the Ruby version to use when executing your code. That should be up the library consumer so choose. Since you want to execute your code with exec, the library consumer will have the added responsbility of making ruby accessible to the node process. How that happens is not up to you as the library developer.
As for dependencies/gemsets, just use bundler.
Maybe you could do something like this - without more information it's hard to say.
On the ruby side, build your gem to do whatever it needs to do and then add a rake task to it. How you build this rake task is obviously up to the demands of the project and how it will be used, but it will provide a way for you to interface from the outside.
In the 'middle' build a bash script that includes RVM - this way you can require a specific gemset/do specifc things before running the rake task. Another benefit is that if you want to change the gemset or other implementation details, you just change the bash script.
On the node side, call the bash script. More info on that in this answer.

gem command . What does that mean

Sometimes I have seen following code.
gem 'factory_girl','= 1.2.3'
require 'factory_girl'
I tried to look at gem doc but could not find answer to the question of what does the first line do in code above?
What you're looking for in the gem docs is about Coding with Rubygems.
The first line basically says "Hey, go get this gem with this version" from the install directory for gems and load it into the environment. This is mainly to help you add version dependencies to your requires instead of just doing require 'factory_girl' by itself.
Edit: To add on to Jörg's point below, I thought that Ryan Tomayko had a pretty good short and sweet article about why doing this is "wrong".
As #theIV already explained, this activates the factory_girl gem, using exactly (because of the = sign) version 1.2.3.
Note, however, that this is very bad practice and should never be done. If you activate gems manually inside your code, it means that people who do not use RubyGems can no longer use your code.
RubyGems is a package manager. Your code should never care about what package manager was used to install it. Some people prefer RubyGems, some dpkg/APT, some RPM/YUM, some RPM/APT, some RPM/URPMI, some RPM/YaST2, Portage, FreeBSD ports, pkgsrc, MacPorts, slashpackage, CoAPP, Conary, Slackware. There's tons of them. Some people like not to use any package manager at all. Or, they use RubyGems just for downloading, but then unpack the gem into their vendor directory.
All of this cannot possibly work, if you use the gem method in your code.

Should I enable RubyGems by default when installing ruby on Windows?

I've decided to have a play around with ruby so I've downloaded the windows one click installer. One of the options in the installer which isn't selected by default is to "Enable RubyGems" which automatically enables RubyGems by pre-appending 'rubygems' to the RUBYOPT environment variable.
Being completely new to Ruby I must admit that I have no idea what that means in terms of the impact it will have as I start developing programs in Ruby.
For one, I don't know what Ruby Gems are...but I also don't know how critical they are to ruby development. Should I just enable them by default or should I wait until I find that I definitely need them?
RubyGems or simply gems are Ruby packages or libraries that you can install and use in your Ruby programs. So you definitely will need them at some point in time and therefore you should enable them. When you will see that you need to install gem named "xxx" then you just need to run from command line:
gem install xxx

How to develop a gem in staging environment?

I am trying to hack through a forked gem (buildr). As such I cloned it from github and began to butcher the code. The official gem is installed on my system (under /usr/lib/ruby.../gems/buildr...). There is an executable which I need to use in my dev process - buildr.
Now I want the buildr executable and the library to point to my forked repo and not the default gem installation. This would be for this gem only. As such, the changes I make against the forked repo is usable directly for testing and so forth.
I would guess I need to load my library prior to the system gem loading. Can somebody recommend the best way to do so?
I did something similar for work when the Spreadsheet gem broke backward compatibility. I put the previous versions code in it's own module and just renamed the gem my-spreadsheet and installed that (I really wanted some of the features of the new gem but I also didn't want to rewrite all my previous code at that point).
If it's just a binary you want to override you could always do some PATH magic, setting the directory of your binary first and thus make sure you always override. But personally I'd prefer making my own copy with a new name and installing that.
you could bump the version in the gemspec for your fork. Then when you install your version of the gem, it will use your (newer) version by default.
change buildr.gemspec
#...
spec.version = '1.3.4.dev'
#...
Then
$ gem build buildr.gemspec
$ sudo gem install buildr-1.3.4.dev.gem
and it should work.

Resources