Support the new option types in build-bash-completion
authorIustin Pop <iustin@google.com>
Fri, 5 Oct 2012 19:34:10 +0000 (21:34 +0200)
committerIustin Pop <iustin@google.com>
Mon, 8 Oct 2012 11:01:36 +0000 (13:01 +0200)
Beside parsing the arguments as well, we also change the serialisation
format for choices/suggests, to make the Python code simpler.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>

autotools/build-bash-completion
htools/Ganeti/Common.hs

index c0295cc..816652c 100755 (executable)
@@ -655,13 +655,54 @@ def HaskellOptToOptParse(opts, kind):
   elif kind == "manyinstances":
     # FIXME: no support for many instances
     return cli.cli_option(*opts, type="string")
-  elif kind.startswith("choices "):
-    choices = kind[len("choices "):].split(",")
+  elif kind.startswith("choices="):
+    choices = kind[len("choices="):].split(",")
     return cli.cli_option(*opts, type="choice", choices=choices)
   else:
     # FIXME: there are many other currently unused completion types,
     # should be added on an as-needed basis
-    raise Exception("Unhnadled option kind '%s'" % kind)
+    raise Exception("Unhandled option kind '%s'" % kind)
+
+
+#: serialised kind to arg type
+_ARG_MAP = {
+  "command": cli.ArgCommand,
+  "file": cli.ArgFile,
+  "host": cli.ArgHost,
+  "jobid": cli.ArgJobId,
+  "onegroup": cli.ArgGroup,
+  "oneinstance": cli.ArgInstance,
+  "onenode": cli.ArgNode,
+  "oneos": cli.ArgOs,
+  "string": cli.ArgUnknown,
+  }
+
+
+def HaskellArgToCliArg(kind, min_cnt, max_cnt):
+  """Converts a Haskell options to Python _Argument.
+
+  @type kind: string
+  @param kind: type generated by Common.hs/argComplToText; needs to be
+      kept in sync
+
+  """
+  min_cnt = int(min_cnt)
+  if max_cnt == "none":
+    max_cnt = None
+  else:
+    max_cnt = int(max_cnt)
+  # pylint: disable=W0142
+  # since we pass **kwargs
+  kwargs = {"min": min_cnt, "max": max_cnt}
+
+  if kind.startswith("choices=") or kind.startswith("suggest="):
+    (kind, choices) = kind.split("=", 1)
+    kwargs["choices"] = choices.split(",")
+
+  if kind not in _ARG_MAP:
+    raise Exception("Unhandled argument kind '%s'" % kind)
+  else:
+    return _ARG_MAP[kind](**kwargs)
 
 
 def WriteHaskellCompletion(sw, script, htools=True, debug=True):
@@ -684,14 +725,24 @@ def WriteHaskellCompletion(sw, script, htools=True, debug=True):
     func_name = script
   output = utils.RunCmd([cmd, "--help-completion"], env=env, cwd=".").output
   cli_opts = []
+  args = []
   for line in output.splitlines():
-    v = line.split(None, 1)
-    if len(v) != 2:
-      raise Exception("Invalid help completion output from %s: %s" %
-                      (script, v))
-    (opts, kind) = v
-    cli_opts.append(HaskellOptToOptParse(opts, kind))
-  WriteCompletion(sw, script_name, func_name, debug, opts=cli_opts, args=[])
+    v = line.split(None)
+    exc = lambda msg: Exception("Invalid %s output from %s: %s" %
+                                (msg, script, v))
+    if len(v) < 2:
+      raise exc("help completion")
+    if v[0].startswith("-"):
+      if len(v) != 2:
+        raise exc("option format")
+      (opts, kind) = v
+      cli_opts.append(HaskellOptToOptParse(opts, kind))
+    else:
+      if len(v) != 3:
+        raise exc("argument format")
+      (kind, min_cnt, max_cnt) = v
+      args.append(HaskellArgToCliArg(kind, min_cnt, max_cnt))
+  WriteCompletion(sw, script_name, func_name, debug, opts=cli_opts, args=args)
 
 
 def main():
index e7e7a1e..1485a91 100644 (file)
@@ -91,8 +91,8 @@ optComplYesNo = OptComplChoices ["yes", "no"]
 
 -- | Text serialisation for 'OptCompletion', used on the Python side.
 complToText :: OptCompletion -> String
-complToText (OptComplChoices choices) = "choices " ++ intercalate "," choices
-complToText (OptComplSuggest choices) = "suggest " ++ intercalate "," choices
+complToText (OptComplChoices choices) = "choices=" ++ intercalate "," choices
+complToText (OptComplSuggest choices) = "suggest=" ++ intercalate "," choices
 complToText compl =
   let show_compl = show compl
       stripped = stripPrefix "OptCompl" show_compl