1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/ed3c78662274/ Changeset: ed3c78662274 User: greg Date: 2013-09-09 20:26:58 Summary: Enable repository dependencies to be specially categorized if they should be installed only to allow the dependent repository's tool dependency to be compiled (in most cases the tool dependency should hopefully be installed as a compiled binary). Affected #: 11 files diff -r 149dbd29acbce6396a969662a9b899cdbb7bdb46 -r ed3c786622741814a07589a1e642cca75c51c822 lib/galaxy/model/__init__.py --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -3571,6 +3571,10 @@ @property def repository_dependencies( self ): + """ + Return all of this repository's repository dependencies, ignoring their attributes like prior_installation_required and + only_if_compiling_contained_td. + """ required_repositories = [] for rrda in self.required_repositories: repository_dependency = rrda.repository_dependency @@ -3608,7 +3612,7 @@ if required_repository.status == self.installation_status.ERROR: required_repositories_with_installation_errors.append( required_repository ) return required_repositories_with_installation_errors - + @property def requires_prior_installation_of( self ): """ @@ -3624,15 +3628,18 @@ if self.has_repository_dependencies: rd_tups = self.metadata[ 'repository_dependencies' ][ 'repository_dependencies' ] for rd_tup in rd_tups: - if len( rd_tup ) == 4: - # For backward compatibility to the 12/20/12 Galaxy release, default prior_installation_required to False. - tool_shed, name, owner, changeset_revision = rd_tup - prior_installation_required = False - elif len( rd_tup ) == 5: + if len( rd_tup ) == 5: tool_shed, name, owner, changeset_revision, prior_installation_required = rd_tup - prior_installation_required = galaxy.util.asbool( str( prior_installation_required ) ) - if prior_installation_required: - required_rd_tups_that_must_be_installed.append( ( tool_shed, name, owner, changeset_revision, prior_installation_required ) ) + if galaxy.util.asbool( prior_installation_required ): + required_rd_tups_that_must_be_installed.append( ( tool_shed, name, owner, changeset_revision, 'True', 'False' ) ) + elif len( rd_tup ) == 6: + tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = rd_tup + # The repository dependency will only be required to be previsously installed if it does not fall into the category of + # a repository that must be installed only so that it's contained tool dependency can be used for compiling the tool + # dependency of the dependent repository. + if not galaxy.util.asbool( only_if_compiling_contained_td ): + if galaxy.util.asbool( prior_installation_required ): + required_rd_tups_that_must_be_installed.append( ( tool_shed, name, owner, changeset_revision, 'True', 'False' ) ) return required_rd_tups_that_must_be_installed @property @@ -3686,6 +3693,19 @@ return tool_shed_url.rstrip( '/' ) @property + def tuples_of_repository_dependencies_needed_for_compiling_td( self ): + """Return this repository's repository dependencies that are necessary only for compiling this repository's tool dependencies.""" + rd_tups_of_repositories_needed_for_compiling_td = [] + if self.has_repository_dependencies: + rd_tups = self.metadata[ 'repository_dependencies' ][ 'repository_dependencies' ] + for rd_tup in rd_tups: + if len( rd_tup ) == 6: + tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = rd_tup + if galaxy.util.asbool( only_if_compiling_contained_td ): + rd_tups_of_repositories_needed_for_compiling_td.append( ( tool_shed, name, owner, changeset_revision, 'False', 'True' ) ) + return rd_tups_of_repositories_needed_for_compiling_td + + @property def uninstalled_repository_dependencies( self ): """Return the repository's repository dependencies that have been uninstalled.""" uninstalled_required_repositories = [] @@ -3723,6 +3743,7 @@ def __init__( self, tool_shed_repository_id=None ): self.tool_shed_repository_id = tool_shed_repository_id + class ToolDependency( object ): installation_status = Bunch( NEVER_INSTALLED='Never installed', INSTALLING='Installing', @@ -3734,6 +3755,7 @@ WARNING = 'queued', ERROR = 'error', UNINSTALLED = 'deleted_new' ) + def __init__( self, tool_shed_repository_id=None, name=None, version=None, type=None, status=None, error_message=None ): self.tool_shed_repository_id = tool_shed_repository_id self.name = name @@ -3741,21 +3763,26 @@ self.type = type self.status = status self.error_message = error_message + @property def can_install( self ): return self.status in [ self.installation_status.NEVER_INSTALLED, self.installation_status.UNINSTALLED ] + @property def can_uninstall( self ): return self.status in [ self.installation_status.ERROR, self.installation_status.INSTALLED ] + @property def can_update( self ): return self.status in [ self.installation_status.NEVER_INSTALLED, self.installation_status.INSTALLED, self.installation_status.ERROR, self.installation_status.UNINSTALLED ] + @property def in_error_state( self ): return self.status == self.installation_status.ERROR + def installation_directory( self, app ): if self.type == 'package': return os.path.join( app.config.tool_dependency_dir, @@ -3772,6 +3799,7 @@ self.tool_shed_repository.name, self.tool_shed_repository.installed_changeset_revision ) + class ToolVersion( object, Dictifiable ): dict_element_visible_keys = ( 'id', 'tool_shed_repository' ) def __init__( self, id=None, create_time=None, tool_id=None, tool_shed_repository=None ): diff -r 149dbd29acbce6396a969662a9b899cdbb7bdb46 -r ed3c786622741814a07589a1e642cca75c51c822 lib/galaxy/webapps/tool_shed/controllers/repository.py --- a/lib/galaxy/webapps/tool_shed/controllers/repository.py +++ b/lib/galaxy/webapps/tool_shed/controllers/repository.py @@ -1648,7 +1648,7 @@ encoded_repository_ids = [] changeset_revisions = [] for required_repository_tup in decoded_required_repository_tups: - tool_shed, name, owner, changeset_revision, prior_installation_required = \ + tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ common_util.parse_repository_dependency_tuple( required_repository_tup ) repository = suc.get_repository_by_name_and_owner( trans.app, name, owner ) encoded_repository_ids.append( trans.security.encode_id( repository.id ) ) diff -r 149dbd29acbce6396a969662a9b899cdbb7bdb46 -r ed3c786622741814a07589a1e642cca75c51c822 lib/tool_shed/galaxy_install/repository_util.py --- a/lib/tool_shed/galaxy_install/repository_util.py +++ b/lib/tool_shed/galaxy_install/repository_util.py @@ -101,7 +101,8 @@ # rd_key is something like: 'http://localhost:9009__ESEP__package_rdkit_2012_12__ESEP__test__ESEP__d635ff...' # rd_val is something like: [['http://localhost:9009', 'package_numpy_1_7', 'test', 'cddd64ecd985', 'True']] try: - tool_shed, name, owner, changeset_revision, prior_installation_required = container_util.get_components_from_key( rd_key ) + tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ + container_util.get_components_from_key( rd_key ) except: tool_shed, name, owner, changeset_revision = container_util.get_components_from_key( rd_val ) installed_repository = suc.get_tool_shed_repository_by_shed_name_owner_changeset_revision( trans.app, tool_shed, name, owner, changeset_revision ) @@ -109,7 +110,7 @@ installed_repositories.append( installed_repository ) for rd_val in rd_vals: try: - tool_shed, name, owner, changeset_revision, prior_installation_required = rd_val + tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = rd_val except: tool_shed, name, owner, changeset_revision = rd_val installed_repository = suc.get_tool_shed_repository_by_shed_name_owner_changeset_revision( trans.app, tool_shed, name, owner, changeset_revision ) @@ -627,7 +628,7 @@ folder_id += 1 # Generate the label by retrieving the repository name. try: - toolshed, name, owner, changeset_revision, prior_installation_required = \ + toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ container_util.get_components_from_key( old_container_repository_dependencies_folder.key ) except ValueError: # For backward compatibility to the 12/20/12 Galaxy release. diff -r 149dbd29acbce6396a969662a9b899cdbb7bdb46 -r ed3c786622741814a07589a1e642cca75c51c822 lib/tool_shed/util/common_install_util.py --- a/lib/tool_shed/util/common_install_util.py +++ b/lib/tool_shed/util/common_install_util.py @@ -165,11 +165,20 @@ missing_rd_tups = [] for tsr in repository.repository_dependencies: prior_installation_required = suc.set_prior_installation_required( repository, tsr ) - rd_tup = [ tsr.tool_shed, tsr.name, tsr.owner, tsr.changeset_revision, prior_installation_required, tsr.id, tsr.status ] + only_if_compiling_contained_td = suc.set_only_if_compiling_contained_td( repository, tsr ) + rd_tup = [ tsr.tool_shed, tsr.name, tsr.owner, tsr.changeset_revision, prior_installation_required, only_if_compiling_contained_td, tsr.id, tsr.status ] if tsr.status == trans.model.ToolShedRepository.installation_status.INSTALLED: installed_rd_tups.append( rd_tup ) else: - missing_rd_tups.append( rd_tup ) + # We'll only add the rd_tup to the missing_rd_tups list if the received repository has tool dependencies that are not + # correctly installed. This may prove to be a weak check since the repository in question may not have anything to do + # with compiling the missing tool dependencies. If we discover that this is a problem, more granular checking will be + # necessary here. + if repository.missing_tool_dependencies: + if not repository_dependency_needed_only_for_compiling_tool_dependency( repository, tsr ): + missing_rd_tups.append( rd_tup ) + else: + missing_rd_tups.append( rd_tup ) if installed_rd_tups or missing_rd_tups: # Get the description from the metadata in case it has a value. repository_dependencies = metadata.get( 'repository_dependencies', {} ) @@ -180,7 +189,8 @@ repository.name, repository.owner, repository.installed_changeset_revision, - prior_installation_required ) + prior_installation_required, + only_if_compiling_contained_td ) if installed_rd_tups: installed_repository_dependencies[ 'root_key' ] = root_key installed_repository_dependencies[ root_key ] = installed_rd_tups @@ -211,7 +221,8 @@ if key in [ 'description', 'root_key' ]: continue for rd_tup in rd_tups: - tool_shed, name, owner, changeset_revision, prior_installation_required = common_util.parse_repository_dependency_tuple( rd_tup ) + tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ + common_util.parse_repository_dependency_tuple( rd_tup ) # Updates to installed repository revisions may have occurred, so make sure to locate the appropriate repository revision if one exists. # We need to create a temporary repo_info_tuple that includes the correct repository owner which we get from the current rd_tup. The current # tuple looks like: ( description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, repository_dependencies, installed_td ) @@ -219,17 +230,39 @@ tmp_repo_info_tuple = ( None, tmp_clone_url, changeset_revision, None, owner, None, None ) repository, current_changeset_revision = suc.repository_was_previously_installed( trans, tool_shed, name, tmp_repo_info_tuple ) if repository: - new_rd_tup = [ tool_shed, name, owner, changeset_revision, str( prior_installation_required ), repository.id, repository.status ] + new_rd_tup = [ tool_shed, + name, + owner, + changeset_revision, + prior_installation_required, + only_if_compiling_contained_td, + repository.id, + repository.status ] if repository.status == trans.model.ToolShedRepository.installation_status.INSTALLED: if new_rd_tup not in installed_rd_tups: installed_rd_tups.append( new_rd_tup ) else: + # A repository dependency that is not installed will not be considered missing if it's value for only_if_compiling_contained_td is + # True This is because this type of repository dependency will only be considered at the time that the specified tool dependency + # is being installed, and even then only if the compiled binary of the tool dependency could not be installed due to the unsupported + # installation environment. + if not util.asbool( only_if_compiling_contained_td ): + if new_rd_tup not in missing_rd_tups: + missing_rd_tups.append( new_rd_tup ) + else: + new_rd_tup = [ tool_shed, + name, + owner, + changeset_revision, + prior_installation_required, + only_if_compiling_contained_td, + None, + 'Never installed' ] + if not util.asbool( only_if_compiling_contained_td ): + # A repository dependency that is not installed will not be considered missing if it's value for only_if_compiling_contained_td is + # True - see above... if new_rd_tup not in missing_rd_tups: missing_rd_tups.append( new_rd_tup ) - else: - new_rd_tup = [ tool_shed, name, owner, changeset_revision, str( prior_installation_required ), None, 'Never installed' ] - if new_rd_tup not in missing_rd_tups: - missing_rd_tups.append( new_rd_tup ) if installed_rd_tups: installed_repository_dependencies[ 'root_key' ] = root_key installed_repository_dependencies[ root_key ] = installed_rd_tups @@ -286,20 +319,32 @@ if key in [ 'root_key', 'description' ]: continue try: - toolshed, name, owner, changeset_revision, prior_installation_required = container_util.get_components_from_key( key ) - components_list = [ toolshed, name, owner, changeset_revision, prior_installation_required ] + toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ + container_util.get_components_from_key( key ) + components_list = [ toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td ] except ValueError: - # For backward compatibility to the 12/20/12 Galaxy release, default prior_installation_required to False in the caller. + # For backward compatibility to the 12/20/12 Galaxy release, default prior_installation_required and only_if_compiling_contained_td + # to False in the caller. toolshed, name, owner, changeset_revision = container_util.get_components_from_key( key ) components_list = [ toolshed, name, owner, changeset_revision ] - if components_list not in required_repository_tups: - required_repository_tups.append( components_list ) - for components_list in val: + only_if_compiling_contained_td = 'False' + # Skip listing a repository dependency if it is required only to compile a tool dependency defined for the dependent repository. + if not util.asbool( only_if_compiling_contained_td ): if components_list not in required_repository_tups: required_repository_tups.append( components_list ) + for components_list in val: + try: + only_if_compiling_contained_td = components_list[ 5 ] + except: + only_if_compiling_contained_td = 'False' + # TODO: Fix this to display the tool dependency if only_if_compiling_contained_td is True, but clarify that installation may not + # happen. + if not util.asbool( only_if_compiling_contained_td ): + if components_list not in required_repository_tups: + required_repository_tups.append( components_list ) else: # We have a single repository with no dependencies. - components_list = [ tool_shed_url, repository_name, repository_owner, changeset_revision, 'False' ] + components_list = [ tool_shed_url, repository_name, repository_owner, changeset_revision, 'False', 'False' ] required_repository_tups.append( components_list ) if required_repository_tups: # The value of required_repository_tups is a list of tuples, so we need to encode it. @@ -393,3 +438,16 @@ app.model.ToolDependency.installation_status.ERROR ]: installed_tool_dependencies.append( tool_dependency ) return installed_tool_dependencies + +def repository_dependency_needed_only_for_compiling_tool_dependency( repository, repository_dependency ): + for rd_tup in repository.tuples_of_repository_dependencies_needed_for_compiling_td: + tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = rd_tup + # TODO: we may discover that we need to check more than just installed_changeset_revision and changeset_revision here, in which + # case we'll need to contact the tool shed to get the list of all possible changeset_revisions. + if repository_dependency.tool_shed == tool_shed and \ + repository_dependency.name == name and \ + repository_dependency.owner == owner and \ + ( repository_dependency.installed_changeset_revision == changeset_revision or \ + repository_dependency.changeset_revision == changeset_revision ): + return True + return False diff -r 149dbd29acbce6396a969662a9b899cdbb7bdb46 -r ed3c786622741814a07589a1e642cca75c51c822 lib/tool_shed/util/common_util.py --- a/lib/tool_shed/util/common_util.py +++ b/lib/tool_shed/util/common_util.py @@ -46,7 +46,8 @@ if rd_key in [ 'root_key', 'description' ]: continue for rd_tup in rd_tups: - tool_shed, name, owner, changeset_revision, prior_installation_required = parse_repository_dependency_tuple( rd_tup ) + tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td \ + = parse_repository_dependency_tuple( rd_tup ) tool_shed_accessible, tool_dependencies = get_tool_dependencies( app, tool_shed, name, @@ -155,26 +156,26 @@ return None def parse_repository_dependency_tuple( repository_dependency_tuple, contains_error=False ): + # Default both prior_installation_required and only_if_compiling_contained_td to False in cases where metadata should be reset on the + # repository containing the repository_dependency definition. + prior_installation_required = 'False' + only_if_compiling_contained_td = 'False' if contains_error: if len( repository_dependency_tuple ) == 5: - # Metadata should have been reset on the repository containing this repository_dependency definition. tool_shed, name, owner, changeset_revision, error = repository_dependency_tuple - # Default prior_installation_required to False. - prior_installation_required = False elif len( repository_dependency_tuple ) == 6: toolshed, name, owner, changeset_revision, prior_installation_required, error = repository_dependency_tuple - prior_installation_required = str( prior_installation_required ) - return toolshed, name, owner, changeset_revision, prior_installation_required, error + elif len( repository_dependency_tuple ) == 7: + toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td, error = repository_dependency_tuple + return toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td, error else: if len( repository_dependency_tuple ) == 4: - # Metadata should have been reset on the repository containing this repository_dependency definition. tool_shed, name, owner, changeset_revision = repository_dependency_tuple - # Default prior_installation_required to False. - prior_installation_required = False elif len( repository_dependency_tuple ) == 5: tool_shed, name, owner, changeset_revision, prior_installation_required = repository_dependency_tuple - prior_installation_required = str( prior_installation_required ) - return tool_shed, name, owner, changeset_revision, prior_installation_required + elif len( repository_dependency_tuple ) == 6: + tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = repository_dependency_tuple + return tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td def tool_shed_get( app, tool_shed_url, uri ): """Make contact with the tool shed via the uri provided.""" diff -r 149dbd29acbce6396a969662a9b899cdbb7bdb46 -r ed3c786622741814a07589a1e642cca75c51c822 lib/tool_shed/util/container_util.py --- a/lib/tool_shed/util/container_util.py +++ b/lib/tool_shed/util/container_util.py @@ -64,13 +64,15 @@ self.repository_dependencies.remove( contained_repository_dependency ) def to_repository_dependency( self, repository_dependency_id ): - toolshed, name, owner, changeset_revision, prior_installation_required = common_util.parse_repository_dependency_tuple( self.key.split( STRSEP ) ) + toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ + common_util.parse_repository_dependency_tuple( self.key.split( STRSEP ) ) return RepositoryDependency( id=repository_dependency_id, toolshed=toolshed, repository_name=name, repository_owner=owner, changeset_revision=changeset_revision, - prior_installation_required=asbool( prior_installation_required ) ) + prior_installation_required=asbool( prior_installation_required ), + only_if_compiling_contained_td=asbool( only_if_compiling_contained_td ) ) class DataManager( object ): @@ -120,13 +122,15 @@ class InvalidRepositoryDependency( object ): """Invalid repository dependency definition object""" - def __init__( self, id=None, toolshed=None, repository_name=None, repository_owner=None, changeset_revision=None, prior_installation_required=False, error=None ): + def __init__( self, id=None, toolshed=None, repository_name=None, repository_owner=None, changeset_revision=None, prior_installation_required=False, + only_if_compiling_contained_td=False, error=None ): self.id = id self.toolshed = toolshed self.repository_name = repository_name self.repository_owner = repository_owner self.changeset_revision = changeset_revision self.prior_installation_required = prior_installation_required + self.only_if_compiling_contained_td = only_if_compiling_contained_td self.error = error @@ -194,19 +198,25 @@ """Repository dependency object""" def __init__( self, id=None, toolshed=None, repository_name=None, repository_owner=None, changeset_revision=None, prior_installation_required=False, - installation_status=None, tool_shed_repository_id=None ): + only_if_compiling_contained_td=False, installation_status=None, tool_shed_repository_id=None ): self.id = id self.toolshed = toolshed self.repository_name = repository_name self.repository_owner = repository_owner self.changeset_revision = changeset_revision self.prior_installation_required = prior_installation_required + self.only_if_compiling_contained_td = only_if_compiling_contained_td self.installation_status = installation_status self.tool_shed_repository_id = tool_shed_repository_id @property def listify( self ): - return [ self.toolshed, self.repository_name, self.repository_owner, self.changeset_revision, asbool( str( self.prior_installation_required ) ) ] + return [ self.toolshed, + self.repository_name, + self.repository_owner, + self.changeset_revision, + self.prior_installation_required, + self.only_if_compiling_contained_td ] class RepositoryInstallationError( object ): @@ -463,9 +473,14 @@ for invalid_repository_dependency in invalid_repository_dependencies: folder_id += 1 invalid_repository_dependency_id += 1 - toolshed, name, owner, changeset_revision, prior_installation_required, error = \ + toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td, error = \ common_util.parse_repository_dependency_tuple( invalid_repository_dependency, contains_error=True ) - key = generate_repository_dependencies_key_for_repository( toolshed, name, owner, changeset_revision, prior_installation_required ) + key = generate_repository_dependencies_key_for_repository( toolshed, + name, + owner, + changeset_revision, + prior_installation_required, + only_if_compiling_contained_td ) label = "Repository <b>%s</b> revision <b>%s</b> owned by <b>%s</b>" % ( name, changeset_revision, owner ) folder = Folder( id=folder_id, key=key, @@ -477,6 +492,7 @@ repository_owner=owner, changeset_revision=changeset_revision, prior_installation_required=asbool( prior_installation_required ), + only_if_compiling_contained_td=asbool( only_if_compiling_contained_td ), error=error ) folder.invalid_repository_dependencies.append( ird ) invalid_repository_dependencies_folder.folders.append( folder ) @@ -1230,12 +1246,13 @@ return cast_empty_repository_dependency_folders( sub_folder, repository_dependency_id ) return folder, repository_dependency_id -def generate_repository_dependencies_folder_label_from_key( repository_name, repository_owner, changeset_revision, prior_installation_required, key ): +def generate_repository_dependencies_folder_label_from_key( repository_name, repository_owner, changeset_revision, prior_installation_required, + only_if_compiling_contained_td, key ): """Return a repository dependency label based on the repository dependency key.""" - if key_is_current_repositorys_key( repository_name, repository_owner, changeset_revision, prior_installation_required, key ): + if key_is_current_repositorys_key( repository_name, repository_owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td, key ): label = 'Repository dependencies' else: - if prior_installation_required: + if asbool( prior_installation_required ): prior_installation_required_str = " <i>(prior install required)</i>" else: prior_installation_required_str = "" @@ -1243,9 +1260,10 @@ ( repository_name, changeset_revision, repository_owner, prior_installation_required_str ) return label -def generate_repository_dependencies_key_for_repository( toolshed_base_url, repository_name, repository_owner, changeset_revision, prior_installation_required ): - # FIXME: assumes tool shed is current tool shed since repository dependencies across tool sheds is not yet supported. - return '%s%s%s%s%s%s%s%s%s' % ( str( toolshed_base_url ).rstrip( '/' ), +def generate_repository_dependencies_key_for_repository( toolshed_base_url, repository_name, repository_owner, changeset_revision, prior_installation_required, + only_if_compiling_contained_td ): + """Assumes tool shed is current tool shed since repository dependencies across tool sheds is not yet supported.""" + return '%s%s%s%s%s%s%s%s%s%s%s' % ( str( toolshed_base_url ).rstrip( '/' ), STRSEP, str( repository_name ), STRSEP, @@ -1253,7 +1271,9 @@ STRSEP, str( changeset_revision ), STRSEP, - str( prior_installation_required ) ) + str( prior_installation_required ), + STRSEP, + str( only_if_compiling_contained_td ) ) def generate_tool_dependencies_key( name, version, type ): return '%s%s%s%s%s' % ( str( name ), STRSEP, str( version ), STRSEP, str( type ) ) @@ -1266,22 +1286,27 @@ return None def get_components_from_repository_dependency_for_installed_repository( trans, repository_dependency ): - """ - Parse a repository dependency and return components necessary for proper display in Galaxy on the Manage repository page. - """ + """Parse a repository dependency and return components necessary for proper display in Galaxy on the Manage repository page.""" + # Default prior_installation_required and only_if_compiling_contained_td to False. + prior_installation_required = 'False' + only_if_compiling_contained_td = 'False' if len( repository_dependency ) == 6: # Metadata should have been reset on this installed repository, but it wasn't. tool_shed_repository_id = repository_dependency[ 4 ] installation_status = repository_dependency[ 5 ] tool_shed, name, owner, changeset_revision = repository_dependency[ 0:4 ] - # Default prior_installation_required to False. - prior_installation_required = False - repository_dependency = [ tool_shed, name, owner, changeset_revision, prior_installation_required ] + repository_dependency = [ tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td ] elif len( repository_dependency ) == 7: - # We have a repository dependency tuple that includes a prior_installation_required value. + # We have a repository dependency tuple that includes a prior_installation_required value but not a only_if_compiling_contained_td value. tool_shed_repository_id = repository_dependency[ 5 ] installation_status = repository_dependency[ 6 ] - repository_dependency = repository_dependency[ 0:5 ] + tool_shed, name, owner, changeset_revision, prior_installation_required = repository_dependency[ 0:5 ] + repository_dependency = [ tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td ] + elif len( repository_dependency ) == 8: + # We have a repository dependency tuple that includes both a prior_installation_required value and a only_if_compiling_contained_td value. + tool_shed_repository_id = repository_dependency[ 6 ] + installation_status = repository_dependency[ 7 ] + repository_dependency = repository_dependency[ 0:6 ] else: tool_shed_repository_id = None installation_status = 'unknown' @@ -1295,31 +1320,41 @@ return tool_shed_repository_id, installation_status, repository_dependency def get_components_from_key( key ): - # FIXME: assumes tool shed is current tool shed since repository dependencies across tool sheds is not yet supported. + """Assumes tool shed is current tool shed since repository dependencies across tool sheds is not yet supported.""" items = key.split( STRSEP ) toolshed_base_url = items[ 0 ] repository_name = items[ 1 ] repository_owner = items[ 2 ] changeset_revision = items[ 3 ] - if len( items ) == 5: - prior_installation_required = asbool( str( items[ 4 ] ) ) - return toolshed_base_url, repository_name, repository_owner, changeset_revision, prior_installation_required + if len( items ) >= 5: + try: + prior_installation_required = items[ 4 ] + except: + prior_installation_required = 'False' + try: + only_if_compiling_contained_td = items[ 5 ] + except: + only_if_compiling_contained_td = 'False' + return toolshed_base_url, repository_name, repository_owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td else: # For backward compatibility to the 12/20/12 Galaxy release we have to return the following, and callers must handle exceptions. return toolshed_base_url, repository_name, repository_owner, changeset_revision def handle_repository_dependencies_container_entry( trans, repository_dependencies_folder, rd_key, rd_value, folder_id, repository_dependency_id, folder_keys ): try: - toolshed, repository_name, repository_owner, changeset_revision, prior_installation_required = get_components_from_key( rd_key ) + toolshed, repository_name, repository_owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ + get_components_from_key( rd_key ) except ValueError: - # For backward compatibility to the 12/20/12 Galaxy release, default prior_installation_required to False. + # For backward compatibility to the 12/20/12 Galaxy release, default prior_installation_required and only_if_compiling_contained_td to 'False'. toolshed, repository_name, repository_owner, changeset_revision = get_components_from_key( rd_key ) - prior_installation_required = False + prior_installation_required = 'False' + only_if_compiling_contained_td = 'False' folder = get_folder( repository_dependencies_folder, rd_key ) label = generate_repository_dependencies_folder_label_from_key( repository_name, repository_owner, changeset_revision, prior_installation_required, + only_if_compiling_contained_td, repository_dependencies_folder.key ) if folder: if rd_key not in folder_keys: @@ -1351,7 +1386,7 @@ installation_status = None can_create_dependency = not is_subfolder_of( sub_folder, repository_dependency ) if can_create_dependency: - toolshed, repository_name, repository_owner, changeset_revision, prior_installation_required = \ + toolshed, repository_name, repository_owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ common_util.parse_repository_dependency_tuple( repository_dependency ) repository_dependency_id += 1 repository_dependency = RepositoryDependency( id=repository_dependency_id, @@ -1360,6 +1395,7 @@ repository_owner=repository_owner, changeset_revision=changeset_revision, prior_installation_required=asbool( prior_installation_required ), + only_if_compiling_contained_td=asbool( only_if_compiling_contained_td ), installation_status=installation_status, tool_shed_repository_id=tool_shed_repository_id ) # Insert the repository_dependency into the folder. @@ -1367,25 +1403,35 @@ return repository_dependencies_folder, folder_id, repository_dependency_id def is_subfolder_of( folder, repository_dependency ): - toolshed, repository_name, repository_owner, changeset_revision, prior_installation_required = \ + toolshed, repository_name, repository_owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ common_util.parse_repository_dependency_tuple( repository_dependency ) - key = generate_repository_dependencies_key_for_repository( toolshed, repository_name, repository_owner, changeset_revision, asbool( prior_installation_required ) ) + key = generate_repository_dependencies_key_for_repository( toolshed, + repository_name, + repository_owner, + changeset_revision, + prior_installation_required, + only_if_compiling_contained_td ) for sub_folder in folder.folders: if key == sub_folder.key: return True return False -def key_is_current_repositorys_key( repository_name, repository_owner, changeset_revision, prior_installation_required, key ): +def key_is_current_repositorys_key( repository_name, repository_owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td, key ): try: - toolshed_base_url, key_name, key_owner, key_changeset_revision, key_prior_installation_required = get_components_from_key( key ) + toolshed_base_url, key_name, key_owner, key_changeset_revision, key_prior_installation_required, key_only_if_compiling_contained_td = \ + get_components_from_key( key ) except ValueError: # For backward compatibility to the 12/20/12 Galaxy release, default key_prior_installation_required to False. toolshed_base_url, key_name, key_owner, key_changeset_revision = get_components_from_key( key ) - key_prior_installation_required = False - return repository_name == key_name and \ + key_prior_installation_required = 'False' + key_only_if_compiling_contained_td = 'False' + if repository_name == key_name and \ repository_owner == key_owner and \ changeset_revision == key_changeset_revision and \ - prior_installation_required == key_prior_installation_required + prior_installation_required == key_prior_installation_required and \ + only_if_compiling_contained_td == key_only_if_compiling_contained_td: + return True + return False def populate_repository_dependencies_container( trans, repository_dependencies_folder, repository_dependencies, folder_id, repository_dependency_id ): folder_keys = repository_dependencies.keys() diff -r 149dbd29acbce6396a969662a9b899cdbb7bdb46 -r ed3c786622741814a07589a1e642cca75c51c822 lib/tool_shed/util/metadata_util.py --- a/lib/tool_shed/util/metadata_util.py +++ b/lib/tool_shed/util/metadata_util.py @@ -199,19 +199,23 @@ def compare_repository_dependencies( trans, ancestor_repository_dependencies, current_repository_dependencies ): """Determine if ancestor_repository_dependencies is the same as or a subset of current_repository_dependencies.""" - # The list of repository_dependencies looks something like: [["http://localhost:9009", "emboss_datatypes", "test", "ab03a2a5f407", False]]. + # The list of repository_dependencies looks something like: + # [["http://localhost:9009", "emboss_datatypes", "test", "ab03a2a5f407", "False", "False"]]. # Create a string from each tuple in the list for easier comparison. if len( ancestor_repository_dependencies ) <= len( current_repository_dependencies ): for ancestor_tup in ancestor_repository_dependencies: - ancestor_tool_shed, ancestor_repository_name, ancestor_repository_owner, ancestor_changeset_revision, ancestor_prior_installation_required = ancestor_tup + a_tool_shed, a_repo_name, a_repo_owner, a_changeset_revision, a_prior_installation_required, a_only_if_compiling_contained_td = \ + ancestor_tup found_in_current = False for current_tup in current_repository_dependencies: - current_tool_shed, current_repository_name, current_repository_owner, current_changeset_revision, current_prior_installation_required = current_tup - if current_tool_shed == ancestor_tool_shed and \ - current_repository_name == ancestor_repository_name and \ - current_repository_owner == ancestor_repository_owner and \ - current_changeset_revision == ancestor_changeset_revision and \ - util.string_as_bool( current_prior_installation_required ) == util.string_as_bool( ancestor_prior_installation_required ): + c_tool_shed, c_repo_name, c_repo_owner, c_changeset_revision, c_prior_installation_required, c_only_if_compiling_contained_td = \ + current_tup + if c_tool_shed == a_tool_shed and \ + c_repo_name == a_repo_name and \ + c_repo_owner == a_repo_owner and \ + c_changeset_revision == a_changeset_revision and \ + util.string_as_bool( c_prior_installation_required ) == util.string_as_bool( a_prior_installation_required ) and \ + util.string_as_bool( c_only_if_compiling_contained_td ) == util.string_as_bool( a_only_if_compiling_contained_td ): found_in_current = True break if not found_in_current: @@ -354,9 +358,11 @@ Determine if the only difference between rd_tup and a dependency definition in the list of repository_dependencies is the changeset_revision value. """ new_metadata_required = False - rd_tool_shed, rd_name, rd_owner, rd_changeset_revision, rd_prior_installation_required = common_util.parse_repository_dependency_tuple( rd_tup ) + rd_tool_shed, rd_name, rd_owner, rd_changeset_revision, rd_prior_installation_required, rd_only_if_compiling_contained_td = \ + common_util.parse_repository_dependency_tuple( rd_tup ) for repository_dependency in repository_dependencies: - tool_shed, name, owner, changeset_revision, prior_installation_required = common_util.parse_repository_dependency_tuple( repository_dependency ) + tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ + common_util.parse_repository_dependency_tuple( repository_dependency ) if rd_tool_shed == tool_shed and rd_name == name and rd_owner == owner: # Determine if the repository represented by the dependency tuple is an instance of the repository type TipOnly. required_repository = suc.get_repository_by_name_and_owner( trans.app, name, owner ) @@ -750,7 +756,9 @@ # We have a complex repository dependency. If the returned value of repository_dependency_is_valid is True, the tool # dependency definition will be set as invalid. This is currently the only case where a tool dependency definition is # considered invalid. - repository_dependency_tup, repository_dependency_is_valid, error_message = handle_repository_elem( app=app, repository_elem=sub_elem ) + repository_dependency_tup, repository_dependency_is_valid, error_message = handle_repository_elem( app=app, + repository_elem=sub_elem, + only_if_compiling_contained_td=False ) elif sub_elem.tag == 'install': package_install_version = sub_elem.get( 'version', '1.0' ) if package_install_version == '1.0': @@ -763,7 +771,8 @@ in_actions_group, actions_elem = actions_elem_tuple if in_actions_group: # Since we're inside an <actions_group> tag set, inspect the actions_elem to see if a complex repository dependency - # is defined. + # is defined. By definition, complex repository dependency definitions contained within the last <actions> tag set + # within an <actions_group> tag set will have the value of "only_if_compiling_contained_td" set to True in for action_elem in actions_elem: if action_elem.tag == 'package': # <package name="libgtextutils" version="0.6"> @@ -776,7 +785,9 @@ if sub_action_elem.tag == 'repository': # We have a complex repository dependency. repository_dependency_tup, repository_dependency_is_valid, error_message = \ - handle_repository_elem( app=app, repository_elem=sub_action_elem ) + handle_repository_elem( app=app, + repository_elem=sub_action_elem, + only_if_compiling_contained_td=True ) if requirements_dict: dependency_key = '%s/%s' % ( package_name, package_version ) if repository_dependency_is_valid: @@ -806,13 +817,21 @@ valid_repository_dependencies_dict = dict( description=root.get( 'description' ) ) valid_repository_dependency_tups = [] for repository_elem in root.findall( 'repository' ): - repository_dependency_tup, repository_dependency_is_valid, error_message = handle_repository_elem( app, repository_elem ) + repository_dependency_tup, repository_dependency_is_valid, error_message = handle_repository_elem( app, + repository_elem, + only_if_compiling_contained_td=False ) if repository_dependency_is_valid: valid_repository_dependency_tups.append( repository_dependency_tup ) else: # Append the error_message to the repository dependencies tuple. - toolshed, name, owner, changeset_revision, prior_installation_required = repository_dependency_tup - repository_dependency_tup = ( toolshed, name, owner, changeset_revision, str( prior_installation_required ), error_message ) + toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = repository_dependency_tup + repository_dependency_tup = ( toolshed, + name, + owner, + changeset_revision, + prior_installation_required, + only_if_compiling_contained_td, + error_message ) invalid_repository_dependency_tups.append( repository_dependency_tup ) if invalid_repository_dependency_tups: invalid_repository_dependencies_dict[ 'repository_dependencies' ] = invalid_repository_dependency_tups @@ -859,8 +878,9 @@ # We have an invalid complex repository dependency, so mark the tool dependency as invalid. tool_dependency_is_valid = False # Append the error message to the invalid repository dependency tuple. - toolshed, name, owner, changeset_revision, prior_installation_required = repository_dependency_tup - repository_dependency_tup = ( toolshed, name, owner, changeset_revision, str( prior_installation_required ), message ) + toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = repository_dependency_tup + repository_dependency_tup = \ + ( toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td, message ) invalid_repository_dependency_tups.append( repository_dependency_tup ) error_message = '%s %s' % ( error_message, message ) elif elem.tag == 'set_environment': @@ -1137,7 +1157,7 @@ deleted_tool_dependency_names.append( original_dependency_val_dict[ 'name' ] ) return updated_tool_dependency_names, deleted_tool_dependency_names -def handle_repository_elem( app, repository_elem ): +def handle_repository_elem( app, repository_elem, only_if_compiling_contained_td=False ): """ Process the received repository_elem which is a <repository> tag either from a repository_dependencies.xml file or a tool_dependencies.xml file. If the former, we're generating repository dependencies metadata for a repository in the tool shed. If the latter, we're generating package @@ -1155,7 +1175,7 @@ owner = repository_elem.get( 'owner' ) changeset_revision = repository_elem.get( 'changeset_revision' ) prior_installation_required = str( repository_elem.get( 'prior_installation_required', False ) ) - repository_dependency_tup = [ toolshed, name, owner, changeset_revision, str( prior_installation_required ) ] + repository_dependency_tup = [ toolshed, name, owner, changeset_revision, prior_installation_required, str( only_if_compiling_contained_td ) ] user = None repository = None if app.name == 'galaxy': @@ -1974,9 +1994,9 @@ repository_dependencies_dict = metadata.get( 'invalid_repository_dependencies', None ) for repository_dependency_tup in repository_dependency_tups: if is_valid: - tool_shed, name, owner, changeset_revision, prior_installation_required = repository_dependency_tup + tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = repository_dependency_tup else: - tool_shed, name, owner, changeset_revision, prior_installation_required, error_message = repository_dependency_tup + tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td, error_message = repository_dependency_tup if repository_dependencies_dict: repository_dependencies = repository_dependencies_dict.get( 'repository_dependencies', [] ) for repository_dependency_tup in repository_dependency_tups: diff -r 149dbd29acbce6396a969662a9b899cdbb7bdb46 -r ed3c786622741814a07589a1e642cca75c51c822 lib/tool_shed/util/repository_dependency_util.py --- a/lib/tool_shed/util/repository_dependency_util.py +++ b/lib/tool_shed/util/repository_dependency_util.py @@ -33,30 +33,30 @@ for key, val in repository_dependencies.items(): if key in [ 'root_key', 'description' ]: continue - dependent_repository = None + d_repository = None try: - dependent_toolshed, dependent_name, dependent_owner, dependent_changeset_revision, dependent_prior_installation_required = \ + d_toolshed, d_name, d_owner, d_changeset_revision, d_prior_installation_required, d_only_if_compiling_contained_td = \ container_util.get_components_from_key( key ) except ValueError: # For backward compatibility to the 12/20/12 Galaxy release. - dependent_toolshed, dependent_name, dependent_owner, dependent_changeset_revision = container_util.get_components_from_key( key ) + d_toolshed, d_name, d_owner, d_changeset_revision = container_util.get_components_from_key( key ) for tsr in tool_shed_repositories: # Get the the tool_shed_repository defined by name, owner and changeset_revision. This is the repository that will be - # dependent upon each of the tool shed repositories contained in val. - # TODO: Check tool_shed_repository.tool_shed as well when repository dependencies across tool sheds is supported. - if tsr.name == dependent_name and tsr.owner == dependent_owner and tsr.changeset_revision == dependent_changeset_revision: - dependent_repository = tsr + # dependent upon each of the tool shed repositories contained in val. We'll need to check tool_shed_repository.tool_shed + # as well if/when repository dependencies across tool sheds is supported. + if tsr.name == d_name and tsr.owner == d_owner and tsr.changeset_revision == d_changeset_revision: + d_repository = tsr break - if dependent_repository is None: + if d_repository is None: # The dependent repository is not in the received list so look in the database. - dependent_repository = suc.get_or_create_tool_shed_repository( trans, dependent_toolshed, dependent_name, dependent_owner, dependent_changeset_revision ) + d_repository = suc.get_or_create_tool_shed_repository( trans, d_toolshed, d_name, d_owner, d_changeset_revision ) # Process each repository_dependency defined for the current dependent repository. for repository_dependency_components_list in val: required_repository = None - rd_toolshed, rd_name, rd_owner, rd_changeset_revision, prior_installation_required = \ + rd_toolshed, rd_name, rd_owner, rd_changeset_revision, rd_prior_installation_required, rd_only_if_compiling_contained_td = \ common_util.parse_repository_dependency_tuple( repository_dependency_components_list ) # Get the the tool_shed_repository defined by rd_name, rd_owner and rd_changeset_revision. This is the repository that will be - # required by the current dependent_repository. + # required by the current d_repository. # TODO: Check tool_shed_repository.tool_shed as well when repository dependencies across tool sheds is supported. for tsr in tool_shed_repositories: if tsr.name == rd_name and tsr.owner == rd_owner and tsr.changeset_revision == rd_changeset_revision: @@ -65,9 +65,9 @@ if required_repository is None: # The required repository is not in the received list so look in the database. required_repository = suc.get_or_create_tool_shed_repository( trans, rd_toolshed, rd_name, rd_owner, rd_changeset_revision ) - # Ensure there is a repository_dependency relationship between dependent_repository and required_repository. + # Ensure there is a repository_dependency relationship between d_repository and required_repository. rrda = None - for rd in dependent_repository.repository_dependencies: + for rd in d_repository.repository_dependencies: if rd.id == required_repository.id: rrda = rd break @@ -78,8 +78,8 @@ repository_dependency = trans.model.RepositoryDependency( tool_shed_repository_id=required_repository.id ) trans.sa_session.add( repository_dependency ) trans.sa_session.flush() - # Build the relationship between the dependent_repository and the required_repository. - rrda = trans.model.RepositoryRepositoryDependencyAssociation( tool_shed_repository_id=dependent_repository.id, + # Build the relationship between the d_repository and the required_repository. + rrda = trans.model.RepositoryRepositoryDependencyAssociation( tool_shed_repository_id=d_repository.id, repository_dependency_id=repository_dependency.id ) trans.sa_session.add( rrda ) trans.sa_session.flush() @@ -257,40 +257,42 @@ if invalid_repository_dependencies_dict: invalid_repository_dependencies = invalid_repository_dependencies_dict.get( 'invalid_repository_dependencies', [] ) for repository_dependency_tup in invalid_repository_dependencies: - toolshed, name, owner, changeset_revision, prior_installation_required, error = \ + toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td, error = \ common_util.parse_repository_dependency_tuple( repository_dependency_tup, contains_error=True ) if error: message = '%s ' % str( error ) return message def get_key_for_repository_changeset_revision( toolshed_base_url, repository, repository_metadata, all_repository_dependencies ): - prior_installation_required = get_prior_installation_required_for_key( toolshed_base_url, repository, repository_metadata, all_repository_dependencies ) + prior_installation_required, only_if_compiling_contained_td = \ + get_prior_installation_required_and_only_if_compiling_contained_td( toolshed_base_url, repository, repository_metadata, all_repository_dependencies ) # Create a key with the value of prior_installation_required defaulted to False. key = container_util.generate_repository_dependencies_key_for_repository( toolshed_base_url=toolshed_base_url, repository_name=repository.name, repository_owner=repository.user.username, changeset_revision=repository_metadata.changeset_revision, - prior_installation_required=prior_installation_required ) + prior_installation_required=prior_installation_required, + only_if_compiling_contained_td=only_if_compiling_contained_td ) return key -def get_prior_installation_required_for_key( toolshed_base_url, repository, repository_metadata, all_repository_dependencies ): +def get_prior_installation_required_and_only_if_compiling_contained_td( toolshed_base_url, repository, repository_metadata, all_repository_dependencies ): """ If all_repository_dependencies contains a repository dependency tuple that is associated with the received repository, return the value of the tuple's prior_installation_required component. """ - rd_tuple = ( toolshed_base_url, repository.name, repository.user.username, repository_metadata.changeset_revision ) for rd_key, rd_tups in all_repository_dependencies.items(): if rd_key in [ 'root_key', 'description' ]: continue for rd_tup in rd_tups: - rd_toolshed, rd_name, rd_owner, rd_changeset_revision, rd_prior_installation_required = common_util.parse_repository_dependency_tuple( rd_tup ) + rd_toolshed, rd_name, rd_owner, rd_changeset_revision, rd_prior_installation_required, rd_only_if_compiling_contained_td = \ + common_util.parse_repository_dependency_tuple( rd_tup ) if rd_toolshed == toolshed_base_url and \ rd_name == repository.name and \ rd_owner == repository.user.username and \ rd_changeset_revision == repository_metadata.changeset_revision: - return rd_prior_installation_required - # Default prior_installation_required to False. - return False + return rd_prior_installation_required, rd_only_if_compiling_contained_td + # Default both prior_installation_required and only_if_compiling_contained_td to False. + return 'False', 'False' def get_repository_dependencies_for_installed_tool_shed_repository( trans, repository ): """ @@ -374,7 +376,7 @@ for key_rd_dict in key_rd_dicts: key = key_rd_dict.keys()[ 0 ] repository_dependency = key_rd_dict[ key ] - rd_toolshed, rd_name, rd_owner, rd_changeset_revision, rd_prior_installation_required = \ + rd_toolshed, rd_name, rd_owner, rd_changeset_revision, rd_prior_installation_required, rd_only_if_compiling_contained_td = \ common_util.parse_repository_dependency_tuple( repository_dependency ) if suc.tool_shed_is_this_tool_shed( rd_toolshed ): repository = suc.get_repository_by_name_and_owner( trans.app, rd_name, rd_owner ) @@ -397,12 +399,13 @@ changeset_revision ) if repository_metadata: new_key_rd_dict = {} - new_key_rd_dict[ key ] = [ rd_toolshed, rd_name, rd_owner, repository_metadata.changeset_revision, str( rd_prior_installation_required ) ] + new_key_rd_dict[ key ] = \ + [ rd_toolshed, rd_name, rd_owner, repository_metadata.changeset_revision, rd_prior_installation_required, rd_only_if_compiling_contained_td ] # We have the updated changset revision. updated_key_rd_dicts.append( new_key_rd_dict ) else: try: - toolshed, repository_name, repository_owner, repository_changeset_revision, prior_installation_required = \ + toolshed, repository_name, repository_owner, repository_changeset_revision, prior_installation_required, rd_only_if_compiling_contained_td = \ container_util.get_components_from_key( key ) except ValueError: # For backward compatibility to the 12/20/12 Galaxy release. @@ -412,7 +415,7 @@ log.debug( message ) else: try: - toolshed, repository_name, repository_owner, repository_changeset_revision, prior_installation_required = \ + toolshed, repository_name, repository_owner, repository_changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ container_util.get_components_from_key( key ) except ValueError: # For backward compatibility to the 12/20/12 Galaxy release. @@ -462,7 +465,8 @@ def handle_key_rd_dicts_for_repository( trans, current_repository_key, repository_key_rd_dicts, key_rd_dicts_to_be_processed, handled_key_rd_dicts, circular_repository_dependencies ): key_rd_dict = repository_key_rd_dicts.pop( 0 ) repository_dependency = key_rd_dict[ current_repository_key ] - toolshed, name, owner, changeset_revision, prior_installation_required = common_util.parse_repository_dependency_tuple( repository_dependency ) + toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ + common_util.parse_repository_dependency_tuple( repository_dependency ) if suc.tool_shed_is_this_tool_shed( toolshed ): required_repository = suc.get_repository_by_name_and_owner( trans.app, name, owner ) required_repository_metadata = metadata_util.get_repository_metadata_by_repository_id_changeset_revision( trans, @@ -691,11 +695,13 @@ clean_key_rd_dicts = [] key = key_rd_dicts[ 0 ].keys()[ 0 ] repository_tup = key.split( container_util.STRSEP ) - rd_toolshed, rd_name, rd_owner, rd_changeset_revision, rd_prior_installation_required = common_util.parse_repository_dependency_tuple( repository_tup ) + rd_toolshed, rd_name, rd_owner, rd_changeset_revision, rd_prior_installation_required, rd_only_if_compiling_contained_td = \ + common_util.parse_repository_dependency_tuple( repository_tup ) for key_rd_dict in key_rd_dicts: k = key_rd_dict.keys()[ 0 ] repository_dependency = key_rd_dict[ k ] - toolshed, name, owner, changeset_revision, prior_installation_required = common_util.parse_repository_dependency_tuple( repository_dependency ) + toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ + common_util.parse_repository_dependency_tuple( repository_dependency ) if rd_toolshed == toolshed and rd_name == name and rd_owner == owner: log.debug( "Removing repository dependency for repository %s owned by %s since it refers to a revision within itself." % ( name, owner ) ) else: @@ -705,8 +711,14 @@ return clean_key_rd_dicts def get_repository_dependency_as_key( repository_dependency ): - tool_shed, name, owner, changeset_revision, prior_installation_required = common_util.parse_repository_dependency_tuple( repository_dependency ) - return container_util.generate_repository_dependencies_key_for_repository( tool_shed, name, owner, changeset_revision, str( prior_installation_required ) ) + tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ + common_util.parse_repository_dependency_tuple( repository_dependency ) + return container_util.generate_repository_dependencies_key_for_repository( tool_shed, + name, + owner, + changeset_revision, + prior_installation_required, + only_if_compiling_contained_td ) def get_repository_dependency_by_repository_id( trans, decoded_repository_id ): return trans.sa_session.query( trans.model.RepositoryDependency ) \ diff -r 149dbd29acbce6396a969662a9b899cdbb7bdb46 -r ed3c786622741814a07589a1e642cca75c51c822 lib/tool_shed/util/shed_util_common.py --- a/lib/tool_shed/util/shed_util_common.py +++ b/lib/tool_shed/util/shed_util_common.py @@ -325,7 +325,8 @@ def generate_clone_url_from_repo_info_tup( repo_info_tup ): """Generate teh URL for cloning a repositoyr given a tuple of toolshed, name, owner, changeset_revision.""" # Example tuple: ['http://localhost:9009', 'blast_datatypes', 'test', '461a4216e8ab', False] - toolshed, name, owner, changeset_revision, prior_installation_required = common_util.parse_repository_dependency_tuple( repo_info_tup ) + toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ + common_util.parse_repository_dependency_tuple( repo_info_tup ) # Don't include the changeset_revision in clone urls. return url_join( toolshed, 'repos', owner, name ) @@ -975,16 +976,24 @@ if key in [ 'description', 'root_key' ]: continue for rd_tup in rd_tups: - tool_shed, name, owner, changeset_revision, prior_installation_required = common_util.parse_repository_dependency_tuple( rd_tup ) - if asbool( prior_installation_required ): - if trans.webapp.name == 'galaxy': - repository = get_repository_for_dependency_relationship( trans.app, tool_shed, name, owner, changeset_revision ) - else: - repository = get_repository_by_name_and_owner( trans.app, name, owner ) - if repository: - encoded_repository_id = trans.security.encode_id( repository.id ) - if encoded_repository_id in tsr_ids: - prior_tsr_ids.append( encoded_repository_id ) + tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \ + common_util.parse_repository_dependency_tuple( rd_tup ) + # If only_if_compiling_contained_td is False, then the repository dependency is not required to be installed prior to the dependent + # repository even if prior_installation_required is True. This is because the only meaningful content of the repository dependency + # is it's contained tool dependency, which is required in order to compile the dependent repository's tool dependency. In the scenario + # where the repository dependency is not installed prior to the dependent repository's tool dependency compilation process, the tool + # dependency compilation framework will install the repository dependency prior to compilation of the dependent repository's tool + # dependency. + if not asbool( only_if_compiling_contained_td ): + if asbool( prior_installation_required ): + if trans.webapp.name == 'galaxy': + repository = get_repository_for_dependency_relationship( trans.app, tool_shed, name, owner, changeset_revision ) + else: + repository = get_repository_by_name_and_owner( trans.app, name, owner ) + if repository: + encoded_repository_id = trans.security.encode_id( repository.id ) + if encoded_repository_id in tsr_ids: + prior_tsr_ids.append( encoded_repository_id ) return prior_tsr_ids def get_repository_in_tool_shed( trans, id ): @@ -1425,9 +1434,21 @@ """Return a reversed list of changesets in the repository changelog up to and including the included_upper_bounds_changeset_revision.""" return reversed_lower_upper_bounded_changelog( repo, INITIAL_CHANGELOG_HASH, included_upper_bounds_changeset_revision ) +def set_only_if_compiling_contained_td( repository, required_repository ): + """Return True if the received required_repository is only needed to compile a tool dependency defined for the received repository.""" + # This method is called only from Galaxy when rendering repository dependencies for an installed tool shed repository. + # TODO: Do we need to check more than changeset_revision here? + required_repository_tup = [ required_repository.tool_shed, required_repository.name, required_repository.owner, required_repository.changeset_revision ] + for tup in repository.tuples_of_repository_dependencies_needed_for_compiling_td: + partial_tup = tup[ 0:4 ] + if partial_tup == required_repository_tup: + return 'True' + return 'False' + def set_prior_installation_required( repository, required_repository ): """Return True if the received required_repository must be installed before the received repository.""" # This method is called only from Galaxy when rendering repository dependencies for an installed tool shed repository. + # TODO: Do we need to check more than changeset_revision here? required_repository_tup = [ required_repository.tool_shed, required_repository.name, required_repository.owner, required_repository.changeset_revision ] # Get the list of repository dependency tuples associated with the received repository where prior_installation_required is True. required_rd_tups_that_must_be_installed = repository.requires_prior_installation_of @@ -1435,9 +1456,9 @@ # Repository dependency tuples in metadata include a prior_installation_required value, so strip it for comparision. partial_required_rd_tup = required_rd_tup[ 0:4 ] if partial_required_rd_tup == required_repository_tup: - # Return the boolean value of prior_installation_required, which defaults to False. - return required_rd_tup[ 4 ] - return False + # Return the string value of prior_installation_required, which defaults to 'False'. + return str( required_rd_tup[ 4 ] ) + return 'False' def size_string( raw_text, size=MAX_DISPLAY_SIZE ): """Return a subset of a string (up to MAX_DISPLAY_SIZE) translated to a safe string for display in a browser.""" diff -r 149dbd29acbce6396a969662a9b899cdbb7bdb46 -r ed3c786622741814a07589a1e642cca75c51c822 lib/tool_shed/util/tool_dependency_util.py --- a/lib/tool_shed/util/tool_dependency_util.py +++ b/lib/tool_shed/util/tool_dependency_util.py @@ -347,15 +347,17 @@ get_installed_and_missing_tool_dependencies( trans, required_repository, tool_dependencies ) if required_repository_installed_tool_dependencies: # Add the install_dir attribute to the tool_dependencies. - required_repository_installed_tool_dependencies = add_installation_directories_to_tool_dependencies( trans=trans, - tool_dependencies=required_repository_installed_tool_dependencies ) + required_repository_installed_tool_dependencies = \ + add_installation_directories_to_tool_dependencies( trans=trans, + tool_dependencies=required_repository_installed_tool_dependencies ) for td_key, td_dict in required_repository_installed_tool_dependencies.items(): if td_key not in repository_installed_tool_dependencies: repository_installed_tool_dependencies[ td_key ] = td_dict if required_repository_missing_tool_dependencies: # Add the install_dir attribute to the tool_dependencies. - required_repository_missing_tool_dependencies = add_installation_directories_to_tool_dependencies( trans=trans, - tool_dependencies=required_repository_missing_tool_dependencies ) + required_repository_missing_tool_dependencies = \ + add_installation_directories_to_tool_dependencies( trans=trans, + tool_dependencies=required_repository_missing_tool_dependencies ) for td_key, td_dict in required_repository_missing_tool_dependencies.items(): if td_key not in repository_missing_tool_dependencies: repository_missing_tool_dependencies[ td_key ] = td_dict diff -r 149dbd29acbce6396a969662a9b899cdbb7bdb46 -r ed3c786622741814a07589a1e642cca75c51c822 templates/webapps/tool_shed/repository/common.mako --- a/templates/webapps/tool_shed/repository/common.mako +++ b/templates/webapps/tool_shed/repository/common.mako @@ -619,7 +619,7 @@ <%def name="render_repository_dependency( repository_dependency, pad, parent, row_counter, row_is_header=False )"><% - from galaxy.util import string_as_bool + from galaxy.util import asbool encoded_id = trans.security.encode_id( repository_dependency.id ) if trans.webapp.name == 'galaxy': if repository_dependency.tool_shed_repository_id: @@ -633,8 +633,7 @@ repository_name = str( repository_dependency.repository_name ) repository_owner = str( repository_dependency.repository_owner ) changeset_revision = str( repository_dependency.changeset_revision ) - prior_installation_required = string_as_bool( str( repository_dependency.prior_installation_required ) ) - if prior_installation_required: + if asbool( str( repository_dependency.prior_installation_required ) ): prior_installation_required_str = " <i>(prior install required)</i>" else: prior_installation_required_str = "" Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.