summaryrefslogtreecommitdiff
path: root/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake
blob: b172da2cda6e51e505a5bfef7f9acd83d579f34b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# prevent older policies from interfearing with this script
cmake_policy(PUSH)
cmake_policy(VERSION ${CMAKE_VERSION})


include(CMakeParseArguments)

message(STATUS "=============================================================================")
message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
message(STATUS "")

if(NOT CPackComponentsDEB_BINARY_DIR)
  message(FATAL_ERROR "CPackComponentsDEB_BINARY_DIR not set")
endif()

if(NOT CPackGen)
  message(FATAL_ERROR "CPackGen not set")
endif()

message("CMAKE_CPACK_COMMAND = ${CMAKE_CPACK_COMMAND}")
if(NOT CMAKE_CPACK_COMMAND)
  message(FATAL_ERROR "CMAKE_CPACK_COMMAND not set")
endif()

if(NOT CPackDEBConfiguration)
  message(FATAL_ERROR "CPackDEBConfiguration not set")
endif()

# run cpack with some options and returns the list of files generated
# -output_expected_file: list of files that match the pattern
function(run_cpack output_expected_file CPack_output_parent CPack_error_parent)
  set(options )
  set(oneValueArgs "EXPECTED_FILE_MASK" "CONFIG_VERBOSE")
  set(multiValueArgs "CONFIG_ARGS")
  cmake_parse_arguments(run_cpack_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )


  # clean-up previously CPack generated files
  if(${run_cpack_deb_EXPECTED_FILE_MASK})
    file(GLOB expected_file "${${run_cpack_deb_EXPECTED_FILE_MASK}}")
    if (expected_file)
      file(REMOVE "${expected_file}")
    endif()
  endif()

  message("config_args = ${run_cpack_deb_CONFIG_ARGS}")
  message("config_verbose = ${run_cpack_deb_CONFIG_VERBOSE}")
  execute_process(COMMAND ${CMAKE_CPACK_COMMAND} ${run_cpack_deb_CONFIG_VERBOSE} -G ${CPackGen} ${run_cpack_deb_CONFIG_ARGS}
      RESULT_VARIABLE CPack_result
      OUTPUT_VARIABLE CPack_output
      ERROR_VARIABLE CPack_error
      WORKING_DIRECTORY ${CPackComponentsDEB_BINARY_DIR})

  set(${CPack_output_parent} ${CPack_output} PARENT_SCOPE)
  set(${CPack_error_parent}  ${CPack_error} PARENT_SCOPE)

  if (CPack_result)
    message(FATAL_ERROR "error: CPack execution went wrong!, CPack_output=${CPack_output}, CPack_error=${CPack_error}")
  else ()
    message(STATUS "CPack_output=${CPack_output}")
    message(STATUS "CPack_error=${CPack_error}")
  endif()


  if(run_cpack_deb_EXPECTED_FILE_MASK)
    file(GLOB _output_expected_file "${run_cpack_deb_EXPECTED_FILE_MASK}")
    set(${output_expected_file} "${_output_expected_file}" PARENT_SCOPE)
  endif()
endfunction()



# This function runs lintian on a .deb and returns its output
function(run_lintian lintian_output)
  set(${lintian_output} "" PARENT_SCOPE)

  find_program(LINTIAN_EXECUTABLE lintian)
  if(LINTIAN_EXECUTABLE)
    set(options "")
    set(oneValueArgs "FILENAME")
    set(multiValueArgs "")
    cmake_parse_arguments(run_lintian_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )


    if(NOT run_lintian_deb_FILENAME)
      message(FATAL_ERROR "error: run_lintian needs FILENAME to be set")
    endif()

    # run dpkg-deb
    execute_process(COMMAND ${LINTIAN_EXECUTABLE} ${run_lintian_deb_FILENAME}
      WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
      OUTPUT_VARIABLE LINTIAN_OUTPUT
      RESULT_VARIABLE LINTIAN_RESULT
      ERROR_VARIABLE LINTIAN_ERROR
      OUTPUT_STRIP_TRAILING_WHITESPACE )

    set(${lintian_output} "${LINTIAN_OUTPUT}" PARENT_SCOPE)
  else()
    message(FATAL_ERROR "run_lintian called without lintian executable being present")
  endif()
endfunction()


# Higher level lintian check that parse the output for errors and required strings
function(lintian_check_specific_errors output_errors)
  set(${output_errors} "" PARENT_SCOPE)
  set(ERROR_ACC)

  set(options "")
  set(oneValueArgs "FILENAME")
  set(multiValueArgs "ERROR_REGEX_STRINGS")
  cmake_parse_arguments(lintian_check_specific_errors_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )

  set(lintian_output)
  run_lintian(lintian_output FILENAME ${lintian_check_specific_errors_deb_FILENAME})

  message(STATUS "Lintian output is ''${lintian_output}'")

  # regex to avoid
  foreach(_s IN LISTS lintian_check_specific_errors_deb_ERROR_REGEX_STRINGS)

    if(_s STREQUAL "")
       continue()
    endif()

    string(REGEX MATCHALL "${_s}" "_TMP_CHECK_ERROR" "${lintian_output}")

    if(NOT _TMP_CHECK_ERROR STREQUAL "")
      string(APPEND ERROR_ACC "\nlintian: ${_f}: output contains an undesirable regex:\n\t${_TMP_CHECK_ERROR}")
    endif()
  endforeach()

  set(${output_errors} "${ERROR_ACC}" PARENT_SCOPE)
