Making an executable GEM from a script - ruby

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.

Related

Calling another Gem as a program from my Gem

I'm working on a command line tool (a ruby gem) to quickly and easily generate custom jekyll repositories from some basic user input for my company. I would like to add a feature where the gem can automatically build the repo and output the finished directory, but the jekyll gem doesn't seem to provide any internal ruby interface to do that, at least not one that would be easy to implement.
Is there a way I could have my gem call their gem as a program, i.e. system 'jekyll build', but without having to worry about whether or not the user has the jekyll gem installed?
You can add jekyll to your gems list of dependencies, by adding the following to your gem's .gemspec file. That means whenever someone installs your gem, jekyll would also be installed.
spec.add_dependency 'jekyll'

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.

What is a Ruby gem?

I've searched on Google, and I just found the uses of gem. As in, gem install, etc.
Are gems collections of .rb scripts?
If I build a series of scripts, for example that wraps the functionality of Google translate, is the preferred way of distributing that for usage a gem?
If not, how would I distribute this code?
According to RubyGems Wiki - RubyGems is a package manager for the Ruby programming language that provides a standard format for distributing Ruby programs and libraries (in a self-contained format called a "gem"), a tool designed to easily manage the installation of gems, and a server for distributing them.
The gem command is used to build, upload, download, and install Gem packages.
Gem Usage
RubyGems is very similar to apt-get, portage, and yum in functionality.
Installation:
gem install mygem
Uninstallation:
gem uninstall mygem
Listing installed gems:
gem list --local
Gem Package Building
The gem command may also be used to build and maintain .gemspec and .gem files.
Build .gem from a .gemspec file:
gem build mygem.gemspec
For more info, refer to RubyGems Manuals.
Here are some nice tutorials :)
http://railscasts.com/episodes/135-making-a-gem
http://railscasts.com/episodes/245-new-gem-with-bundler
A gem is a module/Library that you can install and use in every project on your server.
A plugin is a module/Library that you can use inside your project
Indeed, if you make some code what you like to share you can make a gem or plugin of it. You can publish it on for example github.com. You can check the source of the existing gems on github if you like to know how to make a gem as well.
Gem Package Building
Step : gem build your_gem_name.gemspec
simple steps follow click here

How to create a new Ruby gem?

To create a new Ruby gem, should I use Jeweler or should I use Bundler's built-in gem skeleton to create a base gem? What are the differences that matter?
Use Bundler
From the command line:
bundle gem your_new_gem
This will create a directory called your_new_gem with just a basic set of files and directory structure that are now considered best-practice. It's quick, easy, and a great place to start.
Creating a Gem isn't that difficult and I would advise to try building a gem from scratch, without any tools. After you know what's involved (creating a gemspec, building and pushing it to rubygems.org), you can use tools to speed up the process. My guess is you won't because making a gem is hardly the trouble at all.
I would go with Jeweler. The Bundler skeleton is only going to give you the basics. Jeweler has alot more options to work with and many helpful rake tasks for versioning, pushing to github, creating the gemspec, building and installing.
If you are working with Rails 3 engines, I have a Jeweler fork (definitely a work-in-progress) that will generate the app skelaton and include the engine file. You just have to run the jeweler command with --rails3-engine as an option. Here is the fork if you are interested:
https://github.com/johnmcaliley/jeweler
I would recommend using the built-in bundler command.
bundle gem your_gem_name
There are some rules that you should follow when creating a gem. Such as naming conventions and versioning rules.
I recently wrote a post on creating gems in netguru's blog. I think you'll find what you need in there.
https://netguru.co/blog/posts/creating-a-gem-a-step-by-step-tutorial
Hope this helps.
Here's an alternative that's worth looking at: ore
Bundler gives you a single template for ruby gems, whereas ore has multiple built in templates, plus the ability to create your own. It also supports Git, SVN (urgh) and Mercurial.
You can build a gem in RubyMine too. File > New Project > New Gem. It is that easy. But I want to make some notes about this approach:
For debugging, RubyMine will use the Fast Debugger gem, ruby-debug-ide. I know that most people now are using Pry with Byebug, but ruby-debug-ide is an interface which glues ruby-debug to IDEs like Eclipse (RDT), NetBeans and RubyMine.
Under Run > Edit Configurations > + > Ruby, I add a new debug configuration, according to the documentation here: https://www.jetbrains.com/help/ruby/run-debug-configuration-gem-command.html#1
Under Configuration, under 'Ruby Script', I add the path to the ruby gem file under lib: lib/my_gem.rb
Under Configuration, under 'Ruby SDK', I specify an RVM gemset I am using.
Under Bundler section, I check 'Run the script in context of bundler'. This would use bundle exec, which will read the dependencies in my Gemfile in my project's root. Now for gems, the Gemfile contains a method call "gemspec", which in turn reads the dependencies in dependencies in my_gem.gemspec. There, I have dependencies passed to the Gem::Specification.new block:
spec.add_development_dependency "bundler", "~> 1.7"
spec.add_development_dependency "rake", "~> 10.0"

unpacking/freezing gems into a non-rails ruby app

I'm writing a non-Rails ruby application (gasp!) and would like to be able to include all the gem dependencies which the application requires in a vendor subdirectory. This would be similar to how http://gemsonrails.rubyforge.org/ works for Rails apps.
The goal here is to avoid the situation my team currently experiences when a new dependency is added. Every developer on my team has to install the gem manually, and then someone has to manually update each test and staging and production machine. If we can freeze the dependencies into the distributed application itself then a simple svn update (or git pull for those hipsters in the crowd) would be all that is needed.
UPDATE (New Solution):
Try Yehuda Katz's new bundler gem. gem install bundler then create a Gemfile with all your dependencies. See the documentation for more info.
Old Recommendation:
One easy way is to just manually unpack the gems into your vendor directory and add the lib path of the unpacked gems to the front of the $LOAD_PATH.
To unpack a gem:
$ cd vendor/gems
$ gem unpack active_support
Unpacked gem: '/path/to/myproject/vendor/gems/activesupport-2.3.2'
Just make sure you unpack all the necessary gems and their dependencies (using the correct versions).
To add all gems under vendor/gems to your $LOAD_PATH, try adding something like this to your application's initialization:
Dir.glob(File.join("vendor", "gems", "*", "lib")).each do |lib|
$LOAD_PATH.unshift(File.expand_path(lib))
end
Update: Sarah (in the comments) convinced me it might also be necessary to override the GEM_PATH. Here's one way to do that:
require 'rubygems'
gem_paths = [File.expand_path(File.join("vendor", "gems")), Gem.default_dir]
Gem.clear_paths
Gem.send :set_paths, gem_paths.join(":")
Another option is to look into Rip (Ruby’s Intelligent Packaging) for managing your dependencies. Rip looks really sweet, but it's still new.

Resources