Merge remote-tracking branch 'origin/master' into dockerfile

This commit is contained in:
Guillaume Leclerc 2016-05-14 11:52:43 +02:00
commit 1b3a59e106
7 changed files with 137 additions and 18 deletions

View file

@ -54,6 +54,8 @@ Current Developments
* PLY is no longer a external dependency but is bundled in xonsh/ply. Xonsh can
therefore run without any external dependencies, although having prompt-toolkit
recommended.
* Provide better user feedback when running ``which`` in a platform that doesn't
provide it (e.g. Windows).
**Deprecated:** None
@ -75,6 +77,9 @@ Current Developments
* Sourcing foreign shells will now return a non-zero exit code if the
source operation failed for some reason.
* Fixed PermissionError when running commands in directories without read permissions
* Prevent Windows fixups from overriding environment vars in static config
* Fixed Optional Github project status to reflect added/removed files via git_dirty_working_directory()
* Fixed xonsh.exe launcher on Windows, when Python install directory has a space in it
**Security:** None

View file

@ -92,6 +92,7 @@ Contents
tutorial_hist
tutorial_xontrib
bash_to_xsh
python_virtual_environments
**Configuration & Setup:**

View file

@ -0,0 +1,72 @@
.. highlight:: bash
.. _python_virtual_environments:
===========================
Python Virtual Environments
===========================
The usual tools for creating Python virtual environments—``venv``, ``virtualenv``, ``pew``—don't play well with xonsh. We won't dig deeper into why it is so, but the general gist is that these tools are hacky and hard-coded for bash, zsh, and other mainstream shells.
Luckily, xonsh ships with its own virtual environments manager called **Vox**.
Vox
===
To create a new environment with vox, run ``vox new <envname>``::
$ vox new myenv
Creating environment...
Environment "myenv" created. Activate it with "vox activate myenv".
By default, environments are stored in ``~/.virtualenvs``, but you can override it by setting the ``$VIRTUALENV_HOME`` environment variable.
To see all existing environments, run ``vox list``::
$ vox list
Available environments:
eggs
myenv
spam
To activate an environment, run ``vox activate <envname>``::
$ vox activate myenv
Activated "myenv".
Instead of ``activate``, you can call ``workon`` or ``enter``.
To exit the currently active environment, run ``vox deactivate`` or ``vox exit``::
$ vox deactivate
Deactivated "myenv".
To remove an environment, run ``vox remove <envname>``::
$ vox remove myenv
Environment "myenv" removed.
Instead of ``remove``, you can call ``rm``, ``delete``, or ``del``.
To see all available commands, run ``vox help``, ``vox --help``, or ``vox -h``::
Vox is a virtual environment manager for xonsh.
Available commands:
vox new <env>
Create new virtual environment in $VIRTUALENV_HOME
vox activate (workon, enter) <env>
Activate virtual environment
vox deactivate (exit)
Deactivate current virtual environment
vox list (ls)
List all available environments
vox remove (rm, delete, del) <env>
Remove virtual environment
vox help (-h, --help)
Show help

View file

