Creating a gem structure for command line program

I’ve written a command line program. Would like to distribute it as a
gem.
I’ve run jeweler and generated a structure.

However, I am not sure how to go about it. My project consists of one
main file (lets call it main.rb), it include a couple other files. The
main file is executable, so when installed should go into the path (e.g.
/opt/local/bin).

Should my main file go into “lib” or “bin”?

Looking at jeweler itself, i see a file installed in
/opt/local/bin/jeweler that loads jeweler, it says its been generated by
rubygems. How is this done?

I presume the support files should go into lib/.

Also, currently I do the argument parsing (optparse) in a if FILE =
$0 block in the main file. Will this have to be moved to a method in the
class of the main file. Or will this have to be moved to a file in bin
folder?

thx for help.

On 2010-06-11 00:15:24 -0700, R… Kumar said:

thx for help.

Put your executable in bin/ and any supporting code in lib/

Rubygems will take care of distributing your executable in the way you
mentioned, you don’t have to do anything except add it to the gemspec.

Rein H. wrote:

On 2010-06-11 00:15:24 -0700, R… Kumar said:

thx for help.

Put your executable in bin/ and any supporting code in lib/

Rubygems will take care of distributing your executable in the way you
mentioned, you don’t have to do anything except add it to the gemspec.

Thanks. I was looking at some other gems such as cheat and maruku, and I
was going to model my command line progs on maruku.

Last question, what about the lib/.rb file. Usually it just
contains some “require” statements. In my case, the file in bin
(.rb) already contains the includes. Do i keep an empty file,
or just put the includes in there anyway.

Thanks again for the immed response.

On Jun 11, 3:55 am, “R… Kumar” [email protected] wrote:

Thanks. I was looking at some other gems such as cheat and maruku, and I
was going to model my command line progs on maruku.

Last question, what about the lib/.rb file. Usually it just
contains some “require” statements. In my case, the file in bin
(.rb) already contains the includes. Do i keep an empty file,
or just put the includes in there anyway.

Thanks again for the immed response.

First, there’s two overarching ways to go about this:

  1. put exe code in a bin/ file
  2. only put bootstrap code in bin/ to an lib/ file.

Either way is fine. I tend to use #2 because it has some small
advantages --all code is in one place, relative requires are safe
within lib//. To give you an example, a bin/foo might look like:

#!/usr/bin/env ruby
require ‘foo/main.rb’
Foo.main(*ARGV)

And that’s all. Then in lib/foo/main.rb you would define a Foo.main
method to handle command-line invocation.

And remember the advantages of encapsulation. Maruku’s executables
lack this, so they cannot be reused, inherited, unit tested, etc.

Thomas S. wrote:

First, there’s two overarching ways to go about this:

  1. put exe code in a bin/ file
  2. only put bootstrap code in bin/ to an lib/ file.

Either way is fine. I tend to use #2 because it has some small
advantages --all code is in one place, relative requires are safe
within lib//. To give you an example, a bin/foo might look like:

#!/usr/bin/env ruby
require ‘foo/main.rb’
Foo.main(*ARGV)

And that’s all. Then in lib/foo/main.rb you would define a Foo.main
method to handle command-line invocation.

And remember the advantages of encapsulation. Maruku’s executables
lack this, so they cannot be reused, inherited, unit tested, etc.

This (#2) is roughly how the “cheat” gem does it. I think it will take
me a few minutes to change it. Thanks a lot.

R… Kumar wrote:

Thomas S. wrote:

First, there’s two overarching ways to go about this:

  1. put exe code in a bin/ file
  2. only put bootstrap code in bin/ to an lib/ file.

Either way is fine. I tend to use #2 because it has some small
advantages --all code is in one place, relative requires are safe
within lib//. To give you an example, a bin/foo might look like:

#!/usr/bin/env ruby
require ‘foo/main.rb’
Foo.main(*ARGV)

And that’s all. Then in lib/foo/main.rb you would define a Foo.main
method to handle command-line invocation.

And remember the advantages of encapsulation. Maruku’s executables
lack this, so they cannot be reused, inherited, unit tested, etc.

This (#2) is roughly how the “cheat” gem does it. I think it will take
me a few minutes to change it. Thanks a lot.

Are there any naming conventions here that have to be followed.

Assume project and gem is named foo.

  1. bin/foo - does foo have to be the project/gem name

  2. lib/foo/main.rb - does main.rb have to be foo.rb
    Why i ask is because, typically main.rb would contain
    a class named “Foo”.

  3. lib/foo.rb - currently I’ve got an empty file.

Caleb C. wrote:

If you have a file named lib/foo/main.rb, it should contain a class
named Foo::Main. I take it you have no such class, so you shouldn’t
make a file of that name.

Ahh. Thanks for clarifying. Actually, the support files I have are not
part of module Foo. They are common to various scripts/apps. (I had
actually raised this question in a topic a few days back).

So perhaps I should put those files in lib/common or some such folder,
but not lib/foo.

The class named Foo should reside in your lib/foo.rb.

  1. lib/foo.rb - currently I’ve got an empty file.

Typically, this file would require everything (or many things) in
lib/foo/, as well as the implementation of class/module Foo itself.

Thanks for clarifying this. Now I am clear.

On 6/11/10, R… Kumar [email protected] wrote:

Are there any naming conventions here that have to be followed.

Have to be followed? No. Your gem will still work if you don’t follow
the convention. Should be followed? Yes. People expect your code to
adhere to the standard method of organization that has evolved; it
helps them navigate your project even if they don’t know your code.
Also, these conventions represent collective wisdom about how projects
should be organized.

Assume project and gem is named foo.

  1. bin/foo - does foo have to be the project/gem name

Should be.

  1. lib/foo/main.rb - does main.rb have to be foo.rb
    Why i ask is because, typically main.rb would contain
    a class named “Foo”.

If you have a file named lib/foo/main.rb, it should contain a class
named Foo::Main. I take it you have no such class, so you shouldn’t
make a file of that name.

The class named Foo should reside in your lib/foo.rb.

  1. lib/foo.rb - currently I’ve got an empty file.

Typically, this file would require everything (or many things) in
lib/foo/, as well as the implementation of class/module Foo itself.