def run_pyreverse(self, events:"modified_files") -> plugin.Task: """ Main plugin task. Process `events` of the subscription `modified_files` and put states or events to the hub. """ pyreverse_path = self.config.get(self._section_name, "pyreverse_path") while True: event = yield from events.get() filename = event.key dot_id = md5(filename.encode('utf-8')).hexdigest() exitcode, stdout, stderr = yield from execute( pyreverse_path, '-A', '-o', 'dot', '-p', dot_id, filename, cwd=TEMPDIR) data = {} dotfiles = glob(os.path.join(TEMPDIR, '*_' + dot_id + '*.dot')) for dotfile in dotfiles: dot_type, _ = os.path.basename(dotfile).split('_', 1) with open(dotfile, 'r') as f: data[dot_type] = f.read() os.unlink(dotfile) state = self.new_state(key=filename, **data) yield from self.hub.put(state)
def run_jshint(self, events:"modified_files") -> plugin.Task: """ Main plugin task. Process `events` of the subscription `modified_files` and put states or events to the hub. """ jshint_path = self.config.get(self._section_name, "jshint_path") while True: event = yield from events.get() self.log.debug("Event received in plugin `jshint`") filename = event.key exitcode, stdout, stderr = yield from execute(jshint_path, '--verbose', '--reporter=checkstyle', filename) data = parse_checkstyle(stdout) highlights = [ self.message_to_highlight(message) for message in data ] if data: state = self.new_state(key=filename, data=data) hl_state = self.new_state(content_type="highlight", key=filename, highlights=highlights) else: state = self.new_state(key=filename) hl_state = self.new_state(content_type='highlight', key=filename) yield from self.hub.put(state) yield from self.hub.put(hl_state)
def run_radon_mi(self, events:"modified_files") -> plugin.Task: """ Maintainability index plugin task. Process `events` of the subscription `modified_files` and put states or events to the hub. """ radon_path = self.config.get(self._section_name, "radon_path") while True: event = yield from events.get() filename = event.key task = 'mi' exitcode, stdout, stderr = yield from execute(radon_path, task, '-s', filename) data = stdout.decode('utf-8').strip().split(' - ') rank, strscore = data[1].split() score = float(strscore[1:-1]) state = self.new_state(key=filename, task=task, rank=rank, score=score) if state is not None: yield from self.hub.put(state) else: self.log.debug("No state generated")
def get_tests(self, events:"modified_testfiles") -> plugin.Task: pytest_path = self.config.get(self._section_name, "pytest_path") tests_path = self.config.get(self._section_name, "tests_path") while True: event = yield from events.get() exitcode, stdout, stderr = yield from execute(pytest_path, "--collect-only", tests_path) data = [] current_module = None current_class = None content = stdout.decode('utf-8') for line in stdout.splitlines(): line = line.strip().decode('utf-8') if line.startswith('<'): datatype, key, _ = line.split("'") if datatype[1:-1] == 'Module': current_module = key current_class = None elif datatype[1:-1] == 'UnitTestCase': current_class = key else: data.append({'module': current_module, 'class': current_class, 'function': key}) state = self.new_state(key='pytest-tests', data=data, task='get_tests') yield from self.hub.put(state)
def wip_tests(self, events:"modified_pyfiles") -> plugin.Task: """ Run tests marked with @wip tag. """ pytest_path = self.config.get(self._section_name, "pytest_path") tests_path = self.config.get(self._section_name, "tests_path") wip_mark = self.config.get(self._section_name, "wip_mark") last_wip_status = None status_change_filename = None status_change_differences = None while True: event = yield from events.get() self.log.critical("Event received in plugin `pytest`") yield from self.hub.put(self.new_event(key="wip_tests_status", status="running")) with tempfile.NamedTemporaryFile(mode="r", encoding="utf-8") as logfile: exitcode, stdout, stderr = yield from execute( pytest_path, "-r", "fesxX", "-v", "-m", wip_mark, "--result-log", logfile.name, tests_path) details = self.parse_result_file(logfile.file.read()) if exitcode == 0: status = "passed" else: status = "failed" yield from self.hub.put(self.new_event(key="wip_tests_status", status=status)) new_content = event.content or "" if last_wip_status != exitcode: old_content = self.modified_files.get(event.key, "") status_change_filename = event.key status_change_differences = HtmlDiff().make_table( old_content.splitlines(), new_content.splitlines(), context=True) last_wip_status = exitcode self.modified_files[event.key] = new_content success = (exitcode == 0) state = self.new_state(key="wip_tests", success=success, filename=status_change_filename, differences=status_change_differences, status=status, details=details, task='wip_tests' ) yield from self.hub.put(state)
def generate_state(self, radon_path, task, filename): """ Call radon and convert output to json """ exitcode, stdout, stderr = yield from execute(radon_path, task, '-j', filename) if stderr: self.log.warning('Radon found errors while reading {filename}:' ' {errors}'.format(filename=filename, errors=stderr)) if stdout: data = json.loads(stdout.decode('utf-8'))[filename] state = self.new_state(key=filename, task=task, data=data) return state
def run_clonedigger(self, events: "modified_files") -> plugin.Task: """ Main plugin task. Process `events` of the subscription `modified_files` and put states or events to the hub. """ clonedigger_path = self.config.get(self._section_name, "clonedigger_path") while True: event = yield from events.get() filename = event.key self.log.critical("Event received in plugin `clonedigger`") with tempfile.TemporaryDirectory() as td: execution_stats = yield from execute(clonedigger_path, '--cpd-output', filename, cwd=td) computed_path = os.path.join(td, 'output.xml') # html_output = open(os.path.join(td, 'output.html')).read() if not os.path.exists(computed_path): self.log.warning( 'Clonedigger did not generate output file') continue else: xml_output = open(computed_path, 'rb').read() data = {} # html_data = self.parse_html(html_output) xml_data = self.parse_xml(xml_output) # data['html'] = html_data data['xml'] = xml_data state = self.new_state(key=filename, **data) yield from self.hub.put(state)
def run_pylint(self, events:"modified_files") -> plugin.Task: """ Main plugin task. Process `events` of the subscription `modified_files` and put states or events to the hub. """ pylint_path = self.config.get(self._section_name, "pylint_path") while True: event = yield from events.get() filename = event.key exitcode, stdout, stderr = yield from execute( pylint_path, '--msg-template={}'.format(MSG_TEMPLATE), filename) output = stdout.decode('utf-8') messages = [] for message in MSG_REGEX.finditer(output): values = message.groupdict() values['line'] = int(values.get('line', 0)) values['column'] = int(values.get('column', 0)) messages.append(values) score_match = SCORE_REGEX.search(output) if score_match: group = score_match.groupdict() score = float(group.get('score', 0.0)) else: score = None state = self.new_state(key=filename, messages=messages, task="run_pylint", score=score) yield from self.hub.put(state)
def run_pyflakes(self, events:"modified_files") -> plugin.Task: """ Main plugin task. Process `events` of the subscription `modified_files` and put states or events to the hub. """ pyflakes_path = self.config.get(self._section_name, "pyflakes_path") while True: event = yield from events.get() exitcode, stdout, stderr = yield from execute( pyflakes_path, event.key, stdin=event.raw) lines = [] for line in stdout.decode('utf-8').splitlines(): file, linenum, message = [l.strip() for l in line.split(':', 2)] lines.append({'line': linenum, 'message': message}) state = self.new_state(key=event.key, lines=lines, exitcode=exitcode) yield from self.hub.put(state) # Highlight content_type highlights = [] for message in lines: highlights.append(self.message_to_highlight(message)) if highlights: hl_state = self.new_state(content_type="highlight", key=event.key, highlights=highlights) else: hl_state = self.new_state(content_type="highlight", key=event.key) yield from self.hub.put(hl_state)
def run_cheesecake(self, events:"modified_files") -> plugin.Task: """ Main plugin task. Process `events` of the subscription `modified_files` and put states or events to the hub. """ cheesecake_path = self.config.get(self._section_name, "cheesecake_path") while True: event = yield from events.get() filename = event.key exitcode, stdout, stderr = yield from execute(cheesecake_path, '-v', '-p', filename) data = self.parse_output(stdout) self.log.debug("Event received in plugin `cheesecake`") state = self.new_state(key=filename, **data) yield from self.hub.put(state)
def run_clonedigger(self, events:"modified_files") -> plugin.Task: """ Main plugin task. Process `events` of the subscription `modified_files` and put states or events to the hub. """ clonedigger_path = self.config.get(self._section_name, "clonedigger_path") while True: event = yield from events.get() filename = event.key self.log.critical("Event received in plugin `clonedigger`") with tempfile.TemporaryDirectory() as td: execution_stats = yield from execute(clonedigger_path, '--cpd-output', filename, cwd=td) computed_path = os.path.join(td, 'output.xml') # html_output = open(os.path.join(td, 'output.html')).read() if not os.path.exists(computed_path): self.log.warning('Clonedigger did not generate output file') continue else: xml_output = open(computed_path, 'rb').read() data = {} # html_data = self.parse_html(html_output) xml_data = self.parse_xml(xml_output) # data['html'] = html_data data['xml'] = xml_data state = self.new_state(key=filename, **data) yield from self.hub.put(state)