1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/6f7240344304/ changeset: 6f7240344304 user: jgoecks date: 2012-04-20 23:12:48 summary: Merge affected #: 13 files diff -r 6af88237056f0d4c7ae4c3dd5af647cde4830710 -r 6f7240344304a143a3d70182092c61931595b613 lib/galaxy/model/__init__.py --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -2629,8 +2629,8 @@ class ToolShedRepository( object ): def __init__( self, id=None, create_time=None, tool_shed=None, name=None, description=None, owner=None, installed_changeset_revision=None, - changeset_revision=None, metadata=None, includes_datatypes=False, update_available=False, deleted=False, uninstalled=False, - dist_to_shed=False ): + changeset_revision=None, ctx_rev=None, metadata=None, includes_datatypes=False, update_available=False, deleted=False, + uninstalled=False, dist_to_shed=False ): self.id = id self.create_time = create_time self.tool_shed = tool_shed @@ -2639,6 +2639,7 @@ self.owner = owner self.installed_changeset_revision = installed_changeset_revision self.changeset_revision = changeset_revision + self.ctx_rev = ctx_rev self.metadata = metadata self.includes_datatypes = includes_datatypes self.update_available = update_available diff -r 6af88237056f0d4c7ae4c3dd5af647cde4830710 -r 6f7240344304a143a3d70182092c61931595b613 lib/galaxy/model/mapping.py --- a/lib/galaxy/model/mapping.py +++ b/lib/galaxy/model/mapping.py @@ -382,6 +382,7 @@ Column( "owner", TrimmedString( 255 ), index=True ), Column( "installed_changeset_revision", TrimmedString( 255 ) ), Column( "changeset_revision", TrimmedString( 255 ), index=True ), + Column( "ctx_rev", TrimmedString( 10 ) ), Column( "metadata", JSONType, nullable=True ), Column( "includes_datatypes", Boolean, index=True, default=False ), Column( "update_available", Boolean, default=False ), diff -r 6af88237056f0d4c7ae4c3dd5af647cde4830710 -r 6f7240344304a143a3d70182092c61931595b613 lib/galaxy/model/migrate/versions/0097_add_ctx_rev_column.py --- /dev/null +++ b/lib/galaxy/model/migrate/versions/0097_add_ctx_rev_column.py @@ -0,0 +1,43 @@ +""" +Migration script to add the ctx_rev column to the tool_shed_repository table. +""" + +from sqlalchemy import * +from sqlalchemy.orm import * +from migrate import * +from migrate.changeset import * + +import datetime +now = datetime.datetime.utcnow +# Need our custom types, but don't import anything else from model +from galaxy.model.custom_types import * + +import sys, logging +log = logging.getLogger( __name__ ) +log.setLevel(logging.DEBUG) +handler = logging.StreamHandler( sys.stdout ) +format = "%(name)s %(levelname)s %(asctime)s %(message)s" +formatter = logging.Formatter( format ) +handler.setFormatter( formatter ) +log.addHandler( handler ) + +metadata = MetaData( migrate_engine ) +db_session = scoped_session( sessionmaker( bind=migrate_engine, autoflush=False, autocommit=True ) ) + +def upgrade(): + print __doc__ + metadata.reflect() + ToolShedRepository_table = Table( "tool_shed_repository", metadata, autoload=True ) + col = Column( "ctx_rev", TrimmedString( 10 ) ) + try: + col.create( ToolShedRepository_table ) + assert col is ToolShedRepository_table.c.ctx_rev + except Exception, e: + print "Adding ctx_rev column to the tool_shed_repository table failed: %s" % str( e ) +def downgrade(): + metadata.reflect() + ToolShedRepository_table = Table( "tool_shed_repository", metadata, autoload=True ) + try: + ToolShedRepository_table.c.ctx_rev.drop() + except Exception, e: + print "Dropping column ctx_rev from the tool_shed_repository table failed: %s" % str( e ) diff -r 6af88237056f0d4c7ae4c3dd5af647cde4830710 -r 6f7240344304a143a3d70182092c61931595b613 lib/galaxy/tool_shed/install_manager.py --- a/lib/galaxy/tool_shed/install_manager.py +++ b/lib/galaxy/tool_shed/install_manager.py @@ -7,6 +7,7 @@ from galaxy.util.json import from_json_string, to_json_string from galaxy.util.shed_util import * from galaxy.util.odict import odict + log = logging.getLogger( __name__ ) class InstallManager( object ): @@ -119,7 +120,7 @@ is_displayed = True return is_displayed, tool_sections def handle_repository_contents( self, current_working_dir, repository_clone_url, relative_install_dir, repository_elem, repository_name, description, - changeset_revision, tmp_name ): + changeset_revision, ctx_rev ): # Generate the metadata for the installed tool shed repository, among other things. It is critical that the installed repository is # updated to the desired changeset_revision before metadata is set because the process for setting metadata uses the repository files on disk. # The values for the keys in each of the following dictionaries will be a list to allow for the same tool to be displayed in multiple places @@ -144,6 +145,7 @@ repository_name, description, changeset_revision, + ctx_rev, repository_clone_url, metadata_dict, dist_to_shed=True ) @@ -166,11 +168,6 @@ self.migrated_tools_config, tool_panel_dict=tool_panel_dict_for_display, new_install=True ) - # Remove the temporary file - try: - os.unlink( tmp_name ) - except: - pass if 'datatypes_config' in metadata_dict: datatypes_config = os.path.abspath( metadata_dict[ 'datatypes_config' ] ) # Load proprietary data types required by tools. The value of override is not important here since the Galaxy server will be started @@ -193,7 +190,7 @@ self.app.datatypes_registry.load_display_applications( installed_repository_dict=repository_dict ) return tool_shed_repository, metadata_dict def install_repository( self, repository_elem ): - # Install a single repository, loading contained tools into the tool config. + # Install a single repository, loading contained tools into the tool panel. name = repository_elem.get( 'name' ) description = repository_elem.get( 'description' ) changeset_revision = repository_elem.get( 'changeset_revision' ) @@ -206,65 +203,55 @@ tool_shed_url = self.__get_url_from_tool_shed( self.tool_shed ) repository_clone_url = os.path.join( tool_shed_url, 'repos', self.repository_owner, name ) relative_install_dir = os.path.join( clone_dir, name ) - returncode, tmp_name = clone_repository( name, clone_dir, current_working_dir, repository_clone_url ) - if returncode == 0: - returncode, tmp_name = update_repository( current_working_dir, relative_install_dir, changeset_revision ) - if returncode == 0: - tool_shed_repository, metadata_dict = self.handle_repository_contents( current_working_dir, - repository_clone_url, - relative_install_dir, - repository_elem, - name, - description, - changeset_revision, - tmp_name ) - if 'tools' in metadata_dict: - # Get the tool_versions from the tool shed for each tool in the installed change set. - url = '%s/repository/get_tool_versions?name=%s&owner=%s&changeset_revision=%s&webapp=galaxy' % \ - ( tool_shed_url, tool_shed_repository.name, self.repository_owner, changeset_revision ) - response = urllib2.urlopen( url ) - text = response.read() - response.close() - if text: - tool_version_dicts = from_json_string( text ) - handle_tool_versions( self.app, tool_version_dicts, tool_shed_repository ) - else: - # Set the tool versions since they seem to be missing for this repository in the tool shed. - # CRITICAL NOTE: These default settings may not properly handle all parent/child associations. - for tool_dict in metadata_dict[ 'tools' ]: - flush_needed = False - tool_id = tool_dict[ 'guid' ] - old_tool_id = tool_dict[ 'id' ] - tool_version = tool_dict[ 'version' ] - tool_version_using_old_id = get_tool_version( self.app, old_tool_id ) - tool_version_using_guid = get_tool_version( self.app, tool_id ) - if not tool_version_using_old_id: - tool_version_using_old_id = self.app.model.ToolVersion( tool_id=old_tool_id, - tool_shed_repository=tool_shed_repository ) - self.app.sa_session.add( tool_version_using_old_id ) - self.app.sa_session.flush() - if not tool_version_using_guid: - tool_version_using_guid = self.app.model.ToolVersion( tool_id=tool_id, - tool_shed_repository=tool_shed_repository ) - self.app.sa_session.add( tool_version_using_guid ) - self.app.sa_session.flush() - # Associate the two versions as parent / child. - tool_version_association = get_tool_version_association( self.app, - tool_version_using_old_id, - tool_version_using_guid ) - if not tool_version_association: - tool_version_association = self.app.model.ToolVersionAssociation( tool_id=tool_version_using_guid.id, - parent_id=tool_version_using_old_id.id ) - self.app.sa_session.add( tool_version_association ) - self.app.sa_session.flush() + ctx_rev = get_ctx_rev( tool_shed_url, name, self.repository_owner, changeset_revision ) + clone_repository( repository_clone_url, os.path.abspath( relative_install_dir ), ctx_rev ) + tool_shed_repository, metadata_dict = self.handle_repository_contents( current_working_dir, + repository_clone_url, + relative_install_dir, + repository_elem, + name, + description, + changeset_revision, + ctx_rev ) + if 'tools' in metadata_dict: + # Get the tool_versions from the tool shed for each tool in the installed change set. + url = '%s/repository/get_tool_versions?name=%s&owner=%s&changeset_revision=%s&webapp=galaxy' % \ + ( tool_shed_url, tool_shed_repository.name, self.repository_owner, changeset_revision ) + response = urllib2.urlopen( url ) + text = response.read() + response.close() + if text: + tool_version_dicts = from_json_string( text ) + handle_tool_versions( self.app, tool_version_dicts, tool_shed_repository ) else: - tmp_stderr = open( tmp_name, 'rb' ) - print "Error updating repository ', name, "': ', str( tmp_stderr.read() ) - tmp_stderr.close() - else: - tmp_stderr = open( tmp_name, 'rb' ) - print "Error cloning repository '", name, "': ", str( tmp_stderr.read() ) - tmp_stderr.close() + # Set the tool versions since they seem to be missing for this repository in the tool shed. + # CRITICAL NOTE: These default settings may not properly handle all parent/child associations. + for tool_dict in metadata_dict[ 'tools' ]: + flush_needed = False + tool_id = tool_dict[ 'guid' ] + old_tool_id = tool_dict[ 'id' ] + tool_version = tool_dict[ 'version' ] + tool_version_using_old_id = get_tool_version( self.app, old_tool_id ) + tool_version_using_guid = get_tool_version( self.app, tool_id ) + if not tool_version_using_old_id: + tool_version_using_old_id = self.app.model.ToolVersion( tool_id=old_tool_id, + tool_shed_repository=tool_shed_repository ) + self.app.sa_session.add( tool_version_using_old_id ) + self.app.sa_session.flush() + if not tool_version_using_guid: + tool_version_using_guid = self.app.model.ToolVersion( tool_id=tool_id, + tool_shed_repository=tool_shed_repository ) + self.app.sa_session.add( tool_version_using_guid ) + self.app.sa_session.flush() + # Associate the two versions as parent / child. + tool_version_association = get_tool_version_association( self.app, + tool_version_using_old_id, + tool_version_using_guid ) + if not tool_version_association: + tool_version_association = self.app.model.ToolVersionAssociation( tool_id=tool_version_using_guid.id, + parent_id=tool_version_using_old_id.id ) + self.app.sa_session.add( tool_version_association ) + self.app.sa_session.flush() @property def non_shed_tool_panel_configs( self ): # Get the non-shed related tool panel config file names from the Galaxy config - the default is tool_conf.xml. diff -r 6af88237056f0d4c7ae4c3dd5af647cde4830710 -r 6f7240344304a143a3d70182092c61931595b613 lib/galaxy/util/shed_util.py --- a/lib/galaxy/util/shed_util.py +++ b/lib/galaxy/util/shed_util.py @@ -1,4 +1,4 @@ -import os, tempfile, shutil, subprocess, logging, string +import os, tempfile, shutil, subprocess, logging, string, urllib2 from datetime import date, datetime, timedelta from time import strftime, gmtime from galaxy import util @@ -6,6 +6,7 @@ from galaxy.util.json import * from galaxy.tools.search import ToolBoxSearch from galaxy.model.orm import * +from mercurial import ui, commands pkg_resources.require( 'elementtree' ) from elementtree import ElementTree, ElementInclude @@ -265,20 +266,17 @@ # Eliminate the port, if any, since it will result in an invalid directory name. return tool_shed_url.split( ':' )[ 0 ] return tool_shed_url.rstrip( '/' ) -def clone_repository( name, clone_dir, current_working_dir, repository_clone_url ): - log.debug( "Installing repository '%s'" % name ) - if not os.path.exists( clone_dir ): - os.makedirs( clone_dir ) - log.debug( 'Cloning %s' % repository_clone_url ) - cmd = 'hg clone %s' % repository_clone_url - tmp_name = tempfile.NamedTemporaryFile().name - tmp_stderr = open( tmp_name, 'wb' ) - os.chdir( clone_dir ) - proc = subprocess.Popen( args=cmd, shell=True, stderr=tmp_stderr.fileno() ) - returncode = proc.wait() - os.chdir( current_working_dir ) - tmp_stderr.close() - return returncode, tmp_name +def clone_repository( repository_clone_url, repository_file_dir, ctx_rev ): + """ + Clone the repository up to the specified changeset_revision. No subsequent revisions will be present + in the cloned repository. + """ + commands.clone( get_configured_ui(), + repository_clone_url, + dest=repository_file_dir, + pull=True, + noupdate=False, + rev=[ ctx_rev ] ) def copy_sample_loc_file( app, filename ): """Copy xxx.loc.sample to ~/tool-data/xxx.loc.sample and ~/tool-data/xxx.loc""" head, sample_loc_file = os.path.split( filename ) @@ -298,7 +296,8 @@ tool_dicts=tool_dicts, converter_path=converter_path, display_path=display_path ) -def create_or_update_tool_shed_repository( app, name, description, changeset_revision, repository_clone_url, metadata_dict, owner='', dist_to_shed=False ): +def create_or_update_tool_shed_repository( app, name, description, changeset_revision, ctx_rev, repository_clone_url, metadata_dict, + owner='', dist_to_shed=False ): # The received value for dist_to_shed will be True if the InstallManager is installing a repository that contains tools or datatypes that used # to be in the Galaxy distribution, but have been moved to the main Galaxy tool shed. sa_session = app.model.context.current @@ -311,6 +310,7 @@ if tool_shed_repository: tool_shed_repository.description = description tool_shed_repository.changeset_revision = changeset_revision + tool_shed_repository.ctx_rev = ctx_rev tool_shed_repository.metadata = metadata_dict tool_shed_repository.includes_datatypes = includes_datatypes tool_shed_repository.deleted = False @@ -322,6 +322,7 @@ owner=owner, installed_changeset_revision=changeset_revision, changeset_revision=changeset_revision, + ctx_rev=ctx_rev, metadata=metadata_dict, includes_datatypes=includes_datatypes, dist_to_shed=dist_to_shed ) @@ -672,6 +673,15 @@ else: metadata_dict[ 'workflows' ] = [ ( relative_path, exported_workflow_dict ) ] return metadata_dict +def get_configured_ui(): + # Configure any desired ui settings. + _ui = ui.ui() + # The following will suppress all messages. This is + # the same as adding the following setting to the repo + # hgrc file' [ui] section: + # quiet = True + _ui.setconfig( 'ui', 'quiet', True ) + return _ui def get_converter_and_display_paths( registration_elem, relative_install_dir ): """Find the relative path to data type converters and display applications included in installed tool shed repositories.""" converter_path = None @@ -714,6 +724,12 @@ if converter_path and display_path: break return converter_path, display_path +def get_ctx_rev( tool_shed_url, name, owner, changeset_revision ): + url = '%s/repository/get_ctx_rev?name=%s&owner=%s&changeset_revision=%s&webapp=galaxy' % ( tool_shed_url, name, owner, changeset_revision ) + response = urllib2.urlopen( url ) + ctx_rev = response.read() + response.close() + return ctx_rev def get_shed_tool_conf_dict( app, shed_tool_conf ): """ Return the in-memory version of the shed_tool_conf file, which is stored in the config_elems entry @@ -1014,8 +1030,8 @@ if display_path: # Load or deactivate proprietary datatype display applications app.datatypes_registry.load_display_applications( installed_repository_dict=repository_dict, deactivate=deactivate ) -def load_repository_contents( trans, repository_name, description, owner, changeset_revision, tool_path, repository_clone_url, - relative_install_dir, current_working_dir, tmp_name, tool_shed=None, tool_section=None, shed_tool_conf=None ): +def load_repository_contents( trans, repository_name, description, owner, changeset_revision, ctx_rev, tool_path, repository_clone_url, + relative_install_dir, current_working_dir, tool_shed=None, tool_section=None, shed_tool_conf=None ): """Generate the metadata for the installed tool shed repository, among other things.""" # It is critical that the installed repository is updated to the desired changeset_revision before metadata is set because the # process for setting metadata uses the repository files on disk. This method is called when an admin is installing a new repository @@ -1028,6 +1044,7 @@ repository_name, description, changeset_revision, + ctx_rev, repository_clone_url, metadata_dict, dist_to_shed=False ) @@ -1051,11 +1068,6 @@ shed_tool_conf=shed_tool_conf, tool_panel_dict=tool_panel_dict, new_install=True ) - # Remove the temporary file - try: - os.unlink( tmp_name ) - except: - pass if 'datatypes_config' in metadata_dict: datatypes_config = os.path.abspath( metadata_dict[ 'datatypes_config' ] ) # Load data types required by tools. @@ -1089,18 +1101,12 @@ if k not in [ 'id', 'version', 'name' ]: return True return False -def pull_repository( current_working_dir, repo_files_dir, name ): - # Pull the latest possible contents to the repository. - log.debug( "Pulling latest updates to the repository named '%s'" % name ) - cmd = 'hg pull' - tmp_name = tempfile.NamedTemporaryFile().name - tmp_stderr = open( tmp_name, 'wb' ) - os.chdir( repo_files_dir ) - proc = subprocess.Popen( cmd, shell=True, stderr=tmp_stderr.fileno() ) - returncode = proc.wait() - os.chdir( current_working_dir ) - tmp_stderr.close() - return returncode, tmp_name +def pull_repository( repo, repository_clone_url, ctx_rev ): + """Pull changes from a remote repository to a local one.""" + commands.pull( get_configured_ui(), + repo, + source=repository_clone_url, + rev=ctx_rev ) def remove_from_shed_tool_config( trans, shed_tool_conf_dict, guids_to_remove ): # A tool shed repository is being uninstalled so change the shed_tool_conf file. Parse the config file to generate the entire list # of config_elems instead of using the in-memory list since it will be a subset of the entire list if one or more repositories have @@ -1226,17 +1232,22 @@ elif c not in [ '\r' ]: translated.append( 'X' ) return ''.join( translated ) -def update_repository( current_working_dir, repo_files_dir, changeset_revision ): - # Update the cloned repository to changeset_revision. It is imperative that the - # installed repository is updated to the desired changeset_revision before metadata - # is set because the process for setting metadata uses the repository files on disk. - log.debug( 'Updating cloned repository to revision "%s"' % changeset_revision ) - cmd = 'hg update -r %s' % changeset_revision - tmp_name = tempfile.NamedTemporaryFile().name - tmp_stderr = open( tmp_name, 'wb' ) - os.chdir( repo_files_dir ) - proc = subprocess.Popen( cmd, shell=True, stderr=tmp_stderr.fileno() ) - returncode = proc.wait() - os.chdir( current_working_dir ) - tmp_stderr.close() - return returncode, tmp_name +def update_repository( repo, ctx_rev=None ): + """ + Update the cloned repository to changeset_revision. It is critical that the installed repository is updated to the desired + changeset_revision before metadata is set because the process for setting metadata uses the repository files on disk. + """ + # TODO: We may have files on disk in the repo directory that aren't being tracked, so they must be removed. + # The codes used to show the status of files are as follows. + # M = modified + # A = added + # R = removed + # C = clean + # ! = deleted, but still tracked + # ? = not tracked + # I = ignored + # It would be nice if we could use mercurial's purge extension to remove untracked files. The problem is that + # purging is not supported by the mercurial API. See the deprecated update_for_browsing() method in common.py. + commands.update( get_configured_ui(), + repo, + rev=ctx_rev ) diff -r 6af88237056f0d4c7ae4c3dd5af647cde4830710 -r 6f7240344304a143a3d70182092c61931595b613 lib/galaxy/web/base/controller.py --- a/lib/galaxy/web/base/controller.py +++ b/lib/galaxy/web/base/controller.py @@ -1325,8 +1325,7 @@ message = kwd.get( 'message', '' ) status = kwd.get( 'status', 'done' ) if webapp == 'galaxy': - cloned_repositories = trans.sa_session.query( trans.model.ToolShedRepository ) \ - .first() + cloned_repositories = trans.sa_session.query( trans.model.ToolShedRepository ).first() return trans.fill_template( '/webapps/galaxy/admin/index.mako', webapp=webapp, cloned_repositories=cloned_repositories, diff -r 6af88237056f0d4c7ae4c3dd5af647cde4830710 -r 6f7240344304a143a3d70182092c61931595b613 lib/galaxy/web/controllers/admin_toolshed.py --- a/lib/galaxy/web/controllers/admin_toolshed.py +++ b/lib/galaxy/web/controllers/admin_toolshed.py @@ -3,6 +3,7 @@ from galaxy.util.json import from_json_string, to_json_string from galaxy.util.shed_util import * from galaxy import tools +from mercurial import hg log = logging.getLogger( __name__ ) @@ -290,58 +291,45 @@ current_working_dir = os.getcwd() installed_repository_names = [] for name, repo_info_tuple in repo_info_dict.items(): - description, repository_clone_url, changeset_revision = repo_info_tuple + description, repository_clone_url, changeset_revision, ctx_rev = repo_info_tuple clone_dir = os.path.join( tool_path, self.__generate_tool_path( repository_clone_url, changeset_revision ) ) relative_install_dir = os.path.join( clone_dir, name ) if os.path.exists( clone_dir ): # Repository and revision has already been cloned. message += 'Revision <b>%s</b> of repository <b>%s</b> was previously installed.<br/>' % ( changeset_revision, name ) else: - returncode, tmp_name = clone_repository( name, clone_dir, current_working_dir, repository_clone_url ) - if returncode == 0: - returncode, tmp_name = update_repository( current_working_dir, relative_install_dir, changeset_revision ) - if returncode == 0: - owner = get_repository_owner( clean_repository_clone_url( repository_clone_url ) ) - tool_shed = clean_tool_shed_url( tool_shed_url ) - tool_shed_repository, metadata_dict = load_repository_contents( trans, - repository_name=name, - description=description, - owner=owner, - changeset_revision=changeset_revision, - tool_path=tool_path, - repository_clone_url=repository_clone_url, - relative_install_dir=relative_install_dir, - current_working_dir=current_working_dir, - tmp_name=tmp_name, - tool_shed=tool_shed, - tool_section=tool_section, - shed_tool_conf=shed_tool_conf ) - if 'tools' in metadata_dict: - # Get the tool_versions from the tool shed for each tool in the installed change set. - url = '%s/repository/get_tool_versions?name=%s&owner=%s&changeset_revision=%s&webapp=galaxy' % \ - ( tool_shed_url, name, owner, changeset_revision ) - response = urllib2.urlopen( url ) - text = response.read() - response.close() - if text: - tool_version_dicts = from_json_string( text ) - handle_tool_versions( trans.app, tool_version_dicts, tool_shed_repository ) - else: - message += "Version information for the tools included in the <b>%s</b> repository is missing. " % name - message += "Reset all of this repository's metadata in the tool shed, then set the installed tool versions " - message += "from the installed repository's <b>Repository Actions</b> menu. " - status = 'error' - installed_repository_names.append( name ) + clone_repository( repository_clone_url, os.path.abspath( relative_install_dir ), ctx_rev ) + owner = get_repository_owner( clean_repository_clone_url( repository_clone_url ) ) + tool_shed = clean_tool_shed_url( tool_shed_url ) + tool_shed_repository, metadata_dict = load_repository_contents( trans, + repository_name=name, + description=description, + owner=owner, + changeset_revision=changeset_revision, + ctx_rev=ctx_rev, + tool_path=tool_path, + repository_clone_url=repository_clone_url, + relative_install_dir=relative_install_dir, + current_working_dir=current_working_dir, + tool_shed=tool_shed, + tool_section=tool_section, + shed_tool_conf=shed_tool_conf ) + if 'tools' in metadata_dict: + # Get the tool_versions from the tool shed for each tool in the installed change set. + url = '%s/repository/get_tool_versions?name=%s&owner=%s&changeset_revision=%s&webapp=galaxy' % \ + ( tool_shed_url, name, owner, changeset_revision ) + response = urllib2.urlopen( url ) + text = response.read() + response.close() + if text: + tool_version_dicts = from_json_string( text ) + handle_tool_versions( trans.app, tool_version_dicts, tool_shed_repository ) else: - tmp_stderr = open( tmp_name, 'rb' ) - message += '%s<br/>' % tmp_stderr.read() - tmp_stderr.close() + message += "Version information for the tools included in the <b>%s</b> repository is missing. " % name + message += "Reset all of this repository's metadata in the tool shed, then set the installed tool versions " + message += "from the installed repository's <b>Repository Actions</b> menu. " status = 'error' - else: - tmp_stderr = open( tmp_name, 'rb' ) - message += '%s<br/>' % tmp_stderr.read() - tmp_stderr.close() - status = 'error' + installed_repository_names.append( name ) if installed_repository_names: installed_repository_names.sort() num_repositories_installed = len( installed_repository_names ) @@ -375,7 +363,7 @@ if len( decoded_repo_info_dict ) == 1: name = decoded_repo_info_dict.keys()[ 0 ] repo_info_tuple = decoded_repo_info_dict[ name ] - description, repository_clone_url, changeset_revision = repo_info_tuple + description, repository_clone_url, changeset_revision, ctx_rev = repo_info_tuple owner = get_repository_owner( clean_repository_clone_url( repository_clone_url ) ) url = '%s/repository/get_readme?name=%s&owner=%s&changeset_revision=%s&webapp=galaxy' % ( tool_shed_url, name, owner, changeset_revision ) response = urllib2.urlopen( url ) @@ -444,79 +432,82 @@ repository_clone_url = generate_clone_url( trans, repository ) clone_dir = os.path.join( tool_path, self.__generate_tool_path( repository_clone_url, repository.installed_changeset_revision ) ) relative_install_dir = os.path.join( clone_dir, repository.name ) - returncode, tmp_name = clone_repository( repository.name, clone_dir, current_working_dir, repository_clone_url ) - if returncode == 0: - returncode, tmp_name = update_repository( current_working_dir, relative_install_dir, repository.installed_changeset_revision ) - if returncode == 0: - if repository.includes_tools: - # Get the location in the tool panel in which each tool was originally loaded. - metadata = repository.metadata - if 'tool_panel_section' in metadata: - tool_panel_dict = metadata[ 'tool_panel_section' ] - if not tool_panel_dict: - tool_panel_dict = generate_tool_panel_dict_for_new_install( metadata[ 'tools' ] ) + tool_shed_url = get_url_from_repository_tool_shed( trans.app, repository ) + if not repository.ctx_rev: + # The ctx_rev column was introduced late, so may be null for some installed ToolShedRepositories. + ctx_rev = get_ctx_rev( tool_shed_url, repository.name, repository.owner, repository.installed_changeset_revision ) + else: + ctx_rev = repository.ctx_rev + clone_repository( repository_clone_url, os.path.abspath( relative_install_dir ), ctx_rev ) + if repository.includes_tools: + # Get the location in the tool panel in which each tool was originally loaded. + metadata = repository.metadata + if 'tool_panel_section' in metadata: + tool_panel_dict = metadata[ 'tool_panel_section' ] + if not tool_panel_dict: + tool_panel_dict = generate_tool_panel_dict_for_new_install( metadata[ 'tools' ] ) + else: + tool_panel_dict = generate_tool_panel_dict_for_new_install( metadata[ 'tools' ] ) + # TODO: Fix this to handle the case where the tools are distributed across in more than 1 ToolSection. The + # following assumes everything was loaded into 1 section (or no section) in the tool panel. + tool_section_dicts = tool_panel_dict[ tool_panel_dict.keys()[ 0 ] ] + tool_section_dict = tool_section_dicts[ 0 ] + original_section_id = tool_section_dict[ 'id' ] + original_section_name = tool_section_dict[ 'name' ] + if no_changes_checked: + if original_section_id in [ '' ]: + tool_section = None + else: + section_key = 'section_%s' % str( original_section_id ) + if section_key in trans.app.toolbox.tool_panel: + tool_section = trans.app.toolbox.tool_panel[ section_key ] else: - tool_panel_dict = generate_tool_panel_dict_for_new_install( metadata[ 'tools' ] ) - # TODO: Fix this to handle the case where the tools are distributed across in more than 1 ToolSection. The - # following assumes everything was loaded into 1 section (or no section) in the tool panel. - tool_section_dicts = tool_panel_dict[ tool_panel_dict.keys()[ 0 ] ] - tool_section_dict = tool_section_dicts[ 0 ] - original_section_id = tool_section_dict[ 'id' ] - original_section_name = tool_section_dict[ 'name' ] - if no_changes_checked: - if original_section_id in [ '' ]: - tool_section = None - else: - section_key = 'section_%s' % str( original_section_id ) - if section_key in trans.app.toolbox.tool_panel: - tool_section = trans.app.toolbox.tool_panel[ section_key ] - else: - # The section in which the tool was originally loaded used to be in the tool panel, but no longer is. - elem = Element( 'section' ) - elem.attrib[ 'name' ] = original_section_name - elem.attrib[ 'id' ] = original_section_id - elem.attrib[ 'version' ] = '' - tool_section = tools.ToolSection( elem ) - trans.app.toolbox.tool_panel[ section_key ] = tool_section + # The section in which the tool was originally loaded used to be in the tool panel, but no longer is. + elem = Element( 'section' ) + elem.attrib[ 'name' ] = original_section_name + elem.attrib[ 'id' ] = original_section_id + elem.attrib[ 'version' ] = '' + tool_section = tools.ToolSection( elem ) + trans.app.toolbox.tool_panel[ section_key ] = tool_section + else: + # The user elected to change the tool panel section to contain the tools. + new_tool_panel_section = kwd.get( 'new_tool_panel_section', '' ) + tool_panel_section = kwd.get( 'tool_panel_section', '' ) + if new_tool_panel_section: + section_id = new_tool_panel_section.lower().replace( ' ', '_' ) + new_section_key = 'section_%s' % str( section_id ) + if new_section_key in trans.app.toolbox.tool_panel: + # Appending a tool to an existing section in trans.app.toolbox.tool_panel + log.debug( "Appending to tool panel section: %s" % new_tool_panel_section ) + tool_section = trans.app.toolbox.tool_panel[ new_section_key ] else: - # The user elected to change the tool panel section to contain the tools. - new_tool_panel_section = kwd.get( 'new_tool_panel_section', '' ) - tool_panel_section = kwd.get( 'tool_panel_section', '' ) - if new_tool_panel_section: - section_id = new_tool_panel_section.lower().replace( ' ', '_' ) - new_section_key = 'section_%s' % str( section_id ) - if new_section_key in trans.app.toolbox.tool_panel: - # Appending a tool to an existing section in trans.app.toolbox.tool_panel - log.debug( "Appending to tool panel section: %s" % new_tool_panel_section ) - tool_section = trans.app.toolbox.tool_panel[ new_section_key ] - else: - # Appending a new section to trans.app.toolbox.tool_panel - log.debug( "Loading new tool panel section: %s" % new_tool_panel_section ) - elem = Element( 'section' ) - elem.attrib[ 'name' ] = new_tool_panel_section - elem.attrib[ 'id' ] = section_id - elem.attrib[ 'version' ] = '' - tool_section = tools.ToolSection( elem ) - trans.app.toolbox.tool_panel[ new_section_key ] = tool_section - elif tool_panel_section: - section_key = 'section_%s' % tool_panel_section - tool_section = trans.app.toolbox.tool_panel[ section_key ] - else: - tool_section = None - tool_shed_repository, metadata_dict = load_repository_contents( trans, - repository_name=repository.name, - description=repository.description, - owner=repository.owner, - changeset_revision=repository.installed_changeset_revision, - tool_path=tool_path, - repository_clone_url=repository_clone_url, - relative_install_dir=relative_install_dir, - current_working_dir=current_working_dir, - tmp_name=tmp_name, - tool_shed=repository.tool_shed, - tool_section=tool_section, - shed_tool_conf=shed_tool_conf ) - repository.uninstalled = False + # Appending a new section to trans.app.toolbox.tool_panel + log.debug( "Loading new tool panel section: %s" % new_tool_panel_section ) + elem = Element( 'section' ) + elem.attrib[ 'name' ] = new_tool_panel_section + elem.attrib[ 'id' ] = section_id + elem.attrib[ 'version' ] = '' + tool_section = tools.ToolSection( elem ) + trans.app.toolbox.tool_panel[ new_section_key ] = tool_section + elif tool_panel_section: + section_key = 'section_%s' % tool_panel_section + tool_section = trans.app.toolbox.tool_panel[ section_key ] + else: + tool_section = None + tool_shed_repository, metadata_dict = load_repository_contents( trans, + repository_name=repository.name, + description=repository.description, + owner=repository.owner, + changeset_revision=repository.installed_changeset_revision, + ctx_rev=ctx_rev, + tool_path=tool_path, + repository_clone_url=repository_clone_url, + relative_install_dir=relative_install_dir, + current_working_dir=current_working_dir, + tool_shed=repository.tool_shed, + tool_section=tool_section, + shed_tool_conf=shed_tool_conf ) + repository.uninstalled = False repository.deleted = False trans.sa_session.add( repository ) trans.sa_session.flush() @@ -606,41 +597,32 @@ owner = params.get( 'owner', None ) changeset_revision = params.get( 'changeset_revision', None ) latest_changeset_revision = params.get( 'latest_changeset_revision', None ) + latest_ctx_rev = params.get( 'latest_ctx_rev', None ) repository = get_repository_by_shed_name_owner_changeset_revision( trans.app, tool_shed_url, name, owner, changeset_revision ) - if changeset_revision and latest_changeset_revision: + if changeset_revision and latest_changeset_revision and latest_ctx_rev: if changeset_revision == latest_changeset_revision: message = "The cloned tool shed repository named '%s' is current (there are no updates available)." % name else: current_working_dir = os.getcwd() shed_tool_conf, tool_path, relative_install_dir = get_tool_panel_config_tool_path_install_dir( trans.app, repository ) if relative_install_dir: - repo_files_dir = os.path.join( relative_install_dir, name ) - returncode, tmp_name = pull_repository( current_working_dir, repo_files_dir, name ) - if returncode == 0: - returncode, tmp_name = update_repository( current_working_dir, repo_files_dir, latest_changeset_revision ) - if returncode == 0: - # Update the repository metadata. - repository_clone_url = os.path.join( tool_shed_url, 'repos', owner, name ) - tool_shed = clean_tool_shed_url( tool_shed_url ) - metadata_dict = generate_metadata( trans.app.toolbox, relative_install_dir, repository_clone_url ) - repository.metadata = metadata_dict - # Update the repository changeset_revision in the database. - repository.changeset_revision = latest_changeset_revision - repository.update_available = False - trans.sa_session.add( repository ) - trans.sa_session.flush() - message = "The cloned repository named '%s' has been updated to change set revision '%s'." % \ - ( name, latest_changeset_revision ) - else: - tmp_stderr = open( tmp_name, 'rb' ) - message = tmp_stderr.read() - tmp_stderr.close() - status = 'error' - else: - tmp_stderr = open( tmp_name, 'rb' ) - message = tmp_stderr.read() - tmp_stderr.close() - status = 'error' + repo_files_dir = os.path.abspath( os.path.join( relative_install_dir, name ) ) + repo = hg.repository( get_configured_ui(), path=repo_files_dir ) + repository_clone_url = os.path.join( tool_shed_url, 'repos', owner, name ) + pull_repository( repo, repository_clone_url, latest_ctx_rev ) + update_repository( repo, latest_ctx_rev ) + # Update the repository metadata. + tool_shed = clean_tool_shed_url( tool_shed_url ) + metadata_dict = generate_metadata( trans.app.toolbox, relative_install_dir, repository_clone_url ) + repository.metadata = metadata_dict + # Update the repository changeset_revision in the database. + repository.changeset_revision = latest_changeset_revision + repository.ctx_rev = latest_ctx_rev + repository.update_available = False + trans.sa_session.add( repository ) + trans.sa_session.flush() + message = "The cloned repository named '%s' has been updated to change set revision '%s'." % \ + ( name, latest_changeset_revision ) else: message = "The directory containing the cloned repository named '%s' cannot be found." % name status = 'error' diff -r 6af88237056f0d4c7ae4c3dd5af647cde4830710 -r 6f7240344304a143a3d70182092c61931595b613 lib/galaxy/webapps/community/controllers/admin.py --- a/lib/galaxy/webapps/community/controllers/admin.py +++ b/lib/galaxy/webapps/community/controllers/admin.py @@ -3,6 +3,7 @@ from galaxy.model.orm import * from galaxy.web.framework.helpers import time_ago, iff, grids from galaxy.util import inflector +from galaxy.util.shed_util import get_configured_ui from common import * from repository import RepositoryListGrid, CategoryListGrid from mercurial import hg diff -r 6af88237056f0d4c7ae4c3dd5af647cde4830710 -r 6f7240344304a143a3d70182092c61931595b613 lib/galaxy/webapps/community/controllers/common.py --- a/lib/galaxy/webapps/community/controllers/common.py +++ b/lib/galaxy/webapps/community/controllers/common.py @@ -5,7 +5,7 @@ from galaxy.tools import * from galaxy.util.json import from_json_string, to_json_string from galaxy.util.hash_util import * -from galaxy.util.shed_util import copy_sample_loc_file, generate_datatypes_metadata, generate_tool_metadata, generate_workflow_metadata +from galaxy.util.shed_util import copy_sample_loc_file, get_configured_ui, generate_datatypes_metadata, generate_tool_metadata, generate_workflow_metadata from galaxy.util.shed_util import handle_sample_tool_data_table_conf_file, to_html_escaped, to_html_str, update_repository from galaxy.web.base.controller import * from galaxy.webapps.community import model @@ -283,7 +283,7 @@ # The received metadata_dict includes no metadata for workflows, so a new repository_metadata table # record is not needed. return False -def generate_metadata_for_repository_tip( trans, id, ctx, changeset_revision, repo_dir ): +def generate_metadata_for_repository_tip( trans, id, ctx, changeset_revision, repo, repo_dir ): """ Browse the repository tip files on disk to generate metadata. This is faster than the generate_metadata_for_changeset_revision() method below because fctx.data() does not have @@ -291,8 +291,7 @@ invalid_tool_configs here, while they are ignored in older revisions. """ # If a push from the command line is occurring, update the repository files on disk before setting metadata. - returncode, tmp_name = update_repository( os.getcwd(), os.path.abspath( repo_dir ), changeset_revision ) - # TODO: handle error if returncode is not 0? + update_repository( repo, str( ctx.rev() ) ) metadata_dict = {} invalid_files = [] invalid_tool_configs = [] @@ -449,7 +448,7 @@ invalid_files = [] if ctx is not None: if changeset_revision == repository.tip: - metadata_dict, invalid_files = generate_metadata_for_repository_tip( trans, id, ctx, changeset_revision, repo_dir ) + metadata_dict, invalid_files = generate_metadata_for_repository_tip( trans, id, ctx, changeset_revision, repo, repo_dir ) else: metadata_dict, invalid_files = generate_metadata_for_changeset_revision( trans, id, ctx, changeset_revision, repo_dir ) if metadata_dict: @@ -543,7 +542,7 @@ current_changeset_revision = str( repo.changectx( changeset ) ) ctx = get_changectx_for_changeset( repo, current_changeset_revision ) if current_changeset_revision == repository.tip: - current_metadata_dict, invalid_files = generate_metadata_for_repository_tip( trans, id, ctx, current_changeset_revision, repo_dir ) + current_metadata_dict, invalid_files = generate_metadata_for_repository_tip( trans, id, ctx, current_changeset_revision, repo, repo_dir ) else: current_metadata_dict, invalid_files = generate_metadata_for_changeset_revision( trans, id, ctx, current_changeset_revision, repo_dir ) if current_metadata_dict: @@ -780,15 +779,6 @@ if repository_metadata: return repository_metadata.malicious return False -def get_configured_ui(): - # Configure any desired ui settings. - _ui = ui.ui() - # The following will suppress all messages. This is - # the same as adding the following setting to the repo - # hgrc file' [ui] section: - # quiet = True - _ui.setconfig( 'ui', 'quiet', True ) - return _ui def get_user( trans, id ): """Get a user from the database by id""" return trans.sa_session.query( trans.model.User ).get( trans.security.decode_id( id ) ) @@ -891,9 +881,10 @@ return True return False def update_for_browsing( trans, repository, current_working_dir, commit_message='' ): - # Make a copy of a repository's files for browsing, remove from disk all files that - # are not tracked, and commit all added, modified or removed files that have not yet - # been committed. + # This method id deprecated, but we'll keep it around for a while in case we need it. The problem is that hg purge + # is not supported by the mercurial API. + # Make a copy of a repository's files for browsing, remove from disk all files that are not tracked, and commit all + # added, modified or removed files that have not yet been committed. repo_dir = repository.repo_path repo = hg.repository( get_configured_ui(), repo_dir ) # The following will delete the disk copy of only the files in the repository. diff -r 6af88237056f0d4c7ae4c3dd5af647cde4830710 -r 6f7240344304a143a3d70182092c61931595b613 lib/galaxy/webapps/community/controllers/repository.py --- a/lib/galaxy/webapps/community/controllers/repository.py +++ b/lib/galaxy/webapps/community/controllers/repository.py @@ -10,6 +10,7 @@ from galaxy.web.framework.helpers import time_ago, iff, grids from galaxy.util.json import from_json_string, to_json_string from galaxy.model.orm import * +from galaxy.util.shed_util import get_configured_ui from common import * from mercurial import hg, ui, patch, commands @@ -792,18 +793,33 @@ # Tell the caller if the repository includes Galaxy tools so the page # enabling selection of the tool panel section can be displayed. includes_tools = 'tools' in repository_metadata.metadata + # Get the changelog rev for this changeset_revision. + repo_dir = repository.repo_path + repo = hg.repository( get_configured_ui(), repo_dir ) + ctx = get_changectx_for_changeset( repo, changeset_revision ) repo_info_dict = {} - repo_info_dict[ repository.name ] = ( repository.description, repository_clone_url, changeset_revision ) + repo_info_dict[ repository.name ] = ( repository.description, repository_clone_url, changeset_revision, str( ctx.rev() ) ) encoded_repo_info_dict = encode( repo_info_dict ) # Redirect back to local Galaxy to perform install. url = '%sadmin_toolshed/install_repository?tool_shed_url=%s&repo_info_dict=%s&includes_tools=%s' % \ ( galaxy_url, url_for( '/', qualified=True ), encoded_repo_info_dict, str( includes_tools ) ) return trans.response.send_redirect( url ) @web.expose + def get_ctx_rev( self, trans, **kwd ): + """Given a repository and changeset_revision, return the correct ctx.rev() value.""" + repository_name = kwd[ 'name' ] + repository_owner = kwd[ 'owner' ] + changeset_revision = kwd[ 'changeset_revision' ] + repository = get_repository_by_name_and_owner( trans, repository_name, repository_owner ) + repo_dir = repository.repo_path + repo = hg.repository( get_configured_ui(), repo_dir ) + ctx = get_changectx_for_changeset( repo, changeset_revision ) + if ctx: + return str( ctx.rev() ) + return '' + @web.expose def get_readme( self, trans, **kwd ): - """ - If the received changeset_revision includes a file named readme (case ignored), return it's contents. - """ + """If the received changeset_revision includes a file named readme (case ignored), return it's contents.""" repository_name = kwd[ 'name' ] repository_owner = kwd[ 'owner' ] changeset_revision = kwd[ 'changeset_revision' ] @@ -903,13 +919,17 @@ fh.close() if not ( check_binary( tmp_filename ) or check_image( tmp_filename ) or check_gzip( tmp_filename )[ 0 ] or check_bz2( tmp_filename )[ 0 ] or check_zip( tmp_filename ) ): - try: - tool = load_tool( trans, tmp_filename ) - valid = True - except: - valid = False - if valid and tool is not None: - tool_guids.append( generate_tool_guid( trans, repository, tool ) ) + # Make sure we're looking at a tool config and not a display application config or something else. + element_tree = util.parse_xml( tmp_filename ) + element_tree_root = element_tree.getroot() + if element_tree_root.tag == 'tool': + try: + tool = load_tool( trans, tmp_filename ) + valid = True + except: + valid = False + if valid and tool is not None: + tool_guids.append( generate_tool_guid( trans, repository, tool ) ) try: os.unlink( tmp_filename ) except: @@ -927,11 +947,13 @@ metadata_tool_guids.append( tool_dict[ 'guid' ] ) metadata_tool_guids.sort() if tool_guids == metadata_tool_guids: - # We've found the repository_metadata record whose changeset_revision - # value has been updated. + # We've found the repository_metadata record whose changeset_revision value has been updated. if from_update_manager: return update url += repository_metadata.changeset_revision + # Get the ctx_rev for the discovered changeset_revision. + latest_ctx = get_changectx_for_changeset( repo, repository_metadata.changeset_revision ) + url += '&latest_ctx_rev=%s' % str( latest_ctx.rev() ) found = True break if not found: @@ -941,7 +963,7 @@ return no_update url += changeset_revision else: - # There are not tools in the changeset_revision, so no tool updates are possible. + # There are no tools in the changeset_revision, so no tool updates are possible. if from_update_manager: return no_update url += changeset_revision @@ -1168,13 +1190,10 @@ new_hgweb_config.flush() shutil.move( tmp_fname, os.path.abspath( hgweb_config ) ) def __create_hgrc_file( self, repository ): - # At this point, an entry for the repository is required to be in the hgweb.config - # file so we can call repository.repo_path. - # Since we support both http and https, we set push_ssl to False to override - # the default (which is True) in the mercurial api. - # The hg purge extension purges all files and directories not being tracked by - # mercurial in the current repository. It'll remove unknown files and empty - # directories. This is used in the update_for_browsing() method. + # At this point, an entry for the repository is required to be in the hgweb.config file so we can call repository.repo_path. + # Since we support both http and https, we set push_ssl to False to override the default (which is True) in the mercurial api. + # The hg purge extension purges all files and directories not being tracked by mercurial in the current repository. It'll + # remove unknown files and empty directories. This is not currently used because it is not supported in the mercurial API. repo = hg.repository( get_configured_ui(), path=repository.repo_path ) fp = repo.opener( 'hgrc', 'wb' ) fp.write( '[paths]\n' ) @@ -1198,7 +1217,7 @@ repo = hg.repository( get_configured_ui(), repository.repo_path ) current_working_dir = os.getcwd() # Update repository files for browsing. - update_for_browsing( trans, repository, current_working_dir, commit_message=commit_message ) + update_repository( repo ) is_malicious = change_set_is_malicious( trans, id, repository.tip ) return trans.fill_template( '/webapps/community/repository/browse_repository.mako', repo=repo, @@ -1314,7 +1333,7 @@ repo.commit( user=trans.user.username, text=commit_message ) handle_email_alerts( trans, repository ) # Update the repository files for browsing. - update_for_browsing( trans, repository, current_working_dir, commit_message=commit_message ) + update_repository( repo ) # Get the new repository tip. repo = hg.repository( get_configured_ui(), repo_dir ) if tip != repository.tip: @@ -1868,7 +1887,7 @@ break if found: break - metadata_dict, invalid_files = generate_metadata_for_repository_tip( trans, repository_id, ctx, changeset_revision, repo_dir ) + metadata_dict, invalid_files = generate_metadata_for_repository_tip( trans, repository_id, ctx, changeset_revision, repo, repo_dir ) else: for filename in ctx: if filename == tool_config: diff -r 6af88237056f0d4c7ae4c3dd5af647cde4830710 -r 6f7240344304a143a3d70182092c61931595b613 lib/galaxy/webapps/community/controllers/upload.py --- a/lib/galaxy/webapps/community/controllers/upload.py +++ b/lib/galaxy/webapps/community/controllers/upload.py @@ -3,7 +3,7 @@ from galaxy.model.orm import * from galaxy.datatypes.checkers import * from common import * -from galaxy.util.shed_util import handle_sample_tool_data_table_conf_file +from galaxy.util.shed_util import get_configured_ui, handle_sample_tool_data_table_conf_file from mercurial import hg, ui, commands log = logging.getLogger( __name__ ) @@ -144,7 +144,7 @@ handle_email_alerts( trans, repository, content_alert_str=content_alert_str, new_repo_alert=new_repo_alert, admin_only=admin_only ) if ok: # Update the repository files for browsing. - update_for_browsing( trans, repository, current_working_dir, commit_message=commit_message ) + update_repository( repo ) # Get the new repository tip. if tip != repository.tip: if ( isgzip or isbz2 ) and uncompress_file: diff -r 6af88237056f0d4c7ae4c3dd5af647cde4830710 -r 6f7240344304a143a3d70182092c61931595b613 lib/galaxy/webapps/community/framework/middleware/hg.py --- a/lib/galaxy/webapps/community/framework/middleware/hg.py +++ b/lib/galaxy/webapps/community/framework/middleware/hg.py @@ -3,7 +3,6 @@ """ import os, logging from sqlalchemy import * -from mercurial import ui, hg from paste.auth.basic import AuthBasicAuthenticator from paste.httpheaders import REMOTE_USER, AUTH_TYPE diff -r 6af88237056f0d4c7ae4c3dd5af647cde4830710 -r 6f7240344304a143a3d70182092c61931595b613 lib/galaxy/webapps/community/security/__init__.py --- a/lib/galaxy/webapps/community/security/__init__.py +++ b/lib/galaxy/webapps/community/security/__init__.py @@ -6,7 +6,6 @@ from galaxy.util.bunch import Bunch from galaxy.util import listify from galaxy.model.orm import * -from mercurial import hg, ui log = logging.getLogger(__name__) 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.