Skip to content

Commit 700d115

Browse files
committed
Avoid redirecting cds compiler stdout
Revokes the approach of redirecting stdout for 'cds compile' commands used in the CDS extractor. In some cases, stdout may contain more than just the contents of the generated JSON, which creates errors that are difficult to troubleshoot as they only occur in some environments. Returns to the approach of using CLI arguments to instruct the CDS compiler to output to a specified path, and adds some logic to account for variations in CDS compiler behavior when using the '-o' or '--dest' CLI argument. Because some CDS compiler versions say that they output to a directory but actually output to a file, and some CDS compiler versions actually output to a directory as specified in the CLI docs, we trust the use of the '--dest' argument (more than we trust a redirect of stdout to a JSON file), but we *verify* whether the output is a regular '.cds.json' file or is, indeed, a directory.
1 parent 81627e9 commit 700d115

File tree

2 files changed

+74
-12
lines changed

2 files changed

+74
-12
lines changed

.github/workflows/run-codeql-unit-tests-javascript.yml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,26 @@ jobs:
9696
for cds_file in $(find . -type f \( -iname '*.cds' \) -print)
9797
do
9898
echo "I am compiling $cds_file"
99+
_out_path="${cds_file}.json"
99100
cds compile $cds_file \
100-
-2 json \
101101
--locations \
102-
> "$cds_file.json" 2> "$cds_file.err"
102+
--to json \
103+
--dest "$_out_path" \
104+
2> "$cds_file.err"
105+
# Check if the output is a regular file or a (sub)directory, where
106+
# files generated in an output directory will need to have the file
107+
# extension changed from '.json' to '.cds.json', but we don't need
108+
# to rename anything if the cds compiler just generated a single
109+
# '.cds.json' file.
110+
if [ -d "$_out_path" ]
111+
then
112+
for json_file in $(find "$_out_path" -type f \( -iname '*.json' \) -print)
113+
do
114+
_new_path="${json_file%.json}.cds.json"
115+
echo "Renaming CDS compiler generated JSON file $json_file to $_new_path"
116+
mv "$json_file" "$_new_path"
117+
done
118+
fi
103119
done
104120
popd
105121
done

extractors/cds/tools/index-files.sh

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,62 @@ fi
4848

4949
echo "Processing CDS files to JSON"
5050

