help: help make help great again!

This adds a whole bunch of help docstrings to the various commands that get run.

Change-Id: Ifa4321eb64624d77d63ac7982e14ed871374132a
diff --git a/mdt/config.py b/mdt/config.py
index e7275c9..bc4b6b9 100644
--- a/mdt/config.py
+++ b/mdt/config.py
@@ -59,26 +59,71 @@
         self.setAttribute("ssh-command", command)
 
 
-class Get:
+class GetCommand:
+    '''Usage: mdt get [<variablename>]
+
+Returns the value currently set for a given variable name. Some useful
+variables are:
+
+    preferred-device    - set this to your preferred device name to default
+                          most commands to manipulating this specific device.
+    username            - set this to the username that should be used to
+                          connect to a device with. Defaults to 'mendel'.
+    password            - set this to the password to use to login to a new
+                          device with. Defaults to 'mendel'. Only used
+                          during the initial setup phase of pushing an SSH
+                          key to the board.
+
+If no variable name is provided, 'mdt get' will print out the list of all
+known stored variables and their values. Note: default values are not printed.
+'''
+
     def __init__(self):
         self.config = Config()
 
     def run(self, args):
-        if args:
+        if len(args) == 0:
+            pass
+        elif len(args) == 1:
             print("{0}: {1}".format(args[1], self.config.getAttribute(args[1])))
+        else:
+            print("Usage: mdt get [<variablename>]")
 
 
-class Set:
+class SetCommand:
+    '''Usage: mdt set <variablename> <value>
+
+Sets the value for a given variable name. Some useful variables are:
+
+    preferred-device    - set this to your preferred device name to default
+                          most commands to manipulating this specific device.
+    username            - set this to the username that should be used to
+                          connect to a device with. Defaults to 'mendel'.
+    password            - set this to the password to use to login to a new
+                          device with. Defaults to 'mendel'. Only used
+                          during the initial setup phase of pushing an SSH
+                          key to the board.
+
+Note that setting a variable to the empty string does not clear it back to
+the default value! Use 'mdt clear' for that.
+'''
     def __init__(self):
         self.config = Config()
 
     def run(self, args):
-        if args:
-            self.config.setAttribute(args[1], args[2])
-            print("Set {0} to {1}".format(args[1], args[2]))
+        if len(args) != 2:
+            print("Usage: mdt set <variablename> <value>")
+
+        self.config.setAttribute(args[1], args[2])
+        print("Set {0} to {1}".format(args[1], args[2]))
 
 
-class Clear:
+class ClearCommand:
+    '''Usage: mdt clear <variablename>
+
+Clears the value for a given variable name, resetting it back to its
+default value.
+'''
     def __init__(self):
         self.config = Config()
 
diff --git a/mdt/devices.py b/mdt/devices.py
index 89e3adf..a5e5a7a 100644
--- a/mdt/devices.py
+++ b/mdt/devices.py
@@ -5,6 +5,18 @@
 
 
 class DevicesCommand:
+    '''Usage: mdt devices
+
+Returns a list of device names and IP addresses found on the local network
+segment. Also indicates if a given device is marked as your default.
+
+Variables used:
+   preferred-device: contains the device name you want as your default
+
+Note: MDT uses a python implementation of mDNS ZeroConf for discovery, so
+it does not require a running Avahi daemon.
+'''
+
     def __init__(self):
         self.discoverer = Discoverer()
         self.device = Config().preferredDevice()
@@ -21,6 +33,19 @@
 
 
 class DevicesWaitCommand:
+    '''Usage: mdt wait-for-device
+
+Waits for either the first device found, or your preferred device to be
+discovered on the local network segment.
+
+Variables used:
+   preferred-device: contains the device name you want as your default
+
+Note: if preferred-device is cleared, then this will return on the first
+available device found. Also, MDT uses a python implementation of mDNS
+ZeroConf for discovery, so it does not require a running Avahi daemon.
+'''
+
     def __init__(self):
         self.found_devices = False
         self.discoverer = Discoverer(self)
