Permalink
Browse files

Fixes and enhancements to the 'dirs' builtin (#57)

- Add the ability to print the directory stack with tilde prefixes.
- Fix bug when pushing dirs like .. and .
- Add spec tests.
  • Loading branch information...
timetoplatypus authored and andychu committed Jan 8, 2018
1 parent 8fcdd42 commit fd31f81855a90782d400738aaa363682c37a8688
Showing with 99 additions and 23 deletions.
  1. +30 −20 core/builtin.py
  2. +3 −3 core/cmd_exec.py
  3. +66 −0 spec/builtins2.test.sh
View
@@ -697,28 +697,35 @@ def Cd(argv, mem, dir_stack):
return 0
WITH_PREFIX = 1
WITHOUT_PREFIX = 2
WITH_LINE_NUMBERS = 1
WITHOUT_LINE_NUMBERS = 2
SINGLE_LINE = 3
def _PrintDirStack(dir_stack, style):
def _PrintDirStack(dir_stack, style, home_dir):
"""Helper for 'dirs'."""
if style == WITH_PREFIX:
if style == WITH_LINE_NUMBERS:
for i, entry in enumerate(dir_stack.Iter()):
print('%2d %s' % (i, entry))
print('%2d %s' % (i, _FormatDir(entry, home_dir)))
elif style == WITHOUT_PREFIX:
elif style == WITHOUT_LINE_NUMBERS:
for entry in dir_stack.Iter():
print(entry)
print(_FormatDir(entry, home_dir))
elif style == SINGLE_LINE:
print(' '.join(dir_stack.Iter()))
print(' '.join(_FormatDir(entry, home_dir)
for entry in dir_stack.Iter()))
sys.stdout.flush()
def Pushd(argv, dir_stack):
def _FormatDir(dir_name, home_dir):
if home_dir and home_dir.tag == value_e.Str and (dir_name == home_dir.s or dir_name.startswith(home_dir.s + '/')):
return dir_name.replace(home_dir.s, '~', 1)
return dir_name
def Pushd(argv, home_dir, dir_stack):
num_args = len(argv)
if num_args <= 0:
util.error('pushd: no other directory')
@@ -727,19 +734,19 @@ def Pushd(argv, dir_stack):
util.error('pushd: too many arguments')
return 1
dest_dir = argv[0]
dest_dir = os.path.abspath(argv[0])
try:
os.chdir(dest_dir)
except OSError as e:
util.error("pushd: %r: %s", dest_dir, os.strerror(e.errno))
return 1
dir_stack.Push(dest_dir)
_PrintDirStack(dir_stack, SINGLE_LINE)
_PrintDirStack(dir_stack, SINGLE_LINE, home_dir)
return 0
def Popd(argv, dir_stack):
def Popd(argv, home_dir, dir_stack):
dest_dir = dir_stack.Pop()
if dest_dir is None:
util.error('popd: directory stack is empty')
@@ -751,7 +758,7 @@ def Popd(argv, dir_stack):
util.error("popd: %r: %s", dest_dir, os.strerror(e.errno))
return 1
_PrintDirStack(dir_stack, SINGLE_LINE)
_PrintDirStack(dir_stack, SINGLE_LINE, home_dir)
return 0
@@ -761,19 +768,22 @@ def Popd(argv, dir_stack):
DIRS_SPEC.ShortFlag('-p')
DIRS_SPEC.ShortFlag('-v')
def Dirs(argv, dir_stack):
def Dirs(argv, home_dir, dir_stack):
arg, i = DIRS_SPEC.Parse(argv)
style = SINGLE_LINE
# Following bash order of flag priority
if arg.l:
util.warn('*** dirs -l not implemented ***')
# Following bash behavior
home_dir = None
if arg.c:
dir_stack.Reset()
return 0
elif arg.v:
_PrintDirStack(dir_stack, WITH_PREFIX)
style = WITH_LINE_NUMBERS
elif arg.p:
_PrintDirStack(dir_stack, WITHOUT_PREFIX)
else:
_PrintDirStack(dir_stack, SINGLE_LINE)
style = WITHOUT_LINE_NUMBERS
_PrintDirStack(dir_stack, style, home_dir)
return 0
View
@@ -284,13 +284,13 @@ def _RunBuiltin(self, builtin_id, argv):
status = builtin.Jobs(argv, self.job_state)
elif builtin_id == EBuiltin.PUSHD:
status = builtin.Pushd(argv, self.dir_stack)
status = builtin.Pushd(argv, self.mem.GetVar('HOME'), self.dir_stack)
elif builtin_id == EBuiltin.POPD:
status = builtin.Popd(argv, self.dir_stack)
status = builtin.Popd(argv, self.mem.GetVar('HOME'), self.dir_stack)
elif builtin_id == EBuiltin.DIRS:
status = builtin.Dirs(argv, self.dir_stack)
status = builtin.Dirs(argv, self.mem.GetVar('HOME'), self.dir_stack)
elif builtin_id in (EBuiltin.SOURCE, EBuiltin.DOT):
status = self._Source(argv)
View
@@ -130,3 +130,69 @@ dirs -p
/
## N-I dash/mksh status: 127
## N-I dash/mksh stdout-json: ""
### dirs -l to print in long format, no tilde prefix
# Can't use the OSH test harness for this because
# /home/<username> may be included in a path.
cd /
HOME=/tmp
mkdir -p $HOME/oil_test
pushd $HOME/oil_test >/dev/null
dirs
dirs -l
# status: 0
## STDOUT:
~/oil_test /
/tmp/oil_test /
## END
### dirs to print using tilde-prefix format
cd /
HOME=/tmp
mkdir -p $HOME/oil_test
pushd $HOME/oil_test >/dev/null
dirs
# stdout: ~/oil_test /
# status: 0
### dirs test converting true home directory to tilde
cd /
HOME=/tmp
mkdir -p $HOME/oil_test/$HOME
pushd $HOME/oil_test/$HOME >/dev/null
dirs
# stdout: ~/oil_test/tmp /
# status: 0
### dirs don't convert to tilde when $HOME is substring
cd /
mkdir -p /tmp/oil_test
mkdir -p /tmp/oil_tests
HOME=/tmp/oil_test
pushd /tmp/oil_tests
dirs
### dirs tilde test when $HOME is exactly $PWD
cd /
mkdir -p /tmp/oil_test
HOME=/tmp/oil_test
pushd $HOME
dirs
# STDOUT:
~ /
~ /
# status: 0
### dirs test of path alias `..`
cd /tmp
pushd .. >/dev/null
dirs
# stdout: / /tmp
# status: 0
### dirs test of path alias `.`
cd /tmp
pushd . >/dev/null
dirs
# stdout: /tmp /tmp
# status: 0

0 comments on commit fd31f81

Please sign in to comment.