RubyGems plugin to tame a big ball of already-installed gems? - ruby

Maybe someone knows if this sort of RubyGems plugin exists already, before I try to sink a lot of time into writing one myself.
I'm not using RVM* or Bundler (edit: see thread in comments), so I have a big ball of system gems installed. I want to sort out which ones are gems I really want to use, which ones are dependencies that have to be there for the gems I really want to use, and which ones are just junk that can be cleaned up.
If anyone is familiar with Gentoo, I'm thinking of something similar to Gentoo's package management, but for RubyGems instead--a way to tag a small list of gems I really want to keep, then run a command that can go through all of my gems and clean up the ones that aren't dependencies of those gems. A "#world" set for RubyGems, in other words.
*RVM isn't an option for me anyway, because I have to use Microsoft Windows.

If you install graphviz, then you can runbundle viz this will produce a dot notation mapping of the dependencies and you can use that to trace dependencies down to those gem's you actually need to have installed (but only those that you have installed via bundler).
bundle viz --format=dot

Related

Create a completely self-contained gem?

I am writing my first real gem. It depends on three gems, and those gems have roughly a dozen dependencies. I'd like this all to be self-contained so my gem will always use the dependencies from inside the gem, and will not require the other gems to be installed at the system level. Doable?
I played around with bundle install --path vendor --standalone. It did indeed store all the gems' source code into vendor, but I could then not get my 'requires' to work correctly and the code could not be found.
I suspect either that it's not possible to do this with a gem (only and app) or I was missing some piece of configuration to point my gem's code at the vendored dependencies. I played around with $LOADPATH but could not make it work.
Anyone know if this can be done and, if so, how to make it work? Pointers to info welcome.
I think you need to add those gems as a dependency to your .gemspec file. That way when your gem gets installed, its dependencies will also be installed.
More information can be found here

Why does RVM install duplicate gems for different gemsets?

So, I've created a separate rvm gemset for each of my rails projects. They both use the same version of ruby 1.9.3.
This causes bundle install to completely install a fresh set of gems for both projects. It doesn't matter if the other project has the exact same version of the gem installed in the other gemset. I'm guessing this is the expected behavior to me but it seems like an inefficient use of hard drive space and bandwidth.
I know that I could manually move some of those gems to a global gemset, but that seems tedious to me and also prone to breaking if my dependencies change for a particular project.
Is there a better way to organize things, or have rvm auto detect when a gem version is already installed and just use that copy?
Or is there a better alternative to RVM that I should be using.
This is by design. Gemsets allow you to completely isolate the libraries used so you don't have any accidental interaction between projects. If you don't need the isolate you can just use an interpreter without a gemset:
rvm use 1.9.3
If there are a few gems you use across all projects, just switch to the global gemset for the interpreter:
rvm use 1.9.3#global
gem install the common gems and then they won't be re-installed per-project anymore when you are in a gemset.
While gemsets definitely aren't efficient in terms of bandwidth or HD space, they are extremely handy because you can easily blow away all dependencies for a project and re-bundle from scratch any time you want to. They also completely eliminate accidentally changing versions of your dependencies. If you don't like gemsets, correctly specifying versions in your Gemfile can get you pretty far on this without them.
As far as alternatives, rbenv is the main one I'd check out.

How can I install a gem as if it was specified in a Gemfile?

