Commits

Greg Von Kuster  committed 7547a31

Add the ability for a tool shed repository owner to reset the repository metadata for any change set revision that has associated repository metadata (previously could only be reset for repository tip)

  • Participants
  • Parent commits 148dc33

Comments (0)

Files changed (5)

File lib/galaxy/webapps/community/controllers/common.py

     """Get last metadata defined for a specified repository from the database"""
     return trans.sa_session.query( trans.model.RepositoryMetadata ) \
                            .filter( trans.model.RepositoryMetadata.table.c.repository_id == trans.security.decode_id( id ) ) \
-                           .order_by( trans.model.RepositoryMetadata.table.c.update_time.desc() ) \
+                           .order_by( trans.model.RepositoryMetadata.table.c.id.desc() ) \
                            .first()
 def generate_workflow_metadata( trans, id, changeset_revision, exported_workflow_dict, metadata_dict ):
     """
                                       repository.name,
                                       tool.id,
                                       tool.version )
-def generate_tool_metadata( trans, id, changeset_revision, root, name, tool, metadata_dict ):
+def generate_tool_metadata( trans, id, changeset_revision, tool_config, tool, metadata_dict ):
     """
     Update the received metadata_dict with changes that have been
     applied to the received tool.
                       version=tool.version,
                       description=tool.description,
                       version_string_cmd = tool.version_string_cmd,
-                      tool_config=os.path.join( root, name ),
+                      tool_config=tool_config,
                       requirements=tool_requirements,
                       tests=tool_tests )
     if 'tools' in metadata_dict:
     ctx = get_changectx_for_changeset( trans, repo, changeset_revision )
     if ctx is not None:
         metadata_dict = {}
-        for root, dirs, files in os.walk( repo_dir ):
-            if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0:
-                if '.hg' in dirs:
-                    # Don't visit .hg directories - should be impossible since we don't
-                    # allow uploaded archives that contain .hg dirs, but just in case...
-                    dirs.remove( '.hg' )
-                if 'hgrc' in files:
-                     # Don't include hgrc files in commit.
-                    files.remove( 'hgrc' )
-                for name in files:
-                    # Find all tool configs.
-                    if name.endswith( '.xml' ):
-                        try:
-                            full_path = os.path.abspath( os.path.join( root, name ) )
-                            tool = load_tool( trans, full_path )
-                            if tool is not None:
-                                # Update the list metadata dictionaries for tools in metadata_dict.
-                                metadata_dict = generate_tool_metadata( trans, id, changeset_revision, root, name, tool, metadata_dict )
-                        except Exception, e:
-                            invalid_files.append( ( name, str( e ) ) )
-                    # Find all exported workflows
-                    elif name.endswith( '.ga' ):
-                        try:
-                            full_path = os.path.abspath( os.path.join( root, name ) )
-                            # Convert workflow data from json
-                            fp = open( full_path, 'rb' )
-                            workflow_text = fp.read()
-                            fp.close()
-                            exported_workflow_dict = from_json_string( workflow_text )
-                            # Update the list of metadata dictionaries for workflows in metadata_dict.
-                            metadata_dict = generate_workflow_metadata( trans, id, changeset_revision, exported_workflow_dict, metadata_dict )
-                        except Exception, e:
-                            invalid_files.append( ( name, str( e ) ) )
+        if changeset_revision == repository.tip:
+            for root, dirs, files in os.walk( repo_dir ):
+                if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0:
+                    if '.hg' in dirs:
+                        # Don't visit .hg directories - should be impossible since we don't
+                        # allow uploaded archives that contain .hg dirs, but just in case...
+                        dirs.remove( '.hg' )
+                    if 'hgrc' in files:
+                         # Don't include hgrc files in commit.
+                        files.remove( 'hgrc' )
+                    for name in files:
+                        # Find all tool configs.
+                        if name.endswith( '.xml' ):
+                            try:
+                                full_path = os.path.abspath( os.path.join( root, name ) )
+                                tool = load_tool( trans, full_path )
+                                if tool is not None:
+                                    # Update the list metadata dictionaries for tools in metadata_dict.
+                                    tool_config = os.path.join( root, name )
+                                    metadata_dict = generate_tool_metadata( trans, id, changeset_revision, tool_config, tool, metadata_dict )
+                            except Exception, e:
+                                invalid_files.append( ( name, str( e ) ) )
+                        # Find all exported workflows
+                        elif name.endswith( '.ga' ):
+                            try:
+                                full_path = os.path.abspath( os.path.join( root, name ) )
+                                # Convert workflow data from json
+                                fp = open( full_path, 'rb' )
+                                workflow_text = fp.read()
+                                fp.close()
+                                exported_workflow_dict = from_json_string( workflow_text )
+                                # Update the list of metadata dictionaries for workflows in metadata_dict.
+                                metadata_dict = generate_workflow_metadata( trans, id, changeset_revision, exported_workflow_dict, metadata_dict )
+                            except Exception, e:
+                                invalid_files.append( ( name, str( e ) ) )
+        else:
+            # Get all tool config file names from the hgweb url, something like:
+            # /repos/test/convert_chars1/file/e58dcf0026c7/convert_characters.xml
+            for filename in ctx:
+                # Find all tool configs - should not have to update metadata for workflows.
+                if filename.endswith( '.xml' ):
+                    fctx = ctx[ filename ]
+                    # Write the contents of the old tool config to a temporary file.
+                    fh = tempfile.NamedTemporaryFile( 'w' )
+                    tmp_filename = fh.name
+                    fh.close()
+                    fh = open( tmp_filename, 'w' )
+                    fh.write( fctx.data() )
+                    fh.close()
+                    try:
+                        tool = load_tool( trans, tmp_filename )
+                        if tool is not None:
+                            # Update the list metadata dictionaries for tools in metadata_dict.  Note that filename
+                            # here is the relative path to the config file within the change set context, something
+                            # like filtering.xml, but when the change set was the repository tip, the value was
+                            # something like database/community_files/000/repo_1/filtering.xml.  This shouldn't break
+                            # anything, but may result in a bit of confusion when maintaining the code / data over time.
+                            metadata_dict = generate_tool_metadata( trans, id, changeset_revision, filename, tool, metadata_dict )
+                    except Exception, e:
+                        invalid_files.append( ( name, str( e ) ) )
+                    try:
+                        os.unlink( tmp_filename )
+                    except:
+                        pass
         if metadata_dict:
