1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/8af9e0ac6d2a/ Changeset: 8af9e0ac6d2a User: Dave Bouvier Date: 2013-10-08 22:48:05 Summary: Prevent duplicate lines from being written to an env.sh file when installing a tool dependency or re-running a tool migration script with tool dependencies specified to be installed. Affected #: 3 files diff -r b61927f340f30a636204ec560522acf9b76fd262 -r 8af9e0ac6d2a5fba8e69bd7fb5ae980d7ba1614a lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py --- a/lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py +++ b/lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py @@ -19,12 +19,41 @@ from fabric.api import lcd from fabric.api import local from fabric.api import settings +from fabric.api import hide log = logging.getLogger( __name__ ) INSTALLATION_LOG = 'INSTALLATION.log' VIRTUALENV_URL = 'https://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.9.1.tar.gz' +def add_to_env_shell_file( text, env_shell_file ): + ''' + Append a line to a file, if this line does not already exist in the file. Creates the file and sets the mode to + executable if the file does not exist. Equivalent to a local version of fabric.contrib.files.append. + ''' + if not os.path.exists( env_shell_file ): + local( 'touch %s' % env_shell_file ) + # Explicitly set env.sh executable. + with settings( hide( 'everything' ), warn_only=True ): + local( 'chmod +x %s' % env_shell_file ) + return_code = 0 + # Convert the contents to a list, in order to support adding one or more lines to env.sh. + if isinstance( text, basestring ): + text = [ text ] + for line in text: + # Build a regex to search for the relevant line in env.sh. + regex = td_common_util.egrep_escape( line ) + # If the line exists, egrep will return a success. + with settings( hide( 'everything' ), warn_only=True ): + egrep_cmd = 'egrep "^%s$" %s' % ( regex, env_shell_file ) + contains_line = local( egrep_cmd ).succeeded + if contains_line: + continue + # If not, then append the line, escaping any single quotes in the shell command. + line = line.replace( "'", r"'\\''" ) + return_code = local( "echo '%s' >> %s" % ( line, env_shell_file ) ).return_code + return return_code + def check_fabric_version(): version = env.version if int( version.split( "." )[ 0 ] ) < 1: @@ -301,8 +330,8 @@ for env_var_dict in env_var_dicts: # Check for the presence of the $ENV[] key string and populate it if possible. env_var_dict = handle_environment_variables( app, tool_dependency, install_dir, env_var_dict, cmds ) - env_command = td_common_util.create_or_update_env_shell_file( install_dir, env_var_dict ) - return_code = handle_command( app, tool_dependency, install_dir, env_command ) + env_entry, env_file = td_common_util.create_or_update_env_shell_file( install_dir, env_var_dict ) + return_code = add_to_env_shell_file( env_entry, env_file ) if return_code: return elif action_type == 'set_environment_for_install': @@ -344,13 +373,13 @@ log.error( "virtualenv's site-packages directory '%s' does not exist", output.stdout ) return modify_env_command_dict = dict( name="PYTHONPATH", action="prepend_to", value=output.stdout ) - modify_env_command = td_common_util.create_or_update_env_shell_file( install_dir, modify_env_command_dict ) - return_code = handle_command( app, tool_dependency, install_dir, modify_env_command ) + env_entry, env_file = td_common_util.create_or_update_env_shell_file( install_dir, env_var_dict ) + return_code = add_to_env_shell_file( env_entry, env_file ) if return_code: return modify_env_command_dict = dict( name="PATH", action="prepend_to", value=os.path.join( venv_directory, "bin" ) ) - modify_env_command = td_common_util.create_or_update_env_shell_file( install_dir, modify_env_command_dict ) - return_code = handle_command( app, tool_dependency, install_dir, modify_env_command ) + env_entry, env_file = td_common_util.create_or_update_env_shell_file( install_dir, modify_env_command_dict ) + return_code = add_to_env_shell_file( env_entry, env_file ) if return_code: return elif action_type == 'shell_command': diff -r b61927f340f30a636204ec560522acf9b76fd262 -r 8af9e0ac6d2a5fba8e69bd7fb5ae980d7ba1614a lib/tool_shed/galaxy_install/tool_dependencies/install_util.py --- a/lib/tool_shed/galaxy_install/tool_dependencies/install_util.py +++ b/lib/tool_shed/galaxy_install/tool_dependencies/install_util.py @@ -820,10 +820,10 @@ type='set_environment', status=app.model.ToolDependency.installation_status.INSTALLING, set_status=True ) - cmd = td_common_util.create_or_update_env_shell_file( install_dir, env_var_dict ) + env_entry, env_file = td_common_util.create_or_update_env_shell_file( install_dir, env_var_dict ) if env_var_version == '1.0': # Handle setting environment variables using a fabric method. - fabric_util.handle_command( app, tool_dependency, install_dir, cmd ) + fabric_util.add_to_env_shell_file( env_entry, env_file ) sa_session.refresh( tool_dependency ) if tool_dependency.status != app.model.ToolDependency.installation_status.ERROR: tool_dependency.status = app.model.ToolDependency.installation_status.INSTALLED diff -r b61927f340f30a636204ec560522acf9b76fd262 -r 8af9e0ac6d2a5fba8e69bd7fb5ae980d7ba1614a lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py --- a/lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py +++ b/lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py @@ -1,5 +1,6 @@ import logging import os +import re import shutil import sys import tarfile @@ -170,26 +171,9 @@ changed_value = '%s' % env_var_value elif env_var_action == 'append_to': changed_value = '$%s:%s' % ( env_var_name, env_var_value ) - line = "%s=%s; export %s" % (env_var_name, changed_value, env_var_name) - return create_or_update_env_shell_file_with_command(install_dir, line) - - -def create_or_update_env_shell_file_with_command( install_dir, command ): - """ - Return a shell expression which when executed will create or update - a Galaxy env.sh dependency file in the specified install_dir containing - the supplied command. - """ - env_shell_file_path = '%s/env.sh' % install_dir - if os.path.exists( env_shell_file_path ): - write_action = '>>' - else: - write_action = '>' - cmd = "echo %s %s %s;chmod +x %s" % ( __shellquote(command), - write_action, - __shellquote(env_shell_file_path), - __shellquote(env_shell_file_path)) - return cmd + line = "%s=%s; export %s" % ( env_var_name, changed_value, env_var_name ) + env_shell_file_path = os.path.join( install_dir, 'env.sh' ) + return line, env_shell_file_path def download_binary( url, work_dir ): ''' @@ -199,6 +183,17 @@ dir = url_download( work_dir, downloaded_filename, url, extract=False ) return downloaded_filename +def egrep_escape( text ): + """Escape ``text`` to allow literal matching using egrep.""" + regex = re.escape( text ) + # Seems like double escaping is needed for \ + regex = regex.replace( '\\\\', '\\\\\\' ) + # Triple-escaping seems to be required for $ signs + regex = regex.replace( r'\$', r'\\\$' ) + # Whereas single quotes should not be escaped + regex = regex.replace( r"\'", "'" ) + return regex + def format_traceback(): ex_type, ex, tb = sys.exc_info() return ''.join( traceback.format_tb( tb ) ) 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.