示例#1
0
    def __cmd_line(self):
        """Create GNATcheck command line arguments list.

        :return: the GNATcheck command line
        :rtype: collections.Iterable[str]
        """

        cmd_line = [
            'gnatcheck', '--show-rule', '-o', self.output,
            '-P', GNAThub.Project.path()]

        if GNAThub.u_process_all():
            cmd_line.extend(['-U'])

#  Keeping this for later implemntation of -U main switch
#        if GNAThub.u_main():
#            cmd_line.extend(['-U'])
#            cmd_line.extend([GNAThub.u_main()])

        cmd_line.extend(['-j%d' % GNAThub.jobs()])

        cmd_line = cmd_line + GNAThub.Project.scenario_switches()

        if GNAThub.Project.target():
            cmd = '{}-{}'.format(GNAThub.Project.target(), cmd_line[0])
            if self.__cmd_exists(cmd):
                cmd_line[0] = cmd
            else:
                cmd_line.extend(['--target', GNAThub.Project.target()])

        if GNAThub.Project.runtime():
            cmd_line.extend(('--RTS', GNAThub.Project.runtime()))
        if GNAThub.subdirs():
            cmd_line.extend(['--subdirs=' + GNAThub.subdirs()])
        return cmd_line
示例#2
0
    def __cmd_line(self):
        """Create GNATmetric command line arguments list.

        :return: the GNATmetric command line
        :rtype: collections.Iterable[str]
        """
        cmd_line = [
            self.name, '-ox', self.output, '-P',
            GNAThub.Project.path()
        ]

        if GNAThub.u_process_all():
            cmd_line.extend(['-U'])

#  Keeping this for later implementation of -U main switch
#        if GNAThub.u_main():
#            cmd_line.extend(['-U'])
#            cmd_line.extend([GNAThub.u_main()])

        cmd_line = cmd_line + GNAThub.Project.scenario_switches()

        if GNAThub.Project.target():
            cmd_line[0] = '{}-{}'.format(GNAThub.Project.target(), cmd_line[0])
        if GNAThub.Project.runtime():
            cmd_line.extend(('--RTS', GNAThub.Project.runtime()))
        if GNAThub.subdirs():
            cmd_line.extend(['--subdirs=' + GNAThub.subdirs()])

        return cmd_line
示例#3
0
    def __add_message(self, src, line, column, rule_id, msg, tag=None):
        """Add GNATcheck message to current session database.

        :param str src: Message source file.
        :param str line: Message line number.
        :param str column: Message column number.
        :param str rule_id: Message's rule identifier.
        :param str msg: Description of the message.
        """

        # Cache the rules
        if rule_id in self.rules:
            rule = self.rules[rule_id]
        else:
            rule = GNAThub.Rule(rule_id, rule_id, GNAThub.RULE_KIND, self.tool)
            self.rules[rule_id] = rule

        # Set predefined unspecified ranking for all GNATcheck messages
        ranking = GNAThub.RANKING_UNSPECIFIED

        # Cache the messages
        if (rule, msg, ranking) in self.messages:
            message = self.messages[(rule, msg, ranking)]
        else:
            if tag:
                message = GNAThub.Message(rule, msg, ranking, 0, tag)
            else:
                message = GNAThub.Message(rule, msg, ranking)

            self.messages[(rule, msg, ranking)] = message

        # Add the message to the given resource
        self.bulk_data[src].append(
            [message, int(line), int(column), int(column)])
示例#4
0
    def __cmd_line(self):
        """Create GNATmetric command line arguments list.

        :return: the GNATmetric command line
        :rtype: collections.Iterable[str]
        """
        cmd_line = [
            self.name, '-ox', self.output, '-P', GNAThub.Project.path()]

        if GNAThub.u_process_all():
            cmd_line.extend(['-U'])

#  Keeping this for later implementation of -U main switch
#        if GNAThub.u_main():
#            cmd_line.extend(['-U'])
#            cmd_line.extend([GNAThub.u_main()])

        cmd_line = cmd_line + GNAThub.Project.scenario_switches()

        if GNAThub.Project.target():
            cmd_line[0] = '{}-{}'.format(GNAThub.Project.target(), cmd_line[0])
        if GNAThub.Project.runtime():
            cmd_line.extend(('--RTS', GNAThub.Project.runtime()))
        if GNAThub.subdirs():
            cmd_line.extend(['--subdirs=' + GNAThub.subdirs()])

        return cmd_line
示例#5
0
    def __add_message(self, src, line, column, rule_id, msg, category):
        """Add GNATprove message to current session database.

        :param str src: message source file
        :param str line: message line number
        :param str column: message column number
        :param str rule_id: message rule identifier
        :param str msg: description of the message
        :param str category: the category of the message
        """

        # Get message ranking value
        ranking = self.__get_ranking(category)

        # Cache the rules
        if rule_id in self.rules:
            rule = self.rules[rule_id]
        else:
            rule = GNAThub.Rule(rule_id, rule_id, GNAThub.RULE_KIND, self.tool)
            self.rules[rule_id] = rule

        # Cache messages
        if (rule, msg, ranking) in self.messages:
            message = self.messages[(rule, msg, ranking)]
        else:
            message = GNAThub.Message(rule, msg, ranking)
            self.messages[(rule, msg, ranking)] = message

        # Add the message to the given resource
        self.bulk_data[src].append(
            [message, int(line), int(column),
             int(column)])
    def report(self):
        """Parse GNATmetric XML report and save data to the database.

        Returns according to the success of the analysis:

            * ``GNAThub.EXEC_SUCCESS``: transactions committed to database
            * ``GNAThub.EXEC_FAILURE``: error while parsing the xml report
        """

        self.info('clear existing results if any')
        GNAThub.Tool.clear_references(self.name)

        self.info('analyse report')

        self.tool = GNAThub.Tool(self.name)
        self.log.debug('parse XML report: %s', self.output)

        try:
            tree = ElementTree.parse(self.output)

            # Fetch all files
            files = tree.findall('./file')
            total = len(files)

            # List of resource messages suitable for tool level bulk insertion
            resources_messages = []

            for index, node in enumerate(files, start=1):
                resource = GNAThub.Resource.get(node.attrib.get('name'))

                # Save file level metrics
                if not resource:
                    self.warn('skip "%s" message (file not found)' %
                              node.attrib.get('name'))
                    continue

                self.firstunit = True

                resources_messages.append([resource, self.parse_metrics(node)])

                self.tool.add_messages([], self.parse_units(node, resource))

                Console.progress(index, total, new_line=(index == total))

            # Retrieve the project metrics
            resource = GNAThub.Resource(GNAThub.Project.name(),
                                        GNAThub.PROJECT_KIND)
            resources_messages.append([resource, self.parse_metrics(tree)])
            self.tool.add_messages(resources_messages, [])

        except ParseError as why:
            self.log.exception('failed to parse XML report')
            self.error('%s (%s:%s)' % (why, why.filename, why.lineno))
            return GNAThub.EXEC_FAILURE

        else:
            return GNAThub.EXEC_SUCCESS
示例#7
0
    def execute_reporters():
        """Whether to execute plugins implementing :class:`GNAThub.Reporter`.

        --runners-only and --reporters-only are mutually exclusive. Runners
        should be executed if --reporters-only is specified or if none is
        specified.

        :rtype: boolean
        """
        return GNAThub.reporters_only() or not GNAThub.runners_only()