@ -18,11 +18,13 @@ try:
from setuptools.command.sdist import sdist
from setuptools.command.install import install
from setuptools.command.develop import develop
from setuptools.command.install_scripts import install_scripts
HAVE_SETUPTOOLS = True
except ImportError:
from distutils.core import setup
from distutils.command.sdist import sdist as sdist
from distutils.command.install import install as install
from distutils.command.install_scripts import install_scripts
HAVE_SETUPTOOLS = False
try:
@ -100,6 +102,29 @@ class xsdist(sdist):
sdist.make_release_tree(self, basedir, files)
#-----------------------------------------------------------------------------
# Hack to overcome pip/setuptools problem on Win 10. See:
# https://github.com/tomduck/pandoc-eqnos/issues/6
# https://github.com/pypa/pip/issues/2783
# Custom install_scripts command class for setup()
class install_scripts_quoted_shebang(install_scripts):
"""Ensure there are quotes around shebang paths with spaces."""
def write_script(self, script_name, contents, mode="t", *ignored):
shebang = str(contents.splitlines()[0])
if shebang.startswith('#!') and ' ' in shebang[2:].strip() \
and '"' not in shebang:
quoted_shebang = '#!"%s"' % shebang[2:].strip()
contents = contents.replace(shebang, quoted_shebang)
super().write_script(script_name, contents, mode, *ignored)
# The custom install needs to be used on Windows machines
if os.name == 'nt':
cmdclass = {'install': xinstall, 'sdist': xsdist, 'install_scripts': install_scripts_quoted_shebang}
else:
cmdclass = {'install': xinstall, 'sdist': xsdist}
if HAVE_SETUPTOOLS:
class xdevelop(develop):
"""Xonsh specialization of setuptools develop class."""
@ -138,7 +163,7 @@ def main():
packages=['xonsh', 'xonsh.ptk', 'xonsh.parsers', 'xontrib'],
package_dir={'xonsh': 'xonsh', 'xontrib': 'xontrib'},
package_data={'xonsh': ['*.json'], 'xontrib': ['*.xsh']},
cmdclass={'install': xinstall, 'sdist': xsdist},
cmdclass=cmdclass
)
if HAVE_SETUPTOOLS:
skw['entry_points'] = {

View file

@ -331,15 +331,15 @@ def bang_bang(args, stdin=None):
def which_version():
"""Returns output from system `which -v`"""
try:
subprocess.check_output(['which', '-v'],
stderr=subprocess.PIPE).decode('UTF-8')
_ver = subprocess.check_output(['which', '-v'],
stderr=subprocess.PIPE).decode('UTF-8')
except subprocess.CalledProcessError:
return '<no version number available on your OS>'
_ver = subprocess.check_output(['which','-v']).decode('UTF-8')
_ver = '<no version number available on your OS>'
except FileNotFoundError:
_ver = "<'which' binary not found>"
return _ver
class AWitchAWitch(Action):
SUPPRESS = '==SUPPRESS=='
def __init__(self, option_strings, version=None, dest=SUPPRESS,
@ -352,7 +352,6 @@ class AWitchAWitch(Action):
webbrowser.open('https://github.com/scopatz/xonsh/commit/f49b400')
parser.exit()
def which(args, stdin=None):
"""
Checks if argument is a xonsh alias, then if it's an executable, then
@ -373,6 +372,7 @@ def which(args, stdin=None):
parser.add_argument('--very-small-rocks', action=AWitchAWitch)
pargs = parser.parse_args(args)
#skip alias check if user asks to skip
if (pargs.arg in builtins.aliases and not pargs.skip):
match = pargs.arg
@ -383,6 +383,8 @@ def which(args, stdin=None):
stderr=subprocess.PIPE)
except subprocess.CalledProcessError:
pass
except FileNotFoundError:
print("'which' binary not found")
else:
try:
subprocess.check_call(['which'] + args,
@ -390,6 +392,8 @@ def which(args, stdin=None):
except subprocess.CalledProcessError:
raise XonshError('{} not in {} or xonsh.builtins.aliases'
.format(args[0], ':'.join(__xonsh_env__['PATH'])))
except FileNotFoundError:
print("'which' binary not found")
def xonfig(args, stdin=None):

View file

@ -12,7 +12,7 @@ from xonsh.codecache import (should_use_cache, code_cache_name,
code_cache_check, get_cache_filename,
update_cache, run_compiled_code)
from xonsh.completer import Completer
from xonsh.environ import multiline_prompt, format_prompt
from xonsh.environ import multiline_prompt, format_prompt, partial_format_prompt
if HAVE_PYGMENTS:
from xonsh.pyghooks import XonshStyle
@ -246,7 +246,7 @@ class BaseShell(object):
env = builtins.__xonsh_env__ # pylint: disable=no-member
p = env.get('PROMPT')
try:
p = format_prompt(p)
p = partial_format_prompt(p)
except Exception: # pylint: disable=broad-except
print_exception()
self.settitle()

View file

@ -935,7 +935,7 @@ def git_dirty_working_directory(cwd=None, include_untracked=False):
try:
cmd = ['git', 'status', '--porcelain']
if include_untracked:
cmd.append('--untracked-files=yes')
cmd.append('--untracked-files=normal')
else:
cmd.append('--untracked-files=no')
s = subprocess.check_output(cmd,
@ -1219,10 +1219,8 @@ def xonshrc_context(rcfiles=None, execer=None):
return env
def windows_env_fixes(ctx):
def windows_foreign_env_fixes(ctx):
"""Environment fixes for Windows. Operates in-place."""
# Windows default prompt doesn't work.
ctx['PROMPT'] = DEFAULT_PROMPT
# remove these bash variables which only cause problems.
for ev in ['HOME', 'OLDPWD']:
if ev in ctx:
@ -1243,13 +1241,27 @@ def default_env(env=None, config=None, login=True):
# in order of increasing precedence
ctx = dict(BASE_ENV)
ctx.update(os.environ)
if ON_WINDOWS:
# Windows style PROMPT definitions don't work in XONSH:
try:
del ctx['PROMPT']
except KeyError:
pass
if login:
conf = load_static_config(ctx, config=config)
foreign_env = load_foreign_envs(shells=conf.get('foreign_shells', DEFAULT_SHELLS),
issue_warning=False)
if ON_WINDOWS:
windows_foreign_env_fixes(foreign_env)
ctx.update(foreign_env)
# Do static config environment last, to allow user to override any of
# our environment choices
ctx.update(conf.get('env', ()))
ctx.update(load_foreign_envs(shells=conf.get('foreign_shells', DEFAULT_SHELLS),
issue_warning=False))
if ON_WINDOWS:
windows_env_fixes(ctx)
# finalize env
if env is not None:
ctx.update(env)