1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/0ded962ca5d0/ changeset: 0ded962ca5d0 branch: next-stable user: natefoo date: 2013-02-01 22:19:55 summary: Merged changes from the default branch. affected #: 16 files diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 lib/galaxy/tool_shed/tool_dependencies/install_util.py --- a/lib/galaxy/tool_shed/tool_dependencies/install_util.py +++ b/lib/galaxy/tool_shed/tool_dependencies/install_util.py @@ -227,8 +227,8 @@ tool_dependency_type='package', tool_dependency_name=package_name, tool_dependency_version=package_version ) - assert os.path.exists( required_repository_package_install_dir ), \ - 'Missing required tool dependency directory %s' % str( required_repository_package_install_dir ) + if not os.path.exists( required_repository_package_install_dir ): + print 'Missing required tool dependency directory %s' % str( required_repository_package_install_dir ) repo_files_dir = required_repository.repo_files_directory( app ) tool_dependencies_config = get_absolute_path_to_file_in_repository( repo_files_dir, 'tool_dependencies.xml' ) if tool_dependencies_config: diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 lib/galaxy/util/shed_util_common.py --- a/lib/galaxy/util/shed_util_common.py +++ b/lib/galaxy/util/shed_util_common.py @@ -935,6 +935,11 @@ for repository_components_list in val: tool_shed, name, owner, changeset_revision = repository_components_list repository = get_or_create_tool_shed_repository( trans, tool_shed, name, owner, changeset_revision ) +def generate_citable_link_for_repository_in_tool_shed( trans, repository ): + """Generate the URL for citing a repository that is in the tool shed.""" + base_url = url_for( '/', qualified=True ).rstrip( '/' ) + protocol, base = base_url.split( '://' ) + return '%s://%s/view/%s/%s' % ( protocol, base, repository.user.username, repository.name ) def generate_clone_url_for_installed_repository( app, repository ): """Generate the URL for cloning a repository that has been installed into a Galaxy instance.""" tool_shed_url = get_url_from_repository_tool_shed( app, repository ) @@ -1215,6 +1220,7 @@ """ repository_dependency_tup = [] requirements_dict = {} + error_message = '' package_name = elem.get( 'name', None ) package_version = elem.get( 'version', None ) if package_name and package_version: @@ -1226,15 +1232,15 @@ requirements_dict[ 'readme' ] = sub_elem.text elif sub_elem.tag == 'repository': # We have a complex repository dependency. - current_rd_tups = handle_repository_elem( app=app, - repository_elem=sub_elem, - repository_dependencies_tups=None ) + current_rd_tups, error_message = handle_repository_elem( app=app, + repository_elem=sub_elem, + repository_dependencies_tups=None ) if current_rd_tups: repository_dependency_tup = current_rd_tups[ 0 ] if requirements_dict: dependency_key = '%s/%s' % ( package_name, package_version ) tool_dependencies_dict[ dependency_key ] = requirements_dict - return tool_dependencies_dict, repository_dependency_tup + return tool_dependencies_dict, repository_dependency_tup, error_message def generate_repository_dependency_metadata_for_installed_repository( app, repository_dependencies_config, metadata_dict ): """ Generate a repository dependencies dictionary based on valid information defined in the received repository_dependencies_config. This method @@ -1284,7 +1290,10 @@ is_valid = False if is_valid: for repository_elem in root.findall( 'repository' ): - current_rd_tups = handle_repository_elem( app, repository_elem, repository_dependencies_tups ) + current_rd_tups, error_message = handle_repository_elem( app, repository_elem, repository_dependencies_tups ) + if error_message: + log.debug( error_message ) + return metadata_dict, error_message for crdt in current_rd_tups: repository_dependencies_tups.append( crdt ) if repository_dependencies_tups: @@ -1315,9 +1324,12 @@ repository_dependency_tups = [] for elem in root: if elem.tag == 'package': - tool_dependencies_dict, repository_dependency_tup = generate_package_dependency_metadata( app, elem, tool_dependencies_dict ) + tool_dependencies_dict, repository_dependency_tup, message = generate_package_dependency_metadata( app, elem, tool_dependencies_dict ) if repository_dependency_tup and repository_dependency_tup not in repository_dependency_tups: repository_dependency_tups.append( repository_dependency_tup ) + if message: + log.debug( message ) + error_message = '%s %s' % ( error_message, message ) elif elem.tag == 'set_environment': tool_dependencies_dict = generate_environment_dependency_metadata( elem, tool_dependencies_dict ) if tool_dependencies_dict: @@ -1345,27 +1357,23 @@ err_msg += "because the changeset revision is invalid. " log.debug( err_msg ) error_message += err_msg - continue else: err_msg = "Ignoring repository dependency definition for tool shed %s, name %s, owner %s, changeset revision %s "% \ ( rd_tool_shed, rd_name, rd_owner, rd_changeset_revision ) err_msg += "because the owner is invalid. " log.debug( err_msg ) error_message += err_msg - continue else: err_msg = "Ignoring repository dependency definition for tool shed %s, name %s, owner %s, changeset revision %s "% \ ( rd_tool_shed, rd_name, rd_owner, rd_changeset_revision ) err_msg += "because the name is invalid. " log.debug( err_msg ) error_message += err_msg - continue else: err_msg = "Repository dependencies are currently supported only within the same tool shed. Ignoring repository dependency definition " err_msg += "for tool shed %s, name %s, owner %s, changeset revision %s. " % ( rd_tool_shed, rd_name, rd_owner, rd_changeset_revision ) log.debug( err_msg ) error_message += err_msg - continue else: repository_owner = repository.owner rd_key = container_util.generate_repository_dependencies_key_for_repository( toolshed_base_url=rd_tool_shed, @@ -1836,6 +1844,13 @@ elif len( repo_info_tuple ) == 7: description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, repository_dependencies, tool_dependencies = repo_info_tuple return description, repository_clone_url, changeset_revision, ctx_rev, repository_owner, repository_dependencies, tool_dependencies +def get_repository_by_id( app, id ): + """Get a repository from the database via id.""" + sa_session = app.model.context.current + if app.name == 'galaxy': + return sa_session.query( app.model.ToolShedRepository ).get( id ) + else: + return sa_session.query( app.model.Repository ).get( id ) def get_repository_by_name( app, name ): """Get a repository from the database via name.""" sa_session = app.model.context.current @@ -2470,6 +2485,7 @@ new_rd_tups = [] else: new_rd_tups = [ rdt for rdt in repository_dependencies_tups ] + error_message = '' sa_session = app.model.context.current toolshed = repository_elem.attrib[ 'toolshed' ] name = repository_elem.attrib[ 'name' ] @@ -2485,8 +2501,9 @@ app.model.ToolShedRepository.table.c.owner == owner ) ) \ .first() except: - log.debug( "Invalid name %s or owner %s defined for repository. Repository dependencies will be ignored." % ( name, owner ) ) - return new_rd_tups + error_message = "Invalid name <b>%s</b> or owner <b>%s</b> defined for repository. Repository dependencies will be ignored." % ( name, owner ) + log.debug( error_message ) + return new_rd_tups, error_message repository_dependencies_tup = ( toolshed, name, owner, changeset_revision ) if repository_dependencies_tup not in new_rd_tups: new_rd_tups.append( repository_dependencies_tup ) @@ -2498,25 +2515,39 @@ .filter( app.model.User.table.c.username == owner ) \ .one() except Exception, e: - log.debug( "Invalid owner %s defined for repository %s. Repository dependencies will be ignored." % ( owner, name ) ) - return new_rd_tups + error_message = "Invalid owner <b>%s</b> defined for repository <b>%s</b>. Repository dependencies will be ignored." % ( str( owner ), str( name ) ) + log.debug( error_message ) + return new_rd_tups, error_message try: repository = sa_session.query( app.model.Repository ) \ .filter( and_( app.model.Repository.table.c.name == name, app.model.Repository.table.c.user_id == user.id ) ) \ - .first() + .one() except: - log.debug( "Invalid name %s or owner %s defined for repository. Repository dependencies will be ignored." % ( name, owner ) ) - return new_rd_tups + error_message = "Invalid repository name <b>%s</b> defined. Repository dependencies will be ignored." % str( name ) + log.debug( error_message ) + return new_rd_tups, error_message + # Find the specified changeset revision in the repository's changelog to see if it's valid. + found = False + repo = hg.repository( get_configured_ui(), repository.repo_path( app ) ) + for changeset in repo.changelog: + changeset_hash = str( repo.changectx( changeset ) ) + if changeset_hash == changeset_revision: + found = True + break + if not found: + error_message = "Invalid changeset revision <b>%s</b> defined. Repository dependencies will be ignored." % str( changeset_revision ) + log.debug( error_message ) + return new_rd_tups, error_message repository_dependencies_tup = ( toolshed, name, owner, changeset_revision ) if repository_dependencies_tup not in new_rd_tups: new_rd_tups.append( repository_dependencies_tup ) else: # Repository dependencies are currentlhy supported within a single tool shed. - error_message = "Invalid tool shed %s defined for repository %s. " % ( toolshed, name ) - error_message += "Repository dependencies are currently supported within a single tool shed, so your definition will be ignored." + error_message = "Invalid tool shed <b>%s</b> defined for repository <b>%s</b>. " % ( toolshed, name ) + error_message += "Repository dependencies are currently supported within a single tool shed." log.debug( error_message ) - return new_rd_tups + return new_rd_tups, error_message def handle_sample_files_and_load_tool_from_disk( trans, repo_files_dir, tool_config_filepath, work_dir ): # Copy all sample files from disk to a temporary directory since the sample files may be in multiple directories. message = '' @@ -3147,7 +3178,9 @@ resetting_all_metadata_on_repository=True, updating_installed_repository=False, persist=False ) - invalid_file_tups.extend( invalid_tups ) + # We'll only display error messages for the repository tip (it may be better to display error messages for each installable changeset revision). + if current_metadata_dict == repository.tip( trans.app ): + invalid_file_tups.extend( invalid_tups ) if current_metadata_dict: if not metadata_changeset_revision and not metadata_dict: # We're at the first change set in the change log. diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 lib/galaxy/webapps/community/buildapp.py --- a/lib/galaxy/webapps/community/buildapp.py +++ b/lib/galaxy/webapps/community/buildapp.py @@ -63,6 +63,8 @@ # Create the universe WSGI application webapp = CommunityWebApplication( app, session_cookie='galaxycommunitysession', name="community" ) add_ui_controllers( webapp, app ) + webapp.add_route( '/view/{owner}/', controller='repository', action='citable_owner' ) + webapp.add_route( '/view/{owner}/{name}/', controller='repository', action='citable_repository' ) webapp.add_route( '/:controller/:action', action='index' ) webapp.add_route( '/:action', controller='repository', action='index' ) webapp.add_route( '/repos/*path_info', controller='hg', action='handle_request', path_info='/' ) diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 lib/galaxy/webapps/community/controllers/repository.py --- a/lib/galaxy/webapps/community/controllers/repository.py +++ b/lib/galaxy/webapps/community/controllers/repository.py @@ -893,6 +893,47 @@ url += '&latest_ctx_rev=%s' % str( update_to_ctx.rev() ) return trans.response.send_redirect( url ) @web.expose + def citable_owner( self, trans, owner ): + """Support for citeable URL for each repository owner's tools, e.g. http://example.org/view/owner.""" + try: + user = suc.get_user_by_username( trans, owner ) + except: + user = None + if user: + user_id = trans.security.encode_id( user.id ) + return trans.fill_template( "/webapps/community/citable_repository.mako", + user_id=user_id ) + else: + message = "No repositories exist with owner <b>%s</b>." % str( owner ) + return trans.response.send_redirect( web.url_for( controller='repository', + action='browse_categories', + id=None, + name=None, + owner=None, + message=message, + status='error' ) ) + @web.expose + def citable_repository( self, trans, owner, name ): + """Support for citeable URL for each repository, e.g. http://example.org/view/owner/name.""" + try: + repository = suc.get_repository_by_name_and_owner( trans.app, name, owner ) + except: + repository = None + if repository: + repository_id = trans.security.encode_id( repository.id ) + return trans.fill_template( "/webapps/community/citable_repository.mako", + repository_id=repository_id ) + else: + #TODO - If the owner is OK, show their repositories? + message = "No repositories named <b>%s</b> with owner <b>%s</b> exist." % ( str( name ), str( owner ) ) + return trans.response.send_redirect( web.url_for( controller='repository', + action='browse_categories', + id=None, + name=None, + owner=None, + message=message, + status='error' ) ) + @web.expose def contact_owner( self, trans, id, **kwd ): params = util.Params( kwd ) message = util.restore_text( params.get( 'message', '' ) ) @@ -2551,6 +2592,17 @@ message=message, status=status ) @web.expose + def view_citable_repositories_by_owner( self, trans, user_id, **kwd ): + return trans.response.send_redirect( web.url_for( controller='repository', + action='browse_repositories', + operation="repositories_by_user", + user_id=user_id ) ) + @web.expose + def view_citable_repository( self, trans, repository_id, **kwd ): + return trans.response.send_redirect( web.url_for( controller='repository', + action='view_repository', + id=repository_id ) ) + @web.expose def view_or_manage_repository( self, trans, **kwd ): repository = suc.get_repository_in_tool_shed( trans, kwd[ 'id' ] ) if trans.user_is_admin() or repository.user == trans.user: diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 templates/webapps/community/citable_repository.mako --- /dev/null +++ b/templates/webapps/community/citable_repository.mako @@ -0,0 +1,84 @@ +<%inherit file="/webapps/community/base_panels.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + +<%def name="stylesheets()"> + ${parent.stylesheets()} + ## Include "base.css" for styling tool menu and forms (details) + ${h.css( "base", "autocomplete_tagging", "tool_menu" )} + + ## But make sure styles for the layout take precedence + ${parent.stylesheets()} + + <style type="text/css"> + body { margin: 0; padding: 0; overflow: hidden; } + #left { + background: #C1C9E5 url(${h.url_for('/static/style/menu_bg.png')}) top repeat-x; + } + </style> +</%def> + +<%def name="javascripts()"> + ${parent.javascripts()} +</%def> + +<%def name="init()"> + <% + self.has_left_panel=True + self.has_right_panel=False + self.active_view="tools" + %> + %if trans.app.config.require_login and not trans.user: + <script type="text/javascript"> + if ( window != top ) { + top.location.href = location.href; + } + </script> + %endif +</%def> + +<%def name="left_panel()"> + <div class="page-container" style="padding: 10px;"> + <div class="toolMenu"> + <div class="toolSectionList"> + <div class="toolSectionPad"></div> + <div class="toolSectionTitle"> + Search + </div> + <div class="toolSectionBody"> + <div class="toolTitle"> + <a target="galaxy_main" href="${h.url_for( controller='repository', action='find_tools' )}">Search for valid tools</a> + </div> + <div class="toolTitle"> + <a target="galaxy_main" href="${h.url_for( controller='repository', action='find_workflows' )}">Search for workflows</a> + </div> + </div> + <div class="toolSectionPad"></div> + <div class="toolSectionTitle"> + All Repositories + </div> + <div class="toolTitle"> + <a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_categories' )}">Browse by category</a> + </div> + <div class="toolSectionPad"></div> + <div class="toolSectionTitle"> + Available Actions + </div> + <div class="toolTitle"> + <a target="galaxy_main" href="${h.url_for( controller='/user', action='login' )}">Login to create a repository</a> + </div> + </div> + </div> + </div> +</%def> + +<%def name="center_panel()"> + <% + if trans.app.config.require_login and not trans.user: + center_url = h.url_for( controller='user', action='login' ) + elif repository_id: + center_url = h.url_for( controller='repository', action='view_citable_repository', repository_id=repository_id ) + else: + center_url = h.url_for( controller='repository', action='view_citable_repositories_by_owner', user_id=user_id ) + %> + <iframe name="galaxy_main" id="galaxy_main" frameborder="0" style="position: absolute; width: 100%; height: 100%;" src="${center_url}"></iframe> +</%def> diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 templates/webapps/community/repository/common.mako --- a/templates/webapps/community/repository/common.mako +++ b/templates/webapps/community/repository/common.mako @@ -163,6 +163,14 @@ </script></%def> +<%def name="render_sharable_str( repository )"> + <% + from galaxy.util.shed_util_common import generate_citable_link_for_repository_in_tool_shed + citable_str = generate_citable_link_for_repository_in_tool_shed( trans, repository ) + %> + ${citable_str} +</%def> + <%def name="render_clone_str( repository )"><% from galaxy.util.shed_util_common import generate_clone_url_for_repository_in_tool_shed diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 templates/webapps/community/repository/manage_repository.mako --- a/templates/webapps/community/repository/manage_repository.mako +++ b/templates/webapps/community/repository/manage_repository.mako @@ -146,6 +146,10 @@ <div class="toolFormTitle">Repository '${repository.name | h}'</div><div class="toolFormBody"><form name="edit_repository" id="edit_repository" action="${h.url_for( controller='repository', action='manage_repository', id=trans.security.encode_id( repository.id ) )}" method="post" > + <div class="form-row"> + <label>Sharable link to this repository:</label> + ${render_sharable_str( repository )} + </div> %if can_download: <div class="form-row"><label>Clone this repository:</label> diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 templates/webapps/community/repository/view_repository.mako --- a/templates/webapps/community/repository/view_repository.mako +++ b/templates/webapps/community/repository/view_repository.mako @@ -139,6 +139,10 @@ <div class="toolForm"><div class="toolFormTitle">Repository '${repository.name}'</div><div class="toolFormBody"> + <div class="form-row"> + <label>Sharable link to this repository:</label> + ${render_sharable_str( repository )} + </div> %if can_download: <div class="form-row"><label>Clone this repository:</label> diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 test/tool_shed/base/common.py --- a/test/tool_shed/base/common.py +++ b/test/tool_shed/base/common.py @@ -18,6 +18,14 @@ test_user_3_email = 'test-3@bx.psu.edu' test_user_3_name = 'user3' +complex_repository_dependency_template = '''<?xml version="1.0"?> +<tool_dependency> + <package name="${package}" version="${version}"> +${dependency_lines} + </package> +</tool_dependency> +''' + new_repository_dependencies_xml = '''<?xml version="1.0"?><repositories${description}> ${dependency_lines} diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 test/tool_shed/base/twilltestcase.py --- a/test/tool_shed/base/twilltestcase.py +++ b/test/tool_shed/base/twilltestcase.py @@ -203,6 +203,16 @@ return '%s=%s&%s=%s' % ( field_name, field_value, field_name, field_value ) else: return '%s=%s' % ( field_name, field_value ) + def create_repository_complex_dependency( self, repository, xml_filename, depends_on={} ): + self.generate_repository_dependency_xml( depends_on[ 'repositories' ], + xml_filename, + complex=True, + package=depends_on[ 'package' ], + version=depends_on[ 'version' ] ) + self.upload_file( repository, + 'tool_dependencies.xml', + filepath=os.path.split( xml_filename )[0], + commit_message='Uploaded dependency on %s.' % ', '.join( repo.name for repo in depends_on[ 'repositories' ] ) ) def create_repository_dependency( self, repository=None, depends_on=[], filepath=None ): dependency_description = '%s depends on %s.' % ( repository.name, ', '.join( repo.name for repo in depends_on ) ) self.generate_repository_dependency_xml( depends_on, @@ -426,7 +436,25 @@ self.visit_galaxy_url( "/user/logout" ) self.check_page_for_string( "You have been logged out" ) self.home() - def generate_repository_dependency_xml( self, repositories, xml_filename, dependency_description='' ): + def generate_invalid_dependency_xml( self, xml_filename, url, name, owner, changeset_revision, complex=True, package=None, version=None, description=None ): + file_path = os.path.split( xml_filename )[0] + dependency_entries = [] + template = string.Template( common.new_repository_dependencies_line ) + dependency_entries.append( template.safe_substitute( toolshed_url=url, + owner=owner, + repository_name=name, + changeset_revision=changeset_revision ) ) + if not os.path.exists( file_path ): + os.makedirs( file_path ) + if complex: + dependency_template = string.Template( common.complex_repository_dependency_template ) + repository_dependency_xml = dependency_template.safe_substitute( package=package, version=version, dependency_lines='\n'.join( dependency_entries ) ) + else: + template_parser = string.Template( common.new_repository_dependencies_xml ) + repository_dependency_xml = template_parser.safe_substitute( description=description, dependency_lines='\n'.join( dependency_entries ) ) + # Save the generated xml to the specified location. + file( xml_filename, 'w' ).write( repository_dependency_xml ) + def generate_repository_dependency_xml( self, repositories, xml_filename, dependency_description='', complex=False, package=None, version=None ): file_path = os.path.split( xml_filename )[0] if not os.path.exists( file_path ): os.makedirs( file_path ) @@ -442,8 +470,12 @@ description = ' description="%s"' % dependency_description else: description = dependency_description - template_parser = string.Template( common.new_repository_dependencies_xml ) - repository_dependency_xml = template_parser.safe_substitute( description=description, dependency_lines='\n'.join( dependency_entries ) ) + if complex: + dependency_template = string.Template( common.complex_repository_dependency_template ) + repository_dependency_xml = dependency_template.safe_substitute( package=package, version=version, dependency_lines='\n'.join( dependency_entries ) ) + else: + template_parser = string.Template( common.new_repository_dependencies_xml ) + repository_dependency_xml = template_parser.safe_substitute( description=description, dependency_lines='\n'.join( dependency_entries ) ) # Save the generated xml to the specified location. file( xml_filename, 'w' ).write( repository_dependency_xml ) def generate_temp_path( self, test_script_path, additional_paths=[] ): @@ -655,6 +687,11 @@ if includes_tools: self.submit_form( 1, 'select_tool_panel_section_button', **kwd ) self.check_for_strings( post_submit_strings_displayed, strings_not_displayed ) + else: + self.check_for_strings(strings_displayed=[ 'Choose the configuration file whose tool_path setting will be used for installing repositories' ] ) + args = dict( shed_tool_conf=self.shed_tool_conf ) + self.submit_form( 1, 'select_shed_tool_panel_config_button', **args ) + self.check_for_strings( post_submit_strings_displayed, strings_not_displayed ) repository_ids = self.initiate_installation_process( new_tool_panel_section=new_tool_panel_section ) self.wait_for_repository_installation( repository_ids ) def load_invalid_tool_page( self, repository, tool_xml, changeset_revision, strings_displayed=[], strings_not_displayed=[] ): diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 test/tool_shed/functional/test_0000_basic_repository_features.py --- a/test/tool_shed/functional/test_0000_basic_repository_features.py +++ b/test/tool_shed/functional/test_0000_basic_repository_features.py @@ -158,3 +158,19 @@ '''Verify that resetting the metadata does not change it.''' repository = test_db_util.get_repository_by_name_and_owner( repository_name, common.test_user_1_name ) self.verify_unchanged_repository_metadata( repository ) + def test_0090_verify_reserved_repository_name_handling( self ): + '''Check that reserved repository names are handled correctly.''' + category = test_db_util.get_category_by_name( 'Test 0000 Basic Repository Features 1' ) + self.get_or_create_repository( name='repos', + description=repository_description, + long_description=repository_long_description, + owner=common.test_user_1_name, + category_id=self.security.encode_id( category.id ), + strings_displayed=[ 'The term <b>repos</b> is a reserved word in the tool shed, so it cannot be used as a repository name.' ] ) + def test_0100_verify_reserved_username_handling( self ): + '''Check that reserved usernames are handled correctly.''' + self.logout() + self.login( email='baduser@bx.psu.edu', username='repos' ) + test_user_1 = test_db_util.get_user( 'baduser@bx.psu.edu' ) + assert test_user_1 is None, 'Creating user with public name "repos" succeeded.' + self.check_for_strings( strings_displayed=[ 'The term <b>repos</b> is a reserved word in the tool shed, so it cannot be used as a public user name.' ] ) diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 test/tool_shed/functional/test_0100_complex_repository_dependencies.py --- /dev/null +++ b/test/tool_shed/functional/test_0100_complex_repository_dependencies.py @@ -0,0 +1,154 @@ +from tool_shed.base.twilltestcase import ShedTwillTestCase, common, os +import tool_shed.base.test_db_util as test_db_util + +bwa_base_repository_name = 'bwa_base_repository_0100' +bwa_base_repository_description = "BWA Base" +bwa_base_repository_long_description = "BWA tool that depends on bwa 0.5.9, with a complex repository dependency pointing at bwa_tool_repository_0100" + +bwa_tool_repository_name = 'bwa_tool_repository_0100' +bwa_tool_repository_description = "BWA Tool" +bwa_tool_repository_long_description = "BWA repository with a package tool dependency defined for BWA 0.5.9." + +category_name = 'Test 0100 Complex Repository Dependencies' +category_description = 'Test 0100 Complex Repository Dependencies' + +class TestComplexRepositoryDependencies( ShedTwillTestCase ): + '''Test features related to complex repository dependencies.''' + def test_0000_initiate_users( self ): + """Create necessary user accounts.""" + self.logout() + self.login( email=common.test_user_1_email, username=common.test_user_1_name ) + test_user_1 = test_db_util.get_user( common.test_user_1_email ) + assert test_user_1 is not None, 'Problem retrieving user with email %s from the database' % test_user_1_email + test_user_1_private_role = test_db_util.get_private_role( test_user_1 ) + self.logout() + self.login( email=common.admin_email, username=common.admin_username ) + admin_user = test_db_util.get_user( common.admin_email ) + assert admin_user is not None, 'Problem retrieving user with email %s from the database' % admin_email + admin_user_private_role = test_db_util.get_private_role( admin_user ) + def test_0005_create_bwa_tool_repository( self ): + '''Create and populate bwa_tool_0100.''' + category = self.create_category( name=category_name, description=category_description ) + self.logout() + self.login( email=common.test_user_1_email, username=common.test_user_1_name ) + repository = self.get_or_create_repository( name=bwa_tool_repository_name, + description=bwa_tool_repository_description, + long_description=bwa_tool_repository_long_description, + owner=common.test_user_1_name, + category_id=self.security.encode_id( category.id ), + strings_displayed=[] ) + self.upload_file( repository, + 'bwa/complex/tool_dependencies.xml', + strings_displayed=[], + commit_message='Uploaded tool_dependencies.xml.' ) + self.display_manage_repository_page( repository, strings_displayed=[ 'Tool dependencies', 'may not be', 'in this repository' ] ) + def test_0010_create_bwa_base_repository( self ): + '''Create and populate bwa_base_0100.''' + category = self.create_category( name=category_name, description=category_description ) + self.logout() + self.login( email=common.test_user_1_email, username=common.test_user_1_name ) + repository = self.get_or_create_repository( name=bwa_base_repository_name, + description=bwa_base_repository_description, + long_description=bwa_base_repository_long_description, + owner=common.test_user_1_name, + category_id=self.security.encode_id( category.id ), + strings_displayed=[] ) + tool_repository = test_db_util.get_repository_by_name_and_owner( bwa_tool_repository_name, common.test_user_1_name ) + self.upload_file( repository, + 'bwa/complex/bwa_base.tar', + strings_displayed=[], + commit_message='Uploaded bwa_base.tar with tool wrapper XML, but without tool dependency XML.' ) + def test_0015_generate_complex_repository_dependency_invalid_shed_url( self ): + '''Generate and upload a complex repository definition that specifies an invalid tool shed URL.''' + dependency_path = self.generate_temp_path( 'test_0100', additional_paths=[ 'complex', 'shed' ] ) + xml_filename = self.get_filename( 'tool_dependencies.xml', filepath=dependency_path ) + repository = test_db_util.get_repository_by_name_and_owner( bwa_base_repository_name, common.test_user_1_name ) + url = 'http://http://this is not an url!' + name = repository.name + owner = repository.user.username + changeset_revision = self.get_repository_tip( repository ) + self.generate_invalid_dependency_xml( xml_filename, url, name, owner, changeset_revision, complex=True, package='bwa', version='0.5.9' ) + strings_displayed = [ 'Invalid tool shed %s defined for repository %s' % ( url, repository.name ) ] + self.upload_file( repository, + 'tool_dependencies.xml', + valid_tools_only=False, + filepath=dependency_path, + commit_message='Uploaded dependency on bwa_tool_0100 with invalid url.', + strings_displayed=strings_displayed ) + def test_0020_generate_complex_repository_dependency_invalid_repository_name( self ): + '''Generate and upload a complex repository definition that specifies an invalid repository name.''' + dependency_path = self.generate_temp_path( 'test_0100', additional_paths=[ 'complex', 'shed' ] ) + xml_filename = self.get_filename( 'tool_dependencies.xml', filepath=dependency_path ) + repository = test_db_util.get_repository_by_name_and_owner( bwa_base_repository_name, common.test_user_1_name ) + url = self.url + name = 'invalid_repository!?' + owner = repository.user.username + changeset_revision = self.get_repository_tip( repository ) + self.generate_invalid_dependency_xml( xml_filename, url, name, owner, changeset_revision, complex=True, package='bwa', version='0.5.9' ) + strings_displayed = 'Ignoring repository dependency definition for tool shed %s, name %s, owner %s' % ( url, name, owner ) + strings_displayed += ', changeset revision %s because the name is invalid.' % changeset_revision + self.upload_file( repository, + 'tool_dependencies.xml', + valid_tools_only=False, + filepath=dependency_path, + commit_message='Uploaded dependency on bwa_tool_0100 with invalid repository name.', + strings_displayed=[ strings_displayed ] ) + def test_0025_generate_complex_repository_dependency_invalid_owner_name( self ): + '''Generate and upload a complex repository definition that specifies an invalid owner.''' + dependency_path = self.generate_temp_path( 'test_0100', additional_paths=[ 'complex', 'shed' ] ) + xml_filename = self.get_filename( 'tool_dependencies.xml', filepath=dependency_path ) + repository = test_db_util.get_repository_by_name_and_owner( bwa_base_repository_name, common.test_user_1_name ) + url = self.url + name = repository.name + owner = 'invalid_owner!?' + changeset_revision = self.get_repository_tip( repository ) + self.generate_invalid_dependency_xml( xml_filename, url, name, owner, changeset_revision, complex=True, package='bwa', version='0.5.9' ) + strings_displayed = [ 'Invalid owner %s defined for repository %s. Repository dependencies will be ignored.' % ( owner, name ) ] + self.upload_file( repository, + 'tool_dependencies.xml', + valid_tools_only=False, + filepath=dependency_path, + commit_message='Uploaded dependency on bwa_tool_0100 with invalid owner.', + strings_displayed=strings_displayed ) + def test_0030_generate_complex_repository_dependency_invalid_changeset_revision( self ): + '''Generate and upload a complex repository definition that specifies an invalid changeset revision.''' + dependency_path = self.generate_temp_path( 'test_0100', additional_paths=[ 'complex', 'shed' ] ) + xml_filename = self.get_filename( 'tool_dependencies.xml', filepath=dependency_path ) + repository = test_db_util.get_repository_by_name_and_owner( bwa_base_repository_name, common.test_user_1_name ) + url = self.url + name = repository.name + owner = repository.user.username + changeset_revision = '1234abcd' + self.generate_invalid_dependency_xml( xml_filename, url, name, owner, changeset_revision, complex=True, package='bwa', version='0.5.9' ) + strings_displayed = 'Ignoring repository dependency definition for tool shed %s, name %s, owner %s' % ( url, name, owner ) + strings_displayed += ', changeset revision %s because the changeset revision is invalid.' % changeset_revision + self.upload_file( repository, + 'tool_dependencies.xml', + valid_tools_only=False, + filepath=dependency_path, + commit_message='Uploaded dependency on bwa_tool_0100 with invalid changeset revision.', + strings_displayed=[ strings_displayed ] ) + def test_0035_generate_complex_repository_dependency( self ): + '''Generate and upload a tool_dependencies.xml file that specifies a repository rather than a tool.''' + base_repository = test_db_util.get_repository_by_name_and_owner( bwa_base_repository_name, common.test_user_1_name ) + tool_repository = test_db_util.get_repository_by_name_and_owner( bwa_tool_repository_name, common.test_user_1_name ) + dependency_path = self.generate_temp_path( 'test_0100', additional_paths=[ 'complex' ] ) + self.create_repository_complex_dependency( base_repository, + self.get_filename( 'tool_dependencies.xml', filepath=dependency_path ), + depends_on=dict( package='bwa', version='0.5.9', repositories=[ tool_repository ] ) ) + self.check_repository_dependency( base_repository, tool_repository ) + self.display_manage_repository_page( base_repository, strings_displayed=[ 'bwa', '0.5.9', 'package' ] ) + def test_0040_update_base_repository( self ): + '''Upload a new tool_dependencies.xml to the tool repository, and verify that the base repository displays the new changeset.''' + base_repository = test_db_util.get_repository_by_name_and_owner( bwa_base_repository_name, common.test_user_1_name ) + tool_repository = test_db_util.get_repository_by_name_and_owner( bwa_tool_repository_name, common.test_user_1_name ) + previous_changeset = self.get_repository_tip( tool_repository ) + self.upload_file( tool_repository, + 'bwa/complex/readme/tool_dependencies.xml', + strings_displayed=[], + commit_message='Uploaded new tool_dependencies.xml.' ) + # Verify that the dependency display has been updated as a result of the new tool_dependencies.xml file. + self.display_manage_repository_page( base_repository, + strings_displayed=[ self.get_repository_tip( tool_repository ), 'bwa', '0.5.9', 'package' ], + strings_not_displayed=[ previous_changeset ] ) + diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 test/tool_shed/functional_tests.py --- a/test/tool_shed/functional_tests.py +++ b/test/tool_shed/functional_tests.py @@ -184,27 +184,27 @@ kwargs[ 'object_store' ] = 'distributed' kwargs[ 'distributed_object_store_config_file' ] = 'distributed_object_store_conf.xml.sample' - toolshedapp = ToolshedUniverseApplication( job_queue_workers = 5, - id_secret = 'changethisinproductiontoo', - template_path = 'templates', - database_connection = toolshed_database_connection, - database_engine_option_pool_size = '10', - file_path = shed_file_path, - new_file_path = new_repos_path, - tool_path=tool_path, - datatype_converters_config_file = 'datatype_converters_conf.xml.sample', - tool_parse_help = False, - tool_data_table_config_path = galaxy_tool_data_table_conf_file, - shed_tool_data_table_config = shed_tool_data_table_conf_file, - log_destination = "stdout", - use_heartbeat = False, - allow_user_creation = True, - allow_user_deletion = True, - admin_users = 'test@bx.psu.edu', - global_conf = global_conf, - running_functional_tests = True, - hgweb_config_dir = hgweb_config_dir, - **kwargs ) + toolshedapp = ToolshedUniverseApplication( admin_users = 'test@bx.psu.edu', + allow_user_creation = True, + allow_user_deletion = True, + database_connection = toolshed_database_connection, + database_engine_option_pool_size = '10', + datatype_converters_config_file = 'datatype_converters_conf.xml.sample', + file_path = shed_file_path, + global_conf = global_conf, + hgweb_config_dir = hgweb_config_dir, + job_queue_workers = 5, + id_secret = 'changethisinproductiontoo', + log_destination = "stdout", + new_file_path = new_repos_path, + running_functional_tests = True, + shed_tool_data_table_config = shed_tool_data_table_conf_file, + template_path = 'templates', + tool_path=tool_path, + tool_parse_help = False, + tool_data_table_config_path = galaxy_tool_data_table_conf_file, + use_heartbeat = False, + **kwargs ) log.info( "Embedded Toolshed application started" ) @@ -269,32 +269,32 @@ galaxy_global_conf = { '__file__' : 'universe_wsgi.ini.sample' } if not galaxy_database_connection.startswith( 'sqlite://' ): kwargs[ 'database_engine_option_max_overflow' ] = '20' - galaxyapp = GalaxyUniverseApplication( job_queue_workers = 5, - id_secret = 'changethisinproductiontoo', - template_path = "templates", - database_connection = galaxy_database_connection, - database_engine_option_pool_size = '10', - file_path = galaxy_file_path, - new_file_path = galaxy_tempfiles, - tool_path = tool_path, - tool_data_path = tool_data_path, - shed_tool_path = galaxy_shed_tool_path, - update_integrated_tool_panel = False, - migrated_tools_config = galaxy_migrated_tool_conf_file, - tool_config_file = [ galaxy_tool_conf_file, galaxy_shed_tool_conf_file ], - tool_sheds_config_file = galaxy_tool_sheds_conf_file, - datatype_converters_config_file = "datatype_converters_conf.xml.sample", - tool_parse_help = False, - tool_data_table_config_path = galaxy_tool_data_table_conf_file, - shed_tool_data_table_config = shed_tool_data_table_conf_file, - log_destination = "stdout", - use_heartbeat = False, - allow_user_creation = True, + galaxyapp = GalaxyUniverseApplication( allow_user_creation = True, allow_user_deletion = True, admin_users = 'test@bx.psu.edu', allow_library_path_paste = True, + database_connection = galaxy_database_connection, + database_engine_option_pool_size = '10', + datatype_converters_config_file = "datatype_converters_conf.xml.sample", + file_path = galaxy_file_path, global_conf = global_conf, + id_secret = 'changethisinproductiontoo', + job_queue_workers = 5, + log_destination = "stdout", + migrated_tools_config = galaxy_migrated_tool_conf_file, + new_file_path = galaxy_tempfiles, running_functional_tests=True, + shed_tool_data_table_config = shed_tool_data_table_conf_file, + shed_tool_path = galaxy_shed_tool_path, + template_path = "templates", + tool_data_path = tool_data_path, + tool_path = tool_path, + tool_config_file = [ galaxy_tool_conf_file, galaxy_shed_tool_conf_file ], + tool_sheds_config_file = galaxy_tool_sheds_conf_file, + tool_parse_help = False, + tool_data_table_config_path = galaxy_tool_data_table_conf_file, + update_integrated_tool_panel = False, + use_heartbeat = False, **kwargs ) log.info( "Embedded Galaxy application started" ) diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 test/tool_shed/test_data/bwa/complex/bwa_base.tar Binary file test/tool_shed/test_data/bwa/complex/bwa_base.tar has changed diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 test/tool_shed/test_data/bwa/complex/readme/tool_dependencies.xml --- /dev/null +++ b/test/tool_shed/test_data/bwa/complex/readme/tool_dependencies.xml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<tool_dependency> + <package name="bwa" version="0.5.9"> + <install version="1.0"> + <actions> + <action type="download_by_url">http://downloads.sourceforge.net/project/bio-bwa/bwa-0.5.9.tar.bz2</action> + <action type="shell_command">make</action> + <action type="move_file"> + <source>bwa</source> + <destination>$INSTALL_DIR/bin</destination> + </action> + <action type="set_environment"> + <environment_variable name="PATH" action="prepend_to">$INSTALL_DIR/bin</environment_variable> + </action> + </actions> + </install> + <readme> +Compiling BWA requires zlib and libpthread to be present on your system. + </readme> + </package> +</tool_dependency> \ No newline at end of file diff -r e5aa9721b16dc30ca7183682c3b2b71c941b738b -r 0ded962ca5d04f86bf61087ab0d5df7cdce41ce9 test/tool_shed/test_data/bwa/complex/tool_dependencies.xml --- /dev/null +++ b/test/tool_shed/test_data/bwa/complex/tool_dependencies.xml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<tool_dependency> + <package name="bwa" version="0.5.9"> + <install version="1.0"> + <actions> + <action type="download_by_url">http://downloads.sourceforge.net/project/bio-bwa/bwa-0.5.9.tar.bz2</action> + <action type="shell_command">make</action> + <action type="move_file"> + <source>bwa</source> + <destination>$INSTALL_DIR/bin</destination> + </action> + <action type="set_environment"> + <environment_variable name="PATH" action="prepend_to">$INSTALL_DIR/bin</environment_variable> + </action> + </actions> + </install> + </package> +</tool_dependency> \ No newline at end of file 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.