示例#8
0
    def execute_reporters():
        """Whether to execute plugins implementing :class:`GNAThub.Reporter`.

        --runners-only and --reporters-only are mutually exclusive. Runners
        should be executed if --reporters-only is specified or if none is
        specified.

        :rtype: boolean
        """
        return GNAThub.reporters_only() or not GNAThub.runners_only()
示例#9
0
    def mainloop(self):
        """Plugin main loop."""
        LOG.info('registered %d plugins', len(self.plugins))
        backlog = []

        # Early exit if no plug-in are scheduled to be run
        if not self.plugins:
            self.info('nothing to do')
            return

        # Execute each plug-in in order
        try:
            for cls in self.plugins:
                try:
                    # Create a new instance
                    plugin, elapsed = cls(), None

                    # Execute the plug-in
                    elapsed = self.execute(plugin)
                except KeyboardInterrupt:
                    raise
                except Exception as why:
                    LOG.exception('plug-in execution failed')
                    self.error('%s: unexpected error: %s', plugin.name, why)
                finally:
                    if plugin.exec_status != GNAThub.NOT_EXECUTED:
                        # A plugin could not have been executed depending on
                        # the command line (--runners-only/--reporters-only).
                        backlog.append((plugin.name, {
                            'time':
                            elapsed or 0,
                            'success':
                            (plugin.exec_status == GNAThub.EXEC_SUCCESS)
                        }))
        except KeyboardInterrupt:
            self.info(os.linesep + 'Interrupt caught...')

        # Write results to file
        fname = os.path.join(GNAThub.root(), 'gnathub.backlog')
        try:
            with open(fname, 'w') as fd:
                fd.write(json.dumps(backlog))
        except IOError as why:
            LOG.exception('could not write result file %s', fname)
            self.error('%s: unexpected error: %s', fname, why)

        if not GNAThub.dry_run() and not GNAThub.quiet():
            # Display a summary
            for plugin, results in backlog:
                if results['success']:
                    Console.ok(plugin)
                else:
                    Console.ko(plugin)
示例#10
0
    def mainloop(self):
        """Plugin main loop."""
        LOG.info('registered %d plugins', len(self.plugins))
        backlog = []

        # Early exit if no plug-in are scheduled to be run
        if not self.plugins:
            self.info('nothing to do')
            return

        # Execute each plug-in in order
        try:
            for cls in self.plugins:
                try:
                    # Create a new instance
                    plugin, elapsed = cls(), None

                    # Execute the plug-in
                    elapsed = self.execute(plugin)
                except KeyboardInterrupt:
                    raise
                except Exception as why:
                    LOG.exception('plug-in execution failed')
                    self.error('%s: unexpected error: %s', plugin.name, why)
                finally:
                    if plugin.exec_status != GNAThub.NOT_EXECUTED:
                        # A plugin could not have been executed depending on
                        # the command line (--runners-only/--reporters-only).
                        backlog.append((plugin.name, {
                            'time': elapsed or 0,
                            'success': (
                                plugin.exec_status == GNAThub.EXEC_SUCCESS)
                        }))
        except KeyboardInterrupt:
            self.info(os.linesep + 'Interrupt caught...')

        # Write results to file
        fname = os.path.join(GNAThub.root(), 'gnathub.backlog')
        try:
            with open(fname, 'w') as fd:
                fd.write(json.dumps(backlog))
        except IOError as why:
            LOG.exception('could not write result file %s', fname)
            self.error('%s: unexpected error: %s', fname, why)

        if not GNAThub.dry_run() and not GNAThub.quiet():
            # Display a summary
            for plugin, results in backlog:
                if results['success']:
                    Console.ok(plugin)
                else:
                    Console.ko(plugin)
示例#11
0
    def __msg_reader_cmd_line():
        """Create GNATprove Message Reader command line arguments list.

        :return: the GNATprove message reader command line
        :rtype: collections.Iterable[str]
        """

        cmd_line = ['gnatprove', '-P', GNAThub.Project.path()]
        if GNAThub.subdirs():
            cmd_line.extend(['--subdirs=' + GNAThub.subdirs()])

        cmd_line.extend(['--report=all', '-j', str(GNAThub.jobs()),
                         '--output-msg-only', '--ide-progress-bar'])
        return cmd_line + GNAThub.Project.scenario_switches()
示例#12
0
 def add_message(rule, message, ranking, line_no, col_begin, col_end):
     bulk_messages.append([
         GNAThub.Message(rule, message, ranking=ranking),
         line_no,
         col_begin,
         col_end,
     ])
示例#13
0
    def parse_units(self, node, resource):
        """Recursively parse the unit node until all of them are found"""
        # Map of entities for a ressource
        entities_messages = []

        if not node.findall('./unit'):
            return []

        for unit in node.findall('./unit'):

            ename = unit.attrib.get('name')

            ekind = unit.attrib.get('kind')
            if self.firstunit:
                ekind = "compilation unit"
                self.firstunit = False
            else:
                if ekind.startswith('procedure'):
                    ekind = ekind.replace("procedure", "action")
                elif ekind.startswith('function'):
                    ekind = ekind.replace("function", "action")

            eline = unit.attrib.get('line')
            ecol = unit.attrib.get('col')

            # A resource can have multiple entities with the same name
            entity = GNAThub.Entity(ename, ekind, int(eline), int(ecol),
                                    int(ecol), resource)

            entities_messages.append([entity, self.parse_metrics(unit, True)])
            entities_messages += self.parse_units(unit, resource)
        return entities_messages
示例#14
0
    def __cmd_line(self):
        """Create GNATstack command line arguments list.

        :return: the GNATstack command line
        :rtype: collections.Iterable[str]
        """

        cmd_line = [
            'gnatstack', '-Q', '-x', '-Wa', '-P',
            GNAThub.Project.path()
        ] + GNAThub.Project.scenario_switches()
        if GNAThub.Project.runtime():
            cmd_line.extend(('--RTS', GNAThub.Project.runtime()))
        if GNAThub.subdirs():
            cmd_line.extend(['--subdirs=' + GNAThub.subdirs()])
        return cmd_line
示例#15
0
    def full_json(self, path):
        """Create and fill an object,
        then create the JSON file to the given path

        This one is for debugging purpose

        :param path string: the path to create the file
        """
        tmp = {
            'project':
            GNAThub.Project.name(),
            '_total_message_count':
            sum(self.message_count.itervalues()),
            '_database':
            GNAThub.database(),
            'creation_time':
            int(time.time()),
            'properties':
            self.props or None,
            'tools':
            self.tools or None,
            'rules':
            self.rules or None,
            'ranking':
            self.ranking or None,
            'review_status':
            self.review_status or None,
            'modules':
            [module.to_json() for name, module in self.modules.iteritems()],
            'sources':
            self.sources
        }
        _write_json(path, tmp, indent=2)
示例#16
0
 def add_message(rule, message, ranking, line_no, column_no):
     bulk_messages.append([
         GNAThub.Message(rule, message, ranking=ranking),
         line_no,
         column_no,
         column_no,
     ])
