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)
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)
assertFalse(GNAThub.reporters_only()) assertTrue(os.path.isfile(GNAThub.database())) assertEqual( relpath(GNAThub.database()), os.path.join('obj', 'gnathub', 'gnathub.db') ) # Default for jobs number is 0 assertEqual(GNAThub.jobs(), 0) # The plugin list is expected to be empty assertEqual(len(GNAThub.plugins()), 0) # We ensure that the core and extra plugins directories exist repos = GNAThub.repositories() for kind in ('system', 'global'): assertTrue(os.path.isdir(repos[kind])) # GNAThub.run TO_BE_ECHOED = 'this is the message to display on the standard output' process = GNAThub.Run('echo', ('echo', TO_BE_ECHOED)) assertEqual(process.wait(), 0) assertEqual(process.status, 0) assertEqual(process.name, 'echo') assertEqual(process.cmdline_image(), "echo '%s'" % TO_BE_ECHOED) assertEqual(process.output(), os.path.join(GNAThub.logs(), 'echo.log')) assertTrue(os.path.isfile(process.output()))