Skip to content

Commit

Permalink
[Lit] Add pushd and popd builtins
Browse files Browse the repository at this point in the history
This behaves just like the sh/cmd.exe equivalents.

pushd/popd are useful to verify path handling of the driver,
typically testing prefix maps or relative path handling.

Differential Revision: https://reviews.llvm.org/D125502
  • Loading branch information
DavidGoldman committed May 12, 2022
1 parent b1aed14 commit e91a73d
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 7 deletions.
37 changes: 30 additions & 7 deletions llvm/utils/lit/lit/TestRunner.py
Expand Up @@ -57,12 +57,20 @@ class ShellEnvironment(object):

"""Mutable shell environment containing things like CWD and env vars.
Environment variables are not implemented, but cwd tracking is.
Environment variables are not implemented, but cwd tracking is. In addition,
we maintain a dir stack for pushd/popd.
"""

def __init__(self, cwd, env):
self.cwd = cwd
self.env = dict(env)
self.dirStack = []

def change_dir(self, newdir):
if os.path.isabs(newdir):
self.cwd = newdir
else:
self.cwd = os.path.realpath(os.path.join(self.cwd, newdir))

class TimeoutHelper(object):
"""
Expand Down Expand Up @@ -275,17 +283,30 @@ def updateEnv(env, args):
def executeBuiltinCd(cmd, shenv):
"""executeBuiltinCd - Change the current directory."""
if len(cmd.args) != 2:
raise InternalShellError("'cd' supports only one argument")
newdir = cmd.args[1]
raise InternalShellError(cmd, "'cd' supports only one argument")
# Update the cwd in the parent environment.
if os.path.isabs(newdir):
shenv.cwd = newdir
else:
shenv.cwd = os.path.realpath(os.path.join(shenv.cwd, newdir))
shenv.change_dir(cmd.args[1])
# The cd builtin always succeeds. If the directory does not exist, the
# following Popen calls will fail instead.
return ShellCommandResult(cmd, "", "", 0, False)

def executeBuiltinPushd(cmd, shenv):
"""executeBuiltinPushd - Change the current dir and save the old."""
if len(cmd.args) != 2:
raise InternalShellError(cmd, "'pushd' supports only one argument")
shenv.dirStack.append(shenv.cwd)
shenv.change_dir(cmd.args[1])
return ShellCommandResult(cmd, "", "", 0, False)

def executeBuiltinPopd(cmd, shenv):
"""executeBuiltinPopd - Restore a previously saved working directory."""
if len(cmd.args) != 1:
raise InternalShellError(cmd, "'popd' does not support arguments")
if not shenv.dirStack:
raise InternalShellError(cmd, "popd: directory stack empty")
shenv.cwd = shenv.dirStack.pop()
return ShellCommandResult(cmd, "", "", 0, False)

def executeBuiltinExport(cmd, shenv):
"""executeBuiltinExport - Set an environment variable."""
if len(cmd.args) != 2:
Expand Down Expand Up @@ -629,6 +650,8 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper):
'export': executeBuiltinExport,
'echo': executeBuiltinEcho,
'mkdir': executeBuiltinMkdir,
'popd': executeBuiltinPopd,
'pushd': executeBuiltinPushd,
'rm': executeBuiltinRm,
':': executeBuiltinColon}
# To avoid deadlock, we use a single stderr stream for piped
Expand Down
4 changes: 4 additions & 0 deletions llvm/utils/lit/tests/Inputs/shtest-pushd-popd/lit.cfg
@@ -0,0 +1,4 @@
import lit.formats
config.name = 'shtest-pushd-popd'
config.suffixes = ['.txt']
config.test_format = lit.formats.ShTest(execute_external=False)
@@ -0,0 +1 @@
# RUN: popd invalid
@@ -0,0 +1 @@
# RUN: popd
@@ -0,0 +1,8 @@
# RUN: rm -rf %t/UserFoo && mkdir -p %t/UserFoo/FooDocs
# RUN: touch %t/UserFoo/user.txt %t/UserFoo/FooDocs/doc.txt
# RUN: pushd %t/UserFoo
# RUN: pushd FooDocs
# RUN: cat doc.txt
# RUN: popd
# RUN: cat user.txt
# RUN: popd
@@ -0,0 +1 @@
# RUN: pushd a b
24 changes: 24 additions & 0 deletions llvm/utils/lit/tests/shtest-pushd-popd.py
@@ -0,0 +1,24 @@
# Check the pushd and popd commands

# RUN: not %{lit} -a -v %{inputs}/shtest-pushd-popd \
# RUN: | FileCheck -match-full-lines %s
#
# END.

# CHECK: -- Testing: 4 tests{{.*}}

# CHECK: FAIL: shtest-pushd-popd :: popd-args.txt ({{[^)]*}})
# CHECK: $ "popd" "invalid"
# CHECK: 'popd' does not support arguments

# CHECK: FAIL: shtest-pushd-popd :: popd-no-stack.txt ({{[^)]*}})
# CHECK: $ "popd"
# CHECK: popd: directory stack empty

# CHECK: FAIL: shtest-pushd-popd :: pushd-too-many-args.txt ({{[^)]*}})
# CHECK: $ "pushd" "a" "b"
# CHECK: 'pushd' supports only one argument

# CHECK: Passed: 1
# CHECK: Failed: 3
# CHECK-NOT: {{.}}

0 comments on commit e91a73d

Please sign in to comment.