Ideal Ruby project structure
I think that is pretty much spot on. By default, Rubygems will add the lib directory to the loadpath, but you can push any directory you want onto that using the $: variable. i.e.
$:.push File.expand_path(File.dirname(__FILE__) + '/../surfcompstuff')
That means when you have say, surfer.rb
in that dir, you can require "surfer"
anywhere and the file will be found.
Also, as a convention, classes and singletons get a file and modules get a directory. For instance, if you had the LolCatz
module and the LolCatz::Moar
class that would look like:
lib/
appname.rb
lolcatz/
moar.rb
That is why there is an lib/appname folder because most libraries are in the appname
namespace.
Additionally, if you try running the command newgem --simple [projectname]
that'll quickly generate a scaffold for you with just the bare essentials for a Ruby project (and by extension a Ruby Gem). There are other tools which do this, I know, but newgem is pretty common. I usually get rid of the TODO file and all the script stuff.
What's the standard file structure of a Ruby project?
There isn't necessarily any set way to define a Ruby project. But, generally RubyGems have this file structure:
.
├── bin
│ └── mygem
├── Gemfile
├── lib
│ ├── mygem
│ │ └── version.rb
│ └── mygem.rb
├── LICENSE
├── mygem.gemspec
├── Rakefile
└── README.md
Of course, there is also other directories and files in the project root, for tests, .ruby-version
, etc.
Directory layout for pure Ruby project
Bundler includes the necessary infrastructure to generate a gem:
$ bundle gem --coc --mit --test=minitest --exe spider
Creating gem 'spider'...
MIT License enabled in config
Code of conduct enabled in config
create spider/Gemfile
create spider/lib/spider.rb
create spider/lib/spider/version.rb
create spider/spider.gemspec
create spider/Rakefile
create spider/README.md
create spider/bin/console
create spider/bin/setup
create spider/.gitignore
create spider/.travis.yml
create spider/test/test_helper.rb
create spider/test/spider_test.rb
create spider/LICENSE.txt
create spider/CODE_OF_CONDUCT.md
create spider/exe/spider
Initializing git repo in /Users/francois/Projects/spider
Gem 'spider' was successfully created. For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html
Then, in lib/, you create modules as needed:
lib/
spider/
base.rb
crawler/
base.rb
spider.rb
require "spider/base"
require "crawler/base"
Read the manual page for bundle gem for details on the --coc
, --exe
and --mit
options.
What's the preferred directory structure of a non-Rails project with RSpec?
Build your project like a gem
, as that's where you'll probably end up.
Your code goes in the lib
directory.
my_first_project/
├── bin/
│ └── runme.rb
├── lib/
│ ├── my_first_project/
│ │ ├── user.rb
│ │ ├── widget.rb
│ │ └── ...
│ └── my_first_project.rb
├── spec/
│ └── spec_helper.rb
├── .rspec
└── my_first_project.gemspec
How do I set up a basic Ruby project?
To get a good start, you can use the bundle gem
command and rspec --init
.
~/code $ bundle gem my_lib
create my_lib/Gemfile
create my_lib/Rakefile
create my_lib/LICENSE.txt
create my_lib/README.md
create my_lib/.gitignore
create my_lib/my_lib.gemspec
create my_lib/lib/my_lib.rb
create my_lib/lib/my_lib/version.rb
Initializating git repo in /Users/john/code/my_lib
~/code $ cd my_lib/
~/code/my_lib $ git commit -m "Empty project"
~/code/my_lib $ rspec --init
The --configure option no longer needs any arguments, so true was ignored.
create spec/spec_helper.rb
create .rspec
- code goes in
lib
- specs go in
spec
- test data or documents go in
spec/fixtures/
- Require all your ruby files in
lib/my_lib.rb
. You can define your exceptions in that file, too, or in their own files -- according to your own preference. - C source files go in
ext/my_lib
- shell scripts and executables go in
bin
When in doubt, just look at how other gems are laid out.
Further information:
You should add rspec as a development dependency in your gemspec to make things easier for other developers
- Edit my_lib.gemspec, adding
gem.add_development_dependency 'rspec'
andgem.add_development_dependency 'rake'
near the bottom. - Add
Bundler.setup
andrequire 'my_lib'
to the top of spec/spec_helper.rb to ensure your gem dependencies are loaded when you run your specs. - Add
require "rspec/core/rake_task"
andtask :default => :spec
to your Rakefile, so that runningrake
will run your specs.
While you're working on your newest creation, guard-rspec can save you time and hassle by automatically running your specs as files change, alerting you to spec failures.
~/code/my_lib $ git add spec/spec_helper.rb
~/code/my_lib $ git commit -am "Add RSpec"
~/code/my_lib $ vim my_lib.gemspec # add guard development dependency
~/code/my_lib $ bundle
~/code/my_lib $ bundle exec guard init
~/code/my_lib $ vim Guardfile # Remove the sections below the top one
~/code/my_lib $ git add Guardfile
~/code/my_lib $ git commit -am "Add Guard"
After you're happy with your creation, push it up to github
# create a github repository for your gem, then push it up
~/code/my_lib $ curl -u myusername https://api.github.com/user/repos -d '{"name":"my_lib"}'
~/code/my_lib $ git remote add origin git@github.com:myusername/my_lib.git
~/code/my_lib $ git push
Then, when you're ready to release your gem on Rubygems.org, run rake release
, which will walk you through the steps.
~/code/my_lib $ rake release
Further References
- The Rubygems patterns guide (and home page), from Matheus Moreira's answer. They're really great references
- How I Start by Steve Klabnik
- Exercise 46: A Project Skeleton from Zed Shaw's Learn Ruby The Hard Way
- New Gem with Bundler video on Railscasts
- docs
Ruby and Cucumber Project Structure
You can easily set up cucumber for use with rails by using the cucumber-rails gem https://github.com/cucumber/cucumber-rails
Then in your Gemfile add
group :test do
gem 'cucumber-rails', :require => false
end
Next you'll want to
bundle install
And then use the generator to set up cucumber in your rails app
rails generate cucumber:install
This will set up your cucumber code under the features
directory in your app.
Then you can run your cucumber using
./script/cucumber
Related Topics
What Does a ||= Mean in Ruby Language
Rails Attachments Inline Are Not Shown Correctly in Gmail
Is There a 'Variable_Get' Method? If Not, How to Create My Own
Is Order of a Ruby Hash Literal Guaranteed
In Ruby, Why Does Nil[1]=1 Evaluate to Nil
How to Group by Day Instead of Date
In Ruby Why Won't 'Foo = True Unless Defined(Foo)' Make the Assignment
Uninstall All Installed Gems, in Osx
How Do Rvm and Rbenv Actually Work
How to Find a Hash Key Containing a Matching Value
Ruby Dependency Injection Libraries
How to Parse a CSV File, Update a Field, Then Save
Correct Way to Populate an Array with a Range in Ruby
Gem Install Fails with Openssl Failure
How Would You Parse a Url in Ruby to Get the Main Domain
How to Prompt for a Sudo Password Using Ruby
Can You Ask Ruby to Treat Warnings as Errors
How to Understand the Difference Between Class_Eval() and Instance_Eval()