'Update a cloned repository to the latest revision possible.'

@web.expose
@web.require_admin
def update_to_changeset_revision(self, trans, **kwd):

    message = escape(kwd.get('message', ''))
    status = kwd.get('status', 'done')
    tool_shed_url = kwd.get('tool_shed_url', '')
    tool_shed_url = common_util.get_tool_shed_url_from_tool_shed_registry(trans.app, tool_shed_url)
    name = kwd.get('name', None)
    owner = kwd.get('owner', None)
    changeset_revision = kwd.get('changeset_revision', None)
    latest_changeset_revision = kwd.get('latest_changeset_revision', None)
    latest_ctx_rev = kwd.get('latest_ctx_rev', None)
    repository = repository_util.get_installed_repository(trans.app, tool_shed=tool_shed_url, name=name, owner=owner, changeset_revision=changeset_revision)
    original_metadata_dict = repository.metadata
    original_repository_dependencies_dict = original_metadata_dict.get('repository_dependencies', {})
    original_repository_dependencies = original_repository_dependencies_dict.get('repository_dependencies', [])
    original_tool_dependencies_dict = original_metadata_dict.get('tool_dependencies', {})
    if (changeset_revision and latest_changeset_revision and latest_ctx_rev):
        if (changeset_revision == latest_changeset_revision):
            message = ("The    installed    repository    named    '%s'    is    current,    there    are    no    updates    available.        " % name)
        else:
            (shed_tool_conf, tool_path, relative_install_dir) = suc.get_tool_panel_config_tool_path_install_dir(trans.app, repository)
            if relative_install_dir:
                if tool_path:
                    repo_files_dir = os.path.abspath(os.path.join(tool_path, relative_install_dir, name))
                else:
                    repo_files_dir = os.path.abspath(os.path.join(relative_install_dir, name))
                repo = hg_util.get_repo_for_repository(trans.app, repository=None, repo_path=repo_files_dir, create=False)
                repository_clone_url = os.path.join(tool_shed_url, 'repos', owner, name)
                hg_util.pull_repository(repo, repository_clone_url, latest_ctx_rev)
                hg_util.update_repository(repo, latest_ctx_rev)
                if repository.includes_data_managers:
                    dmh = data_manager.DataManagerHandler(trans.app)
                    dmh.remove_from_data_manager(repository)
                tpm = tool_panel_manager.ToolPanelManager(trans.app)
                irmm = InstalledRepositoryMetadataManager(app=trans.app, tpm=tpm, repository=repository, changeset_revision=latest_changeset_revision, repository_clone_url=repository_clone_url, shed_config_dict=repository.get_shed_config_dict(trans.app), relative_install_dir=relative_install_dir, repository_files_dir=None, resetting_all_metadata_on_repository=False, updating_installed_repository=True, persist=True)
                irmm.generate_metadata_for_changeset_revision()
                irmm_metadata_dict = irmm.get_metadata_dict()
                if ('tools' in irmm_metadata_dict):
                    tool_panel_dict = irmm_metadata_dict.get('tool_panel_section', None)
                    if (tool_panel_dict is None):
                        tool_panel_dict = tpm.generate_tool_panel_dict_from_shed_tool_conf_entries(repository)
                    repository_tools_tups = irmm.get_repository_tools_tups()
                    tpm.add_to_tool_panel(repository_name=str(repository.name), repository_clone_url=repository_clone_url, changeset_revision=str(repository.installed_changeset_revision), repository_tools_tups=repository_tools_tups, owner=str(repository.owner), shed_tool_conf=shed_tool_conf, tool_panel_dict=tool_panel_dict, new_install=False)
                    if ('data_manager' in irmm_metadata_dict):
                        dmh = data_manager.DataManagerHandler(trans.app)
                        dmh.install_data_managers(trans.app.config.shed_data_manager_config_file, irmm_metadata_dict, repository.get_shed_config_dict(trans.app), os.path.join(relative_install_dir, name), repository, repository_tools_tups)
                if (('repository_dependencies' in irmm_metadata_dict) or ('tool_dependencies' in irmm_metadata_dict)):
                    new_repository_dependencies_dict = irmm_metadata_dict.get('repository_dependencies', {})
                    new_repository_dependencies = new_repository_dependencies_dict.get('repository_dependencies', [])
                    new_tool_dependencies_dict = irmm_metadata_dict.get('tool_dependencies', {})
                    if new_repository_dependencies:
                        proceed_to_install = False
                        if (new_repository_dependencies == original_repository_dependencies):
                            for new_repository_tup in new_repository_dependencies:
                                (new_tool_shed, new_name, new_owner, new_changeset_revision, new_pir, new_oicct) = common_util.parse_repository_dependency_tuple(new_repository_tup)
                                repo_info_tuple = ('', new_tool_shed, new_changeset_revision, '', new_owner, [], [])
                                (new_repository_db_record, installed_changeset_revision) = repository_util.repository_was_previously_installed(trans.app, tool_shed_url, new_name, repo_info_tuple, from_tip=True)
                                if new_repository_db_record:
                                    if (new_repository_db_record.status in [trans.install_model.ToolShedRepository.installation_status.ERROR, trans.install_model.ToolShedRepository.installation_status.NEW, trans.install_model.ToolShedRepository.installation_status.UNINSTALLED]):
                                        proceed_to_install = True
                                        break
                                else:
                                    proceed_to_install = True
                                    break
                        if proceed_to_install:
                            new_kwd = dict(tool_shed_url=tool_shed_url, updating_repository_id=trans.security.encode_id(repository.id), updating_to_ctx_rev=latest_ctx_rev, updating_to_changeset_revision=latest_changeset_revision, encoded_updated_metadata=encoding_util.tool_shed_encode(irmm_metadata_dict), updating=True)
                            return self.prepare_for_install(trans, **new_kwd)
                    proceed_to_install = False
                    for (new_key, new_val) in new_tool_dependencies_dict.items():
                        if (new_key not in original_tool_dependencies_dict):
                            proceed_to_install = True
                            break
                        original_val = original_tool_dependencies_dict[new_key]
                        if (new_val != original_val):
                            proceed_to_install = True
                            break
                    if proceed_to_install:
                        encoded_tool_dependencies_dict = encoding_util.tool_shed_encode(irmm_metadata_dict.get('tool_dependencies', {}))
                        encoded_relative_install_dir = encoding_util.tool_shed_encode(relative_install_dir)
                        new_kwd = dict(updating_repository_id=trans.security.encode_id(repository.id), updating_to_ctx_rev=latest_ctx_rev, updating_to_changeset_revision=latest_changeset_revision, encoded_updated_metadata=encoding_util.tool_shed_encode(irmm_metadata_dict), encoded_relative_install_dir=encoded_relative_install_dir, encoded_tool_dependencies_dict=encoded_tool_dependencies_dict, message=message, status=status)
                        return self.install_tool_dependencies_with_update(trans, **new_kwd)
                repository = trans.app.update_repository_manager.update_repository_record(repository=repository, updated_metadata_dict=irmm_metadata_dict, updated_changeset_revision=latest_changeset_revision, updated_ctx_rev=latest_ctx_rev)
                message = ("The    installed    repository    named    '%s'    has    been    updated    to    change    set    revision    '%s'.        " % (name, latest_changeset_revision))
            else:
                message = ("The    directory    containing    the    installed    repository    named    '%s'    cannot    be    found.        " % name)
                status = 'error'
    else:
        message = ("The    latest    changeset    revision    could    not    be    retrieved    for    the    installed    repository    named    '%s'.        " % name)
        status = 'error'
    return trans.response.send_redirect(web.url_for(controller='admin_toolshed', action='manage_repository', id=trans.security.encode_id(repository.id), message=message, status=status))
