[llvm] e91a73d - [Lit] Add pushd and popd builtins

David Goldman via llvm-commits llvm-commits at lists.llvm.org
Thu May 12 16:25:27 PDT 2022


Author: David Goldman
Date: 2022-05-12T19:24:30-04:00
New Revision: e91a73de24d60954700d7ac0293c050ab2cbe90b

URL: https://github.com/llvm/llvm-project/commit/e91a73de24d60954700d7ac0293c050ab2cbe90b
DIFF: https://github.com/llvm/llvm-project/commit/e91a73de24d60954700d7ac0293c050ab2cbe90b.diff

LOG: [Lit] Add pushd and popd builtins

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

Added: 
    llvm/utils/lit/tests/Inputs/shtest-pushd-popd/lit.cfg
    llvm/utils/lit/tests/Inputs/shtest-pushd-popd/popd-args.txt
    llvm/utils/lit/tests/Inputs/shtest-pushd-popd/popd-no-stack.txt
    llvm/utils/lit/tests/Inputs/shtest-pushd-popd/pushd-popd-ok.txt
    llvm/utils/lit/tests/Inputs/shtest-pushd-popd/pushd-too-many-args.txt
    llvm/utils/lit/tests/shtest-pushd-popd.py

Modified: 
    llvm/utils/lit/lit/TestRunner.py

Removed: 
    


################################################################################
diff  --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py
index de711b4eec2ae..0242e0b75af33 100644
--- a/llvm/utils/lit/lit/TestRunner.py
+++ b/llvm/utils/lit/lit/TestRunner.py
@@ -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):
     """
@@ -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:
@@ -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

diff  --git a/llvm/utils/lit/tests/Inputs/shtest-pushd-popd/lit.cfg b/llvm/utils/lit/tests/Inputs/shtest-pushd-popd/lit.cfg
new file mode 100644
index 0000000000000..e7c209220ec06
--- /dev/null
+++ b/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)

diff  --git a/llvm/utils/lit/tests/Inputs/shtest-pushd-popd/popd-args.txt b/llvm/utils/lit/tests/Inputs/shtest-pushd-popd/popd-args.txt
new file mode 100644
index 0000000000000..9ebbf1bc98459
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/shtest-pushd-popd/popd-args.txt
@@ -0,0 +1 @@
+# RUN: popd invalid
\ No newline at end of file

diff  --git a/llvm/utils/lit/tests/Inputs/shtest-pushd-popd/popd-no-stack.txt b/llvm/utils/lit/tests/Inputs/shtest-pushd-popd/popd-no-stack.txt
new file mode 100644
index 0000000000000..2b0168798bd40
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/shtest-pushd-popd/popd-no-stack.txt
@@ -0,0 +1 @@
+# RUN: popd
\ No newline at end of file

diff  --git a/llvm/utils/lit/tests/Inputs/shtest-pushd-popd/pushd-popd-ok.txt b/llvm/utils/lit/tests/Inputs/shtest-pushd-popd/pushd-popd-ok.txt
new file mode 100644
index 0000000000000..61a9583b4484a
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/shtest-pushd-popd/pushd-popd-ok.txt
@@ -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
\ No newline at end of file

diff  --git a/llvm/utils/lit/tests/Inputs/shtest-pushd-popd/pushd-too-many-args.txt b/llvm/utils/lit/tests/Inputs/shtest-pushd-popd/pushd-too-many-args.txt
new file mode 100644
index 0000000000000..01d242014ab47
--- /dev/null
+++ b/llvm/utils/lit/tests/Inputs/shtest-pushd-popd/pushd-too-many-args.txt
@@ -0,0 +1 @@
+# RUN: pushd a b
\ No newline at end of file

diff  --git a/llvm/utils/lit/tests/shtest-pushd-popd.py b/llvm/utils/lit/tests/shtest-pushd-popd.py
new file mode 100644
index 0000000000000..26296a7ffcf59
--- /dev/null
+++ b/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: {{.}}


        


More information about the llvm-commits mailing list