Rakefiles and Gemfiles - ruby

So I understand the basic concepts of a Rakefile and a Gemfile (rakefiles are basically just dependency lists and shell commands to compile and link the application while gemfiles specify gem version dependencies for an application), but how should I use these in unison? More specifically: I have a project for a project at my Uni that I am going to use Ruby 1.8.7 and JRuby 1.7 on with a set of gems I have installed through RVM on my local machine.
The problem is is that my application must compile and run without error on the computer lab at my Uni and the Uni doesn't have JRuby on these machines. I can install onto my shell account, and I did that with JRuby to get my application to compile but now I am required to type in the full path to the jruby installation to compile my project (something like /usr/home/usrname/blah/jruby-1.7.0) and I feel that is annoying and I would like something simpler (and learn at the same time).
The machines at my Uni have Rake installed and I was wondering if it would be possible for me to set up a rake file to do the call to JRuby and all the gems I need (specified in the gemfile with their respective installation paths). Is this possible? Or am I thinking of rakefiles and gemfiles in the wrong way?
Thanks!

The Rakefile is used to set up dependencies for running Rake within the context of your project. You have correctly described the purpose of the Gemfile.
Rake is an independent program from JRuby. It will be included in the bin folder of your JRuby install. By the time you reach your Rakefile, you are already in the context of the wrong version of Rake (the one included with the regular Ruby install).
I think what you are looking for is just a modification to your path. Include your JRuby bin folder in your path, and that will allow you to specify which version of Rake you want to use.
For the JRuby version:
jruby -S rake your:task
Or just the regular Ruby version:
rake your:task

Related

Ruby command line tool crash when switch ruby version in rvm

I am trying to make an CLI tool with ruby.
My tool require some library in bundle (log4r, ...). So problem appear when i switch my ruby version (2.0.0 -> 2.1.2) or when switch gemset, some gem are not install in new ruby environment.
So how can i make my app work like vagrant, which work in every version of ruby i am using?
If you package your application as a Gem, you can include a Gemspec that describes your application. One of the things you can specify is its runtime dependencies; when the user runs gem install myapp, then the gem command will make sure it includes everything you specified (like log4r).
It will be harder to make this happen without Rubygems. You can package your application along with a defined version of Ruby and all its requirements - that's what Vagrant does - but that makes your application a larger download and means you have more to maintain. It's going to be hard work if you want to install your app system-wide and have it work with every single Ruby environment. It's far better to let the gem application install your app (whether systemwide, or via rbenv/rvm) and let that manage your dependencies for you. There's the default gems plugin for rbenv and rvm gemsets to help manage this.

Deploying a Ruby Command Line Application that Depends on Non-Rubygems-Hosted Gems

I am attempting to deploy a small command-line application written in Ruby. Many of the gems that the application depends on are hosted on my github account. I have specified their locations in the Gemfile appropriately. When I clone the repo on the deployment machine and run bundle install from the root, all goes smoothly. I can then run the command line app (named "hippo") with bin/hippo. I would like to install the app to the system so that I do not need to patch $PATH or specify the path to the executable in order to use it.
When I run gem install /path/to/my/.gem/file, installation fails and says that it cannot resolve the dependencies to my personal gems hosted on my Github account. I gather this is because the gem install command does not read the Gemfile, only the gemspec (why on earth did the bundler people name their file Gemfile instead of BundleFile or something?), and the locations of the gems are specified in the Gemfile (there is no way to point to a github gem in a gemspec, right?). I have the same issue when I use the rake install task that comes with a bundle-scaffolded gem. However, when I run bundle exec gem install /path/to/my/gemfile then it installs OK, I guess because it sees my gems on the bundler-altered load path and decides that they are already installed. But then, when I try to run the executable, it fails because it can't find the dependencies when they are required. (Note that the executable has require bundler/setup as its first line after the shebang).
So I ask: what is a good way to deploy, with bundler, a command line application that depends on non-rubygems-hosted gems?
bundle exec sets up your load path correctly so that the gems are visible when you require bundler/setup. One option would be to always run your binary with bundle exec bin/hippo.
Something more suited to your purposes might be to run bundle install --standalone, which generates a bundle/bundler/setup.rb file within your project's directory. That file sets up load paths correctly for you, so you'd just need to do something like require_relative '../bundle/bundler/setup' from your binary instead of require 'bundler/setup'.