-            if new_tool_metadata_required( trans, id, metadata_dict ) or new_workflow_metadata_required( trans, id, metadata_dict ):
-                # Create a new repository_metadata table row.
-                repository_metadata = trans.model.RepositoryMetadata( repository.id, changeset_revision, metadata_dict )
-                trans.sa_session.add( repository_metadata )
-                trans.sa_session.flush()
+            if changeset_revision == repository.tip:
+                if new_tool_metadata_required( trans, id, metadata_dict ) or new_workflow_metadata_required( trans, id, metadata_dict ):
+                    # Create a new repository_metadata table row.
+                    repository_metadata = trans.model.RepositoryMetadata( repository.id, changeset_revision, metadata_dict )
+                    trans.sa_session.add( repository_metadata )
+                    trans.sa_session.flush()
+                else:
+                    # Update the last saved repository_metadata table row.
+                    repository_metadata = get_latest_repository_metadata( trans, id )
+                    repository_metadata.changeset_revision = changeset_revision
+                    repository_metadata.metadata = metadata_dict
+                    trans.sa_session.add( repository_metadata )
+                    trans.sa_session.flush()
             else:
-                # Update the last saved repository_metadata table row.
-                repository_metadata = get_latest_repository_metadata( trans, id )
-                repository_metadata.changeset_revision = changeset_revision
+                # We're re-generating metadata for an old repository revision.
+                repository_metadata = get_repository_metadata_by_changeset_revision( trans, id, changeset_revision )
                 repository_metadata.metadata = metadata_dict
                 trans.sa_session.add( repository_metadata )
                 trans.sa_session.flush()

File lib/galaxy/webapps/community/controllers/repository.py

                 # /repos/test/convert_chars1/file/e58dcf0026c7/convert_characters.xml
                 old_tool_config_file_name = tool_config.split( '/' )[ -1 ]
                 ctx = get_changectx_for_changeset( trans, repo, changeset_revision )
+                fctx = None
                 for filename in ctx:
                     if filename == old_tool_config_file_name:
                         fctx = ctx[ filename ]
                         break
