#!/usr/bin/env python3 ############################################################################# ## ## Copyright (C) 2018 The Qt Company Ltd. ## Contact: https://www.qt.io/licensing/ ## ## This file is part of the plugins of the Qt Toolkit. ## ## $QT_BEGIN_LICENSE:GPL-EXCEPT$ ## Commercial License Usage ## Licensees holding valid commercial Qt licenses may use this file in ## accordance with the commercial license agreement provided with the ## Software or, alternatively, in accordance with the terms contained in ## a written agreement between you and The Qt Company. For licensing terms ## and conditions see https://www.qt.io/terms-conditions. For further ## information use the contact form at https://www.qt.io/contact-us. ## ## GNU General Public License Usage ## Alternatively, this file may be used under the terms of the GNU ## General Public License version 3 as published by the Free Software ## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ## included in the packaging of this file. Please review the following ## information to ensure the GNU General Public License requirements will ## be met: https://www.gnu.org/licenses/gpl-3.0.html. ## ## $QT_END_LICENSE$ ## ############################################################################# from argparse import ArgumentParser import os import re import subprocess import sys import typing def _parse_commandline(): parser = ArgumentParser(description='Calculate the conversion rate to cmake.') parser.add_argument('--debug', dest='debug', action='store_true', help='Turn on debug output') parser.add_argument('source_directory', metavar='', type=str, help='The Qt module source directory') parser.add_argument('binary_directory', metavar='', type=str, help='The CMake build directory (might be empty)') return parser.parse_args() def calculate_baseline(source_directory: str, *, debug: bool=False) -> int: if debug: print('Scanning "{}" for qmake-based tests.'.format(source_directory)) result = subprocess.run('/usr/bin/git grep -E "^\\s*CONFIG\\s*\\+?=.*\\btestcase\\b" | sort -u | wc -l', shell=True, capture_output=True, cwd=source_directory) return int(result.stdout) def build(source_directory: str, binary_directory: str, *, debug=False) -> None: abs_source = os.path.abspath(source_directory) if not os.path.isdir(binary_directory): os.makedirs(binary_directory) if not os.path.exists(os.path.join(binary_directory, 'CMakeCache.txt')): if debug: print('Running cmake in "{}".'.format(binary_directory)) result = subprocess.run(['/usr/bin/cmake', '-GNinja', abs_source], cwd=binary_directory) if debug: print('CMake return code: {}.'.format(result.returncode)) assert result.returncode == 0 if debug: print('Running ninja in "{}".'.format(binary_directory)) result = subprocess.run('/usr/bin/ninja', cwd=binary_directory) if debug: print('Ninja return code: {}.'.format(result.returncode)) assert result.returncode == 0 def test(binary_directory: str, *, debug=False) -> typing.Tuple[int, int]: if debug: print('Running ctest in "{}".'.format(binary_directory)) result = subprocess.run('/usr/bin/ctest -j 250 | grep "tests passed, "', shell=True, capture_output=True, cwd=binary_directory) summary = result.stdout.decode('utf-8').replace('\n', '') if debug: print('Test summary: {} ({}).'.format(summary, result.returncode)) matches = re.fullmatch(r'\d+% tests passed, (\d+) tests failed out of (\d+)', summary) if matches: if debug: print('Matches: failed {}, total {}.'.format(matches.group(1), matches.group(2))) return (int(matches.group(2)), int(matches.group(2)) - int(matches.group(1)), ) return (0, 0,) def main() -> int: args = _parse_commandline() base_line = calculate_baseline(args.source_directory, debug=args.debug) if base_line <= 0: print('Could not find the qmake baseline in {}.'.format(args.source_directory)) return 1 if args.debug: print('qmake baseline: {} test binaries.'.format(base_line)) cmake_total = 0 cmake_success = 0 try: build(args.source_directory, args.binary_directory, debug=args.debug) (cmake_total, cmake_success, ) = test(args.binary_directory, debug=args.debug) finally: if cmake_total == 0: print('\n\n\nCould not calculate the cmake state.') return 2 else: print('\n\n\nCMake test conversion rate: {:.2%}.'.format(cmake_total / base_line)) print('CMake test success rate : {:.2%}.'.format(cmake_success / base_line)) return 0 if __name__ == '__main__': main()