Fix retaining anchors when using with !j2-yaml

Before this change using an anchor/alias in !j2-yaml resulted in an
exception, even if retain_anchors was set to True:

>      File "(...)/jenkins-job-builder/.tox/py38/lib/python3.8/site-packages/yaml/composer.py", line 68, in compose_node
>    raise ComposerError(None, None, "found undefined alias %r"
>    yaml.composer.ComposerError: found undefined alias '<alias-name-xxx>'

The reason was that LateYamlLoader.get_object_to_format() was calling
load() without retain_anchors=True so effectively it was resetting
anchors during deep formatting...

From now on yaml.load() is called directly to avoid unwanted
side-effects of load() which is meant to be called from other modules,
typically by parser.YamlParser().

Change-Id: I0fde43c5c27ddf78f18dc244d8dba5bd768306b7
This commit is contained in:
Adam Romanek 2021-04-01 14:29:41 +02:00
parent 4393f8ba1a
commit aa5d6a538d
4 changed files with 40 additions and 1 deletions

View File

@ -613,7 +613,10 @@ class LateYamlLoader(CustomLoader):
return LateYamlLoader(self._yaml_str, copy.deepcopy(self._loader, memo))
def get_object_to_format(self):
return load(self._yaml_str, search_path=self._loader._search_path)
return yaml.load(
self._yaml_str,
functools.partial(LocalLoader, search_path=self._loader._search_path),
)
class Jinja2YamlLoader(Jinja2Loader):

View File

@ -0,0 +1,12 @@
- job-template:
name: 'test-job-template'
builders:
- shell:
docker run {docker-image}
- project:
name: test-project
jobs:
- 'test-job-template':
docker-image: !j2-yaml: |
*docker-image

View File

@ -0,0 +1,3 @@
- globals:
name: globals
docker-image: &docker-image "ubuntu:latest"

View File

@ -22,6 +22,7 @@ from yaml.composer import ComposerError
from jenkins_jobs.config import JJBConfig
from jenkins_jobs.parser import YamlParser
from jenkins_jobs.registry import ModuleRegistry
from tests import base
@ -118,3 +119,23 @@ class TestCaseLocalYamlRetainAnchors(base.BaseTestCase):
jjb_config.validate()
j = YamlParser(jjb_config)
j.load_files([os.path.join(self.fixtures_path, f) for f in files])
def test_retain_anchors_enabled_j2_yaml(self):
"""
Verify that anchors are retained across files and are properly retained when using !j2-yaml.
"""
files = [
"custom_retain_anchors_j2_yaml_include001.yaml",
"custom_retain_anchors_j2_yaml.yaml",
]
jjb_config = JJBConfig()
jjb_config.yamlparser["retain_anchors"] = True
jjb_config.validate()
j = YamlParser(jjb_config)
j.load_files([os.path.join(self.fixtures_path, f) for f in files])
registry = ModuleRegistry(jjb_config, None)
jobs, _ = j.expandYaml(registry)
self.assertEqual(jobs[0]["builders"][0]["shell"], "docker run ubuntu:latest")