Mercurial > libervia-backend
comparison frontends/src/jp/cmd_shell.py @ 2315:8d9bd5d77336
jp (arg_tools): moved get_cmd_choices, get_use_args and escape to a new arg_tools module, so they can be used in other commands than shell
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 08 Jul 2017 21:45:14 +0200 |
parents | 6ff5212997c7 |
children | f4e05600577b |
comparison
equal
deleted
inserted
replaced
2314:01f0a954d506 | 2315:8d9bd5d77336 |
---|---|
22 import cmd | 22 import cmd |
23 import sys | 23 import sys |
24 from sat.core.i18n import _ | 24 from sat.core.i18n import _ |
25 from sat.core import exceptions | 25 from sat.core import exceptions |
26 from sat_frontends.jp.constants import Const as C | 26 from sat_frontends.jp.constants import Const as C |
27 from sat_frontends.jp import arg_tools | |
27 from sat.tools.common.ansi import ANSI as A | 28 from sat.tools.common.ansi import ANSI as A |
28 import shlex | 29 import shlex |
29 import subprocess | 30 import subprocess |
30 | 31 |
31 __commands__ = ["Shell"] | 32 __commands__ = ["Shell"] |
45 cmd.Cmd.__init__(self) | 46 cmd.Cmd.__init__(self) |
46 | 47 |
47 def parse_args(self, args): | 48 def parse_args(self, args): |
48 """parse line arguments""" | 49 """parse line arguments""" |
49 return shlex.split(args, posix=True) | 50 return shlex.split(args, posix=True) |
50 | |
51 def get_cmd_choices(self, cmd=None, parser=None): | |
52 if parser is None: | |
53 parser = self._cur_parser | |
54 try: | |
55 choices = parser._subparsers._group_actions[0].choices | |
56 return choices[cmd] if cmd is not None else choices | |
57 except (KeyError, AttributeError): | |
58 raise exceptions.NotFound | |
59 | 51 |
60 def update_path(self): | 52 def update_path(self): |
61 self._cur_parser = self.host.parser | 53 self._cur_parser = self.host.parser |
62 self.help = u'' | 54 self.help = u'' |
63 for idx, path_elt in enumerate(self.path): | 55 for idx, path_elt in enumerate(self.path): |
64 try: | 56 try: |
65 self._cur_parser = self.get_cmd_choices(path_elt) | 57 self._cur_parser = arg_tools.get_cmd_choices(path_elt, self._cur_parser) |
66 except exceptions.NotFound: | 58 except exceptions.NotFound: |
67 self.disp(_(u'bad command path'), error=True) | 59 self.disp(_(u'bad command path'), error=True) |
68 self.path=self.path[:idx] | 60 self.path=self.path[:idx] |
69 break | 61 break |
70 else: | 62 else: |
71 self.help = self._cur_parser | 63 self.help = self._cur_parser |
72 | 64 |
73 self.prompt = A.color(C.A_PROMPT_PATH, u'/'.join(self.path)) + A.color(C.A_PROMPT_SUF, u'> ') | 65 self.prompt = A.color(C.A_PROMPT_PATH, u'/'.join(self.path)) + A.color(C.A_PROMPT_SUF, u'> ') |
74 try: | 66 try: |
75 self.actions = self.get_cmd_choices().keys() | 67 self.actions = arg_tools.get_cmd_choices(parser=self._cur_parser).keys() |
76 except exceptions.NotFound: | 68 except exceptions.NotFound: |
77 self.actions = [] | 69 self.actions = [] |
78 | 70 |
79 def add_parser_options(self): | 71 def add_parser_options(self): |
80 pass | 72 pass |
81 | |
82 def escape_arg(self, arg): | |
83 """format arg with quotes""" | |
84 return u'"' + arg.replace(u'"',u'\\"') + u'"' | |
85 | 73 |
86 def format_args(self, args): | 74 def format_args(self, args): |
87 """format argument to be printed with quotes if needed""" | 75 """format argument to be printed with quotes if needed""" |
88 for arg in args: | 76 for arg in args: |
89 if " " in arg: | 77 if " " in arg: |
90 yield self.escape_arg(arg) | 78 yield arg_tools.escape(arg) |
91 else: | 79 else: |
92 yield arg | 80 yield arg |
93 | |
94 def get_use_args(self, args): | |
95 """format args for current parser according to self.use""" | |
96 parser = self._cur_parser | |
97 | |
98 # we check not optional args to see if there | |
99 # is a corresonding parser | |
100 # else USE args would not work correctly (only for current parser) | |
101 cmd_args = [] | |
102 for arg in args: | |
103 if arg.startswith('-'): | |
104 break | |
105 try: | |
106 parser = self.get_cmd_choices(arg, parser) | |
107 except exceptions.NotFound: | |
108 break | |
109 cmd_args.append(arg) | |
110 | |
111 # we remove command args | |
112 # they'll be in returned list (use_args) | |
113 del args[:len(cmd_args)] | |
114 | |
115 opt_args = [] | |
116 pos_args = [] | |
117 actions = {a.dest: a for a in parser._actions} | |
118 for arg, value in self.use.iteritems(): | |
119 try: | |
120 action = actions[arg] | |
121 except KeyError: | |
122 if self.verbose: | |
123 self.disp(_(u'ignoring {name}={value}, not corresponding to any argument (in USE)').format( | |
124 name=arg, | |
125 value=self.escape_arg(value))) | |
126 else: | |
127 if self.verbose: | |
128 self.disp(_(u'arg {name}={value} set (in USE)').format(name=arg, value=self.escape_arg(value))) | |
129 if not action.option_strings: | |
130 pos_args.append(value) | |
131 else: | |
132 opt_args.append(action.option_strings[0]) | |
133 opt_args.append(value) | |
134 return cmd_args + opt_args + pos_args | |
135 | 81 |
136 def run_cmd(self, args, external=False): | 82 def run_cmd(self, args, external=False): |
137 """run command and retur exit code | 83 """run command and retur exit code |
138 | 84 |
139 @param args[list[string]]: arguments of the command | 85 @param args[list[string]]: arguments of the command |
234 def do_do(self, args): | 180 def do_do(self, args): |
235 """lauch a command""" | 181 """lauch a command""" |
236 args = self.parse_args(args) | 182 args = self.parse_args(args) |
237 # args may be modified by use_args | 183 # args may be modified by use_args |
238 # to remove subparsers from it | 184 # to remove subparsers from it |
239 use_args = self.get_use_args(args) | 185 use_args = arg_tools.get_use_args(self.host, |
186 args, | |
187 self.use, | |
188 verbose=self.verbose, | |
189 parser=self._cur_parser | |
190 ) | |
240 cmd_args = self.path + use_args + args | 191 cmd_args = self.path + use_args + args |
241 self.run_cmd(cmd_args) | 192 self.run_cmd(cmd_args) |
242 | 193 |
243 def do_use(self, args): | 194 def do_use(self, args): |
244 """fix an argument""" | 195 """fix an argument""" |
247 if not self.use: | 198 if not self.use: |
248 self.disp(_(u'no argument in USE')) | 199 self.disp(_(u'no argument in USE')) |
249 else: | 200 else: |
250 self.disp(_(u'arguments in USE:')) | 201 self.disp(_(u'arguments in USE:')) |
251 for arg, value in self.use.iteritems(): | 202 for arg, value in self.use.iteritems(): |
252 self.disp(_(A.color(C.A_SUBHEADER, arg, A.RESET, u' = ', self.escape_arg(value)))) | 203 self.disp(_(A.color(C.A_SUBHEADER, arg, A.RESET, u' = ', arg_tools.escape(value)))) |
253 elif len(args) != 2: | 204 elif len(args) != 2: |
254 self.disp(u'bad syntax, please use:\nuse [arg] [value]', error=True) | 205 self.disp(u'bad syntax, please use:\nuse [arg] [value]', error=True) |
255 else: | 206 else: |
256 self.use[args[0]] = u' '.join(args[1:]) | 207 self.use[args[0]] = u' '.join(args[1:]) |
257 if self.verbose: | 208 if self.verbose: |
258 self.disp('set {name} = {value}'.format( | 209 self.disp('set {name} = {value}'.format( |
259 name = args[0], value=self.escape_arg(args[1]))) | 210 name = args[0], value=arg_tools.escape(args[1]))) |
260 | 211 |
261 def do_use_clear(self, args): | 212 def do_use_clear(self, args): |
262 """unset one or many argument(s) in USE, or all of them if no arg is specified""" | 213 """unset one or many argument(s) in USE, or all of them if no arg is specified""" |
263 args = self.parse_args(args) | 214 args = self.parse_args(args) |
264 if not args: | 215 if not args: |