Table of Contents
Introduction
Sharing forms a bridge between everyone involved and it makes things grow. That's the basis for the open-source movement, which gave way and allowed so many great things to happen — especially in the recent years.
This principal applies for Ruby and Ruby based applications. That's why – and how – a developer can get started working on making their idea a reality so rapidly, thanks to all the available tools, libraries, and frameworks that they can take advantage of.
In this the cloud provider article, we aim to help those trying to find ways to give back to the community by sharing their own Ruby-based or Ruby-related creations. We are going to shed some light behind the mystery of packaging code for others to be able to easy download it as a Gem using the RubyGems package manager, which makes the whole process a breeze.
Glossary
1. Packaging Applications
2. RubyGems Package Manager And Ruby Gem Packages
- RubyGems Package Manager
- Ruby Gem Packages
- Gem Package Structure
3. Getting Ruby And Necessary Tools
- Installing Ruby
- Installing Bundler
3. Packaging A Ruby Application
- Preparing The Distribution Directory
- Creating A .gemspec File
- Placing The Application Code
- Modifying The Main Application Script
- Making Sure Everything Works
- Listing Your Gem's Dependencies
- Committing The Gem Package
4. Releasing A Gem Package
—
- Creating The Package
- Publishing The Gem
Packaging Applications
—
One of the ways of distributing applications, libraries, or other programming related code bundles is to put them in archives called *packages*. Application packages contain already compiled and ready-to-use software in an easy-to-keep-track-of and easy-to-use way. They usually come with additional files that contain information about the package and sometimes documentation as well.
Packaging applications, therefore, consists of following a set format defined by package management tools (i.e. the RubyGems) and using these tools to share them with others in an easily accessible way.
In this tutorial, we will begin with understanding RubyGems, the Gem package format, and then learn how to package a Ruby application from start to finish, beginning with creating the package structure to contain the code (and other related material).
RubyGems Package Manager And Ruby Gem Packages
—
Note: The subject matter of this article is to package applications. This section contains a summary of related tools and materials. To learn more about them, you can read the introductory first part of our RubyGems series.
RubyGems Package Manager
—
RubyGems is the default *package manager* for Ruby. It helps with all application package lifecycle from downloading to distributing Ruby applications and relevant binaries or libraries. RubyGems is a powerful package management tool which provides the developers a standardised structure for packing application in archives called *Ruby Gems*.
Ruby Gem Packages
—
A Gem is a Ruby application package which can contain anything from a collection of code to libraries, and/or list of dependencies that the packaged code actually needs to run.
Gem Package Structure
—
Gem packages contain different sets of components. Each component gets placed inside a dedicated location within the gem bundle.
All the below elements (and more) can go inside Gems:
- Application code;
- Tests;
- Description of dependencies;
- Binaries;
- Relevant Documentation;
- Information regarding the package (gemspec).
Gems are formed of a structure similar to the following:
/[package_name] # 1
|__ /bin # 2
|__ /lib # 3
|__ /test # 4
|__ README # 5
|__ Rakefile # 6
|__ [name].gemspec # 7
- [package_name]:
The main root directory of the Gem package.
- /bin:
Location of the executable binaries if the package has any.
- /lib:
Directory containing the main Ruby application code (inc. modules).
- /test:
Location of test files.
- Rakefile:
The Rake-file for libraries which use Rake for builds.
- [packagename].gemspec:
*.gemspec file, which has the name of the main directory, contains all package meta-data, e.g. name, version, directories etc.
Getting Ruby And Necessary Tools
—
Installing Ruby
—
In case you don't have Ruby installed already, you can follow one of the two links below to get it properly set up on your platform of choice.
- CentOS / Rhel:
- Ubuntu / Debian:
Installing Bundler
—
One of the tools we will be using for creating Gems is *Bundler*. Once Ruby and thus RubyGems are installed on your system, you can use the `gem command to get bundler.
Run the following to install bundler using gem:
gem install bundler
Packaging A Ruby Application
—
There are several ways to start creating a Gem package. One the methods is to use the popular Bundler, a Ruby environment and dependency manager that helps with an application's requirements and maintenance of the code. This tool can also be used to scaffold a Gem distribution directory to kick-start the packaging process.
Preparing The Distribution Directory
—
Gem packages are kept in package directories which should be named after your package as we have discussed in the previous structuring section. Since these are simple locations found on the file system, you can use the Unix mkdir command to create them one by one… or get Bundler to do the job.
Run the following command to scaffold all the necessary directories inside a folder, named after your Gem's desired name:
bundle gem my_gem
Note: Gem names need to be unique. Therefore, you should search and make sure that the name you would like to use for your Gem is not already chosen by someone else's project. In order to verify, you can visit and search on RubyGems.org.
The above command will run a series of commands to create our package structure, e.g.:
As you will see, Bundler has also created a brand-new Git repository which comes in handy with various versioning operations.
Note: If you would like to learn more about how to work with Git, check out the the cloud provider community articles on the subject.
Creating A .gemspec File
—
The .gemspec file contains some absolutely vital information regarding Gem packages. Ever Gem must be shipped with one where meta-data from Gem name to version and description to folders to be included by Gem are found.
Tip: .gemspec files are regular Ruby scripts — which means that they are programmable.
To see the contents of the generic *gemspec* created by Bundler, use the following command:
cat my_gem/my_gem.gemspec
You can either edit this file now, or before each time you package and publish.
In order to modify this file, you can use the following command to edit it using nano:
nano my_gem/my_gem.gemspec
This will open up the nano text editor.
One of the recommended additional information you might want to declare here is the minimum Ruby interpreter version required to run your code.
You can do this with the required_ruby_version declaration, which can be added towards the bottom end of the file for consistency.
For example:
spec.required_ruby_version = ">= 2.0"
spec.add_development_dependency "bundler", "~> 1.5"
spec.add_development_dependency "rake"
end
Once you are done editing your file, press CTRL+X and confirm with Y to save and exit.
Note: Do not forget to modify the declarations that contain a "to-do" placeholder (i.e. %q{TODO:) such as the spec.description.
Placing The Application Code
—
Your library (or application, framework, etc.) shall always go inside the /lib directory. Inside this directory, there shall be a Ruby script named exactly the same way as your Gem. This file is the main one that gets imported when another application depends on your Gem.
The recommended and tidiest way to place your application code is to divide it into bits and place them in a directory, inside /lib, where they are used and made available by my_gem.rb to the public.
When you look at the contents of the /lib directory, you will see that the main Ruby script and a directory to contain your code is ready:
ls -l my_gem/lib
And the my_gem directory inside /lib comes with a version file:
cat my_gem/lib/my_gem/version.rb
module MyGem
VERSION = "0.0.1"
end
This VERSION number is set to be automatically imported and used inside the *.gemspec file by Bundler. You can modify it here and change it to match your Gem's current version.
You should move all your code here to be used by your application.
As an example, let's create a Hello [name]! module.
nano my_gem/lib/my_gem/hail.rb
Place the below example inside:
class Hail
def self.name(n = "Dalek")
n
end
end
Press CTRL+X and confirm with Y to save and exit.
Modifying The Main Application Script
—
In the previous step, we have learned that for the purposes of keeping everything in order, applications with especially a lot of classes should be separated into pieces with all elements placed inside the /lib/[gem-name] directory.
Let's see how we can modify the main Ruby script that gets imported when somebody uses your Gem.
Run the following command to edit the imported Ruby file inside /lib using nano:
nano my_gem/lib/my_gem.rb
You will see a very short script similar to the one below:
require "my_gem/version"
module MyGem
end
Here, you should import all your classes and code from the /lib/[gem name] directory and use them.
In our case, let's see how to use Hail class which we created in the previous step.
Modify your code similarly to below example:
require "my_gem/version"
require "my_gem/hail"
module MyGem
def self.hi(n = "Default Name")
hail = Hail
Hail.name(n)
end
end
Press CTRL+X and confirm with Y to save and exit.
Note: Although there is no need to make Hail an *instantiable* class, for the purposes of demonstration, we have made it so and left MyGem as a module to use its methods directly.
Making Sure Everything Works
—
Once you move your code inside and modify your main imported script, you will want to make sure everything works, naturally. The simplest way to go about doing this is to use *Bundler* again — and not by installing the Gem.
First, let's enter the Gem directory and then use Bundler's console feature:
cd my_gem
bundler console
This will load your Gem using the information from the *.gemspec and let you get to work, e.g.:
bundler console
Listing Your Gem's Dependencies
—
In a real world scenario, it is highly likely that your Gem itself will be dependent on others.
These dependencies are also listed in the *.gemspec file.
Run the following command to edit the file using nano:
nano my_gem/my_gem.gemspec
Add the following instructions at an appropriate block to list dependencies:
spec.add_runtime_dependency "activesupport", [">= 4.0"]
Press CTRL+X and confirm with Y to save and exit.
Note: You can list all necessary dependencies by repeating the instructions successively on the *.gemspec file.
Committing The Gem Package
—
Once your Gem is ready to be shipped, you should commit the Git repository for versioning.
Use the following command to commit with Git:
git commit -m "Version 0.1.0"
Git, then, is going to commit all your code and give you the results:
Releasing A Gem Package
—
Once you are happy with your Gem, you can release it to the world on RubyGems.org.
Note: In order to release your code, you will need to have an account at https://rubygems.org/sign_up.
Creating The Package
—
Once all is set, you can create the package using the gem tool.
Run the following to create your package:
gem build mygem.gemspec
Publishing The Gem
—
There are a couple of ways to publish newly minted Gem. Either way, you will need to log-in with a RubyGems.org account so let's start with doing that first.
Run the following command to log-in using gem:
gem push
Enter your email address, and then your password to sign in.
Note: We specifically refrain from giving a Gem-name to push so that we only log-in without performing further action.
In order to simply push your Gem, run the following:
gem push my_gem-0.1.0.gem
Alternatively, you can benefit from Bundler's Rake tasks. You can see a full list with the following:
rake -T
- rake build:
Build my_gem-0.0.1.gem into the pkg directory
- rake install:
Build and install my_gem-0.0.1.gem into system gems
- rake release:
Create tag v0.0.1 and build and push my_gem-0.0.1.gem to Rubygems
If you call rake release, your package will be pushed to your set Git account and then to RubyGems.org, e.g.:
rake build
rake release
To continue, add a remote Git account:
git remote add origin [email protected]:maintainer1/my_gem.git
Then simultaniously release your code using rake:
rake release
And that's it! You can now go to RubyGems.org and check out your Gem:
http://www.rubygems.org/gems/[your gem name]
href="https://twitter.com/ostezer">O.S. Tezer</a></div>