vtk-m/CMake/VTKmCheckCopyright.cmake
Vicente Adolfo Bolea Sanchez d5a90cba1e update readthedocs-sphinx-search
2024-02-14 12:03:42 -05:00

240 lines
7.7 KiB
CMake

##============================================================================
## Copyright (c) Kitware, Inc.
## All rights reserved.
## See LICENSE.txt for details.
##
## This software is distributed WITHOUT ANY WARRANTY; without even
## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
## PURPOSE. See the above copyright notice for more information.
##============================================================================
## This CMake script checks source files for the appropriate VTKM copyright
## statement, which is stored in VTKm_SOURCE_DIR/CMake/VTKmCopyrightStatement.txt.
## To run this script, execute CMake as follows:
##
## cmake -DVTKm_SOURCE_DIR=<VTKm_SOURCE_DIR> -P <VTKm_SOURCE_DIR>/CMake/VTKMCheckCopyright.cmake
##
cmake_minimum_required(VERSION 3.12)
set(FILES_TO_CHECK
*.txt
*.cmake
*.h
*.h.in
*.hxx
*.cxx
*.cu
*.py
*.sh
*.ps1
Dockerfile
*.yaml
*.yml
)
set(EXCEPTIONS
LICENSE.txt
README.txt
docs/users-guide/requirements.txt
)
if (NOT VTKm_SOURCE_DIR)
message(SEND_ERROR "VTKm_SOURCE_DIR not defined.")
endif (NOT VTKm_SOURCE_DIR)
set(copyright_file ${VTKm_SOURCE_DIR}/CMake/VTKmCopyrightStatement.txt)
if (NOT EXISTS ${copyright_file})
message(SEND_ERROR "Cannot find VTKMCopyrightStatement.txt.")
endif (NOT EXISTS ${copyright_file})
set(license_file ${VTKm_SOURCE_DIR}/LICENSE.txt)
if (NOT EXISTS ${license_file})
message(SEND_ERROR "Cannot find LICENSE.txt.")
endif (NOT EXISTS ${license_file})
# Get a list of third party files (with different copyrights) from the
# license file.
file(STRINGS ${license_file} license_lines)
list(FIND
license_lines
"- - - - - - - - - - - - - - - - - - - - - - - - do not remove this line"
separator_index
)
math(EXPR begin_index "${separator_index} + 1")
list(LENGTH license_lines license_file_length)
math(EXPR end_index "${license_file_length} - 1")
foreach (index RANGE ${begin_index} ${end_index})
list(GET license_lines ${index} tpl_file)
set(EXCEPTIONS ${EXCEPTIONS} ${tpl_file})
endforeach(index)
# if the build directory is in the source directory, exclude generated build
# files
find_path(BUILD_DIR CMakeCache.txt .)
get_filename_component(abs_build_dir ${BUILD_DIR} ABSOLUTE)
get_filename_component(build_dir_name ${abs_build_dir} NAME)
set(EXCEPTIONS ${EXCEPTIONS} ${build_dir_name}/*)
message("Copyright Check Exceptions: ${EXCEPTIONS}")
# Gets the current year (if possible).
function (get_year var)
string(TIMESTAMP result "%Y")
set(${var} "${result}" PARENT_SCOPE)
endfunction (get_year)
set(copyright_file_year 2014)
get_year(current_year)
# Escapes ';' characters (list delimiters) and splits the given string into
# a list of its lines without newlines.
function (list_of_lines var string)
string(REGEX REPLACE ";" "\\\\;" conditioned_string "${string}")
string(REGEX REPLACE "\n" ";" conditioned_string "${conditioned_string}")
set(${var} "${conditioned_string}" PARENT_SCOPE)
endfunction (list_of_lines)
# Read in copyright statement file.
file(READ ${copyright_file} COPYRIGHT_STATEMENT)
# Remove trailing whitespace and ending lines. They are sometimes hard to
# see or remove in editors.
string(REGEX REPLACE "[ \t]*\n" "\n" COPYRIGHT_STATEMENT "${COPYRIGHT_STATEMENT}")
string(REGEX REPLACE "\n+$" "" COPYRIGHT_STATEMENT "${COPYRIGHT_STATEMENT}")
# Get a list of lines in the copyright statement.
list_of_lines(COPYRIGHT_LINE_LIST "${COPYRIGHT_STATEMENT}")
# Comment regular expression characters that we want to match literally.
string(REPLACE "." "\\." COPYRIGHT_LINE_LIST "${COPYRIGHT_LINE_LIST}")
string(REPLACE "(" "\\(" COPYRIGHT_LINE_LIST "${COPYRIGHT_LINE_LIST}")
string(REPLACE ")" "\\)" COPYRIGHT_LINE_LIST "${COPYRIGHT_LINE_LIST}")
# Introduce regular expression for years we want to be generic.
string(REPLACE
"${copyright_file_year}"
"20[0-9][0-9]"
COPYRIGHT_LINE_LIST
"${COPYRIGHT_LINE_LIST}"
)
# Replace year in COPYRIGHT_STATEMENT with current year.
string(REPLACE
"${copyright_file_year}"
"${current_year}"
COPYRIGHT_STATEMENT
"${COPYRIGHT_STATEMENT}"
)
# Print an error concerning the missing copyright in the given file.
function(missing_copyright filename comment_prefix)
message("${filename} does not have the appropriate copyright statement:\n")
# Condition the copyright statement
string(REPLACE
"\n"
"\n${comment_prefix} "
comment_copyright
"${COPYRIGHT_STATEMENT}"
)
set(comment_copyright "${comment_prefix} ${comment_copyright}")
string(REPLACE
"\n${comment_prefix} \n"
"\n${comment_prefix}\n"
comment_copyright
"${comment_copyright}"
)
message("${comment_prefix}=============================================================================")
message("${comment_prefix}")
message("${comment_copyright}")
message("${comment_prefix}")
message("${comment_prefix}=============================================================================\n")
message(SEND_ERROR
"Please add the previous statement to the beginning of ${filename}"
)
endfunction(missing_copyright)
# Get an appropriate beginning line comment for the given filename.
function(get_comment_prefix var filename)
get_filename_component(name "${filename}" NAME)
if(name MATCHES "\\.(cmake|py|sh|ps1|yaml|yml)$"
OR name STREQUAL "CMakeLists.txt"
OR name STREQUAL "Dockerfile"
)
set(${var} "##" PARENT_SCOPE)
elseif (name MATCHES "\\.(h|h\\.in|hxx|cxx|cu)$")
set(${var} "//" PARENT_SCOPE)
elseif (name MATCHES "\\.txt$")
set(${var} "" PARENT_SCOPE)
else ()
message(FATAL_ERROR "Could not identify file type of `${name}`.")
endif ()
endfunction(get_comment_prefix)
# Check the given file for the appropriate copyright statement.
function(check_copyright filename)
get_comment_prefix(comment_prefix "${filename}")
# Read in the first 2000 characters of the file and split into lines.
# This is roughly equivalent to the file STRINGS command except that we
# also escape semicolons (list separators) in the input, which the file
# STRINGS command does not currently do.
file(READ "${filename}" header_contents LIMIT 2000)
list_of_lines(header_lines "${header_contents}")
set(printed)
# Check each copyright line.
foreach (copyright_line IN LISTS COPYRIGHT_LINE_LIST)
set(match)
# My original algorithm tried to check the order by removing items from
# header_lines as they were encountered. Unfortunately, CMake 2.8's
# list REMOVE_AT command removed the escaping on the ; in one of the
# header_line's items and cause the compare to fail.
foreach (header_line IN LISTS header_lines)
if (copyright_line)
string(REGEX MATCH
"^${comment_prefix}[ \t]*${copyright_line}[ \t]*$"
match
"${header_line}"
)
else (copyright_line)
if (NOT header_line)
set(match TRUE)
endif (NOT header_line)
endif (copyright_line)
if (match)
break()
endif (match)
endforeach (header_line)
if (NOT match AND NOT printed)
message(STATUS "Could not find match for `${copyright_line}'")
missing_copyright("${filename}" "${comment_prefix}")
set(printed TRUE)
endif (NOT match AND NOT printed)
endforeach (copyright_line)
endfunction(check_copyright)
foreach (glob_expression ${FILES_TO_CHECK})
file(GLOB_RECURSE file_list
RELATIVE "${VTKm_SOURCE_DIR}"
"${VTKm_SOURCE_DIR}/${glob_expression}"
)
foreach (file ${file_list})
set(skip)
foreach(exception ${EXCEPTIONS})
if(file MATCHES "^${exception}(/.*)?$")
# This file is an exception
set(skip TRUE)
endif(file MATCHES "^${exception}(/.*)?$")
endforeach(exception)
if (NOT skip)
check_copyright("${VTKm_SOURCE_DIR}/${file}")
endif (NOT skip)
endforeach (file)
endforeach (glob_expression)