Skip to content

Commit 75dba8e

Browse files
[lit] Add readfile substitution
This patch adds a new %{readfile:<file name>} substitution to lit. This is needed for porting a couple of tests to lit's internal shell. These tests are all using subshells to pass some option to a command are not feasible to run within the internal shell without this functionality. Reviewers: petrhosek, jh7370, ilovepi, cmtice Reviewed By: jh7370, cmtice Pull Request: #158441
1 parent 19bc0d6 commit 75dba8e

File tree

8 files changed

+81
-0
lines changed

8 files changed

+81
-0
lines changed

llvm/docs/CommandGuide/lit.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ TestRunner.py:
664664
Otherwise, %t but with a single leading ``/`` removed.
665665
%:T On Windows, %/T but a ``:`` is removed if its the second character.
666666
Otherwise, %T but with a single leading ``/`` removed.
667+
%{readfile:<filename>} Reads the file specified.
667668
======================= ==============
668669

669670
Other substitutions are provided that are variations on this base set and

llvm/utils/lit/lit/TestRunner.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,30 @@ def processRedirects(cmd, stdin_source, cmd_shenv, opened_files):
720720
return std_fds
721721

722722

723+
def _expandLateSubstitutions(cmd, arguments, cwd):
724+
for i, arg in enumerate(arguments):
725+
if not isinstance(arg, str):
726+
continue
727+
728+
def _replaceReadFile(match):
729+
filePath = match.group(1)
730+
if not os.path.isabs(filePath):
731+
filePath = os.path.join(cwd, filePath)
732+
try:
733+
with open(filePath) as fileHandle:
734+
return fileHandle.read()
735+
except FileNotFoundError:
736+
raise InternalShellError(
737+
cmd,
738+
"File specified in readfile substitution does not exist: %s"
739+
% filePath,
740+
)
741+
742+
arguments[i] = re.sub(r"%{readfile:([^}]*)}", _replaceReadFile, arg)
743+
744+
return arguments
745+
746+
723747
def _executeShCmd(cmd, shenv, results, timeoutHelper):
724748
if timeoutHelper.timeoutReached():
725749
# Prevent further recursion if the timeout has been hit
@@ -834,6 +858,9 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper):
834858
# Ensure args[0] is hashable.
835859
args[0] = expand_glob(args[0], cmd_shenv.cwd)[0]
836860

861+
# Expand all late substitutions.
862+
args = _expandLateSubstitutions(j, args, cmd_shenv.cwd)
863+
837864
inproc_builtin = inproc_builtins.get(args[0], None)
838865
if inproc_builtin and (args[0] != "echo" or len(cmd.commands) == 1):
839866
# env calling an in-process builtin is useless, so we take the safe
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
## Tests that readfile works with absolute paths.
2+
# RUN: echo -n "hello" > %t
3+
# RUN: echo %{readfile:%t}
4+
5+
## Fail the test so we can assert on the output.
6+
# RUN: not echo return
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## Test that readfile reports information appropriately when the file specified
2+
## does not exist.
3+
4+
# RUN: echo %{readfile:/file/does/not/exist}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import lit.formats
2+
3+
config.name = "shtest-readfile"
4+
config.suffixes = [".txt"]
5+
config.test_format = lit.formats.ShTest(execute_external=False)
6+
config.test_source_root = None
7+
config.test_exec_root = None
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## Tests that readfile works with relative paths.
2+
# RUN: mkdir -p rel_path_test_folder
3+
# RUN: echo -n "hello" > rel_path_test_folder/test_file
4+
# RUN: echo %{readfile:rel_path_test_folder/test_file}
5+
6+
## Fail the test so we can assert on the output.
7+
# RUN: not echo return
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## Tests that readfile works with two substitutions on the same line to ensure the
2+
## regular expressions are set up correctly.
3+
# RUN: echo -n "hello" > %t.1
4+
# RUN: echo -n "bye" > %t.2
5+
# RUN: echo %{readfile:%t.1} %{readfile:%t.2}
6+
7+
## Fail the test so we can assert on the output.
8+
# RUN: not echo return
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
## Tests the readfile substitution.
2+
3+
# RUN: not %{lit} -a -v %{inputs}/shtest-readfile | FileCheck -match-full-lines -DTEMP_PATH=%S%{fs-sep}Inputs%{fs-sep}shtest-readfile%{fs-sep}Output %s
4+
5+
# CHECK: -- Testing: 4 tests{{.*}}
6+
7+
# CHECK-LABEL: FAIL: shtest-readfile :: absolute-paths.txt ({{[^)]*}})
8+
# CHECK: echo hello
9+
# CHECK: # executed command: echo '%{readfile:[[TEMP_PATH]]{{[\\\/]}}absolute-paths.txt.tmp}'
10+
11+
# CHECK-LABEL: FAIL: shtest-readfile :: file-does-not-exist.txt ({{[^)]*}})
12+
# CHECK: # executed command: @echo 'echo %{readfile:/file/does/not/exist}'
13+
# CHECK: # | File specified in readfile substitution does not exist: /file/does/not/exist
14+
15+
# CHECK-LABEL: FAIL: shtest-readfile :: relative-paths.txt ({{[^)]*}})
16+
# CHECK: echo hello
17+
# CHECK: # executed command: echo '%{readfile:rel_path_test_folder/test_file}'
18+
19+
# CHECK-LABEL: FAIL: shtest-readfile :: two-same-line.txt ({{[^)]*}})
20+
# CHECK: echo hello bye
21+
# CHECK: # executed command: echo '%{readfile:[[TEMP_PATH]]{{[\\\/]}}two-same-line.txt.tmp.1}' '%{readfile:[[TEMP_PATH]]{{[\\\/]}}two-same-line.txt.tmp.2}'

0 commit comments

Comments
 (0)