1############################################################################# 2## 3## Copyright (C) 2017 The Qt Company Ltd. 4## Contact: https://www.qt.io/licensing/ 5## 6## This file is part of Qt for Python 7## 8## $QT_BEGIN_LICENSE:LGPL$ 9## Commercial License Usage 10## Licensees holding valid commercial Qt licenses may use this file in 11## accordance with the commercial license agreement provided with the 12## Software or, alternatively, in accordance with the terms contained in 13## a written agreement between you and The Qt Company. For licensing terms 14## and conditions see https://www.qt.io/terms-conditions. For further 15## information use the contact form at https://www.qt.io/contact-us. 16## 17## GNU Lesser General Public License Usage 18## Alternatively, this file may be used under the terms of the GNU Lesser 19## General Public License version 3 as published by the Free Software 20## Foundation and appearing in the file LICENSE.LGPL3 included in the 21## packaging of this file. Please review the following information to 22## ensure the GNU Lesser General Public License version 3 requirements 23## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24## 25## GNU General Public License Usage 26## Alternatively, this file may be used under the terms of the GNU 27## General Public License version 2.0 or (at your option) the GNU General 28## Public license version 3 or any later version approved by the KDE Free 29## Qt Foundation. The licenses are as published by the Free Software 30## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31## included in the packaging of this file. Please review the following 32## information to ensure the GNU General Public License requirements will 33## be met: https://www.gnu.org/licenses/gpl-2.0.html and 34## https://www.gnu.org/licenses/gpl-3.0.html. 35## 36## $QT_END_LICENSE$ 37## 38############################################################################# 39 40from __future__ import print_function 41 42""" 43testing/buildlog.py 44 45A BuildLog holds the tests of a build. 46 47BuildLog.classifiers finds the set of classifier strings. 48""" 49 50import os 51import sys 52import shutil 53from collections import namedtuple 54from textwrap import dedent 55 56from .helper import script_dir 57 58LogEntry = namedtuple("LogEntry", ["log_dir", "build_dir", "build_classifiers"]) 59is_ci = os.environ.get("QTEST_ENVIRONMENT", "") == "ci" 60 61 62class BuildLog(object): 63 """ 64 This class is a convenience wrapper around a list of log entries. 65 66 The list of entries is sorted by date and checked for consistency. 67 For simplicity and readability, the log entries are named tuples. 68 69 """ 70 def __init__(self): 71 history_dir = os.path.join(script_dir, 'build_history') 72 build_history = [] 73 for timestamp in os.listdir(history_dir): 74 log_dir = os.path.join(history_dir, timestamp) 75 if not os.path.isdir(log_dir): 76 continue 77 fpath = os.path.join(log_dir, 'build_dir.txt') 78 if not os.path.exists(fpath): 79 continue 80 with open(fpath) as f: 81 f_contents = f.read().strip() 82 f_contents_split = f_contents.splitlines() 83 try: 84 if len(f_contents_split) == 2: 85 build_dir = f_contents_split[0] 86 build_classifiers = f_contents_split[1] 87 else: 88 build_dir = f_contents_split[0] 89 build_classifiers = "" 90 except IndexError: 91 print(dedent(""" 92 Error: There was an issue finding the build dir and its 93 characteristics, in the following considered file: '{}' 94 """.format(fpath))) 95 sys.exit(1) 96 97 if not os.path.exists(build_dir): 98 rel_dir, low_part = os.path.split(build_dir) 99 rel_dir, two_part = os.path.split(rel_dir) 100 if two_part.startswith("pyside") and two_part.endswith("build"): 101 build_dir = os.path.abspath(os.path.join(two_part, low_part)) 102 if os.path.exists(build_dir): 103 print("Note: build_dir was probably moved.") 104 else: 105 print("Warning: missing build dir %s" % build_dir) 106 continue 107 entry = LogEntry(log_dir, build_dir, build_classifiers) 108 build_history.append(entry) 109 # we take the latest build for now. 110 build_history.sort() 111 self.history = build_history 112 self._buildno = None 113 if not is_ci: 114 # there seems to be a timing problem in RHel 7.6, so we better don't touch it 115 self.prune_old_entries(history_dir) 116 117 def prune_old_entries(self, history_dir): 118 lst = [] 119 for timestamp in os.listdir(history_dir): 120 log_dir = os.path.join(history_dir, timestamp) 121 if not os.path.isdir(log_dir): 122 continue 123 lst.append(log_dir) 124 if lst: 125 def warn_problem(func, path, exc_info): 126 cls, ins, tb = exc_info 127 print("rmtree({}) warning: problem with {}:\n {}: {}".format( 128 func.__name__, path, 129 cls.__name__, ins.args)) 130 131 lst.sort() 132 log_dir = lst[-1] 133 fname = os.path.basename(log_dir) 134 ref_date_str = fname[:10] 135 for log_dir in lst: 136 fname = os.path.basename(log_dir) 137 date_str = fname[:10] 138 if date_str != ref_date_str: 139 shutil.rmtree(log_dir, onerror=warn_problem) 140 141 def set_buildno(self, buildno): 142 self.history[buildno] # test 143 self._buildno = buildno 144 145 @property 146 def selected(self): 147 if self._buildno is None: 148 return None 149 if self.history is None: 150 return None 151 return self.history[self._buildno] 152 153 @property 154 def classifiers(self): 155 if not self.selected: 156 raise ValueError('+++ No build with the configuration found!') 157 # Python2 legacy: Correct 'linux2' to 'linux', recommended way. 158 platform = 'linux' if sys.platform.startswith('linux') else sys.platform 159 res = [platform] 160 if self.selected.build_classifiers: 161 # Use classifier string encoded into build_dir.txt file. 162 res.extend(self.selected.build_classifiers.split('-')) 163 else: 164 # the rest must be guessed from the given filename 165 path = self.selected.build_dir 166 base = os.path.basename(path) 167 res.extend(base.split('-')) 168 # add all the python and qt subkeys 169 for entry in res: 170 parts = entry.split(".") 171 for idx in range(len(parts)): 172 key = ".".join(parts[:idx]) 173 if key not in res: 174 res.append(key) 175 return res 176 177builds = BuildLog() 178