You don't have to use Bundler to create new RubyGems
— bundler, ore
Warning: Controversial Content
If you are morally or ethically opposed to using Project Generators and prefer to create RubyGems by hand, STOP READING AND CLICK THE BACK BUTTON.
I am perfectly aware that one does not need any tools to create a RubyGem, and that all you really need is RubyGems and a *.gemspec file. However, the majority of users do not have the time or patience to create each Ruby project from scratch. Thus developers have historically used project generators such as Hoe, Jeweler and now Bundler.
If you are a diehard Bundler user, please read the entire blog post. This blog post is not putting Bundler down, nor is it posing a binary choice between Bundler and some new tool.
Enter Bundler
Bundler was initially created as a more robust way to manage dependencies of Rails3 applications. Once Bundler was integrated into the Rails3 generator templates, developers realized Bundler could also be used to manage the dependencies of any large Ruby application or library.
In order to help developers create projects with Bundler already setup,
template files and a bundle gem
command were added.
Since Bundler was the “new hotness” and developers were becoming increasingly
dissatisfied with Jeweler/Hoe, the community began to
cargo cult Bundler as the defacto way to create RubyGems.
Looking Back
After having extensively used Bundler with Ronin, to keep it’s many
repositories in-sync with each other, I can definitely say Bundler
solved dependency management for large Ruby projects.
However, I began to question using bundle gem
to create new RubyGems.
At first it made sense to provide a bundle gem
command, but project
generation is outside of the original scope of Bundler (dependency management).
Furthermore, adding Bundler to an existing project isn’t that difficult;
just add a .gemspec
file and a Gemfile
.
Given that Bundler’s stated goal is to “manage an application’s dependencies”, it doesn’t seem very pragmatic to use Bundler in libraries with zero or only one runtime dependency.
Bundler’s template files are a bit spartan as well. The Rakefile template does not include Rake tasks for RDoc or RSpec. This omission might encourage developers to not write documentation or tests, and rush to release.
The bundle gem
command isn’t very configurable either. If you want to generate
a project with Textile markup, YARD documentation, RSpec tests and
Mercurial, you are out of luck.
Enter Ore
Ore is a flexible Ruby project generator. Unlike other Ruby project generators, Ore provides many built in templates and allows custom templates to be installed from Git repositories.
$ gem install ore
$ mine my_project
Generating /home/postmodern/my_project
create lib
create lib/my_project
create spec
create .gitignore
create .rspec
create spec/my_project_spec.rb
create spec/spec_helper.rb
create .document
create my_project.gemspec
create ChangeLog.rdoc
create LICENSE.txt
create README.rdoc
create Rakefile
create lib/my_project/version.rb
create lib/my_project.rb
run git init from "."
run git add . from "."
run git commit -m "Initial commit." from "."
$ cd my_project/
$ rake -T
rake build # Builds all packages
rake clobber_rdoc # Remove RDoc HTML files
rake console # Spawns an Interactive Ruby Console
rake install # Installs all built gem packages
rake rdoc # Build RDoc HTML files
rake release # Performs a release
rake rerdoc # Rebuild RDoc HTML files
rake spec # Run RSpec code examples
Ore generates new Ruby projects with sensible defaults, such as
a .gemspec
file, rubygems-tasks, RDoc, RSpec, a .gitignore
file
and initializes the Git repository.
Ore also provides many different templates and options:
$ mine --help
Usage:
mine PATH
Options:
[--gemspec-yml]
[--jeweler-tasks]
[--bundler]
[--rubygems-tasks]
# Default: true
[--yard]
[--bundler-tasks]
[--hg]
[--rspec]
# Default: true
[--rvmrc]
[--gem-test]
[--gem-package-task]
[--gemspec]
# Default: true
[--test-unit]
[--git]
# Default: true
[--bin]
[--rdoc]
# Default: true
[--markdown]
[--textile]
-T, [--templates=TEMPLATE [...]]
-n, [--name=NAME]
-V, [--version=VERSION]
# Default: 0.1.0
-s, [--summary=SUMMARY]
# Default: TODO: Summary
-D, [--description=DESCRIPTION]
# Default: TODO: Description
-a, [--authors=NAME [...]]
# Default: ["postmodern"]
-e, [--email=EMAIL]
-U, [--homepage=HOMEPAGE]
-B, [--bug-tracker=BUG_TRACKER]
-L, [--license=LICENSE]
# Default: MIT
As you can see, Ore is completely configurable and supports:
- Git / Mercurial / SubVersion
- .rvmrc files
- Bundler
- rubygems-tasks / Bundler tasks / Jeweler::Tasks / Gem::PackageTask
- RSpec / Test::Unit
- YARD / RDoc documentation
- RDoc / Markdown / Textile markup
Unlike other project generators, Ore focuses only on project generation and does not force a specific project layout or workflow upon the developer. You can even generate projects with Bundler, YARD + Markdown and Mercurial instead of Git:
$ mine my_project --bundler --yard --markdown --hg
Generating /home/postmodern/my_project
create lib
create lib/my_project
create spec
create .hgignore
create .document
create .yardopts
create Gemfile
create .rspec
create spec/my_project_spec.rb
create spec/spec_helper.rb
create my_project.gemspec
create ChangeLog.md
create LICENSE.txt
create README.md
create Rakefile
create lib/my_project/version.rb
create lib/my_project.rb
run hg init from "."
run hg add . from "."
run hg commit -m "Initial commit." from "."
$ cd my_project && bundle install
$ rake spec
/home/postmodern/.rvm/rubies/ruby-1.9.3-p194/bin/ruby -S rspec ./spec/my_project_spec.rb
MyProject
should have a VERSION constant
Finished in 0.00593 seconds
1 example, 0 failures
Think Outside of the Bundle
Now that you have been introduced to Ore, I hope you will at the very least give it a try. I also hope you will understand that I am not simply anti-Bundler / pro-Ore. Ore gives you the option of generating Ruby projects with/without Bundler. The two tools are not mutually exclusive.