diff --git a/mdt/keys.py b/mdt/keys.py
index 67619dd..011981d 100644
--- a/mdt/keys.py
+++ b/mdt/keys.py
@@ -51,7 +51,15 @@
         return self.pkey
 
 
-class GenKey:
+class GenKeyCommand:
+    '''Usage: mdt genkey
+
+Generates an SSH key and stores it to disk.
+
+Note that this does not prompt if you want to replace an already existing
+key and will happily overwrite without telling you!
+'''
+
     def run(self, args):
         if os.path.exists(KEYFILE_PATH):
             os.unlink(KEYFILE_PATH)
diff --git a/mdt/main.py b/mdt/main.py
index 53904bf..ea91184 100755
--- a/mdt/main.py
+++ b/mdt/main.py
@@ -16,6 +16,12 @@
 
 
 class HelpCommand:
+    '''Usage: mdt help [<subcommand>]
+
+Gets additional information about a given subcommand, or returns a summary
+of subcommands available.
+'''
+
     def run(self, args):
         if len(args) <= 1:
             print('Usage: mdt <subcommand> [<options>]')
@@ -34,7 +40,7 @@
             print()
             return 1
 
-        subcommand = args[1]
+        subcommand = args[1].lower()
         command = COMMANDS[subcommand]
         if command.__doc__:
             print(command.__doc__)
@@ -47,11 +53,11 @@
     'help': HelpCommand(),
     'devices': devices.DevicesCommand(),
     'wait-for-device': devices.DevicesWaitCommand(),
-    'get': config.Get(),
-    'set': config.Set(),
-    'clear': config.Clear(),
-    'genkey': keys.GenKey(),
-    'shell': shell.Shell(),
+    'get': config.GetCommand(),
+    'set': config.SetCommand(),
+    'clear': config.ClearCommand(),
+    'genkey': keys.GenKeyCommand(),
+    'shell': shell.ShellCommand(),
 }
 
 
@@ -62,6 +68,9 @@
         else:
             command = sys.argv[1].lower()
 
+        if command == '--help':
+            command = 'help'
+
         if command in COMMANDS:
             command = COMMANDS[command]
             exit(command.run(sys.argv[1:]))
diff --git a/mdt/shell.py b/mdt/shell.py
index b1010be..936f407 100644
--- a/mdt/shell.py
+++ b/mdt/shell.py
@@ -18,6 +18,7 @@
 from mdt import keys
 
 
+
 class KeyPushError(Exception):
     pass
 
@@ -112,7 +113,38 @@
         self.client.close()
 
 
-class Shell:
+class ShellCommand:
+    '''Usage: mdt shell [<devicename>]
+
+Opens an interactive shell to either your preferred device, the given
+devicename, or to the first device found.
+
+Variables used:
+    preferred-device    - set this to your preferred device name to connect
+                          to by default if no <devicename> is provided on the
+                          command line.
+    username            - set this to the username that should be used to
+                          connect to a device with. Defaults to 'mendel'.
+    password            - set this to the password to use to login to a new
+                          device with. Defaults to 'mendel'. Only used
+                          during the initial setup phase of pushing an SSH
+                          key to the board.
+
+If no SSH key is available on disk (ie: you didn't run genkey before running
+shell), this will implicitly run genkey for you. Additionally, shell will
+attempt to connect to a device by doing the following:
+
+  1. Attempt a connection using your SSH key only, with no password.
+  2. If the connection attempt failed due to authentication, will
+     attempt to push the key to the device by using the default
+     login credentials in the 'username' and 'password' variables.
+  3. Installs your SSH key to the device after logging in.
+  4. Disconnects and reconnects using the SSH key.
+
+Note: this will not return the exit code of the shell executed on the device.
+If you need automation, use 'mdt run' instead.
+'''
+
     def __init__(self):
         self.config = config.Config()
         self.discoverer = discoverer.Discoverer(self)