示例#17
0
    def __msg_reader_cmd_line():
        """Create GNATprove Message Reader command line arguments list.

        :return: the GNATprove message reader command line
        :rtype: collections.Iterable[str]
        """

        cmd_line = ['gnatprove', '-P', GNAThub.Project.path()]
        if GNAThub.subdirs():
            cmd_line.extend(['--subdirs=' + GNAThub.subdirs()])

        cmd_line.extend([
            '--report=all', '-j',
            str(GNAThub.jobs()), '--output-msg-only', '--ide-progress-bar'
        ])
        return cmd_line + GNAThub.Project.scenario_switches()
示例#18
0
    def output_dir(self):
        """Return the path to the directory where to generate the HTML report.

        :return: the full path to the output directory
        :rtype: str
        """

        return os.path.join(GNAThub.root(), self.name)
示例#19
0
    def __msg_reader_cmd_line():
        """Create CodePeer Message Reader command line arguments list.

        :return: the CodePeer message reader command line
        :rtype: collections.Iterable[str]
        """
        cmd_start = ['codepeer', '-P', GNAThub.Project.path()]
        if GNAThub.subdirs():
            cmd_start.extend(['--subdirs=' + GNAThub.subdirs()])

        cmd_start.extend([ToolArgsPlaceholder('codepeer')])

        cmd_end = [
            '-output-msg-only', '-csv',
            ToolArgsPlaceholder('codepeer_msg_reader')
        ]
        return cmd_start + GNAThub.Project.scenario_switches() + cmd_end
示例#20
0
def _import_codepeer_bridge(filename):
    app.logger.info("Import info into codepeer_bridge")
    name = 'codepeer_bridge'
    cmd = [
        'codepeer_bridge', '--output-dir=' + OUTPUT_DIR, '--db-dir=' + DB_DIR,
        '--import-reviews=' + filename
    ]
    GNAThub.Run(name, cmd, out=SERVER_LOG, append_out=True)
示例#21
0
    def __cmd_line(self):
        """Create GNATstack command line arguments list.

        :return: the GNATstack command line
        :rtype: collections.Iterable[str]
        """

        cmd_line = [
            'gnatstack', '-Q', '-x', '-Wa',
            '-P', GNAThub.Project.path()] + GNAThub.Project.scenario_switches()
        if GNAThub.Project.target():
            cmd_line[0] = '{}-{}'.format(GNAThub.Project.target(), cmd_line[0])
        if GNAThub.Project.runtime():
            cmd_line.extend(('--RTS', GNAThub.Project.runtime()))
        if GNAThub.subdirs():
            cmd_line.extend(['--subdirs=' + GNAThub.subdirs()])
        return cmd_line
示例#22
0
    def __msg_reader_cmd_line(report):
        """Create CodePeer Message Reader command line arguments list.

        :return: the CodePeer message reader command line
        :rtype: collections.Iterable[str]
        """
        cmd_start = ['codepeer', '-P', GNAThub.Project.path()]
        if GNAThub.subdirs():
            cmd_start.extend(['--subdirs=' + GNAThub.subdirs()])

        cmd_start.extend([ToolArgsPlaceholder('codepeer')])

        cmd_end = [
                   '-output-msg-only', '-csv', '-out', report,
                   ToolArgsPlaceholder('codepeer_msg_reader')
                  ]

        return cmd_start + GNAThub.Project.scenario_switches() + cmd_end
示例#23
0
    def report(self):
        """Parse GNATcheck output file report.

        Returns according to the success of the analysis:

            * ``GNAThub.EXEC_SUCCESS``: on successful execution and analysis
            * ``GNAThub.EXEC_FAILURE``: on any error

        Identify two type of messages with different format:

            * basic message
            * message for package instantiation
        """

        self.info('clear existing results if any')
        GNAThub.Tool.clear_references(self.name)

        self.info('analyse report')

        self.tool = GNAThub.Tool(self.name)
        self.log.debug('parse report: %s', self.output)

        if not os.path.exists(self.output):
            self.error('no report found')
            return GNAThub.EXEC_FAILURE

        try:
            with open(self.output, 'r') as output:
                lines = output.readlines()
                total = len(lines)

                for index, line in enumerate(lines, start=1):
                    self.log.debug('parse line: %s', line)
                    match = self._MESSAGE.match(line)

                    if match:
                        self.log.debug('matched: %s', str(match.groups()))
                        self.__parse_line(match)
                    else:
                        match2 = self._MESSAGE_INST.match(line)
                        if match2:
                            self.log.debug('matched 2: %s',
                                           str(match2.groups()))
                            self.__parse_line_inst(match2)

                    Console.progress(index, total, new_line=(index == total))

        except IOError as why:
            self.log.exception('failed to parse report')
            self.error('%s (%s:%d)' %
                       (why, os.path.basename(self.output), total))
            return GNAThub.EXEC_FAILURE

        else:
            self.__do_bulk_insert()
            return GNAThub.EXEC_SUCCESS
示例#24
0
def _export_codeper_bridge(filename):
    app.logger.info("Export info from codepeer_bridge")
    name = 'codepeer_bridge'
    cmd = [
        'codepeer_bridge', '--output-dir=' + OUTPUT_DIR, '--db-dir=' + DB_DIR,
        '--export-reviews=' +
        os.path.join(GNAThub.Project.object_dir(), 'gnathub', 'html-report',
                     'data', filename)
    ]
    GNAThub.Run(name, cmd, out=SERVER_LOG, append_out=True)
示例#25
0
    def run(self):
        """Execute GNATstack.

        Returns according to the success of the execution of the tool:

            * ``GNAThub.EXEC_SUCCESS``: on successful execution
            * ``GNAThub.EXEC_FAILURE``: on any error
        """
        return GNAThub.EXEC_SUCCESS if GNAThub.Run(self.name, self.__cmd_line(
        )).status in GNATstack.VALID_EXIT_CODES else GNAThub.EXEC_FAILURE
示例#26
0
    def run(self):
        """Execute GNATmetric.

        Returns according to the success of the execution of the tool:

            * ``GNAThub.EXEC_SUCCESS``: on successful execution
            * ``GNAThub.EXEC_FAILURE``: on any error
        """

        status = GNAThub.Run(self.name, self.__cmd_line()).status
        return GNAThub.EXEC_SUCCESS if status == 0 else GNAThub.EXEC_FAILURE
示例#27
0
    def __init__(self):
        super(GNATmetric, self).__init__()

        if GNAThub.dry_run_without_project():
            return

        self.tool = None
        self.output = os.path.join(GNAThub.Project.object_dir(), 'metrix.xml')
        self.rules = {}
        self.messages = {}
        self.firstunit = False
示例#28
0
    def workdir():
        """Return the path to sonar execution directory.

        Located within GNAThub's root directory:

            :file:`<project_object_dir>/gnathub/sonar`

        :return: the path to the working directory
        :rtype: str
        """
        return os.path.join(GNAThub.root(), SonarQube.EXEC_DIRECTORY)
示例#29
0
    def report(self):
        """Execute the SonarQube Scanner.

        Returns according to the successful of the analysis:

            * ``GNAThub.EXEC_SUCCESS``: on successful execution and analysis
            * ``GNAThub.EXEC_FAILURE``: on any error
        """
        return GNAThub.EXEC_SUCCESS if GNAThub.Run(
            self.name, self.__cmd_line(),
            workdir=SonarQube.workdir()).status == 0 else GNAThub.EXEC_FAILURE
