Is there a preferred tool to edit Gemfiles? - ruby

I have a project that depends on Ruby to do something. I need to tell these people to install bundler, create a Gemfile (or update an existing one) and then run bundler install.
To be very clear, these people do not care about Ruby, they don't know what Ruby is and they don't need to know what Ruby is.
Currently my documentation is:
Run this command in terminal:
gem install bundler
Create a new file name Gemfile and add these contents:
source 'https://rubygems.org'
gem 'lightning_sites'
Or if there is already a Gemfile then edit that file and add the line gem 'lightning_sites' at the bottom.
Go back to the terminal and run:
bundle install --path vendor/bundle
I would like to replace the documentation for step 2 and preferable replace it with a command line. Is there a tool that ships by default with Ruby or bundler that accomplishes this?

If you want to avoid bundler you need to force-bundle all your dependencies inside your application. This is only really practical if none of your dependencies have compiled extensions, so if they're all pure Ruby you'll be able to do it.
What you end up doing is a bundle install --path gems/ for example, then package up everything including that directory as a deployable application. You may want to make a script that performs this step and creates a .zip file of the final result for distribution purposes.
This is a heavy-handed approach, so it's best to do this only if absolutely necessary.

You don't have to use Bundler to install gems, Ruby provides the gem command for installing gems individually.
You could simply run: gem install lightning_sites --install-dir lightning_sites and in whatever Ruby script is using the gem, programatically modify your GEM_PATH using Gem.paths before the require statement to include that install directory.

Related

Bundler config to either look for gems in custom path or download from custom source

How do I configure bundler so that when I run bundle install it looks for gems under /my/custom/path first and if it doesn't find there then try to fetch them from a ruby gem remote repository hosted under https://a.nice.host and downloads those into ./local/relative/path (relative to cwd for example). I would like to avoid the bundler looking at default gem installation system path or rubygems.org
The syntax for sourcing a gem from a local folder is:
gem 'some-gem-name', path: '/my/custom/path'
And the syntax for specifying a custom source is:
gem 'another-gem-name', source: 'https://a.nice.host'
And to install gems into a specific local folder, you can run:
bundle install --path ./local/relative/path
Now, that's probably all the tools you need, in truth... (And in fact, especially for that last requirement, you may instead wish to look into rvm gemsets, or using bundle install --deployment.)
But you did also ask about "looking in a local folder first, and only falling back to a remote source if it doesn't exist". That's quite an odd requirement (usually you'd only want to explicitly opt-in to fetching gems from a local path?!), but to answer this question as you've asked it...
A Gemfile is literally just ruby code! So you can define this logic using... You guessed it, ruby! For example:
if File.exists?('/my/custom/path')
gem 'some-gem-name', path: '/my/custom/path'
else
gem 'some-gem-name', source: 'https://a.nice.host'
end
If this (unusual) pattern needs to be repeated in multiple places, you could wrap it into some helper method.
For more information on the configuration options of bundler, please see the documentation.

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...)

How to contribute to a Ruby Gem

I am trying to contribute to a Ruby gem and I don't understand how to test a local gem without using a globally installed gem.
The gem I want to contribute to is a command line interface gem. I clone the gem into a directory then cd into that directory. However, when I run commands in the terminal when I'm in the cloned project directory it still uses the global gem. I've even run
gem uninstall gemname
then while inside the newly cloned gem directory I redo
gem install gemname.
No matter what changes I make to the gem, I can't see the results or what my contributions are doing because it's always running the global gem.
When I do try to type a command line command that is supposed to interact with the gem while in the cloned gem directory I get:
-bash: ~/.gem/ruby/2.1.0/bin/githubrepo: No such file or directory
I've done a ton of research but I'm just not getting it. Help?
gem install gemname will look for a .gem file in the current directory. If not found it will look for it on the web.
gem install --local /path/to/your/gemname.gem will allow you to target a particular directory. You may need to gem build gemname.gemspec first, so it has your changes.
Instead of doing this, I would write tests in the gem directory itself. It's likely that when running code in there, you can simply require 'gemname' in Ruby to get the gem functionality.
If it's a well-written gem, it should have tests already. They will most likely be in a directory called test or spec. Have a look at these tests and try to carry on in that style to test your changes. This will make your code changes far far more likely to be accepted as a pull request.

Ruby program gems

I wonder whether Gemfile is a rails-tied file or not. If I have something as:
require 'json'
in my ruby file, the user tries to run it, and he doesn't have that gem, what will happen? How do I make sure that someone's computer knows what gems to install before running my script? I know bundle install exists in Rails, but what about outside Rails?
Gemfile isn't a Rails-tied file. It's the file that you can use any Ruby-based project with bundler gem installed. Once you've run bundle install command, another file Gemfile.lock is generated or updated if exists. By the way, gems you'll use are linked with locations in your computer/server you're developing.

Manually adding a Ruby Gem

I am trying to install the mechanize gem that is supposed to work with 1.9 from here: http://github.com/kemiller/mechanize but I do not know how to add it manually.
I am using Windows, I could just copy the folder to the gems directory, but how do I initialize it?
I'm not sure I understand the problem. gem install mechanize doesn't work? It produces version 0.9.3 for me, which matches the gemspec of the library you linked to.
EDIT: you're on 1.9. I knew that. Disregard my hasty post, not familiar enough with Windows to offer any help on building the extensions.
I would use the bundler gem using the command gem install bundler. This will create a file called Gemfile in your project directory where you can put your dependencies for the specific project that you are working on. In the Gemfile, you will need to specify gem mechanize. If you want a specific version include ~> VERSION after. After, run the command bundle install. This will install the gem you want and use it in your project.

Resources