How to create a new Ruby gem? - ruby

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"

Related

Where are gem installs coming from?

I am wondering, while I'm sifting through samples, how I locate the source library when installing gems. For example, I have
require 'oauth2'
and to install, I run
gem install oauth2
What repository is pulled from for gem installs? I want to use reflection to reverse engineer some of the calls in the samples.
By default gem pulls from Rubygems, the main gem repository, but you can install from anywhere if you give it a URL or use the --source option to specify an alternate source. Some prefer to use private gem hosting for their dependencies.
Why not use a Gemfile to manage your dependencies? It makes it a lot more clear:
source 'https://rubygems.org/'
gem 'oauth2'
Then you install:
bundle install
Then you can see where it got installed:
bundle show oauth2
From there you can look at the source. You can also look at the gem listing page for oauth2 where links to documentation and source are provided.
There are a few useful options for looking at source code for ruby gems.
As #tadman has mentioned you generally can expect the default gem source to be hosted at https://rubygems.org and using Bundler is also highly recommended.
In many cases the open source code will be hosted on https://github.com. I tend to prefer to fork the gem source and download my fork locally where I can analyze it in my editor without fear of accidentally breaking anything since your forked repo will contain the full git history/repo etc.
If you're new to ruby, I would highly recommend you use a ruby version manager, i.e. RVM or perhaps RBENV, although I tend to find RVM a bit simpler and less problematic.
My other personal favorite ruby code hacking/inspecting tool is PRY

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.

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

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.

How to quickly initialize ruby project development environment?

How to specify gem dependencies in a way that user with only ruby, rake and rubygems installed could issue a single rake command to install all the dependencies required? Is it possible to use the same dependency specification when building gem with GemBuildTask?
It's actually pretty easy to set up a rake task that installs a bunch of gems:
task :install_gems do
require "rubygems"
require "rubygems/dependency_installer"
installer = Gem::DependencyInstaller.new
[["rack"], ["merb-core", "1.0.12"]].each do |args|
installer.install(*args)
end
end
Of course, you could extract this into a method and write a prettier way to specify your dependencies, but this should work great.
I think currently you'd have to write a custom rake task that talked to the Gem library.
It's possible that rip, the (very) new kid on the block, will make it all easier, but it's very early days.
But someone else may have a better way...
If your app is packaged as a gem, you could add the dependencies to the gemspec and rubygems will attempt to install them for you when you install the gem.
There are a bunch of ways to make a gem out of some ruby code. Recently I have taken to using jeweler.
With it, you can install a project as a gem by running rake install. There are some instructions on how to do dependencies on its github wiki.

Resources