# Built-in cache documentation structural-parity lint. # # The table ``Source/cmCacheDocumentationTable.cxx`` is hand-maintained; # its set of entries is the curated list of CMake cache variables for # which ``cmake-gui`` and ``ccmake`` surface a built-in tooltip when the # on-disk ``HELPSTRING`` is empty (the common case for variables a user # sets via ``-D`` without an accompanying docstring). # # The sibling table ``Source/cmCachePatternTable.cxx`` carries the # placeholder-shaped fallbacks (``CMAKE__FLAGS``, # ``CMAKE_POLICY_DEFAULT_CMP``, ``_VERSION``, ...). # Patterns store their placeholder names with angle brackets; the # corresponding ``Help/variable/.rst`` filenames carry the same # placeholder tokens with the brackets stripped. # # Drift between an entry's wording and its source ``Help/variable/*.rst`` # manual is handled by reviewer discipline : when an ``.rst`` is reworded, # the matching table entry is reviewed in the same change. This test # therefore enforces only the one piece of drift that a human reviewer # would not naturally catch: that every entry NAME in both tables still # resolves to an existing ``Help/variable/.rst`` file (so the # tooltip is never silently divorced from a real manual via a typo, a # rename, or a deletion). if(NOT DEFINED CMake_SOURCE_DIR OR NOT IS_DIRECTORY "${CMake_SOURCE_DIR}") message(FATAL_ERROR "CacheVarHelpCoverage: CMake_SOURCE_DIR was not provided.") endif() set(_help_dir "${CMake_SOURCE_DIR}/Help/variable") set(_table_file "${CMake_SOURCE_DIR}/Source/cmCacheDocumentationTable.cxx") set(_pattern_file "${CMake_SOURCE_DIR}/Source/cmCachePatternTable.cxx") if(NOT IS_DIRECTORY "${_help_dir}") message(FATAL_ERROR "CacheVarHelpCoverage: ${_help_dir} does not exist.") endif() if(NOT EXISTS "${_table_file}") message(FATAL_ERROR "CacheVarHelpCoverage: ${_table_file} does not exist.") endif() if(NOT EXISTS "${_pattern_file}") message(FATAL_ERROR "CacheVarHelpCoverage: ${_pattern_file} does not exist.") endif() # Extract entry names from the C++ exact-match table. Each entry begins # with the fixed pattern ``\n { "NAME",``; see the header comment in # cmCacheDocumentationTable.cxx for the layout convention. file(READ "${_table_file}" _table_text) string(REGEX MATCHALL "\n \\{ \"[^\"]+\"" _hits "${_table_text}") set(_table_names) foreach(_hit IN LISTS _hits) string(REGEX REPLACE "^\n \\{ \"" "" _name "${_hit}") string(REGEX REPLACE "\"$" "" _name "${_name}") list(APPEND _table_names "${_name}") endforeach() list(SORT _table_names) # Extract entry patterns from the C++ pattern table. Same row shape as # above; the pattern strings carry angle-bracketed placeholders like # ``CMAKE__FLAGS`` or ``_VERSION``. Strip the # angle brackets to derive the matching ``.rst`` basename # (``CMAKE_LANG_FLAGS.rst`` etc.). file(READ "${_pattern_file}" _pattern_text) string(REGEX MATCHALL "\n \\{ \"[^\"]+\"" _phits "${_pattern_text}") set(_pattern_names) foreach(_hit IN LISTS _phits) string(REGEX REPLACE "^\n \\{ \"" "" _name "${_hit}") string(REGEX REPLACE "\"$" "" _name "${_name}") list(APPEND _pattern_names "${_name}") endforeach() list(SORT _pattern_names) # Table entries whose NAME does not match an existing # Help/variable/.rst manual. set(_missing_exact) foreach(_name IN LISTS _table_names) if(NOT EXISTS "${_help_dir}/${_name}.rst") list(APPEND _missing_exact "${_name}") endif() endforeach() # Pattern entries whose NAME (with ``<`` and ``>`` stripped) does not # match an existing Help/variable/.rst manual. set(_missing_pattern) foreach(_name IN LISTS _pattern_names) string(REPLACE "<" "" _basename "${_name}") string(REPLACE ">" "" _basename "${_basename}") if(NOT EXISTS "${_help_dir}/${_basename}.rst") list(APPEND _missing_pattern "${_name}") endif() endforeach() if(_missing_exact OR _missing_pattern) set(_msg "Built-in cache documentation coverage check failed.") if(_missing_exact) list(LENGTH _missing_exact _n) string(APPEND _msg "\n\n${_n} entry/entries in Source/cmCacheDocumentationTable.cxx" "\nhave no matching Help/variable/.rst manual:") foreach(_name IN LISTS _missing_exact) string(APPEND _msg "\n ${_name}") endforeach() endif() if(_missing_pattern) list(LENGTH _missing_pattern _n) string(APPEND _msg "\n\n${_n} entry/entries in Source/cmCachePatternTable.cxx" "\nhave no matching Help/variable/.rst manual (the " "placeholder tokens carry through verbatim with ``<``/``>`` " "stripped):") foreach(_name IN LISTS _missing_pattern) string(REPLACE "<" "" _basename "${_name}") string(REPLACE ">" "" _basename "${_basename}") string(APPEND _msg "\n ${_name} -> ${_basename}.rst") endforeach() endif() string(APPEND _msg "\n\nLikely causes and remedies:" "\n * The entry NAME / Pattern is misspelled -- fix the spelling." "\n * Help/variable/.rst was renamed -- update the entry to" "\n match the new filename." "\n * Help/variable/.rst was deleted intentionally -- remove" "\n the corresponding entry from the table.") message(FATAL_ERROR "${_msg}") endif() list(LENGTH _table_names _n_tab) list(LENGTH _pattern_names _n_pat) message(STATUS "Built-in cache documentation coverage OK: " "${_n_tab} exact entry/entries + ${_n_pat} pattern entry/entries, " "all matched to Help/variable/*.rst.")