def get_installed_and_missing_tool_dependencies_for_installed_repository(self, repository, all_tool_dependencies):
     """
     Return the lists of installed tool dependencies and missing tool dependencies for a Tool Shed
     repository that has been installed into Galaxy.
     """
     if all_tool_dependencies:
         tool_dependencies = {}
         missing_tool_dependencies = {}
         for td_key, val in all_tool_dependencies.items():
             if td_key in ["set_environment"]:
                 for index, td_info_dict in enumerate(val):
                     name = td_info_dict["name"]
                     version = None
                     type = td_info_dict["type"]
                     tool_dependency = tool_dependency_util.get_tool_dependency_by_name_type_repository(
                         self.app, repository, name, type
                     )
                     if tool_dependency:
                         td_info_dict["repository_id"] = repository.id
                         td_info_dict["tool_dependency_id"] = tool_dependency.id
                         if tool_dependency.status:
                             tool_dependency_status = str(tool_dependency.status)
                         else:
                             tool_dependency_status = "Never installed"
                         td_info_dict["status"] = tool_dependency_status
                         val[index] = td_info_dict
                         if (
                             tool_dependency.status
                             == self.app.install_model.ToolDependency.installation_status.INSTALLED
                         ):
                             tool_dependencies[td_key] = val
                         else:
                             missing_tool_dependencies[td_key] = val
             else:
                 name = val["name"]
                 version = val["version"]
                 type = val["type"]
                 tool_dependency = tool_dependency_util.get_tool_dependency_by_name_version_type_repository(
                     self.app, repository, name, version, type
                 )
                 if tool_dependency:
                     val["repository_id"] = repository.id
                     val["tool_dependency_id"] = tool_dependency.id
                     if tool_dependency.status:
                         tool_dependency_status = str(tool_dependency.status)
                     else:
                         tool_dependency_status = "Never installed"
                     val["status"] = tool_dependency_status
                     if (
                         tool_dependency.status
                         == self.app.install_model.ToolDependency.installation_status.INSTALLED
                     ):
                         tool_dependencies[td_key] = val
                     else:
                         missing_tool_dependencies[td_key] = val
     else:
         tool_dependencies = None
         missing_tool_dependencies = None
     return tool_dependencies, missing_tool_dependencies
Пример #2
0
 def get_installed_and_missing_tool_dependencies_for_installed_repository(self, repository, all_tool_dependencies):
     """
     Return the lists of installed tool dependencies and missing tool dependencies for a Tool Shed
     repository that has been installed into Galaxy.
     """
     if all_tool_dependencies:
         tool_dependencies = {}
         missing_tool_dependencies = {}
         for td_key, val in all_tool_dependencies.items():
             if td_key in ['set_environment']:
                 for index, td_info_dict in enumerate(val):
                     name = td_info_dict['name']
                     version = None
                     type = td_info_dict['type']
                     tool_dependency = tool_dependency_util.get_tool_dependency_by_name_type_repository(self.app,
                                                                                                        repository,
                                                                                                        name,
                                                                                                        type)
                     if tool_dependency:
                         td_info_dict['repository_id'] = repository.id
                         td_info_dict['tool_dependency_id'] = tool_dependency.id
                         if tool_dependency.status:
                             tool_dependency_status = str(tool_dependency.status)
                         else:
                             tool_dependency_status = 'Never installed'
                         td_info_dict['status'] = tool_dependency_status
                         val[index] = td_info_dict
                         if tool_dependency.status == self.app.install_model.ToolDependency.installation_status.INSTALLED:
                             tool_dependencies[td_key] = val
                         else:
                             missing_tool_dependencies[td_key] = val
             else:
                 name = val['name']
                 version = val['version']
                 type = val['type']
                 tool_dependency = tool_dependency_util.get_tool_dependency_by_name_version_type_repository(self.app,
                                                                                                            repository,
                                                                                                            name,
                                                                                                            version,
                                                                                                            type)
                 if tool_dependency:
                     val['repository_id'] = repository.id
                     val['tool_dependency_id'] = tool_dependency.id
                     if tool_dependency.status:
                         tool_dependency_status = str(tool_dependency.status)
                     else:
                         tool_dependency_status = 'Never installed'
                     val['status'] = tool_dependency_status
                     if tool_dependency.status == self.app.install_model.ToolDependency.installation_status.INSTALLED:
                         tool_dependencies[td_key] = val
                     else:
                         missing_tool_dependencies[td_key] = val
     else:
         tool_dependencies = None
         missing_tool_dependencies = None
     return tool_dependencies, missing_tool_dependencies
