diff --git a/lib/galaxy/webapps/community/controllers/hg.py b/lib/galaxy/webapps/community/controllers/hg.py index 9fb48d505c7..a4626941f95 100644 --- a/lib/galaxy/webapps/community/controllers/hg.py +++ b/lib/galaxy/webapps/community/controllers/hg.py @@ -1,9 +1,12 @@ import os, logging from galaxy.web.base.controller import * from galaxy.webapps.community.controllers.common import * +from galaxy.util.shed_util import update_repository from galaxy import eggs eggs.require('mercurial') +import mercurial.__version__ +from mercurial import hg, ui, commands from mercurial.hgweb.hgwebdir_mod import hgwebdir from mercurial.hgweb.request import wsgiapplication @@ -14,17 +17,32 @@ class HgController( BaseUIController ): def handle_request( self, trans, **kwd ): # The os command that results in this method being called will look something like # hg clone http://test@127.0.0.1:9009/repos/test/convert_characters1 + hg_version = mercurial.__version__.version cmd = kwd.get( 'cmd', None ) wsgi_app = wsgiapplication( make_web_app ) - if cmd == 'pushkey': - # This results from an "hg push" from the command line. When doing this, the following 6 commands, in order, - # will be retrieved from environ: capabilities -> batch -> branchmap -> unbundle -> listkeys -> pushkey + # In mercurial version 2.2.3, section 15.2. Command changes includes a new feature: pushkey: add hooks for pushkey/listkeys (see + # http://mercurial.selenic.com/wiki/WhatsNew#Mercurial_2.2.3_.282012-07-01.29). Older versions require checking for 'listkeys'. + push_from_command_line = ( hg_version < '2.2.3' and cmd == 'listkeys' ) or ( hg_version >= '2.2.3' and cmd == 'pushkey' ) + if push_from_command_line: + # When doing an "hg push" from the command line, the following commands, in order, will be retrieved from environ, depending + # upon the mercurial version being used. There is a weakness if the mercurial version < '2.2.3' because several commands include + # listkeys, so repository metadata will be set, but only for the files currently on disk, so doing so is not too expensive. + # If mercurial version < '2.2.3: + # capabilities -> batch -> branchmap -> unbundle -> listkeys + # If mercurial version >= '2.2.3': + # capabilities -> batch -> branchmap -> unbundle -> listkeys -> pushkey path_info = kwd.get( 'path_info', None ) if path_info: owner, name = path_info.split( '/' ) repository = get_repository_by_name_and_owner( trans, name, owner ) if repository: - error_message, status = reset_all_metadata_on_repository( trans, trans.security.encode_id( repository.id ) ) + if hg_version < '2.2.3': + # We're forced to update the repository so the disk files include the changes in the push. This is handled in the + # pushkey hook in mercurial version 2.2.3 and newer. + repo = hg.repository( ui.ui(), repository.repo_path ) + update_repository( repo ) + # Set metadata using the repository files on disk. + error_message, status = set_repository_metadata( trans, repository ) if status not in [ 'ok' ] and error_message: log.debug( "Error resetting metadata on repository '%s': %s" % ( str( repository.name ), str( error_message ) ) ) elif status in [ 'ok' ] and error_message: diff --git a/lib/galaxy/webapps/community/framework/middleware/hg.py b/lib/galaxy/webapps/community/framework/middleware/hg.py index d5cfe160d01..49a46c78dc0 100644 --- a/lib/galaxy/webapps/community/framework/middleware/hg.py +++ b/lib/galaxy/webapps/community/framework/middleware/hg.py @@ -8,11 +8,13 @@ from paste.httpheaders import REMOTE_USER, AUTH_TYPE from galaxy.webapps.community import model from galaxy.util.hash_util import new_secure_hash +import mercurial.__version__ log = logging.getLogger(__name__) class Hg( object ): def __init__( self, app, config ): + print "mercurial version is:", mercurial.__version__.version self.app = app self.config = config # Authenticate this mercurial request using basic authentication @@ -56,7 +58,7 @@ class Hg( object ): connection.close() if cmd == 'unbundle': # This is an hg push from the command line. When doing this, the following 7 commands, in order, - # will be retrieved from environ: + # will be retrieved from environ (see the docs at http://mercurial.selenic.com/wiki/WireProtocol): # between -> capabilities -> heads -> branchmap -> unbundle -> unbundle -> listkeys # # The mercurial API unbundle() ( i.e., hg push ) method ultimately requires authorization.