-                # Write the contents of the old tool config to a temporary file.
-                fh = tempfile.NamedTemporaryFile( 'w' )
-                tmp_filename = fh.name
-                fh.close()
-                fh = open( tmp_filename, 'w' )
-                fh.write( fctx.data() )
-                fh.close()
-                tool = load_tool( trans, tmp_filename )
-                try:
-                    os.unlink( tmp_filename )
-                except:
-                    pass
+                if fctx:
+                    # Write the contents of the old tool config to a temporary file.
+                    fh = tempfile.NamedTemporaryFile( 'w' )
+                    tmp_filename = fh.name
+                    fh.close()
+                    fh = open( tmp_filename, 'w' )
+                    fh.write( fctx.data() )
+                    fh.close()
+                    tool = load_tool( trans, tmp_filename )
+                    try:
+                        os.unlink( tmp_filename )
+                    except:
+                        pass
+                else:
+                    tool = None
             tool_state = self.__new_state( trans )
             is_malicious = change_set_is_malicious( trans, repository_id, repository.tip )
             return trans.fill_template( "/webapps/community/repository/tool_form.mako",

File lib/galaxy/webapps/community/model/mapping.py

         categories=relation( RepositoryCategoryAssociation ),
         ratings=relation( RepositoryRatingAssociation, order_by=desc( RepositoryRatingAssociation.table.c.update_time ), backref="repositories" ),
         user=relation( User.mapper ),
-        downloadable_revisions=relation( RepositoryMetadata, order_by=desc( RepositoryMetadata.table.c.update_time ) ) ) )
+        downloadable_revisions=relation( RepositoryMetadata, order_by=desc( RepositoryMetadata.table.c.id ) ) ) )
 
 assign_mapper( context, RepositoryMetadata, RepositoryMetadata.table,
     properties=dict( repository=relation( Repository ) ) )

File templates/webapps/community/repository/common.mako

                     %endif
                 %endif
                 %if can_set_metadata:
-                    %if repository.tip == changeset_revision:
-                        ## TODO: when we support previewing older versions of tools, we
-                        ## should allow resetting metadata on the older versions as well.
-                        <form name="set_metadata" action="${h.url_for( controller='repository', action='set_metadata', id=trans.security.encode_id( repository.id ), ctx_str=changeset_revision )}" method="post">
-                            <div class="form-row">
-                                <div style="float: left; width: 250px; margin-right: 10px;">
-                                    <input type="submit" name="set_metadata_button" value="Reset metadata"/>
-                                </div>
-                                <div class="toolParamHelp" style="clear: both;">
-                                    Inspect the repository and reset the above attributes for the repository tip.
-                                </div>
+                    <form name="set_metadata" action="${h.url_for( controller='repository', action='set_metadata', id=trans.security.encode_id( repository.id ), ctx_str=changeset_revision )}" method="post">
+                        <div class="form-row">
+                            <div style="float: left; width: 250px; margin-right: 10px;">
+                                <input type="submit" name="set_metadata_button" value="Reset metadata"/>
                             </div>
-                        </form>
-                    %endif
+                            <div class="toolParamHelp" style="clear: both;">
+                                Inspect the repository and reset the above attributes for the repository tip.
+                            </div>
+                        </div>
+                    </form>
                 %endif
             </div>
         </div>

File templates/webapps/community/repository/tool_form.mako

             ${render_msg( message, status )}
         %endif
 
-        <div class="toolForm" id="${tool.id}">
-            <div class="toolFormTitle">${tool.name} (version ${tool.version})</div>
-            <div class="toolFormBody">
-                <form id="tool_form" name="tool_form" action="" method="get">
-                    <input type="hidden" name="tool_state" value="${util.object_to_string( tool_state.encode( tool, app ) )}">
-                    ${do_inputs( tool.inputs_by_page[ tool_state.page ], tool_state.inputs, "" )}  
-                </form>
+        %if tool:
+            <div class="toolForm" id="${tool.id}">
+                <div class="toolFormTitle">${tool.name} (version ${tool.version})</div>
+                <div class="toolFormBody">
+                    <form id="tool_form" name="tool_form" action="" method="get">
+                        <input type="hidden" name="tool_state" value="${util.object_to_string( tool_state.encode( tool, app ) )}">
+                        ${do_inputs( tool.inputs_by_page[ tool_state.page ], tool_state.inputs, "" )}  
+                    </form>
+                </div>
             </div>
-        </div>
-        %if tool.help:
-            <div class="toolHelp">
-                <div class="toolHelpBody">
-                    <%
-                        # Convert to unicode to display non-ascii characters.
-                        if type( tool.help ) is not unicode:
-                            tool.help = unicode( tool.help, 'utf-8')
-                    %>
-                    ${tool.help}
-                </div>        
-            </div>
+            %if tool.help:
+                <div class="toolHelp">
+                    <div class="toolHelpBody">
+                        <%
+                            # Convert to unicode to display non-ascii characters.
+                            if type( tool.help ) is not unicode:
+                                tool.help = unicode( tool.help, 'utf-8')
+                        %>
+                        ${tool.help}
+                    </div>        
+                </div>
+            %endif
+        %else:
+            Tool not properly loaded.
         %endif
     </body>
 </html>