示例#30
0
    def __cmd_line():
        """Create GNATprove command line arguments list.

        :return: the GNATprove command line
        :rtype: collections.Iterable[str]
        """

        cmd_line = ['gnatprove', '-P', GNAThub.Project.path()]
        if GNAThub.u_process_all():
            cmd_line.extend(['-U'])

#  Keeping this for later implementation of -U main switch
#        if GNAThub.u_main():
#            cmd_line.extend([GNAThub.u_main()])

        if GNAThub.subdirs():
            cmd_line.extend(['--subdirs=' + GNAThub.subdirs()])

        cmd_line.extend(['--report=all', '-j', str(GNAThub.jobs())])
        return cmd_line + GNAThub.Project.scenario_switches()
示例#31
0
    def run(self):
        """Execute GNATprove.

        Sets the exec_status property according to the success of the
        execution of the tool:

            * ``GNAThub.EXEC_SUCCESS``: on successful execution
            * ``GNAThub.EXEC_FAILURE``: on any error
        """
        return GNAThub.EXEC_SUCCESS if GNAThub.Run(
            self.name, self.__cmd_line()).status == 0 else GNAThub.EXEC_FAILURE
示例#32
0
    def __cmd_line():
        """Create GNATprove command line arguments list.

        :return: the GNATprove command line
        :rtype: collections.Iterable[str]
        """

        cmd_line = ['gnatprove', '-P', GNAThub.Project.path()]
        if GNAThub.u_process_all():
            cmd_line.extend(['-U'])

#  Keeping this for later implementation of -U main switch
#        if GNAThub.u_main():
#            cmd_line.extend([GNAThub.u_main()])

        if GNAThub.subdirs():
            cmd_line.extend(['--subdirs=' + GNAThub.subdirs()])

        cmd_line.extend(['--report=all', '-j', str(GNAThub.jobs())])
        return cmd_line + GNAThub.Project.scenario_switches()
示例#33
0
    def parse_metrics(self, node, entity=False):
        """Parse the xml *node* returns a list of metrics"""
        message_data = []

        for metric in node.findall('./metric'):
            name = metric.attrib.get('name')
            if name in self.rules:
                rule = self.rules[name]
            else:
                rule = GNAThub.Rule(name, name, GNAThub.METRIC_KIND, self.tool)
                self.rules[name] = rule

            if (rule, metric.text, GNATmetric.RANKING) in self.messages:
                msg = self.messages[(rule, metric.text, GNATmetric.RANKING)]
            else:
                msg = GNAThub.Message(rule, metric.text, GNATmetric.RANKING)
                self.messages[(rule, metric.text, GNATmetric.RANKING)] = msg

            message_data.append([msg, 0, 1, 1])
        return message_data
示例#34
0
    def __add_message(self, src, line, column, rule_id, msg, category,
                      tool_msg_id, properties):
        """Add CodePeer message to current session database.

        :param str src: message source file
        :param str line: message line number
        :param str column: message column number
        :param str rule_id: message rule identifier
        :param str msg: description of the message
        :param str category: the category of the message
        :param str tool_msg_id: the original id of the message
        :param properties: the message properties
        :type properties: collections.Iterable[GNAThub.Property] or None
        """

        # Get message ranking value
        ranking = self.__get_ranking(category)

        # Cache the rules
        if rule_id in self.rules:
            rule = self.rules[rule_id]
        else:
            rule = GNAThub.Rule(rule_id, rule_id, GNAThub.RULE_KIND, self.tool)
            self.rules[rule_id] = rule

        # Get message id from string
        msg_id = 0
        if tool_msg_id and tool_msg_id.strip().isdigit():
            msg_id = int(tool_msg_id)

        # Cache the messages
        if (rule, msg, ranking, msg_id) in self.messages:
            message = self.messages[(rule, msg, ranking, msg_id)]
        else:
            message = GNAThub.Message(rule, msg, ranking, msg_id, properties)
            self.messages[(rule, msg, ranking, msg_id)] = message

        # Add the message to the given resource
        self.bulk_data[src].append(
            [message, int(line), int(column),
             int(column)])
示例#35
0
    def __cmd_line():
        """Create CodePeer command line arguments list.

        :return: the CodePeer command line
        :rtype: collections.Iterable[str]
        """
        cmd_line = ['codepeer', '-P', GNAThub.Project.path(),
                    '-j%d' % GNAThub.jobs()]

        if GNAThub.u_process_all():
            cmd_line.extend(['-U'])

#  Keeping this for -U main switch implemntation
#        if GNAThub.u_main():
#            cmd_line.extend(['-U'])
#            cmd_line.extend([GNAThub.u_main()])

        if GNAThub.subdirs():
            cmd_line.extend(['--subdirs=' + GNAThub.subdirs()])

        return cmd_line + GNAThub.Project.scenario_switches()
示例#36
0
    def __msg_reader_cmd_line(report):
        """Create CodePeer Message Reader command line arguments list.

        :return: the CodePeer message reader command line
        :rtype: collections.Iterable[str]
        """
        cmd_start = ['codepeer', '-P', GNAThub.Project.path()]
        if GNAThub.subdirs():
            cmd_start.extend(['--subdirs=' + GNAThub.subdirs()])

        cmd_start.extend([ToolArgsPlaceholder('codepeer')])

        dest = os.path.join(GNAThub.Project.artifacts_dir(), 'codepeer',
                            'codepeer_run')

        cmd_end = [
            '-output-msg-only', '-csv', '-csv-out', report,
            ToolArgsPlaceholder('codepeer_msg_reader'), '-db-info', dest
        ]

        return cmd_start + GNAThub.Project.scenario_switches() + cmd_end
示例#37
0
    def emit(self, record):
        """Inherited."""
        if record.name in self.loggers:
            logger = self.loggers[record.name]
        else:
            logger = GNAThub.Logger(record.name)
            self.loggers[record.name] = logger

        try:
            message = self.format(record)
            logger.log(message)
        except KeyboardInterrupt, SystemExit:
            raise
示例#38
0
    def __init__(self):
        super(GNATcoverage, self).__init__()

        if GNAThub.dry_run_without_project():
            return

        self.GNATCOVERAGE_OUTPUT = os.path.join(
            GNAThub.Project.artifacts_dir())
        self.XML_EXT = '.xml'

        self.tool = None
        # Mapping: coverage level -> issue rule for this coverage.
        self.issue_rules = {}
示例#39
0
    def execute(cls, plugin):
        """Execute the plugin.

        Call methods setup, execute and teardown for a plugin instance.

        :param GNAThub.Plugin plugin: instance of the plugin to execute
        :return: the execution time in seconds
        :rtype: int
        """
        elapsed = 0

        if cls.should_execute(plugin):
            cls.info('execute plug-in %s', plugin.name)
            if GNAThub.dry_run():
                # Early exit if dry-run mode is enabled
                plugin.exec_status = GNAThub.EXEC_SUCCESS
                return 0

            LOG.info('%s: set up environment', plugin.name)
            start = time.time()
            plugin.setup()

            if cls.execute_runners() and cls.is_runner(plugin):
                LOG.info('%s: produce results', plugin.name)
                plugin.exec_status = plugin.run()

            if (cls.execute_reporters() and cls.is_reporter(plugin) and
                    plugin.exec_status in (
                        GNAThub.EXEC_SUCCESS, GNAThub.NOT_EXECUTED)):
                LOG.info('%s: collect results', plugin.name)
                plugin.exec_status = plugin.report()

            LOG.info('%s: post execution', plugin.name)
            plugin.teardown()
            elapsed = time.time() - start

        if plugin.exec_status == GNAThub.EXEC_SUCCESS:
            plugin.info('completed (in %d seconds)' % elapsed)
        elif plugin.exec_status == GNAThub.EXEC_FAILURE:
            plugin.error('execution failed')
        else:
            assert plugin.exec_status == GNAThub.NOT_EXECUTED
            plugin.info('not executed')
        return elapsed
