30
30
value type is known).
31
31
"""
32
32
33
+ from copy import deepcopy
33
34
import os
34
35
from pathlib import Path
35
36
import re
51
52
52
53
if t .TYPE_CHECKING :
53
54
from optparse import Values
55
+ from typing import Union
54
56
55
57
56
58
# heading/sections can contain commas (namespace name lists) and any
105
107
_UNCLOSED_MULTILINE = re .compile (
106
108
r'(?<![\w>])\[.*\]'
107
109
)
110
+ TEMPLATING_DETECTED = 'templating_detected'
111
+ TEMPLATE_VARIABLES = 'template_variables'
112
+ EXTRA_VARS_TEMPLATE : t .Dict [str , t .Any ] = {
113
+ 'env' : {},
114
+ TEMPLATE_VARIABLES : {},
115
+ TEMPLATING_DETECTED : None
116
+ }
108
117
109
118
110
119
def get_cylc_env_vars () -> t .Dict [str , str ]:
@@ -242,7 +251,7 @@ def multiline(flines, value, index, maxline):
242
251
return quot + newvalue + line , index
243
252
244
253
245
- def process_plugins (fpath , opts ):
254
+ def process_plugins (fpath : 'Union[str, Path]' , opts : 'Values' ):
246
255
"""Run a Cylc pre-configuration plugin.
247
256
248
257
Plugins should return a dictionary containing:
@@ -253,22 +262,25 @@ def process_plugins(fpath, opts):
253
262
or ``empy``.
254
263
255
264
args:
256
- fpath: Directory where the plugin will look for a config.
265
+ fpath: Path to a config file. Plugin will look at the parent
266
+ directory of this file.
257
267
opts: Command line options to be passed to the plugin.
258
268
259
269
Returns: Dictionary in the form:
260
270
extra_vars = {
261
271
'env': {},
262
272
'template_variables': {},
263
- 'templating_detected' : None
273
+ TEMPLATING_DETECTED : None
264
274
}
265
275
"""
276
+ fpath = Path (fpath )
277
+
266
278
# Set out blank dictionary for return:
267
- extra_vars = {
268
- 'env' : {},
269
- 'template_variables' : {},
270
- 'templating_detected' : None
271
- }
279
+ extra_vars = deepcopy ( EXTRA_VARS_TEMPLATE )
280
+
281
+ # Don't run this on global configs:
282
+ if fpath . name == 'global.cylc' :
283
+ return extra_vars
272
284
273
285
# Run entry point pre_configure items, trying to merge values with each.:
274
286
for entry_point in iter_entry_points (
@@ -278,7 +290,7 @@ def process_plugins(fpath, opts):
278
290
# If you want it to work on sourcedirs you need to get the options
279
291
# to here.
280
292
plugin_result = entry_point .load ()(
281
- srcdir = fpath , opts = opts
293
+ srcdir = fpath . parent , opts = opts
282
294
)
283
295
except Exception as exc :
284
296
# NOTE: except Exception (purposefully vague)
@@ -288,7 +300,7 @@ def process_plugins(fpath, opts):
288
300
entry_point .name ,
289
301
exc
290
302
) from None
291
- for section in ['env' , 'template_variables' ]:
303
+ for section in ['env' , TEMPLATE_VARIABLES ]:
292
304
if section in plugin_result and plugin_result [section ] is not None :
293
305
# Raise error if multiple plugins try to update the same keys.
294
306
section_update = plugin_result .get (section , {})
@@ -302,26 +314,20 @@ def process_plugins(fpath, opts):
302
314
)
303
315
extra_vars [section ].update (section_update )
304
316
317
+ templating_detected = plugin_result .get (TEMPLATING_DETECTED , None )
305
318
if (
306
- 'templating_detected' in plugin_result and
307
- plugin_result ['templating_detected' ] is not None and
308
- extra_vars ['templating_detected' ] is not None and
309
- extra_vars ['templating_detected' ] !=
310
- plugin_result ['templating_detected' ]
319
+ templating_detected is not None
320
+ and extra_vars [TEMPLATING_DETECTED ] is not None
321
+ and extra_vars [TEMPLATING_DETECTED ] != templating_detected
311
322
):
312
323
# Don't allow subsequent plugins with different templating_detected
313
324
raise ParsecError (
314
325
"Can't merge templating languages "
315
- f"{ extra_vars ['templating_detected' ]} and "
316
- f"{ plugin_result [ ' templating_detected' ] } "
326
+ f"{ extra_vars [TEMPLATING_DETECTED ]} and "
327
+ f"{ templating_detected } "
317
328
)
318
- elif (
319
- 'templating_detected' in plugin_result and
320
- plugin_result ['templating_detected' ] is not None
321
- ):
322
- extra_vars ['templating_detected' ] = plugin_result [
323
- 'templating_detected'
324
- ]
329
+ else :
330
+ extra_vars [TEMPLATING_DETECTED ] = templating_detected
325
331
326
332
return extra_vars
327
333
@@ -352,8 +358,8 @@ def merge_template_vars(
352
358
>>> merge_template_vars(a, b)
353
359
{'FOO': 42, 'BAZ': 3.14159, 'BAR': 'Hello World'}
354
360
"""
355
- if plugin_result ['templating_detected' ] is not None :
356
- plugin_tvars = plugin_result ['template_variables' ]
361
+ if plugin_result [TEMPLATING_DETECTED ] is not None :
362
+ plugin_tvars = plugin_result [TEMPLATE_VARIABLES ]
357
363
will_be_overwritten = (
358
364
native_tvars .keys () &
359
365
plugin_tvars .keys ()
@@ -456,7 +462,7 @@ def read_and_proc(
456
462
do_jinja2 = True
457
463
do_contin = True
458
464
459
- extra_vars = process_plugins (Path ( fpath ). parent , opts )
465
+ extra_vars = process_plugins (fpath , opts )
460
466
461
467
if not template_vars :
462
468
template_vars = {}
@@ -483,12 +489,12 @@ def read_and_proc(
483
489
484
490
# Fail if templating_detected ≠ hashbang
485
491
process_with = hashbang_and_plugin_templating_clash (
486
- extra_vars ['templating_detected' ], flines
492
+ extra_vars [TEMPLATING_DETECTED ], flines
487
493
)
488
494
# process with EmPy
489
495
if do_empy :
490
496
if (
491
- extra_vars ['templating_detected' ] == 'empy' and
497
+ extra_vars [TEMPLATING_DETECTED ] == 'empy' and
492
498
not process_with and
493
499
process_with != 'empy'
494
500
):
@@ -508,7 +514,7 @@ def read_and_proc(
508
514
# process with Jinja2
509
515
if do_jinja2 :
510
516
if (
511
- extra_vars ['templating_detected' ] == 'jinja2' and
517
+ extra_vars [TEMPLATING_DETECTED ] == 'jinja2' and
512
518
not process_with and
513
519
process_with != 'jinja2'
514
520
):
0 commit comments