# HG changeset patch # User Goffi # Date 1471775239 -7200 # Node ID 3a5badbb443dd4c437feb753bcc2b51b987bba29 # Parent 0f485f1d627da9c5a698d88af739298bc89bf097 jp: added jp/debug commands: jp/debug hierarchy contain commands useful for developping and debugging. first commands are jp/debug/bridge: - "method" allows to call a bridge method, args are parsed as python arguments (using eval). - "signal" do the same to send a signal from backend, using the new debug plugin. diff -r 0f485f1d627d -r 3a5badbb443d frontends/src/jp/cmd_debug.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/frontends/src/jp/cmd_debug.py Sun Aug 21 12:27:19 2016 +0200 @@ -0,0 +1,107 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- + +# jp: a SàT command line tool +# Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org) + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + + +import base +from sat.core.i18n import _ +from sat_frontends.jp.constants import Const as C +import json + +__commands__ = ["Debug"] + + +class BridgeCommon(object): + + def evalArgs(self): + if self.args.arg: + try: + return eval(u",".join(self.args.arg)) + except SyntaxError as e: + self.disp(u"Can't evaluate arguments: {mess}\n{text}\n{offset}^".format( + mess=e, + text=e.text, + offset=u" "*(e.offset-1) + ), error=True) + self.host.quit(C.EXIT_BAD_ARG) + else: + return [] + + +class Method(base.CommandBase, BridgeCommon): + + def __init__(self, host): + base.CommandBase.__init__(self, host, 'method', help=_(u'call a bridge method')) + BridgeCommon.__init__(self) + self.need_loop=True + + def add_parser_options(self): + self.parser.add_argument("method", type=str, help=_(u"name of the method to execute")) + self.parser.add_argument("arg", nargs="*", help=_(u"argument of the method")) + + def method_cb(self, ret): + self.disp(unicode(ret)) + self.host.quit() + + def method_eb(self, failure): + self.disp(_(u"Error while executing {}: {}".format(self.args.method, failure)), error=True) + self.host.quit(C.EXIT_ERROR) + + def start(self): + method = getattr(self.host.bridge, self.args.method) + args = self.evalArgs() + try: + method(*self.args.arg, profile=self.profile, callback=self.method_cb, errback=self.method_eb) + except TypeError: + # maybe the method doesn't need a profile ? + try: + method(*args, callback=self.method_cb, errback=self.method_eb) + except TypeError: + self.method_eb(_(u"bad arguments")) + + +class Signal(base.CommandBase, BridgeCommon): + + def __init__(self, host): + base.CommandBase.__init__(self, host, 'signal', help=_(u'send a fake signal from backend')) + BridgeCommon.__init__(self) + + def add_parser_options(self): + self.parser.add_argument("signal", type=str, help=_(u"name of the signal to send")) + self.parser.add_argument("arg", nargs="*", help=_(u"argument of the signal")) + + def start(self): + args = self.evalArgs() + json_args = json.dumps(args) + # XXX: we use self.args.profile and not self.profile + # because we want the raw profile_key (so plugin handle C.PROF_KEY_NONE) + self.host.bridge.debugFakeSignal(self.args.signal, json_args, self.args.profile) + + +class Bridge(base.CommandBase): + subcommands = (Method, Signal) + + def __init__(self, host): + super(Bridge, self).__init__(host, 'bridge', use_profile=False, help=_('bridge s(t)imulation')) + + +class Debug(base.CommandBase): + subcommands = (Bridge,) + + def __init__(self, host): + super(Debug, self).__init__(host, 'debug', use_profile=False, help=_('debugging tools'))