示例#40
0
    def filter_to_json(self, path):
        """Create and fill an object,
        then create the JSON file to the given path

        This one is for filter panel

        :param path string: the path to create the file
        """
        tmp = {
            'project': GNAThub.Project.name(),
            '_total_message_count': sum(self.message_count.itervalues()),
            '_database': GNAThub.database(),
            'creation_time': int(time.time()),
            'properties': self.props or None,
            'tools': self.tools or None,
            'rules': self.rules or None,
            'ranking': self.ranking or None,
            'review_status': self.review_status or None
        }
        _write_json(path, tmp, indent=2)
示例#41
0
    def full_json(self, path):
        """Create and fill an object,
        then create the JSON file to the given path

        This one is for debugging purpose

        :param path string: the path to create the file
        """
        tmp = {
            'project': GNAThub.Project.name(),
            '_total_message_count': sum(self.message_count.itervalues()),
            '_database': GNAThub.database(),
            'creation_time': int(time.time()),
            'properties': self.props or None,
            'tools': self.tools or None,
            'rules': self.rules or None,
            'ranking': self.ranking or None,
            'review_status': self.review_status or None,
            'modules': [module.to_json() for name,
                        module in self.modules.iteritems()],
            'sources': self.sources
        }
        _write_json(path, tmp, indent=2)
示例#42
0
    def report(self):
        """Analyse the report files generated by :program:`GNATcoverage`.

        Finds all .xcov files in the object directory and parses them.

        Sets the exec_status property according to the success of the analysis:

            * ``GNAThub.EXEC_SUCCESS``: on successful execution and analysis
            * ``GNAThub.EXEC_FAILURE``: on any error
        """
        # Clear existing references only if not incremental run
        if not GNAThub.incremental():
            self.log.info('clear existing results if any')
            GNAThub.Tool.clear_references(self.name)

        self.info('parse coverage reports (%s)' % self.GNATCOV_EXT)

        # Fetch all files in project object directory and retrieve only
        # .xcov files, absolute path
        files = [os.path.join(GNAThub.Project.object_dir(), filename)
                 for filename in os.listdir(GNAThub.Project.object_dir())
                 if filename.endswith(self.GNATCOV_EXT)]

        # If no .xcov file found, plugin returns on failure
        if not files:
            self.error('no %s file in object directory' % self.GNATCOV_EXT)
            return GNAThub.EXEC_FAILURE

        self.tool = GNAThub.Tool(self.name)
        for cov_level in ('stmt', 'decision', 'mcdc'):
            self.issue_rules[cov_level] = GNAThub.Rule(
                cov_level, cov_level, GNAThub.RULE_KIND, self.tool)

        total = len(files)

        # List of resource messages suitable for tool level bulk insertion
        resources_messages = []

        try:
            for index, filename in enumerate(files, start=1):
                # Retrieve source fullname (`filename` is the *.xcov report
                # file).
                base, _ = os.path.splitext(os.path.basename(filename))
                src = GNAThub.Project.source_file(base)

                resource = GNAThub.Resource.get(src)

                if resource:
                    self.__process_file(resource, filename, resources_messages)

                Console.progress(index, total, new_line=(index == total))

            # Tool level insert for resources messages
            self.tool.add_messages(resources_messages, [])

        except (IOError, ValueError) as why:
            self.log.exception('failed to parse reports')
            self.error(str(why))
            return GNAThub.EXEC_FAILURE

        else:
            return GNAThub.EXEC_SUCCESS
示例#43
0
    def report(self):
        """Execute CodePeer message reader and parses the output.

        Sets the exec_status property according to the success of the analysis:

            * ``GNAThub.EXEC_SUCCESS``: on successful execution and analysis
            * ``GNAThub.EXEC_FAILURE``: on any error
        """

        # Clear existing references only if not incremental run
        if not GNAThub.incremental():
            self.info('clear existing results if any')
            GNAThub.Tool.clear_references(self.name)

        self.info('extract results with msg_reader to %s' % self.csv_report)
        proc = GNAThub.Run(
            self.output_dir, self.__msg_reader_cmd_line(self.csv_report))

        if proc.status != 0:
            return GNAThub.EXEC_FAILURE

        self.info('analyse CSV report form %s' % self.csv_report)
        self.tool = GNAThub.Tool(self.name)

        self.log.debug('parse report: %s', self.csv_report)

        if not os.path.isfile(self.csv_report):
            self.error('no report found')
            return GNAThub.EXEC_FAILURE

        with open(self.csv_report, 'rb') as report:
            # Compute the total number of lines for progress report (-1 because
            # the first line in irrelevant to the analysis).
            index, total = 0, len(report.readlines()) - 1

            # Reset the read cursor to the first byte
            report.seek(0)

            # Create the tag "New" for new CodePeer messages
            added_tag = GNAThub.Property('codepeer:added', 'Added')
            removed_tag = GNAThub.Property('codepeer:removed', 'Removed')
            unchanged_tag = GNAThub.Property('codepeer:unchanged', 'Unchanged')

            try:
                # Parse the file and drop the first line (containing the
                # columns name).
                reader = csv.reader(report, quotechar='\"')

                # Drop the first line (containing the columns name)
                header = reader.next()
                self.log.debug('drop header line: %s', header)

                # Iterate over each relevant record
                for index, record in enumerate(reader, start=1):
                    self.log.debug('parse record: %r', record)

                    # Each row is a list of strings:
                    #
                    #   File, Line, Column, Category, History, Has_Review,
                    #   Ranking, Kind, Message, Classification, CWE, Checks,
                    #   Primary_Checks, Subp, Timestamp, Approved By, Comment,
                    #   Message_Id
                    (
                        source, line, column, rule, history, has_review,
                        severity, category, message, classification, cwe,
                        checks, pchecks, subp, timestamp, app_by, comment,
                        message_id
                    ) = record[:18]

                    if not severity or severity == 'suppressed':
                        # Some versions of codepeer report an empty severity
                        # for suppressed messages: map this to 'info'.
                        severity = 'info'

                    rule_id = rule.lower()
                    self.__add_message(
                        source, line, column, rule_id, message, severity,
                        message_id,
                        [added_tag if history == 'added' else
                         (removed_tag if history == 'removed' else
                          unchanged_tag)]
                    )

                    if index % 100 == 1 or index == total:
                        Console.progress(
                            index, total, new_line=(index == total))

            except csv.Error as why:
                self.log.exception('failed to parse CSV report')
                self.error('%s (%s:%d)' % (
                    why, os.path.basename(self.csv_report), index))
                return GNAThub.EXEC_FAILURE

            else:
                self.__do_bulk_insert()
                return GNAThub.EXEC_SUCCESS
