diff --git a/client/galaxy/scripts/mvc/tools/tools-form-base.js b/client/galaxy/scripts/mvc/tools/tools-form-base.js
index 6da95c6efb5..b95a6ce313d 100644
--- a/client/galaxy/scripts/mvc/tools/tools-form-base.js
+++ b/client/galaxy/scripts/mvc/tools/tools-form-base.js
@@ -61,26 +61,20 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
/** Builds a new model through api call and recreates the entire form
*/
_buildModel: function(options, hide_message) {
- // link this
var self = this;
-
- // update current version
this.options.id = options.id;
this.options.version = options.version;
+ // build request url
+ var build_url = '';
+ var build_data = {};
if ( options.job_id ) {
build_url = Galaxy.root + 'api/jobs/' + options.job_id + '/build_for_rerun';
} else {
- var build_url = Galaxy.root + 'api/tools/' + options.id + '/build?';
- if ( options.version ) {
- build_url += 'tool_version=' + options.version + '&';
- }
+ build_url = Galaxy.root + 'api/tools/' + options.id + '/build';
if ( Galaxy.params && Galaxy.params.tool_id == options.id ) {
- _.each( Galaxy.params, function ( item, key ) {
- if ( [ 'tool_version', 'tool_id' ].indexOf( key ) == -1 ) {
- build_url += key + '=' + item + '&';
- }
- } );
+ build_data = $.extend( {}, Galaxy.params );
+ options.version && ( build_data[ 'tool_version' ] = options.version );
}
}
@@ -91,6 +85,7 @@ define(['utils/utils', 'utils/deferred', 'mvc/ui/ui-misc', 'mvc/form/form-view',
Utils.request({
type : 'GET',
url : build_url,
+ data : build_data,
success : function(new_model) {
// rebuild form
self._buildForm(new_model['tool_model'] || new_model);
diff --git a/config/datatypes_conf.xml.sample b/config/datatypes_conf.xml.sample
index 9589a7dfc7e..b7f3b567a86 100644
--- a/config/datatypes_conf.xml.sample
+++ b/config/datatypes_conf.xml.sample
@@ -179,7 +179,7 @@
-
+
diff --git a/doc/source/admin/index.rst b/doc/source/admin/index.rst
index a3abf3d072e..af7df7a4783 100644
--- a/doc/source/admin/index.rst
+++ b/doc/source/admin/index.rst
@@ -9,3 +9,5 @@ documentation. These resources should be used together.
:maxdepth: 3
interactive_environments.rst
+
+ useful_scripts.rst
diff --git a/doc/source/admin/useful_scripts.rst b/doc/source/admin/useful_scripts.rst
new file mode 100644
index 00000000000..5c17ddbcda8
--- /dev/null
+++ b/doc/source/admin/useful_scripts.rst
@@ -0,0 +1,19 @@
+Useful Scripts and Administration Tricks
+========================================
+
+This page aims to help ease the burden of administration with some easy to use scripts and documentation on what is available for admins to use.
+
+Uploading a directory into a Data Library
+-----------------------------------------
+
+Data libraries can really ease the use of Galaxy for your administrators and end users. They provide a form of shared folders that users can copy datasets from into their history.
+
+This script was developed to be as general as possible, allowing you to pipe the output of a much more complex find command to this script, uploading all of the files into a data library:
+
+.. code-block:: console
+
+ $ find /path/to/sequencing-data/ -name '*.fastq' -or -name '*.fa' | python $GALAXY_ROOT/scripts/api/library_upload_dir.py
+
+Find has an extremely expressive command line for selecting specific files that are of interest to you. These will then be recursively uploaded into Galaxy, maintaining the folder hierarchy, a useful feature when moving legacy data into Galaxy. For a complete description of the options of this script, you can run ``python $GALAXY_ROOT/scripts/api/library_upload_dir.py --help``
+
+This tool will not overwrite or re-upload already uploaded datasets. As a result, one can imagine running this on a cron job to keep an "incoming sequencing data" directory synced with a data library.
diff --git a/doc/source/dev/faq.rst b/doc/source/dev/faq.rst
index d8883d7e82c..e60a0a9eea8 100644
--- a/doc/source/dev/faq.rst
+++ b/doc/source/dev/faq.rst
@@ -2,7 +2,7 @@ How Do I...
===========
This section contains a number of smaller topics with links and examples meant
-to provide relatively concrete answers for specific tool development scenarios.
+to provide relatively concrete answers for specific Galaxy development scenarios.
... interact with the Galaxy codebase interactively?
----------------------------------------------------
diff --git a/lib/galaxy/datatypes/binary.py b/lib/galaxy/datatypes/binary.py
index 4496a72c6e4..6664cebe576 100644
--- a/lib/galaxy/datatypes/binary.py
+++ b/lib/galaxy/datatypes/binary.py
@@ -1053,3 +1053,56 @@ class OxliGraphLabels(OxliBinary):
Binary.register_sniffable_binary_format("oxli.graphlabels", "oxligl",
OxliGraphLabels)
+
+
+class SearchGuiArchive ( CompressedArchive ):
+ """Class describing a SearchGUI archive """
+ MetadataElement( name="searchgui_version", default='1.28.0' , param=MetadataParameter, desc="SearchGui Version",
+ readonly=True, visible=True, no_value=None )
+ MetadataElement( name="searchgui_major_version", default='1' , param=MetadataParameter, desc="SearchGui Major Version",
+ readonly=True, visible=True, no_value=None )
+ file_ext = "searchgui_archive"
+
+ def set_meta( self, dataset, overwrite=True, **kwd ):
+ super( SearchGuiArchive, self ).set_meta( dataset, overwrite=overwrite, **kwd )
+ try:
+ if dataset and zipfile.is_zipfile( dataset.file_name ):
+ tempzip = zipfile.ZipFile( dataset.file_name )
+ if 'searchgui.properties' in tempzip.namelist():
+ fh = tempzip.open('searchgui.properties')
+ for line in fh:
+ if line.startswith('searchgui.version'):
+ version = line.split('=')[1].strip()
+ dataset.metadata.searchgui_version = version
+ dataset.metadata.searchgui_major_version = version.split('.')[0]
+ fh.close()
+ tempzip.close()
+ except Exception as e:
+ log.warn( '%s, set_meta Exception: %s', self, e )
+
+ def sniff( self, filename ):
+ try:
+ if filename and zipfile.is_zipfile( filename ):
+ tempzip = zipfile.ZipFile( filename, 'r' )
+ is_searchgui = 'searchgui.properties' in tempzip.namelist()
+ tempzip.close()
+ return is_searchgui
+ except Exception as e:
+ log.warn( '%s, sniff Exception: %s', self, e )
+ return False
+
+ def set_peek( self, dataset, is_multi_byte=False ):
+ if not dataset.dataset.purged:
+ dataset.peek = "SearchGUI Archive, version %s" % ( dataset.metadata.searchgui_version or 'unknown' )
+ dataset.blurb = nice_size( dataset.get_size() )
+ else:
+ dataset.peek = 'file does not exist'
+ dataset.blurb = 'file purged from disk'
+
+ def display_peek( self, dataset ):
+ try:
+ return dataset.peek
+ except:
+ return "SearchGUI Archive, version %s" % ( dataset.metadata.searchgui_version or 'unknown' )
+
+Binary.register_sniffable_binary_format("searchgui_archive", "searchgui_archive", SearchGuiArchive)
diff --git a/lib/galaxy/tools/loader_directory.py b/lib/galaxy/tools/loader_directory.py
index 8b473a93ee7..b8ea6e6074c 100644
--- a/lib/galaxy/tools/loader_directory.py
+++ b/lib/galaxy/tools/loader_directory.py
@@ -1,5 +1,6 @@
import glob
import os
+import re
from ..tools import loader
import sys
@@ -9,6 +10,7 @@ log = logging.getLogger(__name__)
PATH_DOES_NOT_EXIST_ERROR = "Could not load tools from path [%s] - this path does not exist."
LOAD_FAILURE_ERROR = "Failed to load tool with path %s."
+TOOL_REGEX = re.compile(r"
@@ -163,6 +165,10 @@ class RemoteUser( object ):
# The API handles its own authentication via keys
return self.app( environ, start_response )
else:
+ log.debug("Unable to identify user. %s not found" % self.remote_user_header)
+ for k, v in environ.iteritems():
+ log.debug("%s = %s" , k, v)
+
title = "Access to Galaxy is denied"
message = """
Galaxy is configured to authenticate users via an external
diff --git a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
index dbcc1e3f3ec..5a4eb6a4359 100755
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
@@ -53,7 +53,7 @@ class CompressedFile( object ):
def extract( self, path ):
'''Determine the path to which the archive should be extracted.'''
contents = self.getmembers()
- extraction_path = os.path.join( path )
+ extraction_path = path
common_prefix = ''
if len( contents ) == 1:
# The archive contains a single file, return the extraction path.
@@ -84,8 +84,11 @@ class CompressedFile( object ):
external_attributes = self.archive.getinfo( filename ).external_attr
# The 2 least significant bytes are irrelevant, the next two contain unix permissions.
unix_permissions = external_attributes >> 16
- if unix_permissions != 0 and os.path.exists( absolute_filepath ):
- os.chmod( absolute_filepath, unix_permissions )
+ if unix_permissions != 0:
+ if os.path.exists( absolute_filepath ):
+ os.chmod( absolute_filepath, unix_permissions )
+ else:
+ log.warn("Unable to change permission on extracted file '%s' as it does not exist" % absolute_filepath)
return os.path.abspath( os.path.join( extraction_path, common_prefix ) )
def getmembers_tar( self ):
@@ -1372,7 +1375,7 @@ class SetupREnvironment( Download, RecipeStep ):
# Use raw strings so that python won't automatically unescape the quotes before passing the command
# to subprocess.Popen.
cmd = r'''PATH=$PATH:$R_HOME/bin; export PATH; R_LIBS=$INSTALL_DIR:$R_LIBS; export R_LIBS;
- Rscript -e "tryCatch( install.packages(c('%s'),lib='$INSTALL_DIR', repos=NULL, dependencies=FALSE), error = quit(status = 1))"''' % \
+ Rscript -e "tryCatch( { install.packages(c('%s'), lib = '$INSTALL_DIR', repos = NULL, dependencies = FALSE) }, error = function(e) { print(e); quit(status = 1) }, warning = function(w) { if ( grepl('had non-zero exit status|is not writable|installation of one of more packages failed', as.character(w)) ) { print(w); quit(status = 1) } } )"''' % \
( str( tarball_name ) )
cmd = install_environment.build_command( basic_util.evaluate_template( cmd, install_environment ) )
return_code = install_environment.handle_command( tool_dependency=tool_dependency,
diff --git a/run_tests.sh b/run_tests.sh
index 7eb8a44269a..8119950f727 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -3,8 +3,6 @@
pwd_dir=$(pwd)
cd `dirname $0`
-./scripts/common_startup.sh
-
# A good place to look for nose info: http://somethingaboutorange.com/mrl/projects/nose/
rm -f run_functional_tests.log
@@ -72,6 +70,8 @@ ensure_grunt() {
}
+DOCKER_DEFAULT_IMAGE='galaxy/testing-base:15.10.0'
+
test_script="./scripts/functional_tests.py"
report_file="run_functional_tests.html"
xunit_report_file=""
@@ -85,7 +85,7 @@ then
shift
DOCKER_EXTRA_ARGS=${DOCKER_ARGS:-""}
DOCKER_RUN_EXTRA_ARGS=${DOCKER_RUN_EXTRA_ARGS:-""}
- DOCKER_IMAGE=${DOCKER_IMAGE:-"galaxy/testing-base"}
+ DOCKER_IMAGE=${DOCKER_IMAGE:-${DOCKER_DEFAULT_IMAGE}}
if [ "$1" = "--db" ]; then
db_type=$2
shift 2
@@ -286,6 +286,12 @@ do
watch=1
shift
;;
+ --skip-common-startup)
+ # Don't run ./scripts/common_startup.sh (presumably it has already
+ # been done, or you know what you're doing).
+ skip_common_startup=1
+ shift
+ ;;
--)
shift
break
@@ -301,6 +307,10 @@ do
esac
done
+if [ -z "$skip_common_startup" ]; then
+ ./scripts/common_startup.sh
+fi
+
if [ -n "$migrated_test" ] ; then
[ -n "$test_id" ] && class=":TestForTool_$test_id" || class=""
extra_args="functional.test_toolbox$class -migrated"
diff --git a/scripts/api/library_upload_dir.py b/scripts/api/library_upload_dir.py
new file mode 100644
index 00000000000..9e9b34322b7
--- /dev/null
+++ b/scripts/api/library_upload_dir.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+import sys
+import argparse
+import os
+from bioblend import galaxy
+
+
+class Uploader:
+
+ def __init__(self, url, api, library_id, folder_id, should_link,
+ non_local):
+ self.gi = galaxy.GalaxyInstance(url=url, key=api)
+ self.library_id = library_id
+ self.folder_id = folder_id
+ self.should_link = should_link
+ self.non_local = non_local
+
+ self.memo_path = {}
+ self.prepopulate_memo()
+
+ def prepopulate_memo(self):
+ """
+ Because the Galaxy Data Libraries API/system does not act like any
+ other file system in existence, and allows multiple files/folders with
+ identical names in the same parent directory, we have to prepopulate
+ the memoization cache with everything currently in the target
+ directory.
+
+ Because the Galaxy Data Libraries API does not work from a perspective
+ of "show me what is in this directory", we are forced to get the entire
+ contents of the data library, and then filter out things that are
+ interesting to us based on a folder prefix.
+ """
+ existing = self.gi.libraries.show_library(self.library_id, contents=True)
+
+ uploading_to = [x for x in existing if x['id'] == self.folder_id]
+ if len(uploading_to) == 0:
+ raise Exception("Unknown folder [%s] in library [%s]" %
+ (self.folder_id, self.library_id))
+ else:
+ uploading_to = uploading_to[0]
+
+ for x in existing:
+ # We only care if it's a subdirectory of where we're uploading to
+ if not x['name'].startswith(uploading_to['name']):
+ continue
+
+ name_part = x['name'].split(uploading_to['name'], 1)[-1]
+ if name_part.startswith('/'):
+ name_part = name_part[1:]
+ self.memo_path[name_part] = x['id']
+
+ def memoized_path(self, path_parts, base_folder=None):
+ """Get the folder ID for a given folder path specified by path_parts.
+
+ If the folder does not exist, it will be created ONCE (during the
+ instantiation of this Uploader object). After that it is stored and
+ recycled. If the Uploader object is re-created, it is not aware of
+ previously existing paths and will not respect those. TODO: handle
+ existing paths.
+ """
+ if base_folder is None:
+ base_folder = self.folder_id
+ dropped_prefix = []
+
+ fk = '/'.join(path_parts)
+ if fk in self.memo_path:
+ # print "Cache hit %s" % fk
+ return self.memo_path[fk]
+ else:
+ # print "Cache miss %s" % fk
+ for i in reversed(range(len(path_parts))):
+ fk = '/'.join(path_parts[0:i + 1])
+ if fk in self.memo_path:
+ # print "Parent folder hit %s" % fk
+ dropped_prefix = path_parts[0:i + 1]
+ path_parts = path_parts[i + 1:]
+ base_folder = self.memo_path[fk]
+ break
+
+ nfk = []
+ for i in range(len(path_parts)):
+ nfk.append('/'.join(list(dropped_prefix) + list(path_parts[0:i + 1])))
+
+ # Recursively create the path from our base_folder starting points,
+ # gettting the IDs of each folder per path component
+ ids = self.recursively_build_path(path_parts, base_folder)
+
+ # These are then associated with the paths.
+ for (key, fid) in zip(nfk, ids):
+ self.memo_path[key] = fid
+ return ids[-1]
+
+ def recursively_build_path(self, path_parts, parent_folder_id, ids=None):
+ """Given an iterable of path components and a parent folder id, recursively
+ create directories below parent_folder_id"""
+ if ids is None:
+ ids = []
+ if len(path_parts) == 0:
+ return ids
+ else:
+ pf = self.gi.libraries.create_folder(self.library_id, path_parts[0], base_folder_id=parent_folder_id)
+ ids.append(pf[0]['id'])
+ # print "create_folder(%s, %s, %s) = %s" % (self.library_id, path_parts[0], parent_folder_id, pf[0]['id'])
+ return self.recursively_build_path(path_parts[1:], pf[0]['id'], ids=ids)
+
+ # http://stackoverflow.com/questions/13505819/python-split-path-recursively/13505966#13505966
+ def rec_split(self, s):
+ if s == '/':
+ return ()
+
+ rest, tail = os.path.split(s)
+ if tail == '.':
+ return ()
+ if rest == '':
+ return tail,
+ return self.rec_split(rest) + (tail,)
+
+ def upload(self):
+ all_files = [x.strip() for x in list(sys.stdin.readlines())]
+
+ for idx, path in enumerate(all_files):
+ (dirName, fname) = path.rsplit(os.path.sep, 1)
+ if not os.path.exists(os.path.join(dirName, fname)):
+ continue
+ # Figure out what the memo key will be early
+ basepath = self.rec_split(dirName)
+ if len(basepath) == 0:
+ memo_key = fname
+ else:
+ memo_key = os.path.join(os.path.join(*basepath), fname)
+
+ # So that we can check if it really needs to be uploaded.
+ already_uploaded = memo_key in self.memo_path.keys()
+ fid = self.memoized_path(basepath, base_folder=self.folder_id)
+ print('[%s/%s] %s/%s uploaded=%' % (idx + 1, len(all_files), fid, fname, already_uploaded))
+
+ if not already_uploaded:
+ if self.non_local:
+ self.gi.libraries.upload_file_from_local_path(
+ self.library_id,
+ os.path.join(dirName, fname),
+ folder_id=fid,
+ )
+ else:
+ self.gi.libraries.upload_from_galaxy_filesystem(
+ self.library_id,
+ os.path.join(dirName, fname),
+ folder_id=fid,
+ link_data_only='link_to_files' if self.should_link else 'copy_files',
+ )
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(description='Upload a directory into a data library')
+ parser.add_argument( "-u", "--url", dest="url", required=True, help="Galaxy URL" )
+ parser.add_argument( "-a", "--api", dest="api", required=True, help="API Key" )
+
+ parser.add_argument( "-l", "--lib", dest="library_id", required=True, help="Library ID" )
+ parser.add_argument( "-f", "--folder", dest="folder_id", help="Folder ID. If not specified, will go to root of library." )
+
+ parser.add_argument( "--nonlocal", dest="non_local", action="store_true", default=False,
+ help="Set this flag if you are NOT running this script on your Galaxy head node with access to the full filesystem" )
+ parser.add_argument( "--link", dest="should_link", action="store_true", default=False,
+ help="Link datasets only, do not upload to Galaxy. ONLY Avaialble if you run 'locally' relative to your Galaxy head node/filesystem ")
+ args = parser.parse_args()
+
+ u = Uploader(**vars(args))
+ u.upload()
diff --git a/static/maps/mvc/tools/tools-form-base.js.map b/static/maps/mvc/tools/tools-form-base.js.map
index c63d473ca51..4d6cdc3c810 100644
--- a/static/maps/mvc/tools/tools-form-base.js.map
+++ b/static/maps/mvc/tools/tools-form-base.js.map
@@ -1 +1 @@
-{"version":3,"file":"tools-form-base.js","sources":["../../../src/mvc/tools/tools-form-base.js"],"names":["define","Utils","Deferred","Ui","Form","ToolTemplate","CitationModel","CitationView","Backbone","View","extend","initialize","options","this","merge","setElement","deferred","inputs","_buildForm","_buildModel","self","icon","title","name","description","version","operations","_operations","onchange","reset","execute","_updateModel","customize","form","_footer","$el","empty","append","hide_message","id","job_id","build_url","Galaxy","root","params","tool_id","_","each","item","key","indexOf","process_id","register","request","type","url","success","new_model","message","update","status","persistent","done","console","debug","error","response","error_message","err_msg","is","prepend","Message","large","modal","show","body","buttons","Close","hide","model_url","update_url","current_state","tool_version","$","data","create","wait","versions_button","ButtonMenu","narrow","tooltip","is_workflow","versions","length","i","addMenu","onclick","replace","menu_button","biostar_url","window","open","prompt","location","origin","user","get","href","requirements","visible","sharable_url","menu","help","citations","$citations","ToolCitationCollection","citation_list_view","CitationListView","el","collection","render","fetch"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"tools-form-base.js","sources":["../../../src/mvc/tools/tools-form-base.js"],"names":["define","Utils","Deferred","Ui","Form","ToolTemplate","CitationModel","CitationView","Backbone","View","extend","initialize","options","this","merge","setElement","deferred","inputs","_buildForm","_buildModel","self","icon","title","name","description","version","operations","_operations","onchange","reset","execute","_updateModel","customize","form","_footer","$el","empty","append","hide_message","id","build_url","build_data","job_id","Galaxy","root","params","tool_id","$","process_id","register","request","type","url","data","success","new_model","message","update","status","persistent","done","console","debug","error","response","error_message","err_msg","is","prepend","Message","large","modal","show","body","buttons","Close","hide","model_url","update_url","current_state","tool_version","create","wait","versions_button","ButtonMenu","narrow","tooltip","is_workflow","versions","length","i","addMenu","onclick","replace","menu_button","biostar_url","window","open","prompt","location","origin","user","get","href","requirements","visible","sharable_url","menu","help","citations","$citations","ToolCitationCollection","citation_list_view","CitationListView","el","collection","render","fetch"],"mappings":"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"}
\ No newline at end of file
diff --git a/static/scripts/mvc/tools/tools-form-base.js b/static/scripts/mvc/tools/tools-form-base.js
index a314ec10bec..432fe1eb12a 100644
--- a/static/scripts/mvc/tools/tools-form-base.js
+++ b/static/scripts/mvc/tools/tools-form-base.js
@@ -1,2 +1,2 @@
-define(["utils/utils","utils/deferred","mvc/ui/ui-misc","mvc/form/form-view","mvc/tools/tools-template","mvc/citation/citation-model","mvc/citation/citation-view"],function(a,b,c,d,e,f,g){return Backbone.View.extend({initialize:function(c){this.options=a.merge(c,{}),this.setElement(""),this.deferred=new b,c.inputs?this._buildForm(c):this._buildModel(c,!0)},_buildForm:function(b){var c=this;this.options=a.merge(b,this.options),this.options=a.merge({icon:"fa-wrench",title:""+b.name+" "+b.description+" (Galaxy Tool Version "+b.version+")",operations:this._operations(),onchange:function(){c.deferred.reset(),c.deferred.execute(function(){c._updateModel()})}},this.options),this.options.customize&&this.options.customize(this.options),this.form=new d(this.options),this._footer(),this.$el.empty(),this.$el.append(this.form.$el)},_buildModel:function(b,d){var e=this;if(this.options.id=b.id,this.options.version=b.version,b.job_id)f=Galaxy.root+"api/jobs/"+b.job_id+"/build_for_rerun";else{var f=Galaxy.root+"api/tools/"+b.id+"/build?";b.version&&(f+="tool_version="+b.version+"&"),Galaxy.params&&Galaxy.params.tool_id==b.id&&_.each(Galaxy.params,function(a,b){-1==["tool_version","tool_id"].indexOf(b)&&(f+=b+"="+a+"&")})}var g=this.deferred.register();a.request({type:"GET",url:f,success:function(a){e._buildForm(a.tool_model||a),!d&&e.form.message.update({status:"success",message:"Now you are using '"+e.options.name+"' version "+e.options.version+".",persistent:!1}),e.deferred.done(g),console.debug("tools-form::initialize() - Initial tool model ready."),console.debug(a)},error:function(a){e.deferred.done(g),console.debug("tools-form::initialize() - Initial tool model request failed."),console.debug(a);var b=a&&a.err_msg||"Uncaught error.";e.$el.is(":empty")?e.$el.prepend(new c.Message({message:b,status:"danger",persistent:!0,large:!0}).$el):Galaxy.modal.show({title:"Tool request failed",body:b,buttons:{Close:function(){Galaxy.modal.hide()}}})}})},_updateModel:function(){var b=this.options.update_url||Galaxy.root+"api/tools/"+this.options.id+"/build",c=this,d=this.form,e={tool_id:this.options.id,tool_version:this.options.version,inputs:$.extend(!0,{},c.form.data.create())};d.wait(!0);var f=this.deferred.register();console.debug("tools-form-base::_updateModel() - Sending current state (see below)."),console.debug(e),a.request({type:"POST",url:b,data:e,success:function(a){c.form.update(a.tool_model||a),c.options.update&&c.options.update(a),d.wait(!1),console.debug("tools-form-base::_updateModel() - Received new model (see below)."),console.debug(a),c.deferred.done(f)},error:function(a){c.deferred.done(f),console.debug("tools-form-base::_updateModel() - Refresh request failed."),console.debug(a)}})},_operations:function(){var a=this,b=this.options,d=new c.ButtonMenu({icon:"fa-cubes",title:!b.narrow&&"Versions"||null,tooltip:"Select another tool version"});if(!b.is_workflow&&b.versions&&b.versions.length>1)for(var f in b.versions){var g=b.versions[f];g!=b.version&&d.addMenu({title:"Switch to "+g,version:g,icon:"fa-cube",onclick:function(){var c=b.id.replace(b.version,this.version),d=this.version;a.deferred.reset(),a.deferred.execute(function(){a._buildModel({id:c,version:d})})}})}else d.$el.hide();var h=new c.ButtonMenu({icon:"fa-caret-down",title:!b.narrow&&"Options"||null,tooltip:"View available options"});return b.biostar_url&&(h.addMenu({icon:"fa-question-circle",title:"Question?",tooltip:"Ask a question about this tool (Biostar)",onclick:function(){window.open(b.biostar_url+"/p/new/post/")}}),h.addMenu({icon:"fa-search",title:"Search",tooltip:"Search help for this tool (Biostar)",onclick:function(){window.open(b.biostar_url+"/local/search/page/?q="+b.name)}})),h.addMenu({icon:"fa-share",title:"Share",tooltip:"Share this tool",onclick:function(){prompt("Copy to clipboard: Ctrl+C, Enter",window.location.origin+Galaxy.root+"root?tool_id="+b.id)}}),Galaxy.user&&Galaxy.user.get("is_admin")&&h.addMenu({icon:"fa-download",title:"Download",tooltip:"Download this tool",onclick:function(){window.location.href=Galaxy.root+"api/tools/"+b.id+"/download"}}),b.requirements&&b.requirements.length>0&&h.addMenu({icon:"fa-info-circle",title:"Requirements",tooltip:"Display tool requirements",onclick:function(){this.visible?(this.visible=!1,a.form.message.update({message:""})):(this.visible=!0,a.form.message.update({persistent:!0,message:e.requirements(b),status:"info"}))}}),b.sharable_url&&h.addMenu({icon:"fa-external-link",title:"See in Tool Shed",tooltip:"Access the repository",onclick:function(){window.open(b.sharable_url)}}),{menu:h,versions:d}},_footer:function(){var a=this.options;if(""!=a.help&&this.form.$el.append(e.help(a)),a.citations){var b=$(""),c=new f.ToolCitationCollection;c.tool_id=a.id;var d=new g.CitationListView({el:b,collection:c});d.render(),c.fetch(),this.form.$el.append(b)}}})});
+define(["utils/utils","utils/deferred","mvc/ui/ui-misc","mvc/form/form-view","mvc/tools/tools-template","mvc/citation/citation-model","mvc/citation/citation-view"],function(a,b,c,d,e,f,g){return Backbone.View.extend({initialize:function(c){this.options=a.merge(c,{}),this.setElement(""),this.deferred=new b,c.inputs?this._buildForm(c):this._buildModel(c,!0)},_buildForm:function(b){var c=this;this.options=a.merge(b,this.options),this.options=a.merge({icon:"fa-wrench",title:""+b.name+" "+b.description+" (Galaxy Tool Version "+b.version+")",operations:this._operations(),onchange:function(){c.deferred.reset(),c.deferred.execute(function(){c._updateModel()})}},this.options),this.options.customize&&this.options.customize(this.options),this.form=new d(this.options),this._footer(),this.$el.empty(),this.$el.append(this.form.$el)},_buildModel:function(b,d){var e=this;this.options.id=b.id,this.options.version=b.version;var f="",g={};b.job_id?f=Galaxy.root+"api/jobs/"+b.job_id+"/build_for_rerun":(f=Galaxy.root+"api/tools/"+b.id+"/build",Galaxy.params&&Galaxy.params.tool_id==b.id&&(g=$.extend({},Galaxy.params),b.version&&(g.tool_version=b.version)));var h=this.deferred.register();a.request({type:"GET",url:f,data:g,success:function(a){e._buildForm(a.tool_model||a),!d&&e.form.message.update({status:"success",message:"Now you are using '"+e.options.name+"' version "+e.options.version+".",persistent:!1}),e.deferred.done(h),console.debug("tools-form::initialize() - Initial tool model ready."),console.debug(a)},error:function(a){e.deferred.done(h),console.debug("tools-form::initialize() - Initial tool model request failed."),console.debug(a);var b=a&&a.err_msg||"Uncaught error.";e.$el.is(":empty")?e.$el.prepend(new c.Message({message:b,status:"danger",persistent:!0,large:!0}).$el):Galaxy.modal.show({title:"Tool request failed",body:b,buttons:{Close:function(){Galaxy.modal.hide()}}})}})},_updateModel:function(){var b=this.options.update_url||Galaxy.root+"api/tools/"+this.options.id+"/build",c=this,d=this.form,e={tool_id:this.options.id,tool_version:this.options.version,inputs:$.extend(!0,{},c.form.data.create())};d.wait(!0);var f=this.deferred.register();console.debug("tools-form-base::_updateModel() - Sending current state (see below)."),console.debug(e),a.request({type:"POST",url:b,data:e,success:function(a){c.form.update(a.tool_model||a),c.options.update&&c.options.update(a),d.wait(!1),console.debug("tools-form-base::_updateModel() - Received new model (see below)."),console.debug(a),c.deferred.done(f)},error:function(a){c.deferred.done(f),console.debug("tools-form-base::_updateModel() - Refresh request failed."),console.debug(a)}})},_operations:function(){var a=this,b=this.options,d=new c.ButtonMenu({icon:"fa-cubes",title:!b.narrow&&"Versions"||null,tooltip:"Select another tool version"});if(!b.is_workflow&&b.versions&&b.versions.length>1)for(var f in b.versions){var g=b.versions[f];g!=b.version&&d.addMenu({title:"Switch to "+g,version:g,icon:"fa-cube",onclick:function(){var c=b.id.replace(b.version,this.version),d=this.version;a.deferred.reset(),a.deferred.execute(function(){a._buildModel({id:c,version:d})})}})}else d.$el.hide();var h=new c.ButtonMenu({icon:"fa-caret-down",title:!b.narrow&&"Options"||null,tooltip:"View available options"});return b.biostar_url&&(h.addMenu({icon:"fa-question-circle",title:"Question?",tooltip:"Ask a question about this tool (Biostar)",onclick:function(){window.open(b.biostar_url+"/p/new/post/")}}),h.addMenu({icon:"fa-search",title:"Search",tooltip:"Search help for this tool (Biostar)",onclick:function(){window.open(b.biostar_url+"/local/search/page/?q="+b.name)}})),h.addMenu({icon:"fa-share",title:"Share",tooltip:"Share this tool",onclick:function(){prompt("Copy to clipboard: Ctrl+C, Enter",window.location.origin+Galaxy.root+"root?tool_id="+b.id)}}),Galaxy.user&&Galaxy.user.get("is_admin")&&h.addMenu({icon:"fa-download",title:"Download",tooltip:"Download this tool",onclick:function(){window.location.href=Galaxy.root+"api/tools/"+b.id+"/download"}}),b.requirements&&b.requirements.length>0&&h.addMenu({icon:"fa-info-circle",title:"Requirements",tooltip:"Display tool requirements",onclick:function(){this.visible?(this.visible=!1,a.form.message.update({message:""})):(this.visible=!0,a.form.message.update({persistent:!0,message:e.requirements(b),status:"info"}))}}),b.sharable_url&&h.addMenu({icon:"fa-external-link",title:"See in Tool Shed",tooltip:"Access the repository",onclick:function(){window.open(b.sharable_url)}}),{menu:h,versions:d}},_footer:function(){var a=this.options;if(""!=a.help&&this.form.$el.append(e.help(a)),a.citations){var b=$(""),c=new f.ToolCitationCollection;c.tool_id=a.id;var d=new g.CitationListView({el:b,collection:c});d.render(),c.fetch(),this.form.$el.append(b)}}})});
//# sourceMappingURL=../../../maps/mvc/tools/tools-form-base.js.map
\ No newline at end of file
diff --git a/test/docker/base/run_test_wrapper.sh b/test/docker/base/run_test_wrapper.sh
index 538bac763c2..95851ba2b92 100644
--- a/test/docker/base/run_test_wrapper.sh
+++ b/test/docker/base/run_test_wrapper.sh
@@ -7,7 +7,7 @@ then
su -c '/usr/lib/postgresql/9.3/bin/pg_ctl -o "-F" start -D /opt/galaxy/db' postgres
sleep 3
GALAXY_TEST_INSTALL_DB_MERGED="true"
- GALAXY_TEST_DBURI="postgres://root@localhost:5930/galaxy"
+ GALAXY_TEST_DBURI="postgres://root@localhost:5930/galaxy?client_encoding=utf8"
TOOL_SHED_TEST_DBURI="postgres://root@localhost:5930/toolshed"
elif [ "$GALAXY_TEST_DATABASE_TYPE" = "mysql" ];
then
@@ -32,11 +32,16 @@ cd /galaxy
GALAXY_CONFIG_OVERRIDE_DATABASE_CONNECTION="$GALAXY_TEST_DBURI";
export GALAXY_CONFIG_OVERRIDE_DATABASE_CONNECTION
+./scripts/common_startup.sh || { echo "common_startup.sh failed"; exit 1; }
+
+dev_requirements=./lib/galaxy/dependencies/dev-requirements.txt
+[ -f $dev_requirements ] && ./.venv/bin/pip install -r $dev_requirements
+
sh manage_db.sh upgrade
if [ -z "$GALAXY_NO_TESTS" ];
then
- sh run_tests.sh $@
+ sh run_tests.sh --skip-common-startup $@
else
GALAXY_CONFIG_MASTER_API_KEY=${GALAXY_CONFIG_MASTER_API_KEY:-"testmasterapikey"}
GALAXY_CONFIG_FILE=${GALAXY_CONFIG_FILE:-config/galaxy.ini.sample}