tj / commander

The complete solution for Ruby command-line executables
http://visionmedia.github.com/commander
MIT License
1.09k stars 64 forks source link

Non-zero exit code on invalid command #56

Closed parkr closed 11 years ago

parkr commented 11 years ago

Heyo. We use Commander for mojombo/jekyll and it turns out the InvalidCommandException, rescued and aborted again returns an exit code of 0, when it shouldn't.

Expected:

~/code/jekyll$ bin/jekyll buiild
invalid command. Use --help for more information
~/code/jekyll$ echo $?
1

Erroneous, current behaviour:

~/code/jekyll$ bin/jekyll buiild
invalid command. Use --help for more information
~/code/jekyll$ echo $?
0

Ref: https://github.com/mojombo/jekyll/issues/1110

ggilder commented 11 years ago

Hmm, I'm not sure the problem is with commander. If I run the sample program created with commander init, the exit code is 1 for invalid commands...

ggilder commented 11 years ago

I figured out the cause of the issue — specifying a default_command causes invalid commands to exit with status 0. I'll see if I can track down the bug.

ggilder commented 11 years ago

I looked into the issue a little further and I don't think a fix is actually possible without breaking existing functionality. For instance, let's say you have a commander script with a default command that takes arguments. Currently this works fine. If we wanted to recognize invalid commands as suggested in this issue, we would have to remove the ability for the default command to take arguments, because there's no way to differentiate between an invalid command and a string intended to be an argument for the default command.

Currently I think the best solution is to not specify a default command if you want the exit code to reflect invalid commands. Especially in Jekyll's case where the default command is "help"... the invalid command message prompts you to read the help, so I don't think it's adding much value.

parkr commented 11 years ago

Great, thanks very much for the follow-up. Is there any way we can do command :"" (empty)? That would solve our issue while still preserving our existing functionality. :)

ggilder commented 11 years ago

Unfortunately there's no way to do an empty command. However, you could do something like this:

default_command :default
command :default do |c|
  c.action do |args, options|
    if args.empty?
      command(:help).run
    else
      abort "Invalid command. Use --help for more information"
    end
  end
end

Basically creating a default command that prints the standard help if there are no other arguments, and aborts with an invalid command message if there are arguments.

Hope that helps!