示例#44
0
    def auto_discover_plugins(cls):
        """Retrieve all plugins for GNAThub.

        This routine first lists all available scripts for this run of GNAThub.
        It then tries to load each one of them and collect any Plugin declared
        in those scripts.

        This list of plugins is then filtered given the parameters of the run,
        ie.:
            * If the switch --plugins is supplied on the command line, execute
              only plugins whose name is in this list;
            * Otherwise, if the project file contains the GNATdashboard.Plugins
              attribute, execute only plugins whose name is in this list;
            * Otherwise, execute all available plugins.

        :return: the list of plugins available in the current environment
        :rtype: collections.Iterable[GNAThub.Plugin]
        """
        # Locate all Python scripts that might hold the definition of one or
        # more plugins.
        scripts = set()

        for name, path in GNAThub.repositories().items():
            if not os.path.isdir(path):
                LOG.info('skip repository [%s] (not found)', name)
                continue

            LOG.info('load scripts from [%s] repository', name)
            repo_scripts = list(cls.walk_repository(path))

            LOG.info('  + %d new script(s) found', len(repo_scripts))
            scripts.update(repo_scripts)

            if len(repo_scripts):
                # Add the repository to sys.path so that modules can import
                # themselves. Do this only if scripts were found in this
                # repository.
                sys.path.append(path)

        # Compute the plugins list given the program input and their priority.
        # Priority order:
        #       1. Command line
        #       2. Project file
        #       3. All discoverable plugins

        if GNAThub.plugins():
            LOG.info('use user-defined list of plugins (--plugins switch)')
            explicit = [p.strip() for p in GNAThub.plugins().split(',')]

        elif GNAThub.Project.property_as_list('Plugins'):
            LOG.info('use project-defined list of plugins (attr. Plugins)')
            explicit = GNAThub.Project.property_as_list('Plugins')

        else:
            LOG.info('use all discoverable plugins')
            explicit = None

        # Generate the final list of plugin classes. Inspect Python scripts to
        # extract class definition and filter out those that will not be used.

        LOG.info('located %d scripts', len(scripts))
        plugins = sum([list(cls.inspect(s)) for s in scripts], [])

        def is_plugin(clazz, name):
            """Check whether this plugin name is ``name``.

            :param type clazz: the plugin type object
            :param str name: the expected name
            :return: ``True`` if this plugin name is ``name``
            :rtype: boolean
            """
            return (
                clazz.__name__.lower() == name.lower() or
                clazz().name.lower() == name.lower()
            )

        def contains_plugin_name(clazz, names):
            """Check whether the plugin name is in ``names``.

            :param type clazz: the plugin type object
            :param collections.Iterable[str] names: the list of name
            :return: ``True`` if the plugin name is in ``names``
            :rtype: boolean
            """
            for name in names:
                if is_plugin(clazz, name):
                    return True

            return False

        if explicit:
            # Cleanup user input if needed. The following statement remove
            # None and empty string values as well as duplicates. It also set
            # the plugin name to lower case for future comparison.
            explicit = set([p.lower() for p in explicit if p])

            # Filter out any plugin whose name is not in the "explicit" set
            plugins = [c for c in plugins if contains_plugin_name(c, explicit)]

        # Remove explicitly disabled plugins
        for name in GNAThub.Project.property_as_list('Plugins_Off'):
            for clazz in plugins:
                if is_plugin(clazz, name):
                    LOG.info('disable %s [Plugin_Off]', name)
                    plugins.remove(clazz)
                    break

            LOG.warn('%s explicitly disabled but not loaded', name)

        return cls.schedule(plugins)