How do I make a gem with a binary, when it depends on bundler to find its dependencies?

I have a gem which depends on Bundler's Gemfile to find its dependencies (they are hosted on github:enterprise). I want it to be usable as a lib and also to provide a binary.
Currently it works fine as a binary if I am running it from its own directory, where the binary can load the bundled gems. However, if I run it from a different directory, it can't find the dependencies (they are in their own rvm gemset). I can't install it as a gem because Rubygems can't find the dependencies (currently they are listed in the .gemspec, and then told where to be found in the Gemfile).
I am currently trying bundle package, and it placed all the gems in the vendor/cache directory. As far as I can tell, this will mean that I need to remove the dependencies from the .gemspec and instead into the Gemfile (because Rubygems shouldn't install them since they are vendored). This means that any code using this gem will need to know about these dependencies, and add them to their Gemspecs, but I'm okay with that. I think this could work if I modify the .gemspec to include the vendored gems when building, and if I can manage the load path such that the binary sets the vendored gems at the front of the load path, but any code using it as a library will not add these to the load path, so they will get whatever versions they've installed.
Unfortunately, I don't know how to do that (short of reading in all the gemspecs, reflecting on their require_paths to add them to the $LOAD_PATH), and I'm not really sure that this is the correct way to handle this situation.
So, how do I make a gem that can be used as a lib, or just for its binary, when it needs Bundler to find its gems?
if you are hosting the code in your own github enterprise instance, then it might be a good idea to have a custom rubygems server. you can then publish your internal gems to that server and have bundler retrieve them from there.
this should make a transparent workflow like you would be running your binaries in the real world!

Making an executable GEM from a script

I started developing ruby lately and I really like it, But I feel somehow lost. I developed a script that does "whatever" and that scripts requires many gems like nokogiri and colorize. I now want to deploy the script, so after reading a while I found many people saying that deploying as a gem is the best approach. So my question is simple? Is there any tool that I can use to create a gem of my script file and include all the gem dependencies(nokogiri) in the new gem?
I am using ubuntu!
Thanks alot
Building a gem consists of basically creating a simple directory structure for your script, and a special file known as a gemspec that will list all its dependencies. That gemspec can be used with rubygems to create a gem file (*.gem), which can be installed using rubygems or uploaded to rubygems.org for public consumption.
There are several tools that automate part of this process. A relatively simple one is the Bundler gem, which will both take care of dependencies during development, and make it easy for you to package your gem. This article contains enough information to get you started with gem development using bundler.
The best way to make a gem is to use the bundler program to build a skeleton:
# bundler gem (gem_name)
bundler gem geil_gem
This will create a template gemspec file and give you the basic structure needed for your gem to have a setup command, a console and be ready to build into a working gem (both found in the bin folder of your skeleton project). From here you can add a command binary or build out the gem as a library using the lib directory or start with tests by adding rspec to the gemspec and creating a test folder.

How to use bundler gem binaries in path

I just started using bundler for gem packaging in vendor/. The problem is with certain gems (like rspec and cucumber) that have binaries. The binary path that is under my_app/vendor/gems/ruby/1.8/...cucumber-0.6.2/bin/ is not in my path, therefore when I go to run cucumber i get command cannot be found.
What is the easiest way to execute the bundled gem binaries from within the app rather than adding a large number of folders to my path?
Thanks
Newer version of bundler have an "exec" action. So for cucumber it would be:
bundle exec cucumber
OK, so symlinking was in fact a daft idea. This question did get me thinking though, and I found this: http://litanyagainstfear.com/blog/2009/10/14/gem-bundler-is-the-future/
Bundler will also dump gem executables in your Rails.root/bin directory. This means you can then use bin/rake, for example.
so, from the Rails root, does bin/cucumber work?

Resources