Пример #3
0
def install_package( app, elem, tool_shed_repository, tool_dependencies=None ):
    # The value of tool_dependencies is a partial or full list of ToolDependency records associated with the tool_shed_repository.
    sa_session = app.model.context.current
    tool_dependency = None
    # The value of package_name should match the value of the "package" type in the tool config's <requirements> tag set, but it's not required.
    package_name = elem.get( 'name', None )
    package_version = elem.get( 'version', None )
    if tool_dependencies and package_name and package_version:
        for package_elem in elem:
            if package_elem.tag == 'repository':
                # We have a complex repository dependency definition.
                tool_shed = package_elem.attrib[ 'toolshed' ]
                required_repository_name = package_elem.attrib[ 'name' ]
                required_repository_owner = package_elem.attrib[ 'owner' ]
                default_required_repository_changeset_revision = package_elem.attrib[ 'changeset_revision' ]
                required_repository = get_tool_shed_repository_by_tool_shed_name_owner_changeset_revision( app,
                                                                                                           tool_shed,
                                                                                                           required_repository_name,
                                                                                                           required_repository_owner,
                                                                                                           default_required_repository_changeset_revision )
                tmp_filename = None
                if required_repository:
                    required_repository_changeset_revision = required_repository.installed_changeset_revision
                    # Define the installation directory for the required tool dependency package in the required repository.
                    required_repository_package_install_dir = \
                        get_tool_dependency_install_dir( app=app,
                                                         repository_name=required_repository_name,
                                                         repository_owner=required_repository_owner,
                                                         repository_changeset_revision=required_repository_changeset_revision,
                                                         tool_dependency_type='package',
                                                         tool_dependency_name=package_name,
                                                         tool_dependency_version=package_version )
                    # Define the this dependent repository's tool dependency installation directory that will contain the env.sh file with a path to the
                    # required repository's installed tool dependency package.
                    dependent_install_dir = get_tool_dependency_install_dir( app=app,
                                                                             repository_name=tool_shed_repository.name,
                                                                             repository_owner=tool_shed_repository.owner,
                                                                             repository_changeset_revision=tool_shed_repository.installed_changeset_revision,
                                                                             tool_dependency_type='package',
                                                                             tool_dependency_name=package_name,
                                                                             tool_dependency_version=package_version )
                    # Set this dependent repository's tool dependency env.sh file with a path to the required repository's installed tool dependency package.
                    # We can get everything we need from the discovered installed required_repository.
                    if required_repository.status in [ app.model.ToolShedRepository.installation_status.DEACTIVATED,
                                                       app.model.ToolShedRepository.installation_status.INSTALLED ]:                        
                        if not os.path.exists( required_repository_package_install_dir ):
                            print 'Missing required tool dependency directory %s' % str( required_repository_package_install_dir )
                        repo_files_dir = required_repository.repo_files_directory( app )
                        tool_dependencies_config = get_absolute_path_to_file_in_repository( repo_files_dir, 'tool_dependencies.xml' )
                        if tool_dependencies_config:
                            config_to_use = tool_dependencies_config
                        else:
                            message = "Unable to locate required tool_dependencies.xml file for revision %s of installed repository %s owned by %s." % \
                                ( str( required_repository.changeset_revision ), str( required_repository.name ), str( required_repository.owner ) )
                            raise Exception( message )
                    else:
                        # Make a call to the tool shed to get the changeset revision to which the current value of required_repository_changeset_revision
                        # should be updated if it's not current.
                        text = get_updated_changeset_revisions_from_tool_shed( app=app,
                                                                               tool_shed_url=tool_shed,
                                                                               name=required_repository_name,
                                                                               owner=required_repository_owner,
                                                                               changeset_revision=required_repository_changeset_revision )
                        if text:
                            updated_changeset_revisions = listify( text )
                            # The list of changeset revisions is in reverse order, so the newest will be first.
                            required_repository_changeset_revision = updated_changeset_revisions[ 0 ]
                        # Make a call to the tool shed to get the required repository's tool_dependencies.xml file.
                        tmp_filename = create_temporary_tool_dependencies_config( app,
                                                                                  tool_shed,
                                                                                  required_repository_name,
                                                                                  required_repository_owner,
                                                                                  required_repository_changeset_revision )
                        config_to_use = tmp_filename
                    tool_dependency, actions_dict = populate_actions_dict( app=app,
                                                                           dependent_install_dir=dependent_install_dir,
                                                                           required_install_dir=required_repository_package_install_dir,
                                                                           tool_shed_repository=tool_shed_repository,
                                                                           required_repository=required_repository,
                                                                           package_name=package_name,
                                                                           package_version=package_version,
                                                                           tool_dependencies_config=config_to_use )
                    if tmp_filename:
                        try:
                            os.remove( tmp_filename )
                        except:
                            pass
                    # Install and build the package via fabric.
                    install_and_build_package_via_fabric( app, tool_dependency, actions_dict )
                else:
                    message = "Unable to locate required tool shed repository named %s owned by %s with revision %s." % \
                        ( str( required_repository_name ), str( required_repository_owner ), str( default_required_repository_changeset_revision ) )
                    raise Exception( message )
            elif package_elem.tag == 'install':
                # <install version="1.0">
                # Get the installation directory for tool dependencies that will be installed for the received tool_shed_repository.
                install_dir = get_tool_dependency_install_dir( app=app,
                                                               repository_name=tool_shed_repository.name,
                                                               repository_owner=tool_shed_repository.owner,
                                                               repository_changeset_revision=tool_shed_repository.installed_changeset_revision,
                                                               tool_dependency_type='package',
                                                               tool_dependency_name=package_name,
                                                               tool_dependency_version=package_version )
                if os.path.exists( install_dir ):
                    print '\nSkipping installation of tool dependency', package_name, 'version', package_version, 'since it is installed in', install_dir, '\n'
                    tool_dependency = tool_dependency_util.get_tool_dependency_by_name_version_type_repository( app,
                                                                                                                tool_shed_repository,
                                                                                                                package_name,
                                                                                                                package_version,
                                                                                                                'package' )
                    tool_dependency.status = app.model.ToolDependency.installation_status.INSTALLED
                    sa_session.add( tool_dependency )
                    sa_session.flush()
                else:
                    package_install_version = package_elem.get( 'version', '1.0' )
                    tool_dependency = tool_dependency_util.create_or_update_tool_dependency( app=app,
                                                                                             tool_shed_repository=tool_shed_repository,
                                                                                             name=package_name,
                                                                                             version=package_version,
                                                                                             type='package',
                                                                                             status=app.model.ToolDependency.installation_status.INSTALLING,
                                                                                             set_status=True )
                    if package_install_version == '1.0':
                        # Handle tool dependency installation using a fabric method included in the Galaxy framework.
                        for actions_elem in package_elem:
                            install_via_fabric( app, tool_dependency, actions_elem, install_dir, package_name=package_name )
                            sa_session.refresh( tool_dependency )
                            if tool_dependency.status != app.model.ToolDependency.installation_status.ERROR:
                                print package_name, 'version', package_version, 'installed in', install_dir
                    else:
                        raise NotImplementedError( 'Only install version 1.0 is currently supported (i.e., change your tag to be <install version="1.0">).' )
            elif package_elem.tag == 'readme':
                # Nothing to be done.
                continue
            #elif package_elem.tag == 'proprietary_fabfile':
            #    # TODO: This is not yet supported or functionally correct...
            #    # Handle tool dependency installation where the repository includes one or more proprietary fabric scripts.
            #    if not fabric_version_checked:
            #        check_fabric_version()
            #        fabric_version_checked = True
            #    fabfile_name = package_elem.get( 'name', None )
            #    proprietary_fabfile_path = os.path.abspath( os.path.join( os.path.split( tool_dependencies_config )[ 0 ], fabfile_name ) )
            #    print 'Installing tool dependencies via fabric script ', proprietary_fabfile_path
    return tool_dependency