示例#45
0
    def report(self):
        """Parse GNATstack output file report.

        Returns according to the success of the analysis:

            * ``GNAThub.EXEC_SUCCESS``: on successful execution and analysis
            * ``GNAThub.EXEC_FAILURE``: on any error
        """
        # Clear existing references only if not incremental run
        if not GNAThub.incremental():
            self.log.info('clear existing results if any')
            GNAThub.Tool.clear_references(self.name)

        self.info('analyse report')

        self.tool = GNAThub.Tool(self.name)
        if not os.path.exists(self.output):
            self.error('no report found')
            return GNAThub.EXEC_FAILURE
        self.log.debug('parse XML report: %s', self.output)

        # List of resource messages suitable for tool level bulk insertion
        resources_messages = []
        # Map of list of messages by entities
        entities_messages_map = {}
        # List of entity messages suitable for tool level bulk insertion
        entities_messages = []
        # List of indirect call location
        indirect_loc_list = []

        try:
            tree = ElementTree.parse(self.output)
            global_node = tree.find('./global')

            # Retrieve the metrics and the map of subprogram by id
            subprograms = tree.find('./subprogramset').findall('./subprogram')
            if subprograms:
                unknown_global = GNAThub.Rule("Unknown Global Stack Usage",
                                              "Unknown Global Stack Usage",
                                              GNAThub.METRIC_KIND,
                                              self.tool)
                static_global = GNAThub.Rule("Static Global Stack Usage",
                                             "Static Global Stack Usage",
                                             GNAThub.METRIC_KIND,
                                             self.tool)
                unknown_local = GNAThub.Rule("Unknown Local Stack Usage",
                                             "Unknown Local Stack Usage",
                                             GNAThub.METRIC_KIND,
                                             self.tool)
                static_local = GNAThub.Rule("Static Local Stack Usage",
                                            "Static Local Stack Usage",
                                            GNAThub.METRIC_KIND,
                                            self.tool)
            for node in subprograms:
                subprogram_id = node.attrib.get('id')
                locations = node.find('./locationset').findall('./location')
                global_usage = node.find('./globalstackusage')
                local_usage = node.find('./localstackusage')
                name = node.attrib.get('prefixname')
                if name == "indirect call":
                    # The columns are only defined here so save them for later
                    line = locations[0].attrib.get('line')
                    column = locations[0].attrib.get('column')
                    indirect_loc_list.append([line, column])
                    continue
                else:
                    name = self.pretty_print_name(name)

                for loc in locations:
                    file = loc.attrib.get('file')
                    line = loc.attrib.get('line')
                    column = loc.attrib.get('column')
                    if file in self.resources:
                        resource = self.resources[file]
                    else:
                        resource = GNAThub.Resource(file, GNAThub.FILE_KIND)
                        self.resources[file] = resource

                    # entities default value for kind is set to "porcedure"
                    entity = GNAThub.Entity(name, "action",
                                            int(line), int(column),
                                            int(column), resource)
                    # Only link the id to the first location of the entity
                    if subprogram_id not in self.subprograms:
                        self.subprograms[subprogram_id] = entity
                    else:
                        continue

                    size = global_usage.attrib.get('size')
                    if global_usage.attrib.get('qualifier') == "UNKNOWN":
                        metric = unknown_global
                    else:
                        metric = static_global
                    global_metric = GNAThub.Message(metric,
                                                    size,
                                                    ranking=GNATstack.RANKING)

                    size = local_usage.attrib.get('size')
                    if local_usage.attrib.get('qualifier') == "UNKNOWN":
                        metric = unknown_local
                    else:
                        metric = static_local
                    local_metric = GNAThub.Message(metric,
                                                   size,
                                                   ranking=GNATstack.RANKING)

                    entities_messages_map[subprogram_id] = (
                        [[global_metric, 0, 1, 1], [local_metric, 0, 1, 1]])

            # Analyse the indirect calls
            indirects = global_node.find('./indirectset').findall('./indirect')
            if indirects:
                indirect_rule = GNAThub.Rule("Indirect Call",
                                             "Indirect Call",
                                             GNAThub.RULE_KIND,
                                             self.tool)
            for node in indirects:
                indirect_id = node.attrib.get('id')
                if indirect_id not in self.subprograms:
                    continue

                set = node.find('./indirectcallset').findall('./indirectcall')
                for call in set:
                    line = call.find('./line').find('./value').text
                    # Go through the list of saved locations and use the
                    # line to retrieve a corresponding column
                    column = 1
                    pos = -1
                    for ix in range(len(indirect_loc_list)):
                        if indirect_loc_list[ix][0] == line:
                            pos = ix
                            column = indirect_loc_list[pos][1]
                            continue
                    if pos != -1:
                        indirect_loc_list.pop(pos)
                    message = GNAThub.Message(indirect_rule,
                                              'indirect call',
                                              ranking=GNATstack.RANKING)
                    entities_messages_map[indirect_id].append([message,
                                                               int(line),
                                                               int(column),
                                                               int(column)])

            # Analyse the external calls
            externals = global_node.find('./externalset').findall('./external')
            if externals:
                external_rule = GNAThub.Rule("External Call",
                                             "External Call",
                                             GNAThub.RULE_KIND,
                                             self.tool)
            for node in externals:
                subprogram_id = node.attrib.get('id')
                if subprogram_id not in self.subprograms:
                    continue
                message = GNAThub.Message(external_rule,
                                          "external call",
                                          ranking=GNATstack.RANKING)
                entities_messages_map[subprogram_id].append([message, 0, 1, 1])

            # Analyse the potential cycle
            cycles = global_node.find('./cycleset').findall('./cycle')
            if cycles:
                cycle_rule = GNAThub.Rule("Potential Cycle",
                                          "Potential Cycle",
                                          GNAThub.RULE_KIND,
                                          self.tool)
            for node in cycles:
                cycle_subprograms = node.findall('./subprogram')
                cycle_list = []
                for sub in cycle_subprograms:
                    subprogram_id = sub.attrib.get('id')
                    cycle_list.append(self.subprograms[subprogram_id].name)
                subprogram_id = cycle_subprograms[0].attrib.get('id')
                cycle_list.append(self.subprograms[subprogram_id].name)
                message = GNAThub.Message(cycle_rule,
                                          "potential cycle detected:\n\t\t" +
                                          "\n\t\t".join(cycle_list),
                                          ranking=GNATstack.RANKING)
                entities_messages_map[subprogram_id].append([message, 0, 1, 1])

            # Analyse the unbounded frames
            unboundeds = (
                global_node.find('./unboundedset').findall('./unbounded'))
            if unboundeds:
                unbounded_rule = GNAThub.Rule("Unbounded Frame",
                                              "Unbounded Frame",
                                              GNAThub.RULE_KIND,
                                              self.tool)
            for node in unboundeds:
                subprogram_id = node.attrib.get('id')
                if subprogram_id in self.subprograms:
                    message = GNAThub.Message(unbounded_rule,
                                              "This frame is unbounded",
                                              ranking=GNATstack.RANKING)
                    entities_messages_map[subprogram_id].append([message,
                                                                 0, 1, 1])

            # Analyse the entry points
            entries = tree.find('./entryset').findall('./entry')
            # There is always an entry, so create the rule anyway
            entry_rule = GNAThub.Rule("Entry point",
                                      "Entry point",
                                      GNAThub.RULE_KIND,
                                      self.tool)
            for node in entries:
                subprogram_id = node.attrib.get('id')

                if subprogram_id not in self.subprograms:
                    continue
                entity = self.subprograms[subprogram_id]
                local_stack = node.find('./localstackusage')
                size = local_stack.attrib.get('size')
                qualifier = local_stack.attrib.get('qualifier')

                if qualifier == "UNKNOWN":
                    text = "The estimated"
                else:
                    text = "The"
                text += (' call stack size for the entry point "%s" is %s' %
                         (entity.name, str(size)))

                callchain_list = []
                for sub in node.find('./callchain').findall('./subprogram'):
                    chain_id = sub.attrib.get('id')
                    callchain_list.append(self.subprograms[chain_id].name)
                text += (" and the callchain is:\n\t\t%s" %
                         "\n\t\t".join(callchain_list))
                message = GNAThub.Message(entry_rule,
                                          text,
                                          ranking=GNATstack.RANKING)
                entities_messages_map[subprogram_id].append([message, 0, 1, 1])

            # Project message explaining the accuracy of the metrics
            accurate = global_node.find('./accurate')
            if accurate.find('./value').text == "FALSE":
                project = GNAThub.Resource(GNAThub.Project.name(),
                                           GNAThub.PROJECT_KIND)
                rule = GNAThub.Rule("Accuracy", "Accuracy",
                                    GNAThub.RULE_KIND, self.tool)
                text = ("worst case may not be accurate because of: " +
                        ("indirect calls/" if indirects else "") +
                        ("cycles/" if cycles else "") +
                        ("unbounded frames/" if unboundeds else "") +
                        ("external calls" if externals else ""))
                text = text[:-1] if text[-1] == '/' else text
                message = GNAThub.Message(rule,
                                          text,
                                          ranking=GNATstack.RANKING)
                resources_messages.append([project, [[message, 0, 1, 1]]])

            # Insert the messages and the metrics
            for key, value in entities_messages_map.iteritems():
                entities_messages.append([self.subprograms[key], value])
            self.tool.add_messages(resources_messages, entities_messages)
        except ParseError as why:
            self.log.exception('failed to parse XML report')
            self.error('%s (%s:%s)' % (why, why.filename, why.lineno))
            return GNAThub.EXEC_FAILURE
        else:
            return GNAThub.EXEC_SUCCESS
示例#46
0
    def report(self):
        """Parse GNATmetric XML report and save data to the database.

        Returns according to the success of the analysis:

            * ``GNAThub.EXEC_SUCCESS``: transactions committed to database
            * ``GNAThub.EXEC_FAILURE``: error while parsing the xml report
        """

        # Clear existing references only if not incremental run
        if not GNAThub.incremental():
            self.info('clear existing results if any')
            GNAThub.Tool.clear_references(self.name)

        self.info('analyse report')

        self.tool = GNAThub.Tool(self.name)
        self.log.debug('parse XML report: %s', self.output)

        try:
            tree = ElementTree.parse(self.output)

            # Parse the config first to create the GNAThub rules
            self.parse_config(tree)

            # Fetch all files
            files = tree.findall('./file')
            total = len(files)

            # List of resource messages suitable for tool level bulk insertion
            resources_messages = []

            for index, node in enumerate(files, start=1):
                resource = GNAThub.Resource.get(node.attrib.get('name'))

                # Save file level metrics
                if not resource:
                    self.warn('skip "%s" message (file not found)' %
                              node.attrib.get('name'))
                    continue

                self.firstunit = True

                resources_messages.append([resource, self.parse_metrics(node)])

                self.tool.add_messages([], self.parse_units(node, resource))

                Console.progress(index, total, new_line=(index == total))

            # Retrieve the project metrics
            resource = GNAThub.Resource(GNAThub.Project.name(),
                                        GNAThub.PROJECT_KIND)
            resources_messages.append([resource, self.parse_metrics(tree)])
            self.tool.add_messages(resources_messages, [])

        except ParseError as why:
            self.log.exception('failed to parse XML report')
            self.error('%s (%s:%s)' % (why, why.filename, why.lineno))
            return GNAThub.EXEC_FAILURE

        else:
            return GNAThub.EXEC_SUCCESS
