import os import sys from optparse import make_option import random import signal import subprocess import time from jhbuild.commands import Command, register_command import jhbuild.config scripts_dir = os.path.dirname(__file__) data_dir = os.path.join(scripts_dir, 'data') pylintrc_path = os.path.join(data_dir, 'pylintrc') def check_display(display): result = subprocess.call(['xdpyinfo', '-display', ':%d' % display], stdout=open(os.devnull, "w"), stderr=open(os.devnull, "w")) return result == 0 class UICheck(object): def start(self): self._mainloop = gobject.MainLoop() self._exit_code = 0 self._start_shell() gobject.idle_add(self._start_ui_check_cb) self._mainloop.run() return self._exit_code def _start_shell(self): print 'Launch the shell.' env = os.environ env['SUGAR_PROFILE'] = 'uicheck' env['SUGAR_PROFILE_NAME'] = 'uicheck' args = ['dbus-launch', '--exit-with-session', 'sugar'] shell_process = subprocess.Popen(args, env=env) def _ui_check_exit_cb(self, pid, condition): self._exit_code = os.WEXITSTATUS(condition) self._mainloop.quit() def _ui_check_read_cb(self, fd, condition): sys.stdout.write(os.read(fd, 1024)) return True def _start_ui_check_cb(self): print 'Launch UI check.' pid, stdin, stdout, stderr = gobject.spawn_async( ['sugar-ui-check'], standard_output=True, standard_error=True, flags=gobject.SPAWN_SEARCH_PATH | gobject.SPAWN_DO_NOT_REAP_CHILD) gobject.io_add_watch(stdout, gobject.IO_IN, self._ui_check_read_cb) gobject.io_add_watch(stderr, gobject.IO_IN, self._ui_check_read_cb) gobject.child_watch_add(pid, self._ui_check_exit_cb) class cmd_check(Command): name = 'check' usage_args = '' def __init__(self): Command.__init__(self, [ make_option('-t', '--type', action='store', dest='type', default=None, help='specify the check type') ]) def start_virtual_x(self): result = None for port in range(100, 1000): if not check_display(port): try: p = subprocess.Popen(['Xvnc', '-ac', ':%d' % port], stdout=open(os.devnull, "w"), stderr=subprocess.STDOUT) tries = 10 while tries > 0: if check_display(port): os.environ['DISPLAY'] = ':%d' % port return p.pid else: tries -= 1 time.sleep(0.1) except OSError: break print 'Cannot execute virtual X, will use the default display.' return None def lint(self, module): vx_pid = self.start_virtual_x() try: subprocess.call(['pylint', module, '--rcfile=%s' % pylintrc_path]) finally: os.kill(vx_pid, signal.SIGTERM) def check_ui(self, config): vx_pid = self.start_virtual_x() try: result = UICheck().start() finally: os.kill(vx_pid, signal.SIGTERM) return result def check_pylint(self, config): self.lint('sugar') self.lint('jarabe') ext_path = os.path.join(config.prefix, 'share', 'sugar', 'extensions') jhbuild.config.addpath('PYTHONPATH', ext_path) self.lint('cpsection') self.lint('deviceicon') def run(self, config, options, args): result = 0 if not options.type or options.type == 'pylint': self.check_pylint(config) if not options.type or options.type == 'ui': result = self.check_ui(config) return result try: import gobject register_command(cmd_check) except ImportError: print 'Disable check, pygobject is not installed.'