Пример #4
0
def install_package(app, elem, tool_shed_repository, tool_dependencies=None):
    # The value of tool_dependencies is a partial or full list of ToolDependency records associated with the tool_shed_repository.
    sa_session = app.model.context.current
    tool_dependency = None
    # The value of package_name should match the value of the "package" type in the tool config's <requirements> tag set, but it's not required.
    package_name = elem.get('name', None)
    package_version = elem.get('version', None)
    if tool_dependencies and package_name and package_version:
        for package_elem in elem:
            if package_elem.tag == 'repository':
                # We have a complex repository dependency definition.
                tool_shed = package_elem.attrib['toolshed']
                required_repository_name = package_elem.attrib['name']
                required_repository_owner = package_elem.attrib['owner']
                default_required_repository_changeset_revision = package_elem.attrib[
                    'changeset_revision']
                required_repository = get_tool_shed_repository_by_tool_shed_name_owner_changeset_revision(
                    app, tool_shed, required_repository_name,
                    required_repository_owner,
                    default_required_repository_changeset_revision)
                tmp_filename = None
                if required_repository:
                    required_repository_changeset_revision = required_repository.installed_changeset_revision
                    # Define the installation directory for the required tool dependency package in the required repository.
                    required_repository_package_install_dir = \
                        get_tool_dependency_install_dir( app=app,
                                                         repository_name=required_repository_name,
                                                         repository_owner=required_repository_owner,
                                                         repository_changeset_revision=required_repository_changeset_revision,
                                                         tool_dependency_type='package',
                                                         tool_dependency_name=package_name,
                                                         tool_dependency_version=package_version )
                    # Define the this dependent repository's tool dependency installation directory that will contain the env.sh file with a path to the
                    # required repository's installed tool dependency package.
                    dependent_install_dir = get_tool_dependency_install_dir(
                        app=app,
                        repository_name=tool_shed_repository.name,
                        repository_owner=tool_shed_repository.owner,
                        repository_changeset_revision=tool_shed_repository.
                        installed_changeset_revision,
                        tool_dependency_type='package',
                        tool_dependency_name=package_name,
                        tool_dependency_version=package_version)
                    # Set this dependent repository's tool dependency env.sh file with a path to the required repository's installed tool dependency package.
                    # We can get everything we need from the discovered installed required_repository.
                    if required_repository.status in [
                            app.model.ToolShedRepository.installation_status.
                            DEACTIVATED, app.model.ToolShedRepository.
                            installation_status.INSTALLED
                    ]:
                        if not os.path.exists(
                                required_repository_package_install_dir):
                            print 'Missing required tool dependency directory %s' % str(
                                required_repository_package_install_dir)
                        repo_files_dir = required_repository.repo_files_directory(
                            app)
                        tool_dependencies_config = get_absolute_path_to_file_in_repository(
                            repo_files_dir, 'tool_dependencies.xml')
                        if tool_dependencies_config:
                            config_to_use = tool_dependencies_config
                        else:
                            message = "Unable to locate required tool_dependencies.xml file for revision %s of installed repository %s owned by %s." % \
                                ( str( required_repository.changeset_revision ), str( required_repository.name ), str( required_repository.owner ) )
                            raise Exception(message)
                    else:
                        # Make a call to the tool shed to get the changeset revision to which the current value of required_repository_changeset_revision
                        # should be updated if it's not current.
                        text = get_updated_changeset_revisions_from_tool_shed(
                            app=app,
                            tool_shed_url=tool_shed,
                            name=required_repository_name,
                            owner=required_repository_owner,
                            changeset_revision=
                            required_repository_changeset_revision)
                        if text:
                            updated_changeset_revisions = listify(text)
                            # The list of changeset revisions is in reverse order, so the newest will be first.
                            required_repository_changeset_revision = updated_changeset_revisions[
                                0]
                        # Make a call to the tool shed to get the required repository's tool_dependencies.xml file.
                        tmp_filename = create_temporary_tool_dependencies_config(
                            app, tool_shed, required_repository_name,
                            required_repository_owner,
                            required_repository_changeset_revision)
                        config_to_use = tmp_filename
                    tool_dependency, actions_dict = populate_actions_dict(
                        app=app,
                        dependent_install_dir=dependent_install_dir,
                        required_install_dir=
                        required_repository_package_install_dir,
                        tool_shed_repository=tool_shed_repository,
                        required_repository=required_repository,
                        package_name=package_name,
                        package_version=package_version,
                        tool_dependencies_config=config_to_use)
                    if tmp_filename:
                        try:
                            os.remove(tmp_filename)
                        except:
                            pass
                    # Install and build the package via fabric.
                    install_and_build_package_via_fabric(
                        app, tool_dependency, actions_dict)
                else:
                    message = "Unable to locate required tool shed repository named %s owned by %s with revision %s." % \
                        ( str( required_repository_name ), str( required_repository_owner ), str( default_required_repository_changeset_revision ) )
                    raise Exception(message)
            elif package_elem.tag == 'install':
                # <install version="1.0">
                # Get the installation directory for tool dependencies that will be installed for the received tool_shed_repository.
                install_dir = get_tool_dependency_install_dir(
                    app=app,
                    repository_name=tool_shed_repository.name,
                    repository_owner=tool_shed_repository.owner,
                    repository_changeset_revision=tool_shed_repository.
                    installed_changeset_revision,
                    tool_dependency_type='package',
                    tool_dependency_name=package_name,
                    tool_dependency_version=package_version)
                if os.path.exists(install_dir):
                    print '\nSkipping installation of tool dependency', package_name, 'version', package_version, 'since it is installed in', install_dir, '\n'
                    tool_dependency = tool_dependency_util.get_tool_dependency_by_name_version_type_repository(
                        app, tool_shed_repository, package_name,
                        package_version, 'package')
                    tool_dependency.status = app.model.ToolDependency.installation_status.INSTALLED
                    sa_session.add(tool_dependency)
                    sa_session.flush()
                else:
                    package_install_version = package_elem.get(
                        'version', '1.0')
                    tool_dependency = tool_dependency_util.create_or_update_tool_dependency(
                        app=app,
                        tool_shed_repository=tool_shed_repository,
                        name=package_name,
                        version=package_version,
                        type='package',
                        status=app.model.ToolDependency.installation_status.
                        INSTALLING,
                        set_status=True)
                    if package_install_version == '1.0':
                        # Handle tool dependency installation using a fabric method included in the Galaxy framework.
                        for actions_elem in package_elem:
                            install_via_fabric(app,
                                               tool_dependency,
                                               actions_elem,
                                               install_dir,
                                               package_name=package_name)
                            sa_session.refresh(tool_dependency)
                            if tool_dependency.status != app.model.ToolDependency.installation_status.ERROR:
                                print package_name, 'version', package_version, 'installed in', install_dir
                    else:
                        raise NotImplementedError(
                            'Only install version 1.0 is currently supported (i.e., change your tag to be <install version="1.0">).'
                        )
            elif package_elem.tag == 'readme':
                # Nothing to be done.
                continue
            #elif package_elem.tag == 'proprietary_fabfile':
            #    # TODO: This is not yet supported or functionally correct...
            #    # Handle tool dependency installation where the repository includes one or more proprietary fabric scripts.
            #    if not fabric_version_checked:
            #        check_fabric_version()
            #        fabric_version_checked = True
            #    fabfile_name = package_elem.get( 'name', None )
            #    proprietary_fabfile_path = os.path.abspath( os.path.join( os.path.split( tool_dependencies_config )[ 0 ], fabfile_name ) )
            #    print 'Installing tool dependencies via fabric script ', proprietary_fabfile_path
    return tool_dependency
 def sync_database_with_file_system( self, app, tool_shed_repository, tool_dependency_name, tool_dependency_version,
                                     tool_dependency_install_dir, tool_dependency_type='package' ):
     """
     The installation directory defined by the received tool_dependency_install_dir exists, so check for
     the presence of INSTALLATION_LOG.  If the files exists, we'll assume the tool dependency is installed,
     but not necessarily successfully (it could be in an error state on disk.  However, we can justifiably
     assume here that no matter the state, an associated database record will exist.
     """
     # This method should be reached very rarely.  It implies that either the Galaxy environment
     # became corrupted (i.e., the database records for installed tool dependencies is not synchronized
     # with tool dependencies on disk) or the Tool Shed's install and test framework is running.  The Tool
     # Shed's install and test framework installs repositories in 2 stages, those of type tool_dependency_definition
     # followed by those containing valid tools and tool functional test components.
     log.debug( "Synchronizing the database with the file system..." )
     try:
         log.debug( "The value of app.config.running_functional_tests is: %s" %
             str( app.config.running_functional_tests ) )
     except:
         pass
     sa_session = app.install_model.context
     can_install_tool_dependency = False
     tool_dependency = \
         tool_dependency_util.get_tool_dependency_by_name_version_type_repository( app,
                                                                                   tool_shed_repository,
                                                                                   tool_dependency_name,
                                                                                   tool_dependency_version,
                                                                                   tool_dependency_type )
     if tool_dependency.status == app.install_model.ToolDependency.installation_status.INSTALLING:
         # The tool dependency is in an Installing state, so we don't want to do anything to it.  If the tool
         # dependency is being installed by someone else, we don't want to interfere with that.  This assumes
         # the installation by "someone else" is not hung in an Installing state, which is a weakness if that
         # "someone else" never repaired it.
         log.debug( 'Skipping installation of tool dependency %s version %s because it has a status of %s' %
             ( str( tool_dependency.name ), str( tool_dependency.version ), str( tool_dependency.status ) ) )
     else:
         # We have a pre-existing installation directory on the file system, but our associated database record is
         # in a state that allowed us to arrive here.  At this point, we'll inspect the installation directory to
         # see if we have a "proper installation" and if so, synchronize the database record rather than reinstalling
         # the dependency if we're "running_functional_tests".  If we're not "running_functional_tests, we'll set
         # the tool dependency's installation status to ERROR.
         tool_dependency_installation_directory_contents = os.listdir( tool_dependency_install_dir )
         if basic_util.INSTALLATION_LOG in tool_dependency_installation_directory_contents:
             # Since this tool dependency's installation directory contains an installation log, we consider it to be
             # installed.  In some cases the record may be missing from the database due to some activity outside of
             # the control of the Tool Shed.  Since a new record was created for it and we don't know the state of the
             # files on disk, we will set it to an error state (unless we are running Tool Shed functional tests - see
             # below).
             log.debug( 'Skipping installation of tool dependency %s version %s because it is installed in %s' %
                 ( str( tool_dependency.name ), str( tool_dependency.version ), str( tool_dependency_install_dir ) ) )
             if app.config.running_functional_tests:
                 # If we are running functional tests, the state will be set to Installed because previously compiled
                 # tool dependencies are not deleted by default, from the "install and test" framework..
                 tool_dependency.status = app.install_model.ToolDependency.installation_status.INSTALLED
             else:
                 error_message = 'The installation directory for this tool dependency had contents but the database had no record. '
                 error_message += 'The installation log may show this tool dependency to be correctly installed, but due to the '
                 error_message += 'missing database record it is now being set to Error.'
                 tool_dependency.status = app.install_model.ToolDependency.installation_status.ERROR
                 tool_dependency.error_message = error_message
         else:
             error_message = '\nInstallation path %s for tool dependency %s version %s exists, but the expected file %s' % \
                 ( str( tool_dependency_install_dir ),
                   str( tool_dependency_name ),
                   str( tool_dependency_version ),
                   str( basic_util.INSTALLATION_LOG ) )
             error_message += ' is missing.  This indicates an installation error so the tool dependency is being'
             error_message += ' prepared for re-installation.'
             log.error( error_message )
             tool_dependency.status = app.install_model.ToolDependency.installation_status.NEVER_INSTALLED
             basic_util.remove_dir( tool_dependency_install_dir )
             can_install_tool_dependency = True
         sa_session.add( tool_dependency )
         sa_session.flush()
     try:
         log.debug( "Returning from sync_database_with_file_system with tool_dependency %s, can_install_tool_dependency %s." %
             ( str( tool_dependency.name ), str( can_install_tool_dependency ) ) )
     except Exception as e:
         log.debug( str( e ) )
     return tool_dependency, can_install_tool_dependency
 def create_tool_dependency_with_initialized_env_sh_file( self, dependent_install_dir, tool_shed_repository,
                                                          required_repository, package_name, package_version,
                                                          tool_dependencies_config ):
     """
     Create or get a tool_dependency record that is defined by the received package_name and package_version.
     An env.sh file will be created for the tool_dependency in the received dependent_install_dir.
     """
     # The received required_repository refers to a tool_shed_repository record that is defined as a complex
     # repository dependency for this tool_dependency.  The required_repository may or may not be currently
     # installed (it doesn't matter).  If it is installed, it is associated with a tool_dependency that has
     # an env.sh file that this new tool_dependency must be able to locate and "source".  If it is not installed,
     # we can still determine where that env.sh file will be, so we'll initialize this new tool_dependency's env.sh
     # file in either case.  If the required repository ends up with an installation error, this new tool
     # dependency will still be fine because its containing repository will be defined as missing dependencies.
     tool_dependencies = []
     if not os.path.exists( dependent_install_dir ):
         os.makedirs( dependent_install_dir )
     required_tool_dependency_env_file_path = None
     if tool_dependencies_config:
         required_td_tree, error_message = xml_util.parse_xml( tool_dependencies_config )
         if required_td_tree:
             required_td_root = required_td_tree.getroot()
             for required_td_elem in required_td_root:
                 # Find the appropriate package name and version.
                 if required_td_elem.tag == 'package':
                     # <package name="bwa" version="0.5.9">
                     required_td_package_name = required_td_elem.get( 'name', None )
                     required_td_package_version = required_td_elem.get( 'version', None )
                     # Check the database to see if we have a record for the required tool dependency (we may not which is ok).  If we
                     # find a record, we need to see if it is in an error state and if so handle it appropriately.
                     required_tool_dependency = \
                         tool_dependency_util.get_tool_dependency_by_name_version_type_repository( self.app,
                                                                                                   required_repository,
                                                                                                   required_td_package_name,
                                                                                                   required_td_package_version,
                                                                                                   'package' )
                     if required_td_package_name == package_name and required_td_package_version == package_version:
                         # Get or create a database tool_dependency record with which the installed package on disk will be associated.
                         tool_dependency = \
                             tool_dependency_util.create_or_update_tool_dependency( app=self.app,
                                                                                    tool_shed_repository=tool_shed_repository,
                                                                                    name=package_name,
                                                                                    version=package_version,
                                                                                    type='package',
                                                                                    status=self.app.install_model.ToolDependency.installation_status.NEVER_INSTALLED,
                                                                                    set_status=True )
                         # Create an env.sh file for the tool_dependency whose first line will source the env.sh file located in
                         # the path defined by required_tool_dependency_env_file_path.  It doesn't matter if the required env.sh
                         # file currently exists..
                         required_tool_dependency_env_file_path = \
                             self.get_required_repository_package_env_sh_path( package_name,
                                                                               package_version,
                                                                               required_repository )
                         env_file_builder = EnvFileBuilder( tool_dependency.installation_directory( self.app ) )
                         env_file_builder.append_line( action="source", value=required_tool_dependency_env_file_path )
                         return_code = env_file_builder.return_code
                         if return_code:
                             error_message = 'Error defining env.sh file for package %s, return_code: %s' % \
                                 ( str( package_name ), str( return_code ) )
                             tool_dependency = \
                                 tool_dependency_util.set_tool_dependency_attributes(self.app,
                                                                                     tool_dependency=tool_dependency,
                                                                                     status=self.app.install_model.ToolDependency.installation_status.ERROR,
                                                                                     error_message=error_message)
                         elif required_tool_dependency is not None and required_tool_dependency.in_error_state:
                             error_message = "This tool dependency's required tool dependency %s version %s has status %s." % \
                                 ( str( required_tool_dependency.name ), str( required_tool_dependency.version ), str( required_tool_dependency.status ) )
                             tool_dependency = \
                                 tool_dependency_util.set_tool_dependency_attributes(self.app,
                                                                                     tool_dependency=tool_dependency,
                                                                                     status=self.app.install_model.ToolDependency.installation_status.ERROR,
                                                                                     error_message=error_message)
                         else:
                             tool_dependency = \
                                 tool_dependency_util.set_tool_dependency_attributes( self.app,
                                                                                      tool_dependency=tool_dependency,
                                                                                      status=self.app.install_model.ToolDependency.installation_status.INSTALLED )
                         tool_dependencies.append( tool_dependency )
     return tool_dependencies