51-
# Run the cds compile command on each file in the response file, outputting the compiled JSON to a file with
52-
# the same name
53-
while IFS= read -r cds_file; do
54-
echo "Processing CDS file $cds_file to:"
55-
if ! $cds_command compile "$cds_file" -2 json --locations > "$cds_file.json" 2> "$cds_file.err"; then
56-
stderr_truncated=`grep "^\[ERROR\]" "$cds_file.err" | tail -n 4`
57-
error_message=$'Could not compile the file '"$cds_file"$'.\nReported error(s):\n```\n'"$stderr_truncated"$'\n```'
58-
echo "$error_message"
59-
# Log an error diagnostic which appears on the status page
60-
"$CODEQL_DIST/codeql" database add-diagnostic --extractor-name cds --ready-for-status-page --source-id cds/compilation-failure --source-name "Failure to compile one or more SAP CAP CDS files" --severity error --markdown-message "$error_message" --file-path "$cds_file" "$CODEQL_EXTRACTOR_CDS_WIP_DATABASE"
51+
# Run the cds compile command on each file in the response file in order to generate
52+
# the JSON data we need. Move the generated ".json" files from the temporary output
53+
# to the original directory and rename them to ".cds.json" so that the JS extractor
54+
# can distinguish them from regular JSON files / extract them as CDS files.
55+
while IFS= read -r _cds_file_path; do
56+
# The cds compile command chooses how it outputs the JSON. If it creates output
57+
# files in a directory, then it will create the directory when it runs. If it
58+
# creates a single output file, then it will create the file when it runs. We
59+
# create the output path by simply appending ".json" to the input file path,
60+
# such that there is nothing further to do if the output is a single file.
61+
_cds_compile_json_out="${_cds_file_path}.json"
62+
# Remove any existing output directory to avoid conflicts.
63+
if [ -d "$_cds_compile_json_out" ]; then
64+
echo "WARNING: overwriting existing temporary output path ${_cds_compile_json_out}."
65+
rm -rf "$_cds_compile_json_out"
66+
fi
67+
_cds_file_err_path="${_cds_file_path}.err"
68+
echo "Compiling JSON for source CDS file $_cds_file_path to output path: $_cds_compile_json_out"
69+
if ! $cds_command compile "$_cds_file_path" --to json --dest "$_cds_compile_json_out" --locations 2> "$_cds_file_err_path"; then
70+
stderr_truncated=`grep "^\[ERROR\]" "$_cds_file_err_path" | tail -n 4`
71+
_error_msg=$'ERROR: Could not compile the CDS file '"$_cds_file_path"$'.\nReported error(s):\n```\n'"$stderr_truncated"$'\n```'
72+
echo "$_error_msg"
73+
# Log the error message as a diagnostic which appears on the Tools status page.
74+
"$CODEQL_DIST/codeql" database add-diagnostic --extractor-name cds --ready-for-status-page --source-id cds/compilation-failure --source-name "Failure to compile one or more SAP CAP CDS files" --severity error --markdown-message "$_error_msg" --file-path "$_cds_file_path" "$CODEQL_EXTRACTOR_CDS_WIP_DATABASE"
75+
# Continue to the next file.
76+
continue
77+
fi
78+
# Cleanup the error file if it exists and is empty.
79+
if [[ -f "$_cds_file_err_path" && -s "$_cds_file_err_path" ]]; then
80+
rm -f "$_cds_file_err_path"
81+
fi
82+
# Replace the ".json" extension with a ".cds.json" extension in the files
83+
# generated by the cds compile command. Due to inconsistencies between
84+
# different versions of the cds compiler, and contrary to the command-line
85+
# documentation for the "cds compile" command, the output may be generated
86+
# as a single file in the current directory, or as one or more files in an
87+
# output directory.
88+
if [ -f "$_cds_compile_json_out" ]; then
89+
echo "Compiled CDS source file from $_cds_file_path to $_cds_compile_json_out"
90+
elif [ -d "$_cds_compile_json_out" ]; then
91+
echo "CDS compiler generated JSON to output directory: $_cds_compile_json_out"
92+
if ls "$_cds_compile_json_out"/*.json 1> /dev/null 2>&1; then
93+
for _output_json_file in "$_cds_compile_json_out"/*.json; do
94+
_cds_json_file_path="${_output_json_file%.json}.cds.json"
95+
echo "Renaming CDS compiler generated output '.json' file to $_cds_json_file_path"
96+
mv "$_output_json_file" "$_cds_json_file_path"
97+
done
98+
else
99+
_error_msg="ERROR: Detected no '.json' files in CDS compiler output directory: $_cds_compile_json_out"
100+
# Log the error message as a diagnostic which appears on the Tools status page.
101+
"$CODEQL_DIST/codeql" database add-diagnostic --extractor-name cds --ready-for-status-page --source-id cds/compilation-failure --source-name "Failure to find one or more compiled SAP CAP CDS JSON files" --severity error --markdown-message "$_error_msg" --file-path "$_cds_file_path" "$CODEQL_EXTRACTOR_CDS_WIP_DATABASE"
102+
fi
103+
else
104+
_error_msg="ERROR: Detected no output directory or file for CDS compiler output: $_cds_compile_json_out"
105+
# Log the error message as a diagnostic which appears on the Tools status page.
106+
"$CODEQL_DIST/codeql" database add-diagnostic --extractor-name cds --ready-for-status-page --source-id cds/compilation-failure --source-name "Failure to find one or more compiled SAP CAP CDS JSON files" --severity error --markdown-message "$_error_msg" --file-path "$_cds_file_path" "$CODEQL_EXTRACTOR_CDS_WIP_DATABASE"
61107
fi
62108
done < "$response_file"
63109

0 commit comments

Comments
 (0)