I want to install a gem via gem install, but I need it to resolve with dependencies of the current project.
Basically I want the functionality that bundler gives me when I specify gem 'xyz' in a Gemfile, but I don't want to add that specific gem into the Gemfile.
I tried doing bundle exec gem install ... but it doesn't seem to work.
edit: The reason why I don't want to add it to the Gemfile is that it might be something like metric_fu, metrical, saikuro, rails_best_practices, etc. Simply gems that are kind of utility use and might only cluttler the project.
I might only want to use them temporarily, or install them, try out, if it doesn't work out the way I want do rvm gemset empty and bundle install again to clean up.
The point of Bundler is, in part, to prevent you from doing things like that (to prevent you from injecting gems from outside when your project doesn't declare them).
Looking for a way of doing that is looking for a bug in Bundler. If you did manage to find some way of skirting Bundler's enforcement mechanisms, you should probably not use it; instead, you may consider filing it as a bug with Bundler's issue tracker.
Now we come to the real questions: what can you do? and what should you do?
You should use either RVM gemsets or Bundler to isolate your application and its gem dependencies. You don't need both. I would recommend Bundler for this purpose over RVM gemsets.
You should add to your Gemfile any gems that you want to use and that integrate with your application (i.e., that either load your application or that are loaded as part of your application). This is not a requirement for any gems that refrain from integrating with your application.
You should refrain from committing a changed Gemfile or Gemfile.lock to version control until you are satisfied that your application continues to operate acceptably (tests pass, new gem does something useful, etc.).
Or you should stop using Bundler, because you want to do things it is explicitly designed to prevent you from doing (not recommended).
At the risk of sounding dumb, why not add it to the gemfile? You can always add it to its own group if you don't want to have to install it everywhere.
A slightly different approach is, if you're using version control, such as Git, to create a new branch and install the gems. If it doesn't work out, uninstall the gem (I'm not sure this will be done by bundle update on the old branch) and trash the branch. If it does, work, merge your stuff into the old the branch.
Though I do believe the other answers and comments have some very good points.

Getting newer gems

I'm really just a beginner to ruby, so hopefully this is an easy one. I've got to the point where I'm starting to look into some of the gems that the community have put together. I decided to check out something that would help my application consume rss feeds. So, headed over to rubygems (which is where i thought people go to get these kinds of things) and searched for rss. I found this one;
http://rubygems.org/gems/simple-rss
instructions were to just install the gem with
gem install simple-rss
So far, so good. When i came to actually use the gem, the documentation I received from doing the above was a bit naff, so i searched a bit further and found the git repo;
https://github.com/cardmagic/simple-rss
The documentation there (their code examples) complain about missing methods etc. and after a bit of digging I came to the conclusion that I must have downloaded an older version of the gem than the git trunk.
So, my question is, should I be using rubygems to get the latest gems, and if not, what other resources are out there to help find the latest builds of the comminities gems?
As far as finding a good gem for a task — use Ruby Toolbox, since it also shows you how actively maintained a gem is. Here's, for example, a section on feed parsing.
If you want to get the latest gem code that hasn't been released yet, you could download the code directly from github and build the gem yourself. However, it's easier to use bundler for that. It allows you to create a Gemfile for your project looking something like the following.
gem 'simple_rss', :git => "git://github.com/cardmagic/simple-rss.git"
Then run bundle command to download and build these gems from their corresponding sources.
In general, bundler is a great solution for managing gem dependencies for any ruby project. It provides ways to quickly reference any released gems, automatically builds gems directly from a git source, git refs, or paths on your filesystem, and has other convenient features.
By far the best place for all things Ruby & Ruby on Rails for the devs is the Ruby Toolbox

Easy way to distribute ruby script

I have a bunch of ruby scripts in a folder which is added to $PATH and I think that some of them might be usefult to others. So I want to distribute them and the only 'good' way I know is rubygems (gem containing only binary), it has a very useful advantage of versioning, but also a drawback of initialization time (sometimes it takes some seconds before script starts to run). Are there alternatives?
Gem is good enought for this. I use gem for this purposes as it is very convenient to intall and update.
Gems are built for this. I'm not sure what you think a gem is, but RubyGems is a repository like PEAR for PHP, aptitude for ubuntu, or CPAN for perl, except they contain ruby libraries.
There is no extra overhead or "initialization time" added to your ruby libraries by making them gems. RubyGems simply installs your library - it doesn't do anything else.
Gems are fine for this kind of Ruby script.
To quickly generate a new gem, try out bundle gem.
To quickly distribute gems without using rubygems.org, and in a way that could work for private deployment, check out the idea for microgems.
If you still don't think you need to wrap these in gems, you can simply add the executable bit to your scripts, add shebang lines for ruby, and remove the .rb extension. Then share your script files with whoever wants them.

Resources