4

I'm writing a ruby gem that users can install and use the command line ruby tool to interact with the service. You can start and stop the service (it will spawn off a child process).

I've done a lot of research into the best things to use to write a network service, such as ØMQ/EventMachine and I get how to create a Ruby gem that will install a binary you can use in the command line, but I'm struggling to set out a good code structure.

My command line utility will take various arguments (I'll use Trollop) and the it will use various classes to do things, and use various other ruby gems.

I'm not sure where I should put my class files, and how to require them in my binary so the paths are correct.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
tarnfeld
  • 25,992
  • 41
  • 111
  • 146

3 Answers3

9

Largely, RubyGems will take care of this for you. You'll need to include your executable in the files list, and put it in the executables in your gemspec. It's common to put your executable in bin in your directory, e.g.:

$ ls
bin/   myapp.gemspec  lib/    Rakefile
$ ls bin
bin/myapp

Your gemspec would then look like:

Gem::Specification.new do |s|
  s.name = 'myapp'

  # whatever else is in your gemspec

  s.files = ["bin/myapp","lib/myapp.rb"]  # or whatever other files you want
  s.executables = ["bin/todo"] 
end

At this point, when users install your app via RubyGems, myapp will be in their path, and lib will be in your app's loadpath, so your executable can simply start off with:

#!/usr/bin/env ruby

require 'myapp'
# whatever other requires

The only issue with this is that, during development, you cannot just do bin/myapp and have your app run. Some devs manipulate the load path via $: or $LOAD_PATH, but this is considered bad form.

If you are using bundler, it's easiest to just run your app locally with bundle exec, e.g. bundle exec bin/myapp. You can alternately use the RUBYLIB environment variable, e.g. RUBYLIB=lib bin/myapp, which will put lib in the load path.

davetron5000
  • 24,123
  • 11
  • 70
  • 98
4

You can generate a gem project structure with Bundler.

Briefly:

Install Bundler

$ gem install bundler

Use Bundler to generate the gem project

$ bundle gem myapp
$ cd myapp

Add an executable

$ mkdir bin
$ cat > bin/mycommand << EOSCRIPT
  #!/usr/bin/env ruby

  require 'myapp'

  puts "Executing myapp"
  EOSCRIPT
$ chmod +x bin/mycommand

Install your Gem

$ rake install

Run your script

$ mycommand
Executing mycommand

Share your utility on rubygems.org

$ rake release

More docs on the website

Daniel
  • 10,115
  • 3
  • 44
  • 62
0

Since all gems are open source by nature, you could always have a look at some of the better ones for examples. Using a gem builder like jeweler or hoe would also set you up with some of the basic structure organizationally speaking.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • 3
    "Source-available" might be a better term. Just because you can see the source code doesn't mean that it's "open source" software in the usual sense. – Andrew Marshall Mar 09 '12 at 21:31
  • Thanks, i'll take a look at those! I'm not a ruby developer by day so i'm struggling to get a good footing. – tarnfeld Mar 09 '12 at 21:44
  • I meant more "open source" as in I don't know of any that are deliberately obfuscated. This is where "open source" and "free open source" differ. Still, the vast majority of gems are published with some kind of open-source license. – tadman Mar 10 '12 at 00:07