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
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 = {}
def __init__(self): super(GNATcheck, self).__init__() if GNAThub.dry_run_without_project(): return self.tool = None self.output = os.path.join(GNAThub.Project.artifacts_dir(), '%s.out' % self.name) # Map of rules (couple (name, rule): dict[str,Rule]) self.rules = {} # Map of messages (couple (rule, message): dict[str,Message]) self.messages = {} # Map of bulk data (couple (source, message_data): dict[str,list]) self.bulk_data = collections.defaultdict(list)
def __init__(self): super(GNATstack, self).__init__() if GNAThub.dry_run_without_project(): return self.tool = None # FIXME: For now we can't control where the xml file is created: # it is always created in the project directory self.output = os.path.join(os.path.dirname(GNAThub.Project.path()), "stack_usage.xml") self.resources = {} # Map of ID => entity self.subprograms = {} # Map of ID => name self.subprograms_without_location = {}
def schedule(cls, plugins): """Schedule the plugins execution order. Some system plugins might need to be executed in a specific order, or for example, for the Sonar Runner plugin, last. This routine takes care of ordering the plugins in their final execution order. :param collections.Iterable[GNAThub.Plugin] plugins: list of plugins to be executed :return: the ordered list of plugins :rtype: collection.Iterable[GNAThub.Plugin] """ if GNAThub.dry_run_without_project(): # The list of predefined plugins needs to be gathered, any # sorting is necessary at that point return plugins else: return sorted(plugins, key=lambda p: p().name in cls.POST_PHASE_PLUGINS)
def __init__(self): super(CodePeer, self).__init__() if GNAThub.dry_run_without_project(): return self.tool = None self.csv_report = os.path.join( GNAThub.Project.object_dir(), 'codepeer', '{}.csv'.format(GNAThub.Project.name().lower())) # Map of rules (couple (name, rule): dict[str,Rule]) self.rules = {} # Map of messages (couple (rule, message): dict[str,Message]) self.messages = {} # Map of bulk data (couple (source, message_data): dict[str,list]) self.bulk_data = collections.defaultdict(list)
def schedule(cls, plugins): """Schedule the plugins execution order. Some system plugins might need to be executed in a specific order, or for example, for the Sonar Runner plugin, last. This routine takes care of ordering the plugins in their final execution order. :param collections.Iterable[GNAThub.Plugin] plugins: list of plugins to be executed :return: the ordered list of plugins :rtype: collection.Iterable[GNAThub.Plugin] """ def plugin_sort_fn(a, b): """Sort the plugins. All plugins are equals, apart from the Sonar Runner which should be executed last. Returns a negative, zero or positive number depending on whether the first argument is considered smaller than, equal to, or larger than the second argument. :param GNAThub.Plugin a: first plugin :param GNAThub.Plugin b: second plugin :return: -1, 0 or 1 depending on the input :rtype: int """ if a().name in cls.POST_PHASE_PLUGINS: return 1 if b().name in cls.POST_PHASE_PLUGINS: return -1 return 0 if GNAThub.dry_run_without_project(): # The list of predefined plugins needs to be gathered, any # sorting is necessary at that point return plugins return sorted(plugins, plugin_sort_fn)
def __init__(self): super(SPARK2014, self).__init__() if GNAThub.dry_run_without_project(): return self.tool = None self.output_dir = os.path.join(GNAThub.Project.object_dir(), 'gnatprove') self.output = os.path.join(GNAThub.Project.object_dir(), 'gnatprove-gnathub.out') # Map of message ID (couple (filename, msg_id): dict[*]) self.msg_ids = {} # Map of rules (couple (name, rule): dict[str,Rule]) self.rules = {} # Map of messages (couple (rule, message): dict[str,Message]) self.messages = {} # Map of bulk data (couple (source, message_data): dict[str,list]) self.bulk_data = collections.defaultdict(list)
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 # Early exit when --dry_run mode without project file # and dump the list of plugins if GNAThub.dry_run_without_project(): for cls in self.plugins: plugin = cls() self.info('%s plug-in is available', plugin.name) plugin.exec_status = GNAThub.EXEC_SUCCESS return # Execute each plug-in in order exec_failure = False 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) })) # Compute all plugins execution status exec_failure = (exec_failure or (plugin.exec_status == GNAThub.EXEC_FAILURE)) 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) if exec_failure: self.error('GNAThub error: one or more plugins failed to run!') self.set_failure("Global run failed!")
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 list(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 no object directory was created and --dry-run means that gnathub # was called in discovery mode of predefined plugins if GNAThub.dry_run_without_project(): explicit = None else: 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)] # Return all autodiscovered plugins if is --dry_run mode without # project file as command line parameter if GNAThub.dry_run_without_project(): return cls.schedule(plugins) # 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)