annotate frontends/src/jp/cmd_shell.py @ 2309:c7a72b75232b

jp (shell): shell command (REPL mode), first draft: This command launch jp in REPL mode, allowing do normal jp commands with some facilities. Command can be selected with "cmd" (e.g. "cmd blog"). An argument can be fixed with "use" (e.g. "use output fancy"). Command is launched with "do", or directly with its name if it doesn't conflict with a shell command. Arguments completion is still TODO (only shell commands are completed so far).
author Goffi <goffi@goffi.org>
date Thu, 06 Jul 2017 20:28:25 +0200
parents
children 5996063ecad7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2309
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python2
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
3
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # jp: a SàT command line tool
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
5 # Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
6
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # This program is free software: you can redistribute it and/or modify
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # (at your option) any later version.
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
11
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # This program is distributed in the hope that it will be useful,
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # GNU Affero General Public License for more details.
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
19
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
20
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 import base
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 import cmd
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from sat.core.i18n import _
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from sat.core import exceptions
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from sat_frontends.jp.constants import Const as C
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from sat.tools.common.ansi import ANSI as A
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 import shlex
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
28
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 __commands__ = ["Shell"]
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 INTRO = _(u"""Welcome to {app_name} shell, the Salut à Toi shell !
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
31
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 This enrironment helps you using several {app_name} commands with similar parameters.
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
33
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 To quit, just enter "quit" or press C-c.
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 Enter "help" or "?" to know what to do
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 """).format(app_name = C.APP_NAME)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
37
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
38
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 class Shell(base.CommandBase, cmd.Cmd):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
40
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 def __init__(self, host):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 base.CommandBase.__init__(self, host, 'shell', help=_(u'launch jp in shell (REPL) mode'))
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 cmd.Cmd.__init__(self)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
44
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 def parse_args(self, args):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 """parse line arguments"""
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 return shlex.split(args, posix=True)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
48
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 def get_cmd_choices(self, cmd=None, parser=None):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 if parser is None:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 parser = self._cur_parser
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 try:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 choices = parser._subparsers._group_actions[0].choices
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 return choices[cmd] if cmd is not None else choices
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 except (KeyError, AttributeError):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 raise exceptions.NotFound
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
57
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 def update_path(self):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 self._cur_parser = self.host.parser
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 self.help = u''
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 for idx, path_elt in enumerate(self.path):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 try:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 self._cur_parser = self.get_cmd_choices(path_elt)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 except exceptions.NotFound:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 self.disp(_(u'bad command path'), error=True)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 self.path=self.path[:idx]
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 break
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
68 else:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 self.help = self._cur_parser
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
70
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 self.prompt = A.color(C.A_PROMPT_PATH, u'/'.join(self.path)) + A.color(C.A_PROMPT_SUF, u'> ')
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 try:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
73 self.actions = self.get_cmd_choices().keys()
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
74 except exceptions.NotFound:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 self.actions = []
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
76
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
77 def add_parser_options(self):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 pass
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
79
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
80 def escape_arg(self, arg):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 """format arg with quotes"""
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 return u'"' + arg.replace(u'"',u'\\"') + u'"'
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
83
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 def format_args(self, args):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
85 """format argument to be printed with quotes if needed"""
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
86 for arg in args:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 if " " in arg:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
88 yield self.escape_arg(arg)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 else:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 yield arg
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
91
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
92 def get_use_args(self, args):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 """format args for current parser according to self.use"""
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 parser = self._cur_parser
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
95
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 # we check not optional args to see if there
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
97 # is a corresonding parser
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
98 # else USE args would not work correctly (only for current parser)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 cmd_args = []
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
100 for arg in args:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
101 if arg.startswith(u'-'):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
102 break
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 try:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
104 parser = self.get_cmd_choices(arg, parser)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
105 except exceptions.NotFound:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 break
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 cmd_args.append(arg)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
108
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
109 # we remove command args
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 # they'll be in returned list (use_args)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
111 del args[:len(cmd_args)]
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
112
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 opt_args = []
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
114 pos_args = []
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 actions = {a.dest: a for a in parser._actions}
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 for arg, value in self.use.iteritems():
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
117 try:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
118 action = actions[arg]
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 except KeyError:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
120 if self.verbose:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
121 self.disp(_(u'ignoring {name}={value}, not corresponding to any argument (in USE)').format(
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
122 name=arg,
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
123 value=self.escape_arg(value)))
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
124 else:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
125 if self.verbose:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 self.disp(_(u'arg {name}={value} set (in USE)').format(name=arg, value=self.escape_arg(value)))
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 if not action.option_strings:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
128 pos_args.append(value)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
129 else:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 opt_args.append(action.option_strings[0])
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
131 opt_args.append(value)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 return cmd_args + opt_args + pos_args
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
133
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
134 def default(self, args):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
135 """called when no shell command is recognized
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
136
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
137 will launch the command with args on the line
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
138 (i.e. will launch do [args])
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
139 """
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
140 self.do_do(args)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
141
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
142 def do_help(self, args):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
143 """show help message"""
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
144 self.disp(A.color(C.A_HEADER, _(u'Shell commands:')), no_lf=True)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
145 super(Shell, self).do_help(args)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
146 if not args:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
147 self.disp(A.color(C.A_HEADER, _(u'Action commands:')))
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
148 help_list = self._cur_parser.format_help().split('\n\n')
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
149 print('\n\n'.join(help_list[1 if self.path else 2:]))
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
150
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
151 def do_debug(self, args):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
152 """launch internal debugger"""
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
153 try:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
154 import ipdb as pdb
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
155 except ImportError:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
156 import pdb
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
157 pdb.set_trace()
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
158
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
159 def do_verbose(self, args):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
160 """show verbose mode, or (de)activate it"""
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
161 args = self.parse_args(args)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
162 if args:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
163 self.verbose = C.bool(args[0])
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
164 self.disp(_(u'verbose mode is {status}').format(
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
165 status = _(u'ENABLED') if self.verbose else _(u'DISABLED')))
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
166
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
167 def do_cmd(self, args):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 """change command path"""
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
169 if args == '..':
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
170 self.path = self.path[:-1]
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
171 else:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
172 if not args or args[0] == '/':
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
173 self.path = []
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
174 args = '/'.join(args.split())
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
175 for path_elt in args.split('/'):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
176 path_elt = path_elt.strip()
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
177 if not path_elt:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
178 continue
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
179 self.path.append(path_elt)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 self.update_path()
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
181
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
182 def do_version(self, args):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 """show current SàT/jp version"""
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
184 try:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
185 self.host.run(['--version'])
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
186 except SystemExit:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
187 pass
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
188
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
189 def do_do(self, args):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 """lauch a command"""
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 # we don't want host to really exit
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
192 # we want to stay in the loop
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
193 self.host._no_exit = True
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
194 args = self.parse_args(args)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
195 # args may be modified by use_args
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 # to remove subparsers from it
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
197 use_args = self.get_use_args(args)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
198 cmd_args = self.path + use_args + args
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
199 if self.verbose:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
200 self.disp(u"COMMAND => {args}".format(args=u' '.join(self.format_args(cmd_args))))
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 try:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
202 self.host.run(cmd_args)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
203 except SystemExit as e:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
204 if e.code != 0:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
205 self.disp(A.color(C.A_FAILURE, u'command failed with an error code of {err_no}'.format(err_no=e.code)), error=True)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 except Exception as e:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
207 self.disp(A.color(C.A_FAILURE, u'command failed with an exception: {msg}'.format(msg=e)), error=True)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
208 finally:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
209 self.host._no_exit = False
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
210
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
211 def do_use(self, args):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
212 """fix an argument"""
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
213 args = self.parse_args(args)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
214 if not args:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
215 if not self.use:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
216 self.disp(_(u'no argument in USE'))
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 else:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
218 self.disp(_(u'arguments in USE:'))
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
219 for arg, value in self.use.iteritems():
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 self.disp(_(A.color(C.A_SUBHEADER, arg, A.RESET, u' = ', self.escape_arg(value))))
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
221 elif len(args) != 2:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
222 self.disp(u'bad syntax, please use:\nuse [arg] [value]', error=True)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
223 else:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 self.use[args[0]] = u' '.join(args[1:])
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
225 if self.verbose:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
226 self.disp('set {name} = {value}'.format(
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
227 name = args[0], value=self.escape_arg(args[1])))
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
228
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
229 def do_use_clear(self, args):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
230 """unset one or many argument(s) in USE, or all of them if no arg is specified"""
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
231 args = self.parse_args(args)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
232 if not args:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
233 self.use.clear()
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
234 else:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
235 for arg in args:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
236 try:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
237 del self.use[arg]
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
238 except KeyError:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
239 self.disp(A.color(C.A_FAILURE, _(u'argument {name} not found').format(name=arg)), error=True)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
240 else:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
241 if self.verbose:
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
242 self.disp(_(u'argument {name} removed').format(name=arg))
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
243
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
244 def do_quit(self, args):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
245 u"""quit the shell"""
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
246 self.disp(_(u'good bye!'))
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
247 self.host.quit()
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
248
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
249 def do_exit(self, args):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
250 u"""alias for quit"""
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
251 self.do_quit(args)
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
252
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
253 def start(self):
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
254 self.path = []
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
255 self._cur_parser = self.host.parser
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
256 self.use = {}
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
257 self.verbose = False
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
258 self.update_path()
c7a72b75232b jp (shell): shell command (REPL mode), first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
259 self.cmdloop(INTRO.encode('utf-8'))