Commits

Larry Hastings  committed 468b885

Improved usage further.

  • Participants
  • Parent commits 551473b

Comments (0)

Files changed (1)

             self.value_usage = option_value_usage_formatter(self.type.__name__)
 
 
+class OptionError(RuntimeError):
+    pass
+
 @all
 class DryCommand:
 
                 if a.startswith('--'):
                     option = a[2:]
                     if option not in self.options:
-                        return self.usage(error="Unknown option " + a)
+                        raise OptionError('Unknown option "' + a + '".')
                     handle_option(option, value)
                 else:
                     single_letters = []
                     for c in a[1:]:
                         if c not in self.options:
-                            return self.usage(error="Unknown option -" + c)
+                            raise OptionError('Unknown option "' + a + '".')
                         arg, is_bool = analyze_option(c)
                         single_letters.append([c, unspecified])
                         if not is_bool:
 
         assert not (argv and error)
         if error:
-            print("Error:", error)
-            print()
+            print(error)
         if argv:
             command = argv[0]
             if command not in self.commands:
         have_options = any(command.has_options for command in self.commands.values())
         have_arguments = any(command.has_arguments for command in self.commands.values())
 
-        if self.doc:
-            print(self.doc)
-            print()
         a = ["Usage:", sys.argv[0]]
         add = a.append
         if have_global_options:
             if have_arguments:
                 add("[arguments ...]")
         print(' '.join(a))
-        print()
-
-        if have_commands:
-            self.print_commands()
+        if self.commands:
+            print('Try "' + sys.argv[0] + ' help" for a list of commands.')
 
         return '\n'.join(output)
 
     def print_commands(self):
+        if not self.commands:
+            return
         print("Supported commands:")
         commands = sorted(self.commands)
         longest = len('help')
             print(" ", name.ljust(longest), "", first_line)
 
     def help(self, command=''):
-        if command:
-            return self.commands[command]._usage(global_handler=self.global_handler)
+        if command and (command != 'help'):
+            if command in self.commands:
+                return self.commands[command]._usage(global_handler=self.global_handler)
+            print('Unknown command "' + command + '".')
+            print()
         self.print_commands()
         print()
-        print("Use 'help command' for help on a specific command.")
+        print('Use "' + sys.argv[0] + ' help command" for help on a specific command.')
 
     def main(self, argv=None):
         return_value = None
 
         if self.global_handler:
             have_commands = bool(self.commands)
-            return_value = self.global_handler(argv, return_arguments=have_commands)
             if have_commands:
-                argv = return_value
+                global_argv = []
+                while argv and argv[0].startswith('-'):
+                    global_argv.append(argv.pop(0))
             else:
-                return return_value
+                global_argv = argv
+
+            if global_argv:
+                try:
+                    return_value = self.global_handler(global_argv, return_arguments=have_commands)
+                except OptionError as e:
+                    # try to find the command
+                    command = None
+                    for s in argv:
+                        if s.startswith('-'):
+                            continue
+                        command = self.commands.get(s, None)
+                        break
+
+                    if command:
+                        return command.usage(error=str(e))
+                    return self.usage(error=str(e))
+
+                if have_commands:
+                    argv = return_value
+                else:
+                    return return_value
 
         if not self.commands:
             return return_value
 
         if not argv:
-            return self.usage(error="no command specified")
+            return self.usage(error="No command specified.")
 
-        command = argv.pop(0)
-
-        if command not in self.commands:
-            if command == "help":
+        command_str = argv.pop(0)
+        command = self.commands.get(command_str, None)
+        if not command:
+            if command_str == "help":
                 return self.usage(argv=argv)
-            return self.usage(error="command " + repr(command) + " not recognized")
-        return self.commands[command](argv)
+            return self.usage(error="Command " + repr(command_str) + " not recognized.")
+        try:
+            return command(argv)
+        except OptionError as e:
+            return command.usage(error=str(e))
 
 
 class UnitTests(unittest.TestCase):