diff --git a/kde-modules/KDECMakeSettings.cmake b/kde-modules/KDECMakeSettings.cmake --- a/kde-modules/KDECMakeSettings.cmake +++ b/kde-modules/KDECMakeSettings.cmake @@ -186,6 +186,14 @@ endif() endfunction() +find_package(Python3 COMPONENTS Interpreter QUIET) +function(httpcheck) + if(TARGET Python3::Interpreter AND NOT httpcheck_added) + set(httpcheck_added TRUE PARENT_SCOPE) + add_test(NAME httpcheck COMMAND Python3::Interpreter ${CMAKE_CURRENT_LIST_DIR}/httpcheck.py ${CMAKE_SOURCE_DIR}) + endif() +endfunction() + if(NOT KDE_SKIP_TEST_SETTINGS) # If there is a CTestConfig.cmake, include CTest. @@ -199,6 +207,7 @@ if(BUILD_TESTING) enable_testing() appstreamtest() + httpcheck() endif () endif () diff --git a/kde-modules/httpcheck.py b/kde-modules/httpcheck.py new file mode 100644 --- /dev/null +++ b/kde-modules/httpcheck.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 + +# Copyright 2019 Sandro Knauß +# Copyright 2019 Volker Krause +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import json +import os +import re +import sys + +NONMATCHES = [ + r"HTTPSCHECK_IGNORE: true", # manual ignore a line. + r"http://www.kde.org/standards/kcfg/", + r"http://www.kde.org/standards/kxmlgui/", + r"http://www.freedesktop.org/standards/", + r"http://www.w3.org/", + r"xmlns", + r"rdf:resource", + r"!DOCTYPE", + r"http://www.inkscape.org/\) -->", + r"http://purl.org/", + r"http://schema.org", + r"http://xml.org/sax/", + r"schemas.google.com", + r"schemas.microsoft.com", + r"semanticdesktop.org/onto", + r"http://nepomuk.kde.org/ontologies/", + r"Generator: DocBook XSL Stylesheets .* ", + r"http://www.gnu.org/licenses/", # Technically this is an issue, but all license headers have this url in place and hiding the real issues. + r"http://www.qt-project.org/legal/", # Technically this is an issue, but we refer it a lot in headers, as we copy a lot form Qt +] + +class HTTPChecker: + def __init__(self, nonmatches): + self.nonmatches = nonmatches + self.reNonmatches = list(map(lambda r:re.compile(r,re.I), nonmatches)) + self.matcher = re.compile(r'http', re.I) + + def checkFile(self, fpath): + findings = [] + with open(fpath, 'r') as f: + if fpath.startswith('./'): + fpath = fpath[2:] + linenumber = 0 + for line in f: + linenumber += 1 + m = self.matcher.search(line) + if m: + if not any(map(lambda r: r.search(line), self.reNonmatches)): + print("{}:{}:\t{}".format(fpath,linenumber,line.strip())) + findings.append((linenumber, line)) + return findings + +def main(): + nonmatches = NONMATCHES.copy() + overwrites = {} + path = "." + if len(sys.argv) > 1: + path = sys.argv[1] + try: + with open(os.path.join(path, '.httpcheck-overwrite')) as f: + for line in f: + nonmatches.append(line) + except FileNotFoundError: + pass + checker = HTTPChecker(nonmatches) + findings = {} + for dirpath, dirnames, filenames in os.walk(path): + parts = dirpath.split("/") + if any(map(lambda p: p in parts, ['.git', 'tests', 'autotests'])): + continue + for fname in filenames: + try: + fpath = os.path.join(dirpath, fname) + issues = checker.checkFile(fpath) + if issues: + findings[fpath] = issues + except UnicodeDecodeError: + pass + if findings: + sys.exit(1) + else: + sys.exit(0) + + + +if __name__ == "__main__": + main()