mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 08:24:40 +01:00
Merge remote-tracking branch 'origin/master' into dockerfile
This commit is contained in:
commit
1b3a59e106
7 changed files with 137 additions and 18 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ Contents
|
|||
tutorial_hist
|
||||
tutorial_xontrib
|
||||
bash_to_xsh
|
||||
python_virtual_environments
|
||||
|
||||
**Configuration & Setup:**
|
||||
|
||||
|
|
72
docs/python_virtual_environments.rst
Normal file
72
docs/python_virtual_environments.rst
Normal 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
|
27
setup.py
27
setup.py
|
@ -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'] = {
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue