Packaging precompiled binaries inside of a gem - ruby

I've got a ruby web app that uses lilypond to generate sheet music based on user input. I'd like to move the hosting to heroku (I've recently used heroku on a few projects and really liked it, plus my traffic is low enough that it'd be free host it on heroku, for a while at least). However, heroku's dyno architecture doesn't allow you to ssh in and install whatever packages you want...instead, you give it a gems manifest, and it will install the gems for you.
So, if I'm going to deploy to heroku, I'm going to need to package lilypond as a gem. I've released a few pure-ruby gems, but haven't dealt with native extensions or precompiled binaries, or anything like that.
Is it possible to take some precompiled binaries and package it inside a gem? Ideally, this would include binaries for OS X (which I develop on) and debian linux (which is what's running on heroku), and would install the proper binary when the gem was installed.

it is possible, since precompiled binary gems for windows are the norm. Take a look at rake compiler, perhaps.
also https://github.com/rdp/ruby_tutorials_core/wiki/gem (https://en.wikibooks.org/wiki/Ruby_Programming/RubyGems) might help
-r

I think you've got a few options here:
You could get the Lilypond source and package it into a gem with a native C extension. There are some useful guides on how to do that at http://guides.rubygems.org/c-extensions/ and http://patshaughnessy.net/2011/10/31/dont-be-terrified-of-building-native-extensions
There's also a gem called gitara but I haven't been able to find any information about using it on Heroku. It might be worth emailing the author and asking if he knows anything about that.
You could create a Heroku buildpack that installs Lilypond as part of your deployment. I wasn't able to find any for Lilypond, but there are plenty of examples that do similar things - for example, this one installs Imagemagick (which is included by default on Heroku, so probably not necessary anymore - but hopefully the code is helpful). More documentation at https://devcenter.heroku.com/articles/buildpack-api and https://devcenter.heroku.com/articles/buildpack-binaries
Based on my reading, I think the buildpack option is the best way to go.
Hopefully this helps!

Instead of precompiling, you should be able to just list the gem in your .gems file, see the Heroku documentation. Of course, this requires your gem builds the native code correctly - this is still a task, but hopefully an easier one.

Related

Installing nginx as a ruby gem vs using apt-get

I'm new to running a Linux server and slowly getting up to speed with things.
I have already installed nginx via the apt-get function, although I'm following a tutorial which recommends installing it as a ruby gem instead.
Is there any difference in the functionality/limitations to installing it as a gem than by using apt-get? - I'm worried that it won't work for non-ruby applications if it is gem installed?
Is there any difference in the functionality/limitations to installing it as a gem than by using apt-get? - I'm worried that it won't work for non-ruby applications if it is gem installed?
There aren't any limitations on the version of Nginx that Passenger installs for you. You should be able to use it with other languages as you normally would (providing you know how to configure Nginx.) I was able to use it to connect to both Ruby and Node.js sites with no problems.
The people at Phusion have a nice page explaining why they are forced to provide their own version of Nginx (rather than using the standalone one) and it comes down to the fact that Nginx does not allow to be extended at runtime. Extensions like Passenger must be compiled into it. See this page for more information on it: https://github.com/phusion/passenger/wiki/Why-can%27t-Phusion-Passenger-extend-my-existing-Nginx%3F
(Note: When I tested this I used the installation instructions from the Phusion web site https://www.phusionpassenger.com/documentation/Users%20guide%20Nginx.html#install_on_debian_ubuntu , rather than the gem that is indicated in your tutorial, but I suspect they are both equivalent.)
I have run into this too. Where I am recommended to use one package manager over the other. I would question the age of the tutorial first, if it is not relatively recent you may want to consider if the information is no longer up to date. The libraries installed with that method may not be up to date.
However, if you intend to follow through with the tutorial you may end up needing it installed as the tutorial describes.
The difference is that one may not have all the libraries that are required or may not have the most up to date version. One tool could be buggy, I don't think this is the case in your situation but it is in Macports v.s Homebrew in my opinion. It might install to a different directory based on what install method you use, if you use a method off the web and then go back to the tutorial it could be installed to a different location then your tutorial expects.
If you have to follow the tutorial then I would all the way through, but if you don't need to use the preferred method that the program/library maintainers recommend. If the tutorial is out of date you could try to find an up to date tutorial.
good luck!

Feasibility of vendoring binary executables within a gem?

I've written a sprockets processor for losslessly compressing jpgs and pngs, you check it out it here: https://github.com/botandrose/sprockets-image_compressor
However, I can't use this gem on heroku, because the jpegoptim and pngcrush programs aren't available within their environment. Furthermore, users of the gem will need to remember to install these programs on every system they want to use my gem. So, I think it'd be nice if I could vendor in these binaries as a fallback if the system doesn't have them installed already.
So, is this totally crazy? Would I need to provide a 64bit binary as well as a 32bit? Would I still require some sort of external library to be installed? Would I be better off writing some sort of C extension that hooks into these programs?
I haven't seen many gems in the wild that do this sort of thing. One other option, however, is to provide rake tasks that go out and fetch the programs if they aren't already installed on the machine. It might be tricky to make it work for all the different platforms, though.
With regard to using your gem on Heroku: remember that Heroku has a read-only filesystem (except for the /tmp directory), so running Sprockets processors like yours on Heroku isn't really a practicable option anyways. I personally just use rake assets:precompile and commit all the precompiled assets to my Git repo before pushing to Heroku. Yes, I know it messes up the repo history, but it's the easiest way to go (at least for now). Hopefully Heroku will come up with some other option in the future.
As far as the main question you asked, hopefully someone else can provide a good answer. Your project looks very cool; I am just going to try it out.

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

'deploying' a ruby script with gems

i've written several Ruby scripts that work together to from a console application.
These scripts are written on an Ubuntu platform, but I want to be able to run them from a Windows platform as well.
The problem I'm currently facing is porting over all the gems. I've downloaded sources of most gems and made some bug fixes on them, but is it possible to package them for example with my scripts so they're available?
I'm thinking a bit DLL like here as Windows does.
I can probably add a readme file, stating which gems are required and where/how to obtain them, but it would be easier if I could package them.
Maybe you could look at http://www.erikveen.dds.nl/rubyscript2exe/index.html which does some packaging for ruby application (including the ruby interpreter, too)
You could also build a gem with your script in it along with all needed gems directly inside the gem. Provided their licences allow you to do that, it could be a reasonable solution ( Gem supports platform flavoured gems http://docs.rubygems.org/read/chapter/20#platform )

Are the svn ruby bindings provided as a gem?

I see a couple dozen gems that relate to svn, but what little documentation I can find on any of them shows that they are command-line wrappers and misc helpers. (svn-command, svn-hooks, etc.)
I've seen code in the wild that does things like: require 'svn/core' and SVN.Repos.add(...), but the author of that module pulled his svn ruby tools via apt-get. This would not be an option for me, as I'm developing a windows/osx tool.
This page lists a number of projects, but in particular, I'm in need of something that will make it possible to access an svn+ssh repository and I don't have the kind of time it would take to dig through docs on a half-dozen projects, trying to bootstrap each one.
Which gem am I after? From there, I'm happy to dig through code in lieu of documents, but with a call to gem query --name-matches svn --remote returning about 30 hits, I need to narrow it down a bit first.
Exactly what was being pulled by the apt-get command? Was it the bindings themselves (apt-get install libsvn-ruby) or the ruby modules? Since the bindings aren't ruby modules, they can't be pulled in by the gem command. You have to install them via apt-get or manually download them and install them into your system.
You can try svn_wc which requires svn_core. And, I believe svn_core uses the SWIG bindings and the Ruby bindings are included when you install Subversion. You can also try svn_tools which was created by Mark Bates who wrote Distributed Programming with Ruby. I haven't found any documentation on svn_tools though.
I noticed that the RSCM module, which is a unified way of interfacing to various SCM tools, uses the Subversion command line. If there was one tool I thought would use Subversion's API bindings, I thought this would be it, but it too uses the Subversion command line.

Resources