示例#47
0
# of the license.

import os
import inspect
import logging

import GNAThub
from GNAThub import Console

# Create this script logger
__file__ = inspect.getfile(inspect.currentframe())
MODULE, _ = os.path.splitext(os.path.basename(__file__))
LOG = logging.getLogger(MODULE)

# Define default path to server.py script
DEFAULT_SCRIPT_PATH = GNAThub.engine_repository()
SCRIPT_NAME = 'server.py'

# Default port value
DEFAULT_PORT = 8080

# Determine script path and check is different of default value
script_path = DEFAULT_SCRIPT_PATH
#  TO DO : Add handling when path is given via --server-dir

if not os.path.exists(script_path):
    repo_msg = script_path + ' repository does not exist'
    Console.error(repo_msg, prefix=MODULE)

else:
    msg = 'load script from ' + script_path + ' repository'
示例#48
0
        if tool.name == tool_name:
            return True
    return False

def relpath(path):
    """Returns the relative path to :param:`path` from BASEDIR.

    :param str path: The full path.
    :returns: str

    """

    return os.path.relpath(path, BASEDIR)


assertTrue(os.path.isdir(GNAThub.root()))
assertEqual(relpath(GNAThub.root()), os.path.join('obj', 'gnathub'))

assertTrue(os.path.isdir(GNAThub.logs()))
assertEqual(relpath(GNAThub.logs()), os.path.join('obj', 'gnathub', 'logs'))

assertTrue(os.path.isfile(GNAThub.database()))
assertEqual(
    relpath(GNAThub.database()),
    os.path.join('obj', 'gnathub', 'gnathub.db')
)

#DB content check

# Check tool exists
TOOL = 'gnatmetric'
示例#49
0
    def report(self):
        """Analyse the report files generated by :program:`Gcov`.

        Finds all .gcov files in the object directory and parses them.

        Sets the exec_status property according to the success of the analysis:

            * ``GNAThub.EXEC_SUCCESS``: on successful execution and analysis
            * ``GNAThub.EXEC_FAILURE``: on any error
        """

        # Clear existing references only if not incremental run
        if not GNAThub.incremental():
            self.log.info('clear existing results if any')
            GNAThub.Tool.clear_references(self.name)

        self.info('parse coverage reports (%s)' % self.GCOV_EXT)

        # Handle multiple object directories
        if GNAThub.Project.object_dirs():
            # If there are object directories defined in the project tree, look
            # for .gcov files there.

            files = []
            for obj_dir in GNAThub.Project.object_dirs():
                # Fetch all files in project object directories and retrieve
                # only .gcov files, absolute path
                for filename in os.listdir(obj_dir):
                    if filename.endswith(self.GCOV_EXT):
                        files.append(os.path.join(obj_dir, filename))

        else:
            # If any object directory is defined in .gpr, fetch all files in
            # default project object directory and retrieve only .gcov files,
            # absolute path
            files = [os.path.join(GNAThub.Project.object_dir(), filename)
                     for filename in os.listdir(GNAThub.Project.object_dir())
                     if filename.endswith(self.GCOV_EXT)]

        # If no .gcov file found, plugin returns on failure
        if not files:
            self.error('no %s file in object directory' % self.GCOV_EXT)
            return GNAThub.EXEC_FAILURE

        self.tool = GNAThub.Tool(self.name)
        self.rule = GNAThub.Rule('coverage', 'coverage',
                                 GNAThub.METRIC_KIND, self.tool)

        total = len(files)

        # List of resource messages suitable for tool level bulk insertion
        resources_messages = []

        try:
            for index, filename in enumerate(files, start=1):
                # Retrieve source fullname (`filename` is the *.gcov report
                # file).

                base, _ = os.path.splitext(os.path.basename(filename))
                src = GNAThub.Project.source_file(base)

                resource = GNAThub.Resource.get(src)

                if resource:
                    self.__process_file(resource, filename, resources_messages)

                Console.progress(index, total, new_line=(index == total))

            # Tool level insert for resources messages
            self.tool.add_messages(resources_messages, [])

        except IOError as why:
            self.log.exception('failed to parse reports')
            self.error(str(why))
            return GNAThub.EXEC_FAILURE

        else:
            return GNAThub.EXEC_SUCCESS
示例#50
0
    def report(self):
        """Execute GNATprove message reader and parses the output.

        Sets the exec_status property according to the success of the analysis:

            * ``GNAThub.EXEC_SUCCESS``: on successful execution and analysis
            * ``GNAThub.EXEC_FAILURE``: on any error
        """
        # Clear existing references only if not incremental run
        if not GNAThub.incremental():
            self.info('clear existing results if any')
            GNAThub.Tool.clear_references(self.name)

        self.info('extract results with msg_reader')
        proc = GNAThub.Run(
            self.output_dir, self.__msg_reader_cmd_line(), out=self.output)

        if proc.status != 0:
            return GNAThub.EXEC_FAILURE

        self.info('analyse report')
        self.tool = GNAThub.Tool(self.name)

        self.log.debug('parse report: %s', self.output_dir)

        if not os.path.isdir(self.output_dir):
            self.error('no report found')
            return GNAThub.EXEC_FAILURE

        for entry in os.listdir(self.output_dir):
            filename, ext = os.path.splitext(entry)
            if not ext == '.spark':
                continue

            self.log.debug('parse file: %s', entry)
            try:
                with open(os.path.join(self.output_dir, entry), 'rb') as spark:
                    results = json.load(spark)
                    for record in chain(results['flow'], results['proof']):
                        if 'msg_id' not in record or 'file' not in record:
                            continue
                        self.log.debug('found record %s', json.dumps(record))

                        msg_id = record['msg_id']
                        filename = record['file']
                        self.msg_ids[(filename, msg_id)] = record

            except IOError as why:
                self.log.exception('failed to parse GNATprove .spark file')
                self.error('%s (%s:%d)' % (
                    why, os.path.basename(self.output)))

        try:
            with open(self.output, 'rb') as fdin:
                # Compute the total number of lines for progress report
                lines = fdin.readlines()
                index, total = 0, len(lines)

                for index, line in enumerate(lines, start=1):
                    self.log.debug('parse line: %r', line)
                    match = self._MESSAGE.match(line)

                    if match:
                        self.log.debug('matched: %s', str(match.groups()))
                        self.__parse_line(match)

                    Console.progress(index, total, new_line=(index == total))

        except IOError as why:
            self.log.exception('failed to parse GNATprove output')
            self.error('%s (%s:%d)' % (
                why, os.path.basename(self.output), total))
            return GNAThub.EXEC_FAILURE

        else:
            self.__do_bulk_insert()
            return GNAThub.EXEC_SUCCESS