Mercurial > libervia-backend
annotate libervia/backend/bridge/bridge_constructor/base_constructor.py @ 4318:27bb22eace65
tests (unit/email gateway): add test for XEP-0131 handling:
rel 451
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 28 Sep 2024 15:59:48 +0200 |
parents | 4cf98f506269 |
children |
rev | line source |
---|---|
3028 | 1 #!/usr/bin/env python3 |
3137 | 2 |
2085 | 3 |
3480
7550ae9cfbac
Renamed the project from "Salut à Toi" to "Libervia":
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
4 # Libervia: an XMPP client |
3479 | 5 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) |
2085 | 6 |
7 # This program is free software: you can redistribute it and/or modify | |
8 # it under the terms of the GNU Affero General Public License as published by | |
9 # the Free Software Foundation, either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU Affero General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU Affero General Public License | |
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | |
20 """base constructor class""" | |
21 | |
4071
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
22 from libervia.backend.bridge.bridge_constructor.constants import Const as C |
3028 | 23 from configparser import NoOptionError |
2085 | 24 import sys |
25 import os | |
26 import os.path | |
27 import re | |
28 from importlib import import_module | |
29 | |
30 | |
31 class ParseError(Exception): | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
32 # Used when the signature parsing is going wrong (invalid signature ?) |
2085 | 33 pass |
34 | |
35 | |
36 class Constructor(object): | |
37 NAME = None # used in arguments parsing, filename will be used if not set | |
38 # following attribute are used by default generation method | |
39 # they can be set to dict of strings using python formatting syntax | |
40 # dict keys will be used to select part to replace (e.g. "signals" key will | |
41 # replace ##SIGNALS_PART## in template), while the value is the format | |
42 # keys starting with "signal" will be used for signals, while ones starting with | |
43 # "method" will be used for methods | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
44 # check D-Bus constructor for an example |
2085 | 45 CORE_FORMATS = None |
46 CORE_TEMPLATE = None | |
47 CORE_DEST = None | |
48 FRONTEND_FORMATS = None | |
49 FRONTEND_TEMPLATE = None | |
50 FRONTEND_DEST = None | |
51 | |
3538
c605a0d6506f
bridge (constructor/base_constructor): add `args_no_default` to `completion`
Goffi <goffi@goffi.org>
parents:
3480
diff
changeset
|
52 # set to False if your bridge needs only core |
2087
159250d66407
bridge (constructor): embedded bridge generator:
Goffi <goffi@goffi.org>
parents:
2085
diff
changeset
|
53 FRONTEND_ACTIVATE = True |
159250d66407
bridge (constructor): embedded bridge generator:
Goffi <goffi@goffi.org>
parents:
2085
diff
changeset
|
54 |
2085 | 55 def __init__(self, bridge_template, options): |
56 self.bridge_template = bridge_template | |
57 self.args = options | |
58 | |
59 @property | |
60 def constructor_dir(self): | |
61 constructor_mod = import_module(self.__module__) | |
62 return os.path.dirname(constructor_mod.__file__) | |
63 | |
64 def getValues(self, name): | |
65 """Return values of a function in a dict | |
66 @param name: Name of the function to get | |
67 @return: dict, each key has the config value or None if the value is not set""" | |
68 function = {} | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
69 for option in ["type", "category", "sig_in", "sig_out", "doc"]: |
2085 | 70 try: |
71 value = self.bridge_template.get(name, option) | |
72 except NoOptionError: | |
73 value = None | |
74 function[option] = value | |
75 return function | |
76 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
77 def get_default(self, name): |
2085 | 78 """Return default values of a function in a dict |
79 @param name: Name of the function to get | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
80 @return: dict, each key is the integer param number (no key if no default value) |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
81 """ |
2085 | 82 default_dict = {} |
83 def_re = re.compile(r"param_(\d+)_default") | |
84 | |
85 for option in self.bridge_template.options(name): | |
86 match = def_re.match(option) | |
87 if match: | |
88 try: | |
89 idx = int(match.group(1)) | |
90 except ValueError: | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
91 raise ParseError( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
92 "Invalid value [%s] for parameter number" % match.group(1) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
93 ) |
2085 | 94 default_dict[idx] = self.bridge_template.get(name, option) |
95 | |
96 return default_dict | |
97 | |
98 def getFlags(self, name): | |
99 """Return list of flags set for this function | |
100 | |
101 @param name: Name of the function to get | |
102 @return: List of flags (string) | |
103 """ | |
104 flags = [] | |
105 for option in self.bridge_template.options(name): | |
106 if option in C.DECLARATION_FLAGS: | |
107 flags.append(option) | |
108 return flags | |
109 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
110 def get_arguments_doc(self, name): |
2085 | 111 """Return documentation of arguments |
112 @param name: Name of the function to get | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
113 @return: dict, each key is the integer param number (no key if no argument doc), value is a tuple (name, doc) |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
114 """ |
2085 | 115 doc_dict = {} |
116 option_re = re.compile(r"doc_param_(\d+)") | |
117 value_re = re.compile(r"^(\w+): (.*)$", re.MULTILINE | re.DOTALL) | |
118 for option in self.bridge_template.options(name): | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
119 if option == "doc_return": |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
120 doc_dict["return"] = self.bridge_template.get(name, option) |
2085 | 121 continue |
122 match = option_re.match(option) | |
123 if match: | |
124 try: | |
125 idx = int(match.group(1)) | |
126 except ValueError: | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
127 raise ParseError( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
128 "Invalid value [%s] for parameter number" % match.group(1) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
129 ) |
2085 | 130 value_match = value_re.match(self.bridge_template.get(name, option)) |
131 if not value_match: | |
132 raise ParseError("Invalid value for parameter doc [%i]" % idx) | |
133 doc_dict[idx] = (value_match.group(1), value_match.group(2)) | |
134 return doc_dict | |
135 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
136 def get_doc(self, name): |
2085 | 137 """Return documentation of the method |
138 @param name: Name of the function to get | |
139 @return: string documentation, or None""" | |
140 if self.bridge_template.has_option(name, "doc"): | |
141 return self.bridge_template.get(name, "doc") | |
142 return None | |
143 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
144 def arguments_parser(self, signature): |
2085 | 145 """Generator which return individual arguments signatures from a global signature""" |
146 start = 0 | |
147 i = 0 | |
148 | |
149 while i < len(signature): | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
150 if signature[i] not in [ |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
151 "b", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
152 "y", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
153 "n", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
154 "i", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
155 "x", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
156 "q", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
157 "u", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
158 "t", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
159 "d", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
160 "s", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
161 "a", |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
162 ]: |
2085 | 163 raise ParseError("Unmanaged attribute type [%c]" % signature[i]) |
164 | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
165 if signature[i] == "a": |
2085 | 166 i += 1 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
167 if ( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
168 signature[i] != "{" and signature[i] != "(" |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
169 ): # FIXME: must manage tuples out of arrays |
2085 | 170 i += 1 |
171 yield signature[start:i] | |
172 start = i | |
173 continue # we have a simple type for the array | |
174 opening_car = signature[i] | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
175 assert opening_car in ["{", "("] |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
176 closing_car = "}" if opening_car == "{" else ")" |
2085 | 177 opening_count = 1 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
178 while True: # we have a dict or a list of tuples |
2085 | 179 i += 1 |
180 if i >= len(signature): | |
181 raise ParseError("missing }") | |
182 if signature[i] == opening_car: | |
183 opening_count += 1 | |
184 if signature[i] == closing_car: | |
185 opening_count -= 1 | |
186 if opening_count == 0: | |
187 break | |
188 i += 1 | |
189 yield signature[start:i] | |
190 start = i | |
191 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
192 def get_arguments(self, signature, name=None, default=None, unicode_protect=False): |
2085 | 193 """Return arguments to user given a signature |
194 | |
195 @param signature: signature in the short form (using s,a,i,b etc) | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
196 @param name: dictionary of arguments name like given by get_arguments_doc |
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
197 @param default: dictionary of default values, like given by get_default |
2085 | 198 @param unicode_protect: activate unicode protection on strings (return strings as unicode(str)) |
2091
f413bfc24458
bridge, quick_frontend: preparation for async bridge
Goffi <goffi@goffi.org>
parents:
2087
diff
changeset
|
199 @return (str): arguments that correspond to a signature (e.g.: "sss" return "arg1, arg2, arg3") |
2085 | 200 """ |
201 idx = 0 | |
202 attr_string = [] | |
203 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
204 for arg in self.arguments_parser(signature): |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
205 attr_string.append( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
206 ( |
3028 | 207 "str(%(name)s)%(default)s" |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
208 if (unicode_protect and arg == "s") |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
209 else "%(name)s%(default)s" |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
210 ) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
211 % { |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
212 "name": name[idx][0] if (name and idx in name) else "arg_%i" % idx, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
213 "default": "=" + default[idx] if (default and idx in default) else "", |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
214 } |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
215 ) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
216 # give arg_1, arg2, etc or name1, name2=default, etc. |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
217 # give unicode(arg_1), unicode(arg_2), etc. if unicode_protect is set and arg is a string |
2085 | 218 idx += 1 |
219 | |
220 return ", ".join(attr_string) | |
221 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
222 def get_template_path(self, template_file): |
2085 | 223 """return template path corresponding to file name |
224 | |
225 @param template_file(str): name of template file | |
226 """ | |
227 return os.path.join(self.constructor_dir, template_file) | |
228 | |
229 def core_completion_method(self, completion, function, default, arg_doc, async_): | |
230 """override this method to extend completion""" | |
231 pass | |
232 | |
233 def core_completion_signal(self, completion, function, default, arg_doc, async_): | |
234 """override this method to extend completion""" | |
235 pass | |
236 | |
237 def frontend_completion_method(self, completion, function, default, arg_doc, async_): | |
238 """override this method to extend completion""" | |
239 pass | |
240 | |
241 def frontend_completion_signal(self, completion, function, default, arg_doc, async_): | |
242 """override this method to extend completion""" | |
243 pass | |
244 | |
245 def generate(self, side): | |
246 """generate bridge | |
247 | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
248 call generate_core_side or generateFrontendSide if they exists |
2085 | 249 else call generic self._generate method |
250 """ | |
251 try: | |
252 if side == "core": | |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
253 method = self.generate_core_side |
2085 | 254 elif side == "frontend": |
2087
159250d66407
bridge (constructor): embedded bridge generator:
Goffi <goffi@goffi.org>
parents:
2085
diff
changeset
|
255 if not self.FRONTEND_ACTIVATE: |
3028 | 256 print("This constructor only handle core, please use core side") |
2087
159250d66407
bridge (constructor): embedded bridge generator:
Goffi <goffi@goffi.org>
parents:
2085
diff
changeset
|
257 sys.exit(1) |
2085 | 258 method = self.generateFrontendSide |
259 except AttributeError: | |
260 self._generate(side) | |
261 else: | |
262 method() | |
263 | |
264 def _generate(self, side): | |
265 """generate the backend | |
266 | |
267 this is a generic method which will use formats found in self.CORE_SIGNAL_FORMAT | |
268 and self.CORE_METHOD_FORMAT (standard format method will be used) | |
269 @param side(str): core or frontend | |
270 """ | |
271 side_vars = [] | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
272 for var in ("FORMATS", "TEMPLATE", "DEST"): |
2085 | 273 attr = "{}_{}".format(side.upper(), var) |
274 value = getattr(self, attr) | |
275 if value is None: | |
276 raise NotImplementedError | |
277 side_vars.append(value) | |
278 | |
279 FORMATS, TEMPLATE, DEST = side_vars | |
280 del side_vars | |
281 | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
282 parts = {part.upper(): [] for part in FORMATS} |
2085 | 283 sections = self.bridge_template.sections() |
284 sections.sort() | |
285 for section in sections: | |
286 function = self.getValues(section) | |
3028 | 287 print(("Adding %s %s" % (section, function["type"]))) |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
288 default = self.get_default(section) |
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
289 arg_doc = self.get_arguments_doc(section) |
2085 | 290 async_ = "async" in self.getFlags(section) |
291 completion = { | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
292 "sig_in": function["sig_in"] or "", |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
293 "sig_out": function["sig_out"] or "", |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
294 "category": "plugin" if function["category"] == "plugin" else "core", |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
295 "name": section, |
2087
159250d66407
bridge (constructor): embedded bridge generator:
Goffi <goffi@goffi.org>
parents:
2085
diff
changeset
|
296 # arguments with default values |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
297 "args": self.get_arguments( |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
298 function["sig_in"], name=arg_doc, default=default |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
299 ), |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
300 "args_no_default": self.get_arguments(function["sig_in"], name=arg_doc), |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
301 } |
2085 | 302 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
303 extend_method = getattr( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
304 self, "{}_completion_{}".format(side, function["type"]) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
305 ) |
2085 | 306 extend_method(completion, function, default, arg_doc, async_) |
307 | |
3028 | 308 for part, fmt in FORMATS.items(): |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
309 if part.startswith(function["type"]) or part.startswith( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
310 f"async_{function['type']}" |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
311 ): |
2085 | 312 parts[part.upper()].append(fmt.format(**completion)) |
313 | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
314 # at this point, signals_part, methods_part and direct_calls should be filled, |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
315 # we just have to place them in the right part of the template |
2085 | 316 bridge = [] |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
317 const_override = { |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
318 env[len(C.ENV_OVERRIDE) :]: v |
3028 | 319 for env, v in os.environ.items() |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
320 if env.startswith(C.ENV_OVERRIDE) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
321 } |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
322 template_path = self.get_template_path(TEMPLATE) |
2085 | 323 try: |
324 with open(template_path) as template: | |
325 for line in template: | |
326 | |
3028 | 327 for part, extend_list in parts.items(): |
4280
4cf98f506269
bridge(constructor): fix template parsing, which was broken following `black` reformating.
Goffi <goffi@goffi.org>
parents:
4270
diff
changeset
|
328 if line.lstrip().startswith("##{}_PART##".format(part)): |
2085 | 329 bridge.extend(extend_list) |
330 break | |
331 else: | |
332 # the line is not a magic part replacement | |
4280
4cf98f506269
bridge(constructor): fix template parsing, which was broken following `black` reformating.
Goffi <goffi@goffi.org>
parents:
4270
diff
changeset
|
333 if line.lstrip().startswith("const_"): |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
334 const_name = line[len("const_") : line.find(" = ")].strip() |
2085 | 335 if const_name in const_override: |
3028 | 336 print(("const {} overriden".format(const_name))) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
337 bridge.append( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
338 "const_{} = {}".format( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
339 const_name, const_override[const_name] |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
340 ) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
341 ) |
2085 | 342 continue |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
343 bridge.append(line.replace("\n", "")) |
2085 | 344 except IOError: |
3028 | 345 print(("can't open template file [{}]".format(template_path))) |
2085 | 346 sys.exit(1) |
347 | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
348 # now we write to final file |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
349 self.final_write(DEST, bridge) |
2085 | 350 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3538
diff
changeset
|
351 def final_write(self, filename, file_buf): |
2085 | 352 """Write the final generated file in [dest dir]/filename |
353 | |
354 @param filename: name of the file to generate | |
355 @param file_buf: list of lines (stings) of the file | |
356 """ | |
357 if os.path.exists(self.args.dest_dir) and not os.path.isdir(self.args.dest_dir): | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
358 print( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
359 "The destination dir [%s] can't be created: a file with this name already exists !" |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
360 ) |
2085 | 361 sys.exit(1) |
362 try: | |
363 if not os.path.exists(self.args.dest_dir): | |
364 os.mkdir(self.args.dest_dir) | |
365 full_path = os.path.join(self.args.dest_dir, filename) | |
366 if os.path.exists(full_path) and not self.args.force: | |
4270
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
367 print( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
368 ( |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
369 "The destination file [%s] already exists ! Use --force to overwrite it" |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
370 % full_path |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
371 ) |
0d7bb4df2343
Reformatted code base using black.
Goffi <goffi@goffi.org>
parents:
4071
diff
changeset
|
372 ) |
2085 | 373 try: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
374 with open(full_path, "w") as dest_file: |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
375 dest_file.write("\n".join(file_buf)) |
2085 | 376 except IOError: |
3028 | 377 print(("Can't open destination file [%s]" % full_path)) |
2085 | 378 except OSError: |
379 print("It's not possible to generate the file, check your permissions") | |
380 exit(1) |