# Creating a gem structure for command line program

**URL:** <https://www.ruby-forum.com/t/creating-a-gem-structure-for-command-line-program/190004>\
**Category:** Ruby\
**Created:** [June 11, 2010, 9:15am UTC](https://www.ruby-forum.com/t/creating-a-gem-structure-for-command-line-program/190004 "2010-06-11T09:15:21Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![sentinel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/fbc32d/32.png) [@sentinel](https://www.ruby-forum.com/u/sentinel)\
**Post date:** [June 11, 2010, 9:15am UTC](https://www.ruby-forum.com/t/creating-a-gem-structure-for-command-line-program/190004/1 "2010-06-11T09:15:21Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![sentinel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/fbc32d/32.png) [@sentinel](https://www.ruby-forum.com/u/sentinel)\
**Post date:** [June 11, 2010, 9:36am UTC](https://www.ruby-forum.com/t/creating-a-gem-structure-for-command-line-program/190004/2 "2010-06-11T09:36:12Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![sentinel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/fbc32d/32.png) [@sentinel](https://www.ruby-forum.com/u/sentinel)\
**Post date:** [June 11, 2010, 9:55am UTC](https://www.ruby-forum.com/t/creating-a-gem-structure-for-command-line-program/190004/3 "2010-06-11T09:55:03Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![sentinel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/fbc32d/32.png) [@sentinel](https://www.ruby-forum.com/u/sentinel)\
**Post date:** [June 11, 2010, 11:01am UTC](https://www.ruby-forum.com/t/creating-a-gem-structure-for-command-line-program/190004/4 "2010-06-11T11:01:40Z")

</div>

On Jun 11, 3:55 am, “R… Kumar” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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.

---

<div class="post-metadata">

**Author:** ![sentinel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/fbc32d/32.png) [@sentinel](https://www.ruby-forum.com/u/sentinel)\
**Post date:** [June 11, 2010, 11:06am UTC](https://www.ruby-forum.com/t/creating-a-gem-structure-for-command-line-program/190004/5 "2010-06-11T11:06:11Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![sentinel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/fbc32d/32.png) [@sentinel](https://www.ruby-forum.com/u/sentinel)\
**Post date:** [June 11, 2010, 11:10am UTC](https://www.ruby-forum.com/t/creating-a-gem-structure-for-command-line-program/190004/6 "2010-06-11T11:10:57Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![sentinel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/fbc32d/32.png) [@sentinel](https://www.ruby-forum.com/u/sentinel)\
**Post date:** [June 11, 2010, 3:15pm UTC](https://www.ruby-forum.com/t/creating-a-gem-structure-for-command-line-program/190004/7 "2010-06-11T15:15:35Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![sentinel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/fbc32d/32.png) [@sentinel](https://www.ruby-forum.com/u/sentinel)\
**Post date:** [June 11, 2010, 12:48pm UTC](https://www.ruby-forum.com/t/creating-a-gem-structure-for-command-line-program/190004/8 "2010-06-11T12:48:13Z")

</div>

On 6/11/10, R… Kumar [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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.
