Advertisement
Guest User

Untitled

a guest
Dec 10th, 2015
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.79 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. # Copyright (C) 2014 Canonical
  3. #
  4. # Authors:
  5. # Didier Roche
  6. #
  7. # This program is free software; you can redistribute it and/or modify it under
  8. # the terms of the GNU General Public License as published by the Free Software
  9. # Foundation; version 3.
  10. #
  11. # This program is distributed in the hope that it will be useful, but WITHOUT
  12. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  13. # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  14. # details.
  15. #
  16. # You should have received a copy of the GNU General Public License along with
  17. # this program; if not, write to the Free Software Foundation, Inc.,
  18. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19.  
  20. """Module for loading the command line interface"""
  21.  
  22. import argcomplete
  23. from contextlib import suppress
  24. import logging
  25. import os
  26. from progressbar import ProgressBar, BouncingBar
  27. import readline
  28. import sys
  29. from umake.interactions import InputText, TextWithChoices, LicenseAgreement, DisplayMessage, UnknownProgress
  30. from umake.ui import UI
  31. from umake.frameworks import BaseCategory
  32. from umake.tools import InputError, MainLoop
  33. from umake.settings import get_version
  34. from umake.frameworks import load_frameworks
  35.  
  36. logger = logging.getLogger(__name__)
  37.  
  38.  
  39. def rlinput(prompt, prefill=''):
  40. readline.set_startup_hook(lambda: readline.insert_text(prefill))
  41. try:
  42. return input(prompt + " ")
  43. finally:
  44. readline.set_startup_hook()
  45.  
  46.  
  47. class CliUI(UI):
  48.  
  49. def __init__(self):
  50. # This this UI as current
  51. super().__init__(self)
  52.  
  53. def _return_main_screen(self, status_code=0):
  54. # quit the shell
  55. MainLoop().quit(status_code=status_code)
  56.  
  57. def _display(self, contentType):
  58. # print depending on the content type
  59. while True:
  60. try:
  61. if isinstance(contentType, InputText):
  62. contentType.run_callback(result=rlinput(contentType.content, contentType.default_input))
  63. elif isinstance(contentType, LicenseAgreement):
  64. print(contentType.content)
  65. contentType.choose(answer=input(contentType.input))
  66. elif isinstance(contentType, TextWithChoices):
  67. contentType.choose(answer=input(contentType.prompt))
  68. elif isinstance(contentType, DisplayMessage):
  69. print(contentType.text)
  70. elif isinstance(contentType, UnknownProgress):
  71. if not contentType.bar:
  72. contentType.bar = ProgressBar(widgets=[BouncingBar()])
  73. with suppress(StopIteration):
  74. # pulse and add a timeout callback
  75. contentType.bar(contentType._iterator()).next()
  76. UI.delayed_display(contentType)
  77. # don't recall the callback
  78. return False
  79. else:
  80. logger.error("Unexcepted content type to display to CLI UI: {}".format(contentType))
  81. MainLoop().quit(status_code=1)
  82. break
  83. except InputError as e:
  84. logger.error(str(e))
  85. continue
  86.  
  87.  
  88. @MainLoop.in_mainloop_thread
  89. def run_command_for_args(args):
  90. """Run correct command for args"""
  91. # args.category can be a category or a framework in main
  92. target = None
  93. try:
  94. target = BaseCategory.categories[args.category]
  95. except AttributeError:
  96. target = BaseCategory.main_category.frameworks[args.category]
  97. target.run_for(args)
  98.  
  99.  
  100. def mangle_args_for_default_framework(args):
  101. """return the potentially changed args_to_parse for the parser for handling default frameworks
  102.  
  103. "./<command> [global_or_common_options] category [options from default framework]"
  104. as subparsers can't define default options and are not optional: http://bugs.python.org/issue9253
  105. """
  106.  
  107. result_args = []
  108. skip_all = False
  109. pending_args = []
  110. category_name = None
  111. framework_completed = False
  112. args_to_append = []
  113.  
  114. for arg in args:
  115. # --remove is both installed as global and per-framework optional arguments. argparse will only analyze the
  116. # per framework one and will override the global one. So if --remove is before the category name, it will be
  117. # ignored. Mangle the arg and append it last then.
  118. if not category_name and arg in ("--remove", "-r"):
  119. args_to_append.append(arg)
  120. continue
  121. if not arg.startswith('-') and not skip_all:
  122. if not category_name:
  123. if arg in BaseCategory.categories.keys():
  124. category_name = arg
  125. # file global and common options
  126. result_args.extend(pending_args)
  127. pending_args = []
  128. result_args.append(arg)
  129. continue
  130. else:
  131. skip_all = True # will just append everything at the end
  132. elif not framework_completed:
  133. # if we found a real framework or not, consider that one. pending_args will be then filed
  134. framework_completed = True
  135. if arg in BaseCategory.categories[category_name].frameworks.keys():
  136. result_args.append(arg)
  137. continue
  138. # take default framework if any after some sanitization check
  139. elif BaseCategory.categories[category_name].default_framework is not None:
  140. # before considering automatically inserting default framework, check that this argument has
  141. # some path separator into it. This is to avoid typos in framework selection and selecting default
  142. # framework with installation path where we didn't want to.
  143. if os.path.sep in arg:
  144. result_args.append(BaseCategory.categories[category_name].default_framework.prog_name)
  145. # current arg will be appending in pending_args
  146. else:
  147. skip_all = True # will just append everything at the end
  148. pending_args.append(arg)
  149.  
  150. # this happened only if there is no argument after the category name
  151. if category_name and not framework_completed:
  152. if BaseCategory.categories[category_name].default_framework is not None:
  153. result_args.append(BaseCategory.categories[category_name].default_framework.prog_name)
  154.  
  155. # let the rest in
  156. result_args.extend(pending_args)
  157. result_args.extend(args_to_append)
  158. return result_args
  159.  
  160.  
  161. def main(parser):
  162. """Main entry point of the cli command"""
  163. print(BaseCategory.categories)
  164.  
  165.  
  166. categories_parser = parser.add_subparsers(help='Developer environment', dest="category")
  167. for category in BaseCategory.categories.values():
  168. category.install_category_parser(categories_parser)
  169.  
  170. argcomplete.autocomplete(parser)
  171. # autocomplete will stop there. Can start more expensive operations now.
  172.  
  173. arg_to_parse = sys.argv[1:]
  174. if "--help" not in arg_to_parse:
  175. # manipulate sys.argv for default frameworks:
  176. arg_to_parse = mangle_args_for_default_framework(arg_to_parse)
  177. args = parser.parse_args(arg_to_parse)
  178.  
  179.  
  180. load_frameworks()
  181. for category in BaseCategory.categories:
  182. cat = BaseCategory(category)
  183. print(category)
  184. print(cat.frameworks)
  185. for framework in cat.frameworks:
  186. if framework.is_installed:
  187. print(framework.name)
  188.  
  189. sys.exit(0)
  190. if args.version:
  191. print(get_version())
  192. sys.exit(0)
  193.  
  194. if not args.category:
  195. parser.print_help()
  196. sys.exit(0)
  197.  
  198. CliUI()
  199. run_command_for_args(args)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement