1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#############################################################################
##
## Copyright (C) 2021 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of the release tools 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$
##
#############################################################################
import os
import re
import sys
import argparse
from typing import List, Dict
from configparser import ConfigParser, ExtendedInterpolation
from logging_util import init_logger
log = init_logger(__name__, debug_mode=False)
class ReleaseTaskError(Exception):
pass
class ReleaseTask:
def __init__(self, name: str, settings: Dict[str, str]):
if not len(name.split(".")) >= 3:
raise ReleaseTaskError("The '[{0}]' has too few dot separated elements!".format(name))
self.name = name
self.config_file = settings["config_file"]
self.project_name = settings.get("project_name", "")
self.version = settings.get("version", "")
self.prerelease_version = settings.get("prerelease_version", "")
self.substitutions = settings.get("substitutions", "")
self.repo_path = settings.get("repo_path", "")
self.repo_components_to_update = settings.get("repo_components_to_update", "")
self.installer_name = settings.get("installer_name", "")
self.rta_key_list = settings.get("rta_key_list", "")
tmpList = [x.strip() for x in self.substitutions.split(',')] if self.substitutions else [] # type: List[str]
self.installer_string_replacement_list = list(filter(None, tmpList))
self.source_online_repository_path = ""
self.source_pkg_path = ""
def add_to_substitutions_list(self, substitutions: List[str]) -> None:
self.installer_string_replacement_list += substitutions
def is_repository_task(self) -> bool:
return self.name.split(".")[1] == "repository"
def is_offline_installer_task(self) -> bool:
return self.name.split(".")[1] == "offline"
def is_online_installer_task(self) -> bool:
return self.name.split(".")[1] == "online"
def get_config_file(self) -> str:
return self.config_file
def get_substitutions(self) -> str:
return self.substitutions
def get_installer_string_replacement_list(self) -> List[str]:
return self.installer_string_replacement_list
def get_repo_components_to_update(self) -> str:
return self.repo_components_to_update
def get_installer_name(self) -> str:
return self.installer_name
def get_project_name(self) -> str:
return self.project_name
def get_version(self) -> str:
return self.version
def get_prerelease_version(self) -> str:
return self.prerelease_version.strip()
def get_repo_path(self) -> str:
return self.repo_path
def get_rta_key_list(self) -> List[str]:
tmpList = self.rta_key_list.strip().replace(' ', '').split(",")
return list(filter(None, tmpList))
def get_source_online_repository_path(self) -> str:
# this points to local repository build path
return self.source_online_repository_path
def get_source_pkg_path(self) -> str:
# this points to local repository build path
return self.source_pkg_path
def parse_substitutions_list(parser, section) -> List[str]:
try:
args = parser[section]['substitutions']
return [x.strip() for x in args.split(',')]
except KeyError:
# it's ok, the 'substitutions' is not mandatory
pass
return []
def get_filter_parts(section_filters: str) -> List[str]:
return list(filter(None, re.split("[, ;:]+", section_filters)))
def parse_data(settings, task_filters: List[str]) -> List[ReleaseTask]:
tasks = [] # type: List[ReleaseTask]
common_substitution_list = parse_substitutions_list(settings, 'common.substitutions')
section_filters_list = [get_filter_parts(x) for x in task_filters]
for section in settings.sections():
parts = section.split(".")
if not parts[0].startswith("task"):
continue
appendTask = True
if section_filters_list:
appendTask = False
for section_filters in section_filters_list:
if set(section_filters).issubset(set(parts)):
appendTask = True
break
if appendTask:
log.info("Parsing Task: %s", section)
releaseTask = ReleaseTask(section, settings[section])
releaseTask.add_to_substitutions_list(common_substitution_list)
tasks.append(releaseTask)
else:
log.info("Skipping task: [%s] - not included by task filter(s): %s", section, section_filters_list)
return tasks
def parse_config(configFile: str, task_filters: List[str]) -> List[ReleaseTask]:
if not os.path.isfile(configFile):
raise ReleaseTaskError("Not such file: {0}".format(configFile))
settings = ConfigParser(interpolation=ExtendedInterpolation())
settings.read(configFile)
return parse_data(settings, task_filters)
if __name__ == "__main__":
parser = argparse.ArgumentParser(prog="Script to parse top level release config file")
parser.add_argument("--config", dest="config", type=str, default=os.getenv("RELEASE_DESCRIPTION_FILE"),
help="Path to top level release config file")
parser.add_argument("--task-filter", dest="task_filters", action='append',
help="Task include filters per section name in the --config file to match with " \
"the section name, e.g. 'offline', 'repository', ...")
args = parser.parse_args(sys.argv[1:])
assert os.path.isfile(args.config), "Not a valid file: {0}".format(args.config)
parse_config(args.config, args.task_filters)
|