endfunction()




# This function runs dpkg-deb on a .deb and returns its output
# the default behaviour it to run "--info" on the specified Debian package
# ACTION is one of the option accepted by dpkg-deb
function(run_dpkgdeb dpkg_deb_output)
  set(${dpkg_deb_output} "" PARENT_SCOPE)

  find_program(DPKGDEB_EXECUTABLE dpkg-deb)
  if(DPKGDEB_EXECUTABLE)

    set(options "")
    set(oneValueArgs "FILENAME" "ACTION")
    set(multiValueArgs "")
    cmake_parse_arguments(run_dpkgdeb_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )


    if(NOT run_dpkgdeb_deb_FILENAME)
      message(FATAL_ERROR "error: run_dpkgdeb needs FILENAME to be set")
    endif()

    if(NOT run_dpkgdeb_deb_ACTION)
      set(run_dpkgdeb_deb_ACTION "--info")
    endif()

    # run dpkg-deb
    execute_process(COMMAND ${DPKGDEB_EXECUTABLE} ${run_dpkgdeb_deb_ACTION} ${run_dpkgdeb_deb_FILENAME}
      WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
      OUTPUT_VARIABLE DPKGDEB_OUTPUT
      RESULT_VARIABLE DPKGDEB_RESULT
      ERROR_VARIABLE DPKGDEB_ERROR
      OUTPUT_STRIP_TRAILING_WHITESPACE )

    if(NOT DPKGDEB_RESULT EQUAL "0")
      message(FATAL_ERROR "Error '${DPKGDEB_RESULT}' returned by dpkg-deb: '${DPKGDEB_ERROR}'")
    endif()

    set(${dpkg_deb_output} "${DPKGDEB_OUTPUT}" PARENT_SCOPE)
  else()
    message(FATAL_ERROR "run_dpkgdeb called without dpkg-deb executable being present")
  endif()
endfunction()


# returns a particular line of the metadata of the .deb, for checking
# a previous call to run_dpkgdeb should provide the DPKGDEB_OUTPUT entry.
function(dpkgdeb_return_specific_metaentry output)
  set(${output} "" PARENT_SCOPE)

  set(options "")
  set(oneValueArgs "DPKGDEB_OUTPUT" "METAENTRY")
  set(multiValueArgs "")
  cmake_parse_arguments(dpkgdeb_return_specific_metaentry_deb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )

  if(NOT dpkgdeb_return_specific_metaentry_deb_METAENTRY)
    message(FATAL_ERROR "error: dpkgdeb_return_specific_metaentry needs METAENTRY to be set")
  endif()

  string(REGEX MATCH "${dpkgdeb_return_specific_metaentry_deb_METAENTRY}([^\r\n]*)" _TMP_STR "${dpkgdeb_return_specific_metaentry_deb_DPKGDEB_OUTPUT}")
  #message("################ _TMP_STR = ${CMAKE_MATCH_1} ##################")
  if(NOT "${CMAKE_MATCH_1}" STREQUAL "")
    string(STRIP "${CMAKE_MATCH_1}" _TMP_STR)
    set(${output} "${_TMP_STR}" PARENT_SCOPE)
  endif()
endfunction()

function(get_package_description DPKG_OUTPUT RESULT_VAR)
  string(UUID uuid NAMESPACE 00000000-0000-0000-0000-000000000000 TYPE SHA1)
  string(REPLACE ";" "${uuid}" DPKG_OUTPUT "${DPKG_OUTPUT}")
  string(REPLACE "\n" ";" DPKG_OUTPUT "${DPKG_OUTPUT}")

  unset(_actual_description)
  set(_parse_description FALSE)
  foreach(_line IN LISTS DPKG_OUTPUT)
    if(_line MATCHES " Description:.*")
      set(_parse_description TRUE)
      string(REPLACE " Description: " "" _line "${_line}")
      list(APPEND _actual_description "${_line}")
    elseif(_parse_description)
      if(_line MATCHES " [A-Z][A-Za-z\-]+: .*")
        set(_parse_description FALSE)
      else()
        list(APPEND _actual_description "${_line}")
      endif()
    endif()
  endforeach()
  list(JOIN _actual_description "\n" _actual_description)

  set(${RESULT_VAR} "${_actual_description}" PARENT_SCOPE)
endfunction()

cmake_policy(POP)