1# run-and-compare.cmake -- Runs a command and compares its output to an expected value
2
3# Copyright (C) 2021 Nathan Moinvaziri
4# Licensed under the Zlib license, see LICENSE.md for details
5
6# Required Variables
7#   COMMAND             - Command to run
8#   OUTPUT              - Standard output
9#   COMPARE             - String to compare output against
10
11# Optional Variables
12#   INPUT               - Standard input
13#   IGNORE_LINE_ENDINGS - Ignore line endings when comparing output
14
15if(NOT DEFINED OUTPUT OR NOT DEFINED COMPARE OR NOT DEFINED COMMAND)
16    message(FATAL_ERROR "Run and compare arguments missing")
17endif()
18
19# Ensure directory exists for output files
20get_filename_component(OUTPUT_DIR "${OUTPUT}" DIRECTORY)
21file(MAKE_DIRECTORY "${OUTPUT_DIR}")
22
23if(INPUT)
24    # Run command with stdin input and redirect stdout to output
25    execute_process(COMMAND ${CMAKE_COMMAND}
26        "-DCOMMAND=${COMMAND}"
27        -DINPUT=${INPUT}
28        -DOUTPUT=${OUTPUT}
29        "-DSUCCESS_EXIT=${SUCCESS_EXIT}"
30        -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake
31        RESULT_VARIABLE CMD_RESULT)
32else()
33    # Run command and redirect stdout to output
34    execute_process(COMMAND ${CMAKE_COMMAND}
35        "-DCOMMAND=${COMMAND}"
36        -DOUTPUT=${OUTPUT}
37        "-DSUCCESS_EXIT=${SUCCESS_EXIT}"
38        -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake
39        RESULT_VARIABLE CMD_RESULT)
40endif()
41
42if(CMD_RESULT)
43    message(FATAL_ERROR "Run before compare failed: ${CMD_RESULT}")
44endif()
45
46# Use configure_file to normalize line-endings
47if(IGNORE_LINE_ENDINGS)
48    # Rewrite files with normalized line endings to temporary directory
49    get_filename_component(COMPARE_NAME ${COMPARE} NAME)
50    set(COMPARE_TEMP ${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/${COMPARE_NAME}.cmp)
51    configure_file(${COMPARE} ${COMPARE_TEMP} NEWLINE_STYLE LF)
52    set(COMPARE ${COMPARE_TEMP})
53
54    get_filename_component(OUTPUT_NAME ${OUTPUT} NAME)
55    set(OUTPUT_TEMP ${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/${OUTPUT_NAME}.cmp)
56    configure_file(${OUTPUT} ${OUTPUT_TEMP} NEWLINE_STYLE LF)
57    set(OUTPUT ${OUTPUT_TEMP})
58endif()
59
60# Compare that output is equal to specified file
61execute_process(COMMAND ${CMAKE_COMMAND}
62    -E compare_files ${COMPARE} ${OUTPUT}
63    RESULT_VARIABLE CMD_RESULT)
64
65# Delete temporary files used to normalize line-endings
66if(IGNORE_LINE_ENDINGS)
67    file(REMOVE ${COMPARE} ${OUTPUT})
68endif()
69
70if(CMD_RESULT)
71    message(FATAL_ERROR "Run compare failed: ${CMD_RESULT}")
72endif()
73