From 7587809bb6f08a1ff4754b8d13b8ebfafaabc259 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 5 Jan 2016 00:28:24 +0000 Subject: [PATCH] Improve tour directory logic. - Refactor plugin framework logic for finding configuration directories out into util. - Rework tours to use the plugin framework logic to parse configuration directories. - Rework tour logic to allow multiple tour configuration directories. - Fix up config.ini.sample comments on interactive environments and tours to reflect these changes and include more information like the viz directory does. --- config/galaxy.ini.sample | 8 +++++-- lib/galaxy/tours/__init__.py | 28 ++++++++++++++++-------- lib/galaxy/util/__init__.py | 29 +++++++++++++++++++++++++ lib/galaxy/web/base/pluginframework.py | 30 +------------------------- 4 files changed, 55 insertions(+), 40 deletions(-) diff --git a/config/galaxy.ini.sample b/config/galaxy.ini.sample index 1465c91919f..c1a6fee7001 100644 --- a/config/galaxy.ini.sample +++ b/config/galaxy.ini.sample @@ -273,12 +273,16 @@ paste.app_factory = galaxy.web.buildapp:app_factory # environment plugins. By default none will be loaded. Set to # config/plugins/interactive_environments to load Galaxy's stock plugins # (currently just IPython). These will require Docker to be configured and -# have security considerations, so proceed with caution. +# have security considerations, so proceed with caution. The path is relative to the +# Galaxy root dir. To use an absolute path begin the path with '/'. This is a comma +# separated list. #interactive_environment_plugins_directory = # Interactive tour directory: where to store interactive tour definition files. # Galaxy ships with several basic interface tours enabled, though a different -# directory with custom tours can be specified here. +# directory with custom tours can be specified here. The path is relative to the +# Galaxy root dir. To use an absolute path begin the path with '/'. This is a comma +# separated list. #tour_config_dir = config/plugins/tours # Each job is given a unique empty directory as its current working directory. diff --git a/lib/galaxy/tours/__init__.py b/lib/galaxy/tours/__init__.py index 6fab4cffcf7..00e0be4ebc9 100644 --- a/lib/galaxy/tours/__init__.py +++ b/lib/galaxy/tours/__init__.py @@ -5,6 +5,9 @@ This module manages loading/etc of Galaxy interactive tours. import os import yaml import logging + +from galaxy import util + log = logging.getLogger( __name__ ) @@ -25,8 +28,8 @@ def tour_loader(contents_dict): class ToursRegistry(object): - def __init__(self, tour_dir): - self.tour_dir = tour_dir + def __init__(self, tour_directories): + self.tour_directories = util.config_directories_from_setting( tour_directories ) self.load_tours() def tours_by_id_with_description(self): @@ -36,16 +39,23 @@ class ToursRegistry(object): for k in self.tours.keys()] def load_tour(self, tour_id): - tour_path = os.path.join(self.tour_dir, tour_id + ".yaml") - if not os.path.exists(tour_path): - tour_path = os.path.join(self.tour_dir, tour_id + ".yml") - return self._load_tour_from_path(tour_path) + for tour_dir in self.tour_directories: + tour_path = os.path.join(self.tour_dir, tour_id + ".yaml") + if not os.path.exists(tour_path): + tour_path = os.path.join(self.tour_dir, tour_id + ".yml") + if os.path.exists(tour_path): + break + if os.path.exists(tour_path): + return self._load_tour_from_path(tour_path) + else: + return None def load_tours(self): self.tours = {} - for filename in os.listdir(self.tour_dir): - if filename.endswith('.yaml') or filename.endswith('.yml'): - self._load_tour_from_path(os.path.join(self.tour_dir, filename)) + for tour_dir in self.tour_directories: + for filename in os.listdir(tour_dir): + if filename.endswith('.yaml') or filename.endswith('.yml'): + self._load_tour_from_path(os.path.join(tour_dir, filename)) return self.tours_by_id_with_description() def tour_contents(self, tour_id): diff --git a/lib/galaxy/util/__init__.py b/lib/galaxy/util/__init__.py index c94f2e8b0de..139b57138ba 100644 --- a/lib/galaxy/util/__init__.py +++ b/lib/galaxy/util/__init__.py @@ -1269,6 +1269,35 @@ def galaxy_directory(): return os.path.abspath(galaxy_root_path) +def config_directories_from_setting( directories_setting, galaxy_root=galaxy_root_path ): + """ + Parse the ``directories_setting`` into a list of relative or absolute + filesystem paths that will be searched to discover plugins. + + :type galaxy_root: string + :param galaxy_root: the root path of this galaxy installation + :type directories_setting: string (default: None) + :param directories_setting: the filesystem path (or paths) + to search for plugins. Can be CSV string of paths. Will be treated as + absolute if a path starts with '/', relative otherwise. + :rtype: list of strings + :returns: list of filesystem paths + """ + directories = [] + if not directories_setting: + return directories + + for directory in listify( directories_setting ): + directory = directory.strip() + if not directory.startswith( '/' ): + directory = os.path.join( galaxy_root, directory ) + if not os.path.exists( directory ): + log.warn( 'directory not found: %s', directory ) + continue + directories.append( directory ) + return directories + + def parse_int(value, min_val=None, max_val=None, default=None, allow_none=False): try: value = int(value) diff --git a/lib/galaxy/web/base/pluginframework.py b/lib/galaxy/web/base/pluginframework.py index f52e5f08023..2bc1d269be9 100644 --- a/lib/galaxy/web/base/pluginframework.py +++ b/lib/galaxy/web/base/pluginframework.py @@ -64,39 +64,11 @@ class PluginManager( object ): self.skip_bad_plugins = skip_bad_plugins self.plugins = odict.odict() - self.directories = self.parse_directories_setting( app.config.root, directories_setting ) + self.directories = util.config_directories_from_setting( directories_setting, app.config.root ) self.load_configuration() self.load_plugins() - def parse_directories_setting( self, galaxy_root, directories_setting ): - """ - Parse the ``directories_setting`` into a list of relative or absolute - filesystem paths that will be searched to discover plugins. - - :type galaxy_root: string - :param galaxy_root: the root path of this galaxy installation - :type directories_setting: string (default: None) - :param directories_setting: the filesystem path (or paths) - to search for plugins. Can be CSV string of paths. Will be treated as - absolute if a path starts with '/', relative otherwise. - :rtype: list of strings - :returns: list of filesystem paths - """ - directories = [] - if not directories_setting: - return directories - - for directory in util.listify( directories_setting ): - directory = directory.strip() - if not directory.startswith( '/' ): - directory = os.path.join( galaxy_root, directory ) - if not os.path.exists( directory ): - log.warn( '%s, directory not found: %s', self, directory ) - continue - directories.append( directory ) - return directories - def load_configuration( self ): """ Override to load some framework/plugin specifc configuration.