mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 16:34:47 +01:00
Fix how `$PWD
` is managed in order to work with symlinks gracefully
This commit is contained in:
parent
580f43c2dc
commit
72d04e9961
3 changed files with 37 additions and 9 deletions
16
news/fix_pwd.rst
Normal file
16
news/fix_pwd.rst
Normal file
|
@ -0,0 +1,16 @@
|
|||
**Added:**
|
||||
|
||||
* Add a ``-P`` flag to the ``cd`` function in order to change directory and
|
||||
following symlinks.
|
||||
|
||||
**Changed:** None
|
||||
|
||||
**Deprecated:** None
|
||||
|
||||
**Removed:** None
|
||||
|
||||
**Fixed:**
|
||||
|
||||
* Fix how ``$PWD`` is managed in order to work with symlinks gracefully
|
||||
|
||||
**Security:** None
|
|
@ -372,14 +372,15 @@ class BaseShell(object):
|
|||
hist.last_cmd_rtn = hist.last_cmd_out = None
|
||||
|
||||
def _fix_cwd(self):
|
||||
"""Check if the cwd changed out from under us"""
|
||||
"""Check if the cwd changed out from under us."""
|
||||
env = builtins.__xonsh_env__
|
||||
cwd = os.getcwd()
|
||||
if cwd != builtins.__xonsh_env__.get('PWD'):
|
||||
old = builtins.__xonsh_env__.get('PWD') # working directory changed without updating $PWD
|
||||
builtins.__xonsh_env__['PWD'] = cwd # track it now
|
||||
if 'PWD' in env and os.path.realpath(cwd) != os.path.realpath(env['PWD']):
|
||||
old = env['PWD'] # working directory changed without updating $PWD
|
||||
env['PWD'] = cwd # track it now
|
||||
if old is not None:
|
||||
builtins.__xonsh_env__['OLDPWD'] = old # and update $OLDPWD like dirstack.
|
||||
events.on_chdir.fire(olddir=old, newdir=cwd) # fire event after cwd actually changed.
|
||||
env['OLDPWD'] = old # and update $OLDPWD like dirstack.
|
||||
events.on_chdir.fire(olddir=old, newdir=cwd) # fire event after cwd actually changed.
|
||||
|
||||
def push(self, line):
|
||||
"""Pushes a line onto the buffer and compiles the code in a way that
|
||||
|
|
|
@ -129,11 +129,15 @@ def _get_cwd():
|
|||
return None
|
||||
|
||||
|
||||
def _change_working_directory(newdir):
|
||||
def _change_working_directory(newdir, follow_symlinks=False):
|
||||
env = builtins.__xonsh_env__
|
||||
old = env['PWD']
|
||||
new = os.path.join(old, newdir)
|
||||
absnew = os.path.abspath(new)
|
||||
|
||||
if follow_symlinks:
|
||||
absnew = os.path.realpath(absnew)
|
||||
|
||||
try:
|
||||
os.chdir(absnew)
|
||||
except (OSError, FileNotFoundError):
|
||||
|
@ -180,6 +184,11 @@ def cd(args, stdin=None):
|
|||
oldpwd = env.get('OLDPWD', None)
|
||||
cwd = env['PWD']
|
||||
|
||||
follow_symlinks = False
|
||||
if len(args) > 0 and args[0] == '-P':
|
||||
follow_symlinks = True
|
||||
del args[0]
|
||||
|
||||
if len(args) == 0:
|
||||
d = os.path.expanduser('~')
|
||||
elif len(args) == 1:
|
||||
|
@ -207,7 +216,9 @@ def cd(args, stdin=None):
|
|||
else:
|
||||
d = _try_cdpath(d)
|
||||
else:
|
||||
return '', 'cd takes 0 or 1 arguments, not {0}\n'.format(len(args)), 1
|
||||
return '', ('cd takes 0 or 1 arguments, not {0}. An additional `-P` '
|
||||
'flag can be passed in first position to follow symlinks.'
|
||||
'\n'.format(len(args))), 1
|
||||
if not os.path.exists(d):
|
||||
return '', 'cd: no such file or directory: {0}\n'.format(d), 1
|
||||
if not os.path.isdir(d):
|
||||
|
@ -223,7 +234,7 @@ def cd(args, stdin=None):
|
|||
pushd(['-n', '-q', cwd])
|
||||
if ON_WINDOWS and _is_unc_path(d):
|
||||
d = _unc_map_temp_drive(d)
|
||||
_change_working_directory(d)
|
||||
_change_working_directory(d, follow_symlinks)
|
||||
return None, None, 0
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue