set error on exit for foriegn shelles

This commit is contained in:
Anthony Scopatz 2016-05-07 16:29:48 -04:00
parent 33785dd9b0
commit 6c2940d8cf
2 changed files with 61 additions and 42 deletions

View file

@ -3,17 +3,17 @@ Static Configuration File
In addition to the run control file, xonsh allows you to have a static config file.
This JSON-formatted file lives at ``$XONSH_CONFIG_DIR/config.json``, which is
normally ``~/.config/xonsh/config.json``. The purpose of this file is to allow
users to set runtime parameters *before* anything else happens. This includes
users to set runtime parameters *before* anything else happens. This includes
loading data from various foreign shells or setting critical environment
variables.
This is a dictionary or JSON object at its top-level. It has the following
This is a dictionary or JSON object at its top-level. It has the following
top-level keys. All top-level keys are optional.
``env``
--------
This is a simple string-keyed dictionary that lets you set environment
variables. For example,
This is a simple string-keyed dictionary that lets you set environment
variables. For example,
.. code:: json
@ -28,9 +28,9 @@ variables. For example,
--------------------
This is a list (JSON Array) of dicts (JSON objects) that represent the
foreign shells to inspect for extra start up information, such as environment
variables, aliases, and foreign shell functions. The suite of data gathered
variables, aliases, and foreign shell functions. The suite of data gathered
may be expanded in the future. Each shell dictionary unpacked and passed into
the ``xonsh.foreign_shells.foreign_shell_data()`` function. Thus, these
the ``xonsh.foreign_shells.foreign_shell_data()`` function. Thus, these
dictionaries have the following structure:
:shell: *str, required* - The name or path of the shell, such as "bash" or "/bin/sh".
@ -42,27 +42,34 @@ dictionaries have the following structure:
``default="env"``
:aliascmd: *str, optional* - The command to generate alais output with.
``default="alias"``
:extra_args: *list of str, optional* - Addtional command line options to pass
:extra_args: *list of str, optional* - Addtional command line options to pass
into the shell. ``default=[]``
:currenv: *dict or null, optional* - Manual override for the current environment.
``default=null``
:safe: *bool, optional* - Flag for whether or not to safely handle exceptions
:safe: *bool, optional* - Flag for whether or not to safely handle exceptions
and other errors. ``default=true``
:prevcmd: *str, optional* - An additional command or script to run before
anything else, useful for sourcing and other commands that may require
:prevcmd: *str, optional* - An additional command or script to run before
anything else, useful for sourcing and other commands that may require
environment recovery. ``default=''``
:postcmd: *str, optional* - A command to run after everything else, useful for
cleaning up any damage that the ``prevcmd`` may have caused. ``default=''``
:funcscmd: *str or None, optional* - This is a command or script that can be
:funcscmd: *str or None, optional* - This is a command or script that can be
used to determine the names and locations of any functions that are native
to the foreign shell. This command should print *only* a whitespace
to the foreign shell. This command should print *only* a whitespace
separated sequence of pairs function name & filenames where the functions
are defined. If this is None (null), then a default script will attempted
to be looked up based on the shell name. Callable wrappers for these
to be looked up based on the shell name. Callable wrappers for these
functions will be returned in the aliases dictionary. ``default=null``
:sourcer: *str or None, optional* - How to source a foreign shell file for
purposes of calling functions in that shell. If this is None, a default
:sourcer: *str or None, optional* - How to source a foreign shell file for
purposes of calling functions in that shell. If this is None, a default
value will attempt to be looked up based on the shell name. ``default=null``
:runcmd : *str or None, optional* - Command line switches to use when
running the script, such as ``-c`` for Bash and ``/C`` for cmd.exe.
``default=null``
:seterrcmd : *str or None, optional* - Command that enables exit-on-error
for the shell. For example, this is "set -e" in Bash. To disable
exit-on-error behavior, simply pass in an empty string. ``default=null``
Some examples can be seen below:
@ -77,8 +84,8 @@ Some examples can be seen below:
# load bash as a login shell with custom rcfile
{"foreign_shells": [
{"shell": "bash",
"login": true,
{"shell": "bash",
"login": true,
"extra_args": ["--rcfile", "/path/to/rcfile"]
}
]

View file

@ -15,6 +15,7 @@ from xonsh.tools import to_bool, ensure_string
COMMAND = """
{seterrcmd}
{prevcmd}
echo __XONSH_ENV_BEG__
{envcmd}
@ -80,54 +81,52 @@ fi
echo ${namefile}
""".strip()
# mapping of shell name alises to keys in other lookup dictionaries.
CANON_SHELL_NAMES = {
'bash': 'bash',
'/bin/bash': 'bash',
'zsh': 'zsh',
'/bin/zsh': 'zsh',
'/usr/bin/zsh': 'zsh',
'cmd': 'cmd',
'cmd.exe': 'cmd',
}
DEFAULT_ENVCMDS = {
'bash': 'env',
'/bin/bash': 'env',
'zsh': 'env',
'/bin/zsh': 'env',
'/usr/bin/zsh': 'env',
'cmd': 'set',
}
DEFAULT_ALIASCMDS = {
'bash': 'alias',
'/bin/bash': 'alias',
'zsh': 'alias -L',
'/bin/zsh': 'alias -L',
'/usr/bin/zsh': 'alias -L',
'cmd': '',
}
DEFAULT_FUNCSCMDS = {
'bash': DEFAULT_BASH_FUNCSCMD,
'/bin/bash': DEFAULT_BASH_FUNCSCMD,
'zsh': DEFAULT_ZSH_FUNCSCMD,
'/bin/zsh': DEFAULT_ZSH_FUNCSCMD,
'/usr/bin/zsh': DEFAULT_ZSH_FUNCSCMD,
'cmd': '',
}
DEFAULT_SOURCERS = {
'bash': 'source',
'/bin/bash': 'source',
'zsh': 'source',
'/bin/zsh': 'source',
'/usr/bin/zsh': 'source',
'cmd': 'call',
}
DEFAULT_TMPFILE_EXT = {
'bash': '.sh',
'/bin/bash': '.sh',
'zsh': '.zsh',
'/bin/zsh': '.zsh',
'/usr/bin/zsh': '.zsh',
'cmd': '.bat',
}
DEFAULT_RUNCMD = {
'bash': '-c',
'/bin/bash': '-c',
'zsh': '-c',
'/bin/zsh': '-c',
'/usr/bin/zsh': '-c',
'cmd': '/C',
}
DEFAULT_SETERRCMD = {
'bash': 'set -e',
'zsh': 'set -e',
'cmd': '',
}
@lru_cache()
@ -135,7 +134,7 @@ def foreign_shell_data(shell, interactive=True, login=False, envcmd=None,
aliascmd=None, extra_args=(), currenv=None,
safe=True, prevcmd='', postcmd='', funcscmd=None,
sourcer=None, use_tmpfile=False, tmpfile_ext=None,
runcmd=None):
runcmd=None, seterrcmd=None):
"""Extracts data from a foreign (non-xonsh) shells. Currently this gets
the environment, aliases, and functions but may be extended in the future.
@ -180,6 +179,13 @@ def foreign_shell_data(shell, interactive=True, login=False, envcmd=None,
parsed directly to the shell
tmpfile_ext : str or None, optional
If tmpfile is True this sets specifies the extension used.
runcmd : str or None, optional
Command line switches to use when running the script, such as
-c for Bash and /C for cmd.exe.
seterrcmd : str or None, optional
Command that enables exit-on-error for the shell. For example, this
is "set -e" in Bash. To disable exit-on-error behavior, simply pass
in an empty string.
Returns
-------
@ -195,13 +201,16 @@ def foreign_shell_data(shell, interactive=True, login=False, envcmd=None,
cmd.append('-i')
if login:
cmd.append('-l')
envcmd = DEFAULT_ENVCMDS.get(shell, 'env') if envcmd is None else envcmd
aliascmd = DEFAULT_ALIASCMDS.get(shell, 'alias') if aliascmd is None else aliascmd
funcscmd = DEFAULT_FUNCSCMDS.get(shell, 'echo {}') if funcscmd is None else funcscmd
tmpfile_ext = DEFAULT_TMPFILE_EXT.get(shell, 'sh') if tmpfile_ext is None else tmpfile_ext
runcmd = DEFAULT_RUNCMD.get(shell, '-c') if runcmd is None else runcmd
shkey = CANON_SHELL_NAMES[shell]
envcmd = DEFAULT_ENVCMDS.get(shkey, 'env') if envcmd is None else envcmd
aliascmd = DEFAULT_ALIASCMDS.get(shkey, 'alias') if aliascmd is None else aliascmd
funcscmd = DEFAULT_FUNCSCMDS.get(shkey, 'echo {}') if funcscmd is None else funcscmd
tmpfile_ext = DEFAULT_TMPFILE_EXT.get(shkey, 'sh') if tmpfile_ext is None else tmpfile_ext
runcmd = DEFAULT_RUNCMD.get(shkey, '-c') if runcmd is None else runcmd
seterrcmd = DEFAULT_SETERRCMD.get(shkey, '') if seterrcmd is None else seterrcmd
command = COMMAND.format(envcmd=envcmd, aliascmd=aliascmd, prevcmd=prevcmd,
postcmd=postcmd, funcscmd=funcscmd).strip()
postcmd=postcmd, funcscmd=funcscmd,
seterrcmd=seterrcmd).strip()
cmd.append(runcmd)
@ -424,6 +433,9 @@ def ensure_shell(shell):
if 'sourcer' in shell_keys:
shell['sourcer'] = None if shell['sourcer'] is None \
else ensure_string(shell['sourcer'])
if 'seterrcmd' in shell_keys:
shell['seterrcmd'] = None if shell['seterrcmd'] is None \
else ensure_string(shell['seterrcmd'])
return shell