mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Fixes for setting metadata on tool shed repositories and specific add tool lineage information on the view tool metadata page in the tool shed as well as for tool shed repositories installed into a local Galaxy instance.
This commit is contained in:
@@ -132,7 +132,11 @@ class InstallManager( object ):
|
||||
tool_panel_dict_for_tool_config = generate_tool_panel_dict_for_tool_config( guid, tool_config, tool_sections=tool_sections )
|
||||
for k, v in tool_panel_dict_for_tool_config.items():
|
||||
tool_panel_dict_for_display[ k ] = v
|
||||
metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( self.app, relative_install_dir, repository_clone_url )
|
||||
metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( app=self.app,
|
||||
repository_clone_url=repository_clone_url,
|
||||
relative_install_dir=relative_install_dir,
|
||||
repository_files_dir=None,
|
||||
resetting_all_metadata_on_repository=False )
|
||||
tool_shed_repository.metadata = metadata_dict
|
||||
self.app.sa_session.add( tool_shed_repository )
|
||||
self.app.sa_session.flush()
|
||||
|
||||
@@ -324,7 +324,7 @@ def clean_tool_shed_url( tool_shed_url ):
|
||||
# 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( repository_clone_url, repository_file_dir, ctx_rev ):
|
||||
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(),
|
||||
str( repository_clone_url ),
|
||||
@@ -548,24 +548,55 @@ def can_generate_tool_dependency_metadata( root, metadata_dict ):
|
||||
if not can_generate_dependency_metadata:
|
||||
break
|
||||
return can_generate_dependency_metadata
|
||||
def generate_metadata_for_changeset_revision( app, repository_files_dir, repository_clone_url ):
|
||||
def generate_metadata_for_changeset_revision( app, repository_clone_url, relative_install_dir=None, repository_files_dir=None, resetting_all_metadata_on_repository=False ):
|
||||
"""
|
||||
Generate metadata for a repository using it's files on disk. To generate metadata for changeset revisions older than the repository tip,
|
||||
the repository will have been cloned to a temporary location and updated to a specified changeset revision to access that changeset revision's
|
||||
disk files, so the value of repository_files_dir will not always be repository.repo_path (it could be a temporary directory containing a clone).
|
||||
disk files, so the value of repository_files_dir will not always be repository.repo_path (it could be an absolute path to a temporary directory
|
||||
containing a clone). If it is an absolute path, the value of relative_install_dir must contain repository.repo_path.
|
||||
"""
|
||||
metadata_dict = {}
|
||||
invalid_file_tups = []
|
||||
invalid_tool_configs = []
|
||||
tool_dependencies_config = None
|
||||
datatypes_config = get_config_from_disk( 'datatypes_conf.xml', repository_files_dir )
|
||||
original_tool_data_path = app.config.tool_data_path
|
||||
if resetting_all_metadata_on_repository:
|
||||
if not relative_install_dir:
|
||||
raise Exception( "The value of repository.repo_path must be sent when resetting all metadata on a repository." )
|
||||
# Keep track of the location where the repository is temporarily cloned so that we can strip the path when setting metadata. The value of
|
||||
# repository_files_dir is the full path to the temporary directory to which the repository was cloned.
|
||||
work_dir = repository_files_dir
|
||||
files_dir = repository_files_dir
|
||||
# Since we're working from a temporary directory, we can safely copy sample files included in the repository to the repository root.
|
||||
app.config.tool_data_path = repository_files_dir
|
||||
else:
|
||||
# Use a temporary working directory to copy all sample files.
|
||||
work_dir = tempfile.mkdtemp()
|
||||
# All other files are on disk in the repository's repo_path, which is the value of relative_install_dir.
|
||||
files_dir = relative_install_dir
|
||||
app.config.tool_data_path = work_dir
|
||||
# Handle proprietary datatypes, if any.
|
||||
datatypes_config = get_config_from_disk( 'datatypes_conf.xml', files_dir )
|
||||
if datatypes_config:
|
||||
metadata_dict = generate_datatypes_metadata( datatypes_config, metadata_dict )
|
||||
sample_files = get_sample_files_from_disk( repository_files_dir )
|
||||
# Get the relative path to all sample files included in the repository for storage in the repository's metadata.
|
||||
sample_files = get_sample_files_from_disk( repository_files_dir=files_dir,
|
||||
relative_install_dir=relative_install_dir,
|
||||
resetting_all_metadata_on_repository=resetting_all_metadata_on_repository )
|
||||
if sample_files:
|
||||
metadata_dict[ 'sample_files' ] = sample_files
|
||||
# Find all tool configs and exported workflows.
|
||||
for root, dirs, files in os.walk( repository_files_dir ):
|
||||
# Copy all sample files included in the repository to a single directory location so we can load tools that depend on them.
|
||||
for sample_file in sample_files:
|
||||
copy_sample_file( app, sample_file, dest_path=work_dir )
|
||||
# If the list of sample files includes a tool_data_table_conf.xml.sample file, laad it's table elements into memory.
|
||||
relative_path, filename = os.path.split( sample_file )
|
||||
if filename == 'tool_data_table_conf.xml.sample':
|
||||
new_table_elems = app.tool_data_tables.add_new_entries_from_config_file( config_filename=sample_file,
|
||||
tool_data_path=app.config.tool_data_path,
|
||||
tool_data_table_config_path=app.config.tool_data_table_config_path,
|
||||
persist=False )
|
||||
# Find all tool configs and exported workflows and add them to the repository's metadata.
|
||||
for root, dirs, files in os.walk( files_dir ):
|
||||
if root.find( '.hg' ) < 0 and root.find( 'hgrc' ) < 0:
|
||||
if '.hg' in dirs:
|
||||
dirs.remove( '.hg' )
|
||||
@@ -586,11 +617,19 @@ def generate_metadata_for_changeset_revision( app, repository_files_dir, reposit
|
||||
if is_tool:
|
||||
try:
|
||||
tool = app.toolbox.load_tool( full_path )
|
||||
except KeyError, e:
|
||||
tool = None
|
||||
invalid_tool_configs.append( name )
|
||||
error_message = 'This file requires an entry for "%s" in the tool_data_table_conf.xml file. Upload a file ' % str( e )
|
||||
error_message += 'named tool_data_table_conf.xml.sample to the repository that includes the required entry to correct '
|
||||
error_message += 'this error. '
|
||||
invalid_file_tups.append( ( name, error_message ) )
|
||||
except Exception, e:
|
||||
tool = None
|
||||
invalid_tool_configs.append( name )
|
||||
invalid_file_tups.append( ( name, str( e ) ) )
|
||||
if tool is not None:
|
||||
invalid_files_and_errors_tups = check_tool_input_params( app, repository_files_dir, name, tool, sample_files )
|
||||
invalid_files_and_errors_tups = check_tool_input_params( app, files_dir, name, tool, sample_files )
|
||||
can_set_metadata = True
|
||||
for tup in invalid_files_and_errors_tups:
|
||||
if name in tup:
|
||||
@@ -598,7 +637,15 @@ def generate_metadata_for_changeset_revision( app, repository_files_dir, reposit
|
||||
invalid_tool_configs.append( name )
|
||||
break
|
||||
if can_set_metadata:
|
||||
metadata_dict = generate_tool_metadata( os.path.join( root, name ), tool, repository_clone_url, metadata_dict )
|
||||
if resetting_all_metadata_on_repository:
|
||||
full_path_to_tool_config = os.path.join( root, name )
|
||||
stripped_path_to_tool_config = full_path_to_tool_config.replace( work_dir, '' )
|
||||
if stripped_path_to_tool_config.startswith( '/' ):
|
||||
stripped_path_to_tool_config = stripped_path_to_tool_config[ 1: ]
|
||||
relative_path_to_tool_config = os.path.join( relative_install_dir, stripped_path_to_tool_config )
|
||||
else:
|
||||
relative_path_to_tool_config = os.path.join( root, name )
|
||||
metadata_dict = generate_tool_metadata( relative_path_to_tool_config, tool, repository_clone_url, metadata_dict )
|
||||
else:
|
||||
invalid_file_tups.extend( invalid_files_and_errors_tups )
|
||||
# Find all exported workflows
|
||||
@@ -612,11 +659,16 @@ def generate_metadata_for_changeset_revision( app, repository_files_dir, reposit
|
||||
metadata_dict = generate_workflow_metadata( relative_path, exported_workflow_dict, metadata_dict )
|
||||
if 'tools' in metadata_dict:
|
||||
# This step must be done after metadata for tools has been defined.
|
||||
tool_dependencies_config = get_config_from_disk( 'tool_dependencies.xml', repository_files_dir )
|
||||
tool_dependencies_config = get_config_from_disk( 'tool_dependencies.xml', files_dir )
|
||||
if tool_dependencies_config:
|
||||
metadata_dict = generate_tool_dependency_metadata( tool_dependencies_config, metadata_dict )
|
||||
if invalid_tool_configs:
|
||||
metadata_dict [ 'invalid_tools' ] = invalid_tool_configs
|
||||
if resetting_all_metadata_on_repository:
|
||||
# Reset the tool_data_tables by loading the empty tool_data_table_conf.xml file.
|
||||
reset_tool_data_tables( app )
|
||||
# Reset the value of the app's tool_data_path to it's original value.
|
||||
app.config.tool_data_path = original_tool_data_path
|
||||
return metadata_dict, invalid_file_tups
|
||||
def generate_package_dependency_metadata( elem, tool_dependencies_dict ):
|
||||
"""The value of package_name must match the value of the "package" type in the tool config's <requirements> tag set."""
|
||||
@@ -1028,13 +1080,24 @@ def get_repository_tools_tups( app, metadata_dict ):
|
||||
if tool:
|
||||
repository_tools_tups.append( ( relative_path, guid, tool ) )
|
||||
return repository_tools_tups
|
||||
def get_sample_files_from_disk( relative_install_dir ):
|
||||
def get_sample_files_from_disk( repository_files_dir, relative_install_dir=None, resetting_all_metadata_on_repository=False ):
|
||||
if resetting_all_metadata_on_repository:
|
||||
# Keep track of the location where the repository is temporarily cloned so that we can strip it when setting metadata.
|
||||
work_dir = repository_files_dir
|
||||
sample_files = []
|
||||
for root, dirs, files in os.walk( relative_install_dir ):
|
||||
for root, dirs, files in os.walk( repository_files_dir ):
|
||||
if root.find( '.hg' ) < 0:
|
||||
for name in files:
|
||||
if name.endswith( '.sample' ):
|
||||
sample_files.append( os.path.join( root, name ) )
|
||||
if resetting_all_metadata_on_repository:
|
||||
full_path_to_sample_file = os.path.join( root, name )
|
||||
stripped_path_to_sample_file = full_path_to_sample_file.replace( work_dir, '' )
|
||||
if stripped_path_to_sample_file.startswith( '/' ):
|
||||
stripped_path_to_sample_file = stripped_path_to_sample_file[ 1: ]
|
||||
relative_path_to_sample_file = os.path.join( relative_install_dir, stripped_path_to_sample_file )
|
||||
else:
|
||||
relative_path_to_sample_file = os.path.join( root, name )
|
||||
sample_files.append( relative_path_to_sample_file )
|
||||
return sample_files
|
||||
def get_shed_tool_conf_dict( app, shed_tool_conf ):
|
||||
"""
|
||||
|
||||
@@ -497,6 +497,9 @@ class AdminToolshed( AdminGalaxy ):
|
||||
trans.response.headers['Pragma'] = 'no-cache'
|
||||
trans.response.headers['Expires'] = '0'
|
||||
return get_repository_file_contents( file_path )
|
||||
def get_versions_of_tool( self, app, guid ):
|
||||
tool_version = get_tool_version( app, guid )
|
||||
return tool_version.get_version_ids( app )
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def initiate_repository_installation( self, trans, shed_repository_ids, encoded_kwd, reinstalling=False ):
|
||||
@@ -684,7 +687,11 @@ class AdminToolshed( AdminGalaxy ):
|
||||
Generate the metadata for the installed tool shed repository, among other things. This method is called from Galaxy (never the tool shed)
|
||||
when an admin is installing a new repository or reinstalling an uninstalled repository.
|
||||
"""
|
||||
metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( trans.app, relative_install_dir, repository_clone_url )
|
||||
metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( app=trans.app,
|
||||
repository_clone_url=repository_clone_url,
|
||||
relative_install_dir=relative_install_dir,
|
||||
repository_files_dir=None,
|
||||
resetting_all_metadata_on_repository=False )
|
||||
tool_shed_repository.metadata = metadata_dict
|
||||
trans.sa_session.add( tool_shed_repository )
|
||||
trans.sa_session.flush()
|
||||
@@ -779,7 +786,14 @@ class AdminToolshed( AdminGalaxy ):
|
||||
message = "The repository information has been updated."
|
||||
elif params.get( 'set_metadata_button', False ):
|
||||
repository_clone_url = generate_clone_url( trans, repository )
|
||||
metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( trans.app, relative_install_dir, repository_clone_url )
|
||||
# TODO: Fix this by setting up a temporary work_dir - there is currently no way for an admin to reset metadata on an
|
||||
# installed tool shed repository because the manage_repository template checs the value of can_reset_metadata, whic is
|
||||
# currently always False.
|
||||
metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( app=trans.app,
|
||||
repository_clone_url=repository_clone_url,
|
||||
relative_install_dir=None,
|
||||
repository_files_dir=repository_files_dir,
|
||||
resetting_all_metadata_on_repository=True )
|
||||
if metadata_dict:
|
||||
repository.metadata = metadata_dict
|
||||
trans.sa_session.add( repository )
|
||||
@@ -1479,7 +1493,11 @@ class AdminToolshed( AdminGalaxy ):
|
||||
update_repository( repo, latest_ctx_rev )
|
||||
# Update the repository metadata.
|
||||
tool_shed = clean_tool_shed_url( tool_shed_url )
|
||||
metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( trans.app, relative_install_dir, repository_clone_url )
|
||||
metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( app=trans.app,
|
||||
repository_clone_url=repository_clone_url,
|
||||
relative_install_dir=relative_install_dir,
|
||||
repository_files_dir=None,
|
||||
resetting_all_metadata_on_repository=False )
|
||||
repository.metadata = metadata_dict
|
||||
# Update the repository changeset_revision in the database.
|
||||
repository.changeset_revision = latest_changeset_revision
|
||||
@@ -1515,17 +1533,21 @@ class AdminToolshed( AdminGalaxy ):
|
||||
webapp = get_webapp( trans, **kwd )
|
||||
repository = get_repository( trans, repository_id )
|
||||
metadata = {}
|
||||
tool_lineage = []
|
||||
tool = None
|
||||
if 'tools' in repository.metadata:
|
||||
for tool_metadata_dict in repository.metadata[ 'tools' ]:
|
||||
if tool_metadata_dict[ 'id' ] == tool_id:
|
||||
metadata = tool_metadata_dict
|
||||
tool = trans.app.toolbox.load_tool( os.path.abspath( metadata[ 'tool_config' ] ), guid=metadata[ 'guid' ] )
|
||||
if tool:
|
||||
tool_lineage = self.get_versions_of_tool( trans.app, tool.id )
|
||||
break
|
||||
return trans.fill_template( "/admin/tool_shed_repository/view_tool_metadata.mako",
|
||||
repository=repository,
|
||||
tool=tool,
|
||||
metadata=metadata,
|
||||
tool_lineage=tool_lineage,
|
||||
message=message,
|
||||
status=status )
|
||||
def __generate_clone_url( self, trans, repository ):
|
||||
|
||||
@@ -105,34 +105,6 @@ class ItemRatings( UsesItemRatings ):
|
||||
trans.sa_session.flush()
|
||||
return item_rating
|
||||
|
||||
def add_repository_metadata_tool_versions( trans, id, changeset_revisions ):
|
||||
# If a repository includes tools, build a dictionary of { 'tool id' : 'parent tool id' } pairs for each tool in each changeset revision.
|
||||
for index, changeset_revision in enumerate( changeset_revisions ):
|
||||
tool_versions_dict = {}
|
||||
repository_metadata = get_repository_metadata_by_changeset_revision( trans, id, changeset_revision )
|
||||
if repository_metadata:
|
||||
metadata = repository_metadata.metadata
|
||||
if metadata:
|
||||
tool_dicts = metadata.get( 'tools', [] )
|
||||
if index == 0:
|
||||
# The first changset_revision is a special case because it will have no ancestor changeset_revisions in which to match tools.
|
||||
# The parent tool id for tools in the first changeset_revision will be the "old_id" in the tool config.
|
||||
for tool_dict in tool_dicts:
|
||||
tool_versions_dict[ tool_dict[ 'guid' ] ] = tool_dict[ 'id' ]
|
||||
else:
|
||||
for tool_dict in tool_dicts:
|
||||
# We have at least 2 changeset revisions to compare tool guids and tool ids.
|
||||
parent_id = get_parent_id( trans,
|
||||
id,
|
||||
tool_dict[ 'id' ],
|
||||
tool_dict[ 'version' ],
|
||||
tool_dict[ 'guid' ],
|
||||
changeset_revisions[ 0:index ] )
|
||||
tool_versions_dict[ tool_dict[ 'guid' ] ] = parent_id
|
||||
if tool_versions_dict:
|
||||
repository_metadata.tool_versions = tool_versions_dict
|
||||
trans.sa_session.add( repository_metadata )
|
||||
trans.sa_session.flush()
|
||||
def changeset_is_malicious( trans, id, changeset_revision, **kwd ):
|
||||
"""Check the malicious flag in repository metadata for a specified change set"""
|
||||
repository_metadata = get_repository_metadata_by_changeset_revision( trans, id, changeset_revision )
|
||||
@@ -155,7 +127,6 @@ def clean_repository_metadata( trans, id, changeset_revisions ):
|
||||
# We sometimes see multiple records with the same changeset revision value - no idea how this happens. We'll assume we can delete the older
|
||||
# records, so we'll order by update_time descending and delete records that have the same changeset_revision we come across later..
|
||||
changeset_revisions_checked = []
|
||||
cleaned_changeset_revisions = []
|
||||
for repository_metadata in 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.changeset_revision,
|
||||
@@ -165,9 +136,6 @@ def clean_repository_metadata( trans, id, changeset_revisions ):
|
||||
if can_delete:
|
||||
trans.sa_session.delete( repository_metadata )
|
||||
trans.sa_session.flush()
|
||||
else:
|
||||
cleaned_changeset_revisions.append( changeset_revision )
|
||||
return cleaned_changeset_revisions
|
||||
def compare_changeset_revisions( ancestor_changeset_revision, ancestor_metadata_dict, current_changeset_revision, current_metadata_dict ):
|
||||
# The metadata associated with ancestor_changeset_revision is ancestor_metadata_dict. This changeset_revision is an ancestor of
|
||||
# current_changeset_revision which is associated with current_metadata_dict. A new repository_metadata record will be created only
|
||||
@@ -599,7 +567,7 @@ def load_tool_from_changeset_revision( trans, repository_id, changeset_revision,
|
||||
is a valid (downloadable) changset revision. The tool config will be located in the repository manifest between the received valid changeset
|
||||
revision and the first changeset revision in the repository, searching backwards.
|
||||
"""
|
||||
def load_from_tmp_config( ctx, ctx_file, work_dir ):
|
||||
def load_from_tmp_config( toolbox, ctx, ctx_file, work_dir ):
|
||||
tool = None
|
||||
message = ''
|
||||
tmp_tool_config = get_named_tmpfile_from_ctx( ctx, ctx_file, work_dir )
|
||||
@@ -614,10 +582,12 @@ def load_tool_from_changeset_revision( trans, repository_id, changeset_revision,
|
||||
if tmp_code_file_name:
|
||||
tmp_code_files.append( tmp_code_file_name )
|
||||
try:
|
||||
tool = load_tool( trans, tmp_tool_config )
|
||||
tool = toolbox.load_tool( tmp_tool_config )
|
||||
except KeyError, e:
|
||||
message = '<b>%s</b> - This file requires an entry for %s in the tool_data_table_conf.xml file. ' % ( tool_config_filename, str( e ) )
|
||||
message += 'Upload a file named tool_data_table_conf.xml.sample to the repository that includes the required entry to correct this error. '
|
||||
except Exception, e:
|
||||
tool = None
|
||||
message = "Error loading tool: %s. " % str( e )
|
||||
message = 'Error loading tool: %s. ' % str( e )
|
||||
for tmp_code_file in tmp_code_files:
|
||||
try:
|
||||
os.unlink( tmp_code_file )
|
||||
@@ -634,16 +604,15 @@ def load_tool_from_changeset_revision( trans, repository_id, changeset_revision,
|
||||
repo_files_dir = repository.repo_path
|
||||
repo = hg.repository( get_configured_ui(), repo_files_dir )
|
||||
ctx = get_changectx_for_changeset( repo, changeset_revision )
|
||||
tool = None
|
||||
message = ''
|
||||
work_dir = tempfile.mkdtemp()
|
||||
sample_files, deleted_sample_files = get_list_of_copied_sample_files( repo, ctx, dir=work_dir )
|
||||
if sample_files:
|
||||
trans.app.config.tool_data_path = work_dir
|
||||
# Load entries into the tool_data_tables if the tool requires them.
|
||||
tool_data_table_config = copy_file_from_manifest( repo, ctx, 'tool_data_table_conf.xml.sample', work_dir )
|
||||
if tool_data_table_config:
|
||||
error, correction_msg = handle_sample_tool_data_table_conf_file( trans.app, tool_data_table_config )
|
||||
if 'tool_data_table_conf.xml.sample' in sample_files:
|
||||
# Load entries into the tool_data_tables if the tool requires them.
|
||||
tool_data_table_config = os.path.join( work_dir, 'tool_data_table_conf.xml' )
|
||||
error, correction_msg = handle_sample_tool_data_table_conf_file( trans.app, tool_data_table_config )
|
||||
found = False
|
||||
# Get the latest revision of the tool config from the repository manifest up to the value of changeset_revision.
|
||||
for changeset in reversed_upper_bounded_changelog( repo, changeset_revision ):
|
||||
@@ -655,16 +624,16 @@ def load_tool_from_changeset_revision( trans, repository_id, changeset_revision,
|
||||
found = True
|
||||
break
|
||||
if found:
|
||||
tool, message = load_from_tmp_config( manifest_ctx, ctx_file, work_dir )
|
||||
tool, message = load_from_tmp_config( trans.app.toolbox, manifest_ctx, ctx_file, work_dir )
|
||||
break
|
||||
# Reset the tool_data_tables by loading the empty tool_data_table_conf.xml file.
|
||||
reset_tool_data_tables( trans.app )
|
||||
try:
|
||||
shutil.rmtree( work_dir )
|
||||
except:
|
||||
pass
|
||||
if sample_files:
|
||||
trans.app.config.tool_data_path = original_tool_data_path
|
||||
# Reset the tool_data_tables by loading the empty tool_data_table_conf.xml file.
|
||||
reset_tool_data_tables( trans.app )
|
||||
return tool, message
|
||||
def load_tool_from_tmp_directory( trans, repo, repo_dir, ctx, filename, dir ):
|
||||
is_tool_config = False
|
||||
@@ -763,6 +732,41 @@ def new_workflow_metadata_required( trans, repository, metadata_dict ):
|
||||
# The received metadata_dict includes no metadata for workflows, so a new repository_metadata table record is not needed.
|
||||
return False
|
||||
def reset_all_metadata_on_repository( trans, id, **kwd ):
|
||||
def reset_all_tool_versions( trans, id, repo ):
|
||||
changeset_revisions = []
|
||||
for changeset in repo.changelog:
|
||||
changeset_revision = str( repo.changectx( changeset ) )
|
||||
repository_metadata = get_repository_metadata_by_changeset_revision( trans, id, changeset_revision )
|
||||
if repository_metadata:
|
||||
metadata = repository_metadata.metadata
|
||||
if metadata:
|
||||
if metadata.get( 'tools', None ):
|
||||
changeset_revisions.append( changeset_revision )
|
||||
# The list of changeset_revisions is now filtered to contain only those that are downloadable and contain tools.
|
||||
# If a repository includes tools, build a dictionary of { 'tool id' : 'parent tool id' } pairs for each tool in each changeset revision.
|
||||
for index, changeset_revision in enumerate( changeset_revisions ):
|
||||
tool_versions_dict = {}
|
||||
repository_metadata = get_repository_metadata_by_changeset_revision( trans, id, changeset_revision )
|
||||
metadata = repository_metadata.metadata
|
||||
tool_dicts = metadata[ 'tools' ]
|
||||
if index == 0:
|
||||
# The first changset_revision is a special case because it will have no ancestor changeset_revisions in which to match tools.
|
||||
# The parent tool id for tools in the first changeset_revision will be the "old_id" in the tool config.
|
||||
for tool_dict in tool_dicts:
|
||||
tool_versions_dict[ tool_dict[ 'guid' ] ] = tool_dict[ 'id' ]
|
||||
else:
|
||||
for tool_dict in tool_dicts:
|
||||
parent_id = get_parent_id( trans,
|
||||
id,
|
||||
tool_dict[ 'id' ],
|
||||
tool_dict[ 'version' ],
|
||||
tool_dict[ 'guid' ],
|
||||
changeset_revisions[ 0:index ] )
|
||||
tool_versions_dict[ tool_dict[ 'guid' ] ] = parent_id
|
||||
if tool_versions_dict:
|
||||
repository_metadata.tool_versions = tool_versions_dict
|
||||
trans.sa_session.add( repository_metadata )
|
||||
trans.sa_session.flush()
|
||||
params = util.Params( kwd )
|
||||
message = util.restore_text( params.get( 'message', '' ) )
|
||||
status = params.get( 'status', 'done' )
|
||||
@@ -784,10 +788,14 @@ def reset_all_metadata_on_repository( trans, id, **kwd ):
|
||||
work_dir = tempfile.mkdtemp()
|
||||
current_changeset_revision = str( repo.changectx( changeset ) )
|
||||
ctx = repo.changectx( changeset )
|
||||
print "Cloning repository revision: ", str( ctx.rev() )
|
||||
log.debug( "Cloning repository revision: %s", str( ctx.rev() ) )
|
||||
clone_repository( repository_clone_url, work_dir, str( ctx.rev() ) )
|
||||
print "Generating metadata for changset revision: ", str( ctx.rev() )
|
||||
current_metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( trans.app, work_dir, repository_clone_url )
|
||||
log.debug( "Generating metadata for changset revision: %s", str( ctx.rev() ) )
|
||||
current_metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( app=trans.app,
|
||||
repository_clone_url=repository_clone_url,
|
||||
relative_install_dir=repo_dir,
|
||||
repository_files_dir=work_dir,
|
||||
resetting_all_metadata_on_repository=True )
|
||||
if current_metadata_dict:
|
||||
if not metadata_changeset_revision and not metadata_dict:
|
||||
# We're at the first change set in the change log.
|
||||
@@ -842,27 +850,49 @@ def reset_all_metadata_on_repository( trans, id, **kwd ):
|
||||
except:
|
||||
pass
|
||||
# Delete all repository_metadata records for this repository that do not have a changeset_revision value in changeset_revisions.
|
||||
cleaned_changeset_revisions = clean_repository_metadata( trans, id, changeset_revisions )
|
||||
# Set tool version information for all downloadable changeset revisions.
|
||||
add_repository_metadata_tool_versions( trans, id, cleaned_changeset_revisions )
|
||||
clean_repository_metadata( trans, id, changeset_revisions )
|
||||
# Set tool version information for all downloadable changeset revisions. Get the list of changeset revisions from the changelog.
|
||||
reset_all_tool_versions( trans, id, repo )
|
||||
def set_repository_metadata( trans, repository, content_alert_str='', **kwd ):
|
||||
"""
|
||||
Set metadata using the repository's current disk files, returning specific error messages (if any) to alert the repository owner that the changeset
|
||||
has problems.
|
||||
"""
|
||||
def add_tool_versions( trans, id, repository_metadata, changeset_revisions ):
|
||||
# Build a dictionary of { 'tool id' : 'parent tool id' } pairs for each tool in repository_metadata.
|
||||
metadata = repository_metadata.metadata
|
||||
tool_versions_dict = {}
|
||||
for tool_dict in metadata.get( 'tools', [] ):
|
||||
# We have at least 2 changeset revisions to compare tool guids and tool ids.
|
||||
parent_id = get_parent_id( trans,
|
||||
id,
|
||||
tool_dict[ 'id' ],
|
||||
tool_dict[ 'version' ],
|
||||
tool_dict[ 'guid' ],
|
||||
changeset_revisions )
|
||||
tool_versions_dict[ tool_dict[ 'guid' ] ] = parent_id
|
||||
if tool_versions_dict:
|
||||
repository_metadata.tool_versions = tool_versions_dict
|
||||
trans.sa_session.add( repository_metadata )
|
||||
trans.sa_session.flush()
|
||||
message = ''
|
||||
status = 'done'
|
||||
repository_clone_url = generate_clone_url( trans, trans.security.encode_id( repository.id ) )
|
||||
encoded_id = trans.security.encode_id( repository.id )
|
||||
repository_clone_url = generate_clone_url( trans, encoded_id )
|
||||
repo_dir = repository.repo_path
|
||||
repo = hg.repository( get_configured_ui(), repo_dir )
|
||||
metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( trans.app, repo_dir, repository_clone_url )
|
||||
metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( app=trans.app,
|
||||
repository_clone_url=repository_clone_url,
|
||||
relative_install_dir=repo_dir,
|
||||
repository_files_dir=None,
|
||||
resetting_all_metadata_on_repository=False )
|
||||
if metadata_dict:
|
||||
downloadable = is_downloadable( metadata_dict )
|
||||
repository_metadata = None
|
||||
if new_tool_metadata_required( trans, repository, metadata_dict ) or new_workflow_metadata_required( trans, repository, metadata_dict ):
|
||||
# Create a new repository_metadata table row.
|
||||
repository_metadata = create_or_update_repository_metadata( trans,
|
||||
trans.security.encode_id( repository.id ),
|
||||
encoded_id,
|
||||
repository,
|
||||
repository.tip,
|
||||
metadata_dict )
|
||||
@@ -882,21 +912,18 @@ def set_repository_metadata( trans, repository, content_alert_str='', **kwd ):
|
||||
else:
|
||||
# There are no tools in the repository, and we're setting metadata on the repository tip.
|
||||
repository_metadata = create_or_update_repository_metadata( trans,
|
||||
trans.security.encode_id( repository.id ),
|
||||
encoded_id,
|
||||
repository,
|
||||
repository.tip,
|
||||
metadata_dict )
|
||||
if 'tools' in metadata_dict and repository_metadata and status != 'error':
|
||||
# Set tool versions on the new downloadable change set. The order of the list of changesets is critical, so we use the repo's changelog.
|
||||
downloadable_changeset_revisions = [ rm.changeset_revision for rm in repository.downloadable_revisions ]
|
||||
changeset_revisions = []
|
||||
for changeset in repo.changelog:
|
||||
changeset_revision = str( repo.changectx( changeset ) )
|
||||
if changeset_revision in downloadable_changeset_revisions:
|
||||
if get_repository_metadata_by_changeset_revision( trans, encoded_id, changeset_revision ):
|
||||
changeset_revisions.append( changeset_revision )
|
||||
# Now append the latest changeset_revision we just updated above.
|
||||
changeset_revisions.append( repository_metadata.changeset_revision )
|
||||
add_repository_metadata_tool_versions( trans, trans.security.encode_id( repository.id ), changeset_revisions )
|
||||
add_tool_versions( trans, encoded_id, repository_metadata, changeset_revisions )
|
||||
elif len( repo ) == 1 and not invalid_file_tups:
|
||||
message = "Revision '%s' includes no tools, datatypes or exported workflows for which metadata can " % str( repository.tip )
|
||||
message += "be defined so this revision cannot be automatically installed into a local Galaxy instance."
|
||||
|
||||
@@ -6,7 +6,6 @@ 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
|
||||
|
||||
@@ -20,33 +19,24 @@ class HgController( BaseUIController ):
|
||||
hg_version = mercurial.__version__.version
|
||||
cmd = kwd.get( 'cmd', None )
|
||||
wsgi_app = wsgiapplication( make_web_app )
|
||||
# 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:
|
||||
if hg_version >= '2.2.3' and cmd == 'pushkey':
|
||||
# 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
|
||||
# upon the mercurial version being used. 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).
|
||||
# We require version 2.2.3 since the pushkey hook was added in that version.
|
||||
# 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:
|
||||
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:
|
||||
log.debug( "Successfully reset metadata on repository %s, but encountered problem: %s" % ( str( repository.name ), str( error_message ) ) )
|
||||
if hg_version >= '2.2.3':
|
||||
# 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:
|
||||
log.debug( "Successfully reset metadata on repository %s, but encountered problem: %s" % ( str( repository.name ), str( error_message ) ) )
|
||||
return wsgi_app
|
||||
|
||||
def make_web_app():
|
||||
|
||||
@@ -10,7 +10,8 @@ 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 create_repo_info_dict, get_changectx_for_changeset, get_configured_ui, get_repository_file_contents, NOT_TOOL_CONFIGS
|
||||
from galaxy.util.shed_util import open_repository_files_folder, reversed_lower_upper_bounded_changelog, strip_path, to_html_escaped, update_repository
|
||||
from galaxy.util.shed_util import open_repository_files_folder, reversed_lower_upper_bounded_changelog, reversed_upper_bounded_changelog, strip_path
|
||||
from galaxy.util.shed_util import to_html_escaped, update_repository
|
||||
from galaxy.tool_shed.encoding_util import *
|
||||
from common import *
|
||||
|
||||
@@ -1268,6 +1269,36 @@ class RepositoryController( BaseUIController, ItemRatings ):
|
||||
update_dict[ 'changeset_revision' ] = str( latest_changeset_revision )
|
||||
update_dict[ 'ctx_rev' ] = str( update_to_ctx.rev() )
|
||||
return tool_shed_encode( update_dict )
|
||||
def get_versions_of_tool( self, trans, repository, repository_metadata, guid ):
|
||||
"""Return the tool lineage in descendant order for the received guid contained in the received repsitory_metadata.tool_versions."""
|
||||
encoded_id = trans.security.encode_id( repository.id )
|
||||
repo_dir = repository.repo_path
|
||||
repo = hg.repository( get_configured_ui(), repo_dir )
|
||||
# Initialize the tool lineage
|
||||
tool_guid_lineage = [ guid ]
|
||||
# Get all ancestor guids of the received guid.
|
||||
current_child_guid = guid
|
||||
for changeset in reversed_upper_bounded_changelog( repo, repository_metadata.changeset_revision ):
|
||||
ctx = repo.changectx( changeset )
|
||||
rm = get_repository_metadata_by_changeset_revision( trans, encoded_id, str( ctx ) )
|
||||
if rm:
|
||||
parent_guid = rm.tool_versions.get( current_child_guid, None )
|
||||
if parent_guid:
|
||||
tool_guid_lineage.append( parent_guid )
|
||||
current_child_guid = parent_guid
|
||||
# Get all descendant guids of the received guid.
|
||||
current_parent_guid = guid
|
||||
for changeset in reversed_lower_upper_bounded_changelog( repo, repository_metadata.changeset_revision, repository.tip ):
|
||||
ctx = repo.changectx( changeset )
|
||||
rm = get_repository_metadata_by_changeset_revision( trans, encoded_id, str( ctx ) )
|
||||
if rm:
|
||||
tool_versions = rm.tool_versions
|
||||
for child_guid, parent_guid in tool_versions.items():
|
||||
if parent_guid == current_parent_guid:
|
||||
tool_guid_lineage.insert( 0, child_guid )
|
||||
current_parent_guid = child_guid
|
||||
break
|
||||
return tool_guid_lineage
|
||||
@web.expose
|
||||
def help( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
@@ -1348,23 +1379,12 @@ class RepositoryController( BaseUIController, ItemRatings ):
|
||||
webapp = get_webapp( trans, **kwd )
|
||||
repository_clone_url = generate_clone_url( trans, repository_id )
|
||||
repository = get_repository( trans, repository_id )
|
||||
repo_dir = repository.repo_path
|
||||
repo = hg.repository( get_configured_ui(), repo_dir )
|
||||
ctx = get_changectx_for_changeset( repo, changeset_revision )
|
||||
invalid_message = ''
|
||||
metadata_dict, invalid_file_tups = generate_metadata_for_changeset_revision( trans.app, repo_dir, repository_clone_url )
|
||||
for invalid_file_tup in invalid_file_tups:
|
||||
invalid_tool_config, invalid_msg = invalid_file_tup
|
||||
invalid_tool_config_name = strip_path( invalid_tool_config )
|
||||
if tool_config == invalid_tool_config_name:
|
||||
invalid_message = invalid_msg
|
||||
break
|
||||
tool, error_message = load_tool_from_changeset_revision( trans, repository_id, changeset_revision, tool_config )
|
||||
tool_state = self.__new_state( trans )
|
||||
is_malicious = changeset_is_malicious( trans, repository_id, repository.tip )
|
||||
try:
|
||||
if invalid_message:
|
||||
message = invalid_message
|
||||
if error_message:
|
||||
message = error_message
|
||||
return trans.fill_template( "/webapps/community/repository/tool_form.mako",
|
||||
repository=repository,
|
||||
changeset_revision=changeset_revision,
|
||||
@@ -2165,20 +2185,25 @@ class RepositoryController( BaseUIController, ItemRatings ):
|
||||
status = params.get( 'status', 'done' )
|
||||
webapp = get_webapp( trans, **kwd )
|
||||
repository = get_repository( trans, repository_id )
|
||||
metadata = {}
|
||||
tool_metadata_dict = {}
|
||||
tool_lineage = []
|
||||
tool = None
|
||||
guid = None
|
||||
revision_label = get_revision_label( trans, repository, changeset_revision )
|
||||
repository_metadata = get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision ).metadata
|
||||
if 'tools' in repository_metadata:
|
||||
for tool_metadata_dict in repository_metadata[ 'tools' ]:
|
||||
repository_metadata = get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision )
|
||||
metadata = repository_metadata.metadata
|
||||
if 'tools' in metadata:
|
||||
for tool_metadata_dict in metadata[ 'tools' ]:
|
||||
if tool_metadata_dict[ 'id' ] == tool_id:
|
||||
metadata = tool_metadata_dict
|
||||
guid = tool_metadata_dict[ 'guid' ]
|
||||
try:
|
||||
# We may be attempting to load a tool that no longer exists in the repository tip.
|
||||
tool = load_tool( trans, os.path.abspath( metadata[ 'tool_config' ] ) )
|
||||
tool = load_tool( trans, os.path.abspath( tool_metadata_dict[ 'tool_config' ] ) )
|
||||
except:
|
||||
tool = None
|
||||
break
|
||||
if guid:
|
||||
tool_lineage = self.get_versions_of_tool( trans, repository, repository_metadata, guid )
|
||||
is_malicious = changeset_is_malicious( trans, repository_id, repository.tip )
|
||||
changeset_revision_select_field = build_changeset_revision_select_field( trans,
|
||||
repository,
|
||||
@@ -2188,7 +2213,8 @@ class RepositoryController( BaseUIController, ItemRatings ):
|
||||
return trans.fill_template( "/webapps/community/repository/view_tool_metadata.mako",
|
||||
repository=repository,
|
||||
tool=tool,
|
||||
metadata=metadata,
|
||||
tool_metadata_dict=tool_metadata_dict,
|
||||
tool_lineage=tool_lineage,
|
||||
changeset_revision=changeset_revision,
|
||||
revision_label=revision_label,
|
||||
changeset_revision_select_field=changeset_revision_select_field,
|
||||
|
||||
@@ -57,9 +57,9 @@ class Hg( object ):
|
||||
connection.execute( "update repository set times_downloaded = %d where user_id = %d and name = '%s'" % ( times_downloaded, user_id, name.lower() ) )
|
||||
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 (see the docs at http://mercurial.selenic.com/wiki/WireProtocol):
|
||||
# between -> capabilities -> heads -> branchmap -> unbundle -> unbundle -> listkeys
|
||||
# This is an hg push from the command line. When doing this, the following commands, in order,
|
||||
# will be retrieved from environ (see the docs at http://mercurial.selenic.com/wiki/WireProtocol):
|
||||
# # If mercurial version >= '2.2.3': capabilities -> batch -> branchmap -> unbundle -> listkeys -> pushkey
|
||||
#
|
||||
# The mercurial API unbundle() ( i.e., hg push ) method ultimately requires authorization.
|
||||
# We'll force password entry every time a change set is pushed.
|
||||
|
||||
@@ -200,7 +200,7 @@ class RepositoryCategoryAssociation( object ):
|
||||
self.repository = repository
|
||||
self.category = category
|
||||
|
||||
class Tag ( object ):
|
||||
class Tag( object ):
|
||||
def __init__( self, id=None, type=None, parent_id=None, name=None ):
|
||||
self.id = id
|
||||
self.type = type
|
||||
@@ -209,7 +209,7 @@ class Tag ( object ):
|
||||
def __str__ ( self ):
|
||||
return "Tag(id=%s, type=%i, parent_id=%s, name=%s)" % ( self.id, self.type, self.parent_id, self.name )
|
||||
|
||||
class ItemTagAssociation ( object ):
|
||||
class ItemTagAssociation( object ):
|
||||
def __init__( self, id=None, user=None, item_id=None, tag_id=None, user_tname=None, value=None ):
|
||||
self.id = id
|
||||
self.user = user
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">${metadata[ 'name' ]} tool metadata</div>
|
||||
<div class="toolFormBody">
|
||||
<div class="form-row">
|
||||
<table width="100%">
|
||||
<tr bgcolor="#D8D8D8" width="100%"><td><b>Miscellaneous</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Name:</label>
|
||||
${metadata[ 'name' ]}
|
||||
@@ -65,33 +70,35 @@
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
%endif
|
||||
%if tool:
|
||||
<div class="form-row">
|
||||
<label>Command:</label>
|
||||
<pre>${tool.command}</pre>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Interpreter:</label>
|
||||
${tool.interpreter}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Is multi-byte:</label>
|
||||
${tool.is_multi_byte}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Forces a history refresh:</label>
|
||||
${tool.force_history_refresh}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Parallelism:</label>
|
||||
${tool.parallelism}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
%endif
|
||||
<div class="form-row">
|
||||
<table width="100%">
|
||||
<tr bgcolor="#D8D8D8" width="100%"><td><b>Version lineage of this tool (guids ordered most recent to oldest)</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
%if tool_lineage:
|
||||
<table class="grid">
|
||||
%for guid in tool_lineage:
|
||||
<tr>
|
||||
<td>
|
||||
%if guid == metadata[ 'guid' ]:
|
||||
${guid} <b>(this tool)</b>
|
||||
%else:
|
||||
${guid}
|
||||
%endif
|
||||
</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</table>
|
||||
%else:
|
||||
No tool versions are defined for this tool so it is critical that you <b>Set tool versions</b> from the <b>Manage repository</b> page.
|
||||
%endif
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<table width="100%">
|
||||
<tr bgcolor="#D8D8D8" width="100%"><td><b>Requirements (dependencies defined in the <requirements> tag set)</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<%
|
||||
if 'requirements' in metadata:
|
||||
requirements = metadata[ 'requirements' ]
|
||||
@@ -122,7 +129,48 @@
|
||||
</table>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
%else:
|
||||
<div class="form-row">
|
||||
No requirements defined
|
||||
</div>
|
||||
%endif
|
||||
%if tool:
|
||||
<div class="form-row">
|
||||
<table width="100%">
|
||||
<tr bgcolor="#D8D8D8" width="100%"><td><b>Additional information about this tool</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Command:</label>
|
||||
<pre>${tool.command}</pre>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Interpreter:</label>
|
||||
${tool.interpreter}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Is multi-byte:</label>
|
||||
${tool.is_multi_byte}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Forces a history refresh:</label>
|
||||
${tool.force_history_refresh}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Parallelism:</label>
|
||||
${tool.parallelism}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
%endif
|
||||
<div class="form-row">
|
||||
<table width="100%">
|
||||
<tr bgcolor="#D8D8D8" width="100%"><td><b>Functional tests</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<%
|
||||
if 'tests' in metadata:
|
||||
tests = metadata[ 'tests' ]
|
||||
@@ -166,6 +214,10 @@
|
||||
%endfor
|
||||
</table>
|
||||
</div>
|
||||
%else:
|
||||
<div class="form-row">
|
||||
No functional tests defined
|
||||
</div>
|
||||
%endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -85,31 +85,14 @@
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Repository revision</div>
|
||||
<div class="toolFormBody">
|
||||
%if len( changeset_revision_select_field.options ) > 1:
|
||||
<form name="change_revision" id="change_revision" action="${h.url_for( controller='repository', action='view_tool_metadata', repository_id=trans.security.encode_id( repository.id ), tool_id=metadata[ 'id' ], webapp=webapp )}" method="post" >
|
||||
<div class="form-row">
|
||||
<%
|
||||
if changeset_revision == repository.tip:
|
||||
tip_str = 'repository tip'
|
||||
else:
|
||||
tip_str = ''
|
||||
%>
|
||||
${changeset_revision_select_field.get_html()} <i>${tip_str}</i>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
Select a revision to inspect and download versions of tools from this repository.
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
%else:
|
||||
<div class="form-row">
|
||||
<label>Revision:</label>
|
||||
%if can_view_change_log:
|
||||
<a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${revision_label}</a>
|
||||
%else:
|
||||
${revision_label}
|
||||
%endif
|
||||
</div>
|
||||
%endif
|
||||
<div class="form-row">
|
||||
<label>Revision:</label>
|
||||
%if can_view_change_log:
|
||||
<a href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ) )}">${revision_label}</a>
|
||||
%else:
|
||||
${revision_label}
|
||||
%endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p/>
|
||||
@@ -127,47 +110,89 @@
|
||||
<b>Repository name:</b><br/>
|
||||
${repository.name}
|
||||
%endif
|
||||
%if metadata:
|
||||
%if tool_metadata_dict:
|
||||
<p/>
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">${metadata[ 'name' ]} tool metadata</div>
|
||||
<div class="toolFormTitle">${tool_metadata_dict[ 'name' ]} tool metadata</div>
|
||||
<div class="toolFormBody">
|
||||
<div class="form-row">
|
||||
<table width="100%">
|
||||
<tr bgcolor="#D8D8D8" width="100%"><td><b>Miscellaneous</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Name:</label>
|
||||
<a href="${h.url_for( controller='repository', action='display_tool', repository_id=trans.security.encode_id( repository.id ), tool_config=metadata[ 'tool_config' ], changeset_revision=changeset_revision, webapp=webapp )}">${metadata[ 'name' ]}</a>
|
||||
<a href="${h.url_for( controller='repository', action='display_tool', repository_id=trans.security.encode_id( repository.id ), tool_config=tool_metadata_dict[ 'tool_config' ], changeset_revision=changeset_revision, webapp=webapp )}">${tool_metadata_dict[ 'name' ]}</a>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
%if 'description' in metadata:
|
||||
%if 'description' in tool_metadata_dict:
|
||||
<div class="form-row">
|
||||
<label>Description:</label>
|
||||
${metadata[ 'description' ]}
|
||||
${tool_metadata_dict[ 'description' ]}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
%endif
|
||||
%if 'id' in metadata:
|
||||
%if 'id' in tool_metadata_dict:
|
||||
<div class="form-row">
|
||||
<label>Id:</label>
|
||||
${metadata[ 'id' ]}
|
||||
${tool_metadata_dict[ 'id' ]}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
%endif
|
||||
%if 'guid' in metadata:
|
||||
%if 'guid' in tool_metadata_dict:
|
||||
<div class="form-row">
|
||||
<label>Guid:</label>
|
||||
${metadata[ 'guid' ]}
|
||||
${tool_metadata_dict[ 'guid' ]}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
%endif
|
||||
%if 'version' in metadata:
|
||||
%if 'version' in tool_metadata_dict:
|
||||
<div class="form-row">
|
||||
<label>Version:</label>
|
||||
${metadata[ 'version' ]}
|
||||
${tool_metadata_dict[ 'version' ]}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
%endif
|
||||
%if 'version_string_cmd' in tool_metadata_dict:
|
||||
<div class="form-row">
|
||||
<label>Version command string:</label>
|
||||
${tool_metadata_dict[ 'version_string_cmd' ]}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
%endif
|
||||
<div class="form-row">
|
||||
<table width="100%">
|
||||
<tr bgcolor="#D8D8D8" width="100%"><td><b>Version lineage of this tool (guids ordered most recent to oldest)</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
%if tool_lineage:
|
||||
<table class="grid">
|
||||
%for guid in tool_lineage:
|
||||
<tr>
|
||||
<td>
|
||||
%if guid == tool_metadata_dict[ 'guid' ]:
|
||||
${guid} <b>(this tool)</b>
|
||||
%else:
|
||||
${guid}
|
||||
%endif
|
||||
</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</table>
|
||||
%else:
|
||||
No tool versions are defined for this tool so it is critical that you <b>Reset all repository metadata</b> from the
|
||||
<b>Manage repository</b> page.
|
||||
%endif
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<table width="100%">
|
||||
<tr bgcolor="#D8D8D8" width="100%"><td><b>Requirements (dependencies defined in the <requirements> tag set)</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<%
|
||||
if 'requirements' in metadata:
|
||||
requirements = metadata[ 'requirements' ]
|
||||
if 'requirements' in tool_metadata_dict:
|
||||
requirements = tool_metadata_dict[ 'requirements' ]
|
||||
else:
|
||||
requirements = None
|
||||
%>
|
||||
@@ -195,15 +220,17 @@
|
||||
</table>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
%endif
|
||||
%if 'version_string_cmd' in metadata:
|
||||
%else:
|
||||
<div class="form-row">
|
||||
<label>Version command string:</label>
|
||||
${metadata[ 'version_string_cmd' ]}
|
||||
<div style="clear: both"></div>
|
||||
No requirements defined
|
||||
</div>
|
||||
%endif
|
||||
%if tool:
|
||||
<div class="form-row">
|
||||
<table width="100%">
|
||||
<tr bgcolor="#D8D8D8" width="100%"><td><b>Additional information about this tool</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Command:</label>
|
||||
<pre>${tool.command}</pre>
|
||||
@@ -230,9 +257,14 @@
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
%endif
|
||||
<div class="form-row">
|
||||
<table width="100%">
|
||||
<tr bgcolor="#D8D8D8" width="100%"><td><b>Functional tests</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<%
|
||||
if 'tests' in metadata:
|
||||
tests = metadata[ 'tests' ]
|
||||
if 'tests' in tool_metadata_dict:
|
||||
tests = tool_metadata_dict[ 'tests' ]
|
||||
else:
|
||||
tests = None
|
||||
%>
|
||||
@@ -273,6 +305,10 @@
|
||||
%endfor
|
||||
</table>
|
||||
</div>
|
||||
%else:
|
||||
<div class="form-row">
|
||||
No functional tests defined
|
||||
</div>
|
||||
%endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user