Revision 24476fa0

b/autotools/build-bash-completion
722 722
    return _ARG_MAP[kind](**kwargs)
723 723

  
724 724

  
725
def WriteHaskellCompletion(sw, script, htools=True, debug=True):
726
  """Generates completion information for a Haskell program.
727

  
728
  This Converts completion info from a Haskell program into 'fake'
729
  cli_opts and then builds completion for them.
725
def ParseHaskellOptsArgs(script, output):
726
  """Computes list of options/arguments from help-completion output.
730 727

  
731 728
  """
732
  if htools:
733
    cmd = "./htools/htools"
734
    env = {"HTOOLS": script}
735
    script_name = script
736
    func_name = "htools_%s" % script
737
  else:
738
    cmd = "./" + script
739
    env = {}
740
    script_name = os.path.basename(script)
741
    func_name = script_name
742
  func_name = func_name.replace("-", "_")
743
  output = utils.RunCmd([cmd, "--help-completion"], env=env, cwd=".").output
744 729
  cli_opts = []
745
  args = []
730
  cli_args = []
746 731
  for line in output.splitlines():
747 732
    v = line.split(None)
748 733
    exc = lambda msg: Exception("Invalid %s output from %s: %s" %
......
758 743
      if len(v) != 3:
759 744
        raise exc("argument format")
760 745
      (kind, min_cnt, max_cnt) = v
761
      args.append(HaskellArgToCliArg(kind, min_cnt, max_cnt))
762
  WriteCompletion(sw, script_name, func_name, debug, opts=cli_opts, args=args)
746
      cli_args.append(HaskellArgToCliArg(kind, min_cnt, max_cnt))
747
  return (cli_opts, cli_args)
748

  
749

  
750
def WriteHaskellCompletion(sw, script, htools=True, debug=True):
751
  """Generates completion information for a Haskell program.
752

  
753
  This converts completion info from a Haskell program into 'fake'
754
  cli_opts and then builds completion for them.
755

  
756
  """
757
  if htools:
758
    cmd = "./htools/htools"
759
    env = {"HTOOLS": script}
760
    script_name = script
761
    func_name = "htools_%s" % script
762
  else:
763
    cmd = "./" + script
764
    env = {}
765
    script_name = os.path.basename(script)
766
    func_name = script_name
767
  func_name = GetFunctionName(func_name)
768
  output = utils.RunCmd([cmd, "--help-completion"], env=env, cwd=".").output
769
  (opts, args) = ParseHaskellOptsArgs(script_name, output)
770
  WriteCompletion(sw, script_name, func_name, debug, opts=opts, args=args)
771

  
772

  
773
def WriteHaskellCmdCompletion(sw, script, debug=True):
774
  """Generates completion information for a Haskell multi-command program.
775

  
776
  This gathers the list of commands from a Haskell program and
777
  computes the list of commands available, then builds the sub-command
778
  list of options/arguments for each command, using that for building
779
  a unified help output.
780

  
781
  """
782
  cmd = "./" + script
783
  script_name = os.path.basename(script)
784
  func_name = script_name
785
  func_name = GetFunctionName(func_name)
786
  output = utils.RunCmd([cmd, "--help-completion"], cwd=".").output
787
  commands = {}
788
  lines = output.splitlines()
789
  if len(lines) != 1:
790
    raise Exception("Invalid lines in multi-command mode: %s" % str(lines))
791
  v = lines[0].split(None)
792
  exc = lambda msg: Exception("Invalid %s output from %s: %s" %
793
                              (msg, script, v))
794
  if len(v) != 3:
795
    raise exc("help completion in multi-command mode")
796
  if not v[0].startswith("choices="):
797
    raise exc("invalid format in multi-command mode '%s'" % v[0])
798
  for subcmd in v[0][len("choices="):].split(","):
799
    output = utils.RunCmd([cmd, subcmd, "--help-completion"], cwd=".").output
800
    (opts, args) = ParseHaskellOptsArgs(script, output)
801
    commands[subcmd] = (None, args, opts, None, None)
802
  WriteCompletion(sw, script_name, func_name, debug, commands=commands)
763 803

  
764 804

  
765 805
def main():
......
772 812
  if args:
773 813
    parser.error("Wrong number of arguments")
774 814

  
815
  # Whether to build debug version of completion script
816
  debug = not options.compact
817

  
775 818
  buf = StringIO()
776
  sw = utils.ShellWriter(buf, indent=not options.compact)
819
  sw = utils.ShellWriter(buf, indent=debug)
777 820

  
778 821
  # Remember original state of extglob and enable it (required for pattern
779 822
  # matching; must be enabled while parsing script)
780 823
  sw.Write("gnt_shopt_extglob=$(shopt -p extglob || :)")
781 824
  sw.Write("shopt -s extglob")
782 825

  
783
  WritePreamble(sw, not options.compact)
826
  WritePreamble(sw, debug)
784 827

  
785 828
  # gnt-* scripts
786 829
  for scriptname in _autoconf.GNT_SCRIPTS:
787 830
    filename = "scripts/%s" % scriptname
788 831

  
789
    WriteCompletion(sw, scriptname, GetFunctionName(scriptname),
790
                    not options.compact,
832
    WriteCompletion(sw, scriptname, GetFunctionName(scriptname), debug,
791 833
                    commands=GetCommands(filename,
792 834
                                         build.LoadModule(filename)))
793 835

  
794 836
  # Burnin script
795 837
  burnin = build.LoadModule("tools/burnin")
796 838
  WriteCompletion(sw, "%s/burnin" % pathutils.TOOLSDIR, "_ganeti_burnin",
797
                  not options.compact,
839
                  debug,
798 840
                  opts=burnin.OPTIONS, args=burnin.ARGUMENTS)
799 841

  
800 842
  # ganeti-cleaner
......
804 846
  # htools, if enabled
805 847
  if _autoconf.HTOOLS:
806 848
    for script in _autoconf.HTOOLS_PROGS:
807
      WriteHaskellCompletion(sw, script, htools=True,
808
                             debug=not options.compact)
849
      WriteHaskellCompletion(sw, script, htools=True, debug=debug)
809 850

  
810 851
  # ganeti-confd, if enabled
811 852
  if _autoconf.ENABLE_CONFD:
812 853
    WriteHaskellCompletion(sw, "htools/ganeti-confd", htools=False,
813
                           debug=not options.compact)
854
                           debug=debug)
814 855

  
815 856
  # Reset extglob to original value
816 857
  sw.Write("[[ -n \"$gnt_shopt_extglob\" ]] && $gnt_shopt_extglob")

Also available in: Unified diff