|
14 | 14 | from time import sleep
|
15 | 15 | from typing import TYPE_CHECKING, Any
|
16 | 16 |
|
| 17 | +from jinja2 import Environment, StrictUndefined, meta |
17 | 18 | from lxml import etree
|
18 | 19 | from lxml.builder import E # type: ignore[import-not-found]
|
19 | 20 | from lxml.etree import Element, SubElement, _Element
|
20 | 21 |
|
21 | 22 | from uwtools.config.formats.yaml import YAMLConfig
|
| 23 | +from uwtools.config.jinja2 import unrendered |
22 | 24 | from uwtools.config.validator import validate_external as validate_yaml
|
23 |
| -from uwtools.exceptions import UWConfigError, UWError |
24 |
| -from uwtools.logging import log |
| 25 | +from uwtools.exceptions import UWConfigError, UWConfigRealizeError, UWError |
| 26 | +from uwtools.logging import INDENT, log |
25 | 27 | from uwtools.utils.file import readable, resource_path, writable
|
26 | 28 | from uwtools.utils.processing import run_shell_cmd
|
27 | 29 |
|
@@ -58,6 +60,15 @@ def realize(config: YAMLConfig | Path | None, output_file: Path | None = None) -
|
58 | 60 | """
|
59 | 61 | rxml = _RocotoXML(config)
|
60 | 62 | xml = str(rxml).strip()
|
| 63 | + if unrendered(xml): |
| 64 | + log.error(xml) |
| 65 | + log.error("Value(s) needed to render this XML are:") |
| 66 | + for var in meta.find_undeclared_variables( |
| 67 | + Environment(undefined=StrictUndefined).parse(xml) |
| 68 | + ): |
| 69 | + log.error("%s%s", INDENT, var) |
| 70 | + msg = "Rocoto XML could not be totally realized" |
| 71 | + raise UWConfigRealizeError(msg) |
61 | 72 | if not validate_string(xml):
|
62 | 73 | msg = "Internal error: Invalid Rocoto XML"
|
63 | 74 | raise UWError(msg)
|
|
0 commit comments