diff --git a/doc/configuration.rst b/doc/configuration.rst index e084c6f8..08a1d419 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -255,7 +255,10 @@ There a couple common format specifiers available for both the options: * ``disc_type`` **image_name_format** [optional] - (*str*) -- Python's format string to serve as template for image names + (*str|dict*) -- Python's format string to serve as template for image + names. The value can also be a dict mapping variant UID regexes to the + format string. The pattern should not overlap, otherwise it is undefined + which one will be used. This format will be used for all phases generating images. Currently that means ``createiso``, ``live_images`` and ``buildinstall``. diff --git a/pungi/checks.py b/pungi/checks.py index 614be512..fbf925c9 100644 --- a/pungi/checks.py +++ b/pungi/checks.py @@ -810,7 +810,23 @@ def make_schema(): "default": [], }, - "image_name_format": {"type": "string"}, + "image_name_format": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "patternProperties": { + # Warning: this pattern is a variant uid regex, but the + # format does not let us validate it as there is no regular + # expression to describe all regular expressions. + ".+": _one_or_list({"type": "string"}), + }, + "additionalProperties": False, + }, + ], + }, "image_volid_formats": { "$ref": "#/definitions/list_of_strings", "default": [ diff --git a/pungi/compose.py b/pungi/compose.py index 07dd79ee..341124c0 100644 --- a/pungi/compose.py +++ b/pungi/compose.py @@ -35,7 +35,9 @@ from dogpile.cache import make_region from pungi.wrappers.variants import VariantsXmlParser from pungi.paths import Paths from pungi.wrappers.scm import get_file_from_scm -from pungi.util import makedirs, get_arch_variant_data, get_format_substs +from pungi.util import ( + makedirs, get_arch_variant_data, get_format_substs, get_variant_data +) from pungi.metadata import compose_to_composeinfo try: @@ -336,6 +338,10 @@ class Compose(kobo.log.LoggingBase): default_format = "{compose_id}-{variant}-{arch}-{disc_type}{disc_num}{suffix}" format = format or self.conf.get('image_name_format', default_format) + if isinstance(format, dict): + conf = get_variant_data(self.conf, "image_name_format", variant) + format = conf[0] if conf else default_format + if arch == "src": arch = "source" diff --git a/tests/test_compose.py b/tests/test_compose.py index d7969a44..fd007595 100644 --- a/tests/test_compose.py +++ b/tests/test_compose.py @@ -80,6 +80,32 @@ class ComposeTestCase(unittest.TestCase): 'RC-1.0', '1', 'rel_short', '2', '.iso', 'nightly', '.n', 'Server', '3.0'])) + @mock.patch('pungi.compose.ComposeInfo') + def test_get_image_name_variant_mapping(self, ci): + conf = {"image_name_format": {"^Server$": "whatever"}} + variant = mock.Mock(uid='Server', type='variant') + + compose = Compose(conf, self.tmp_dir) + + name = compose.get_image_name( + 'x86_64', variant, disc_num=7, disc_type='live', suffix='.iso' + ) + + self.assertEqual(name, "whatever") + + @mock.patch('pungi.compose.ComposeInfo') + def test_get_image_name_variant_mapping_no_match(self, ci): + conf = {"image_name_format": {"^Client$": "whatever"}} + variant = mock.Mock(uid='Server', type='variant') + ci.return_value.compose.id = 'compose_id' + + compose = Compose(conf, self.tmp_dir) + name = compose.get_image_name( + 'x86_64', variant, disc_num=7, disc_type='live', suffix='.iso' + ) + + self.assertEqual(name, "compose_id-Server-x86_64-live7.iso") + @mock.patch('pungi.compose.ComposeInfo') def test_get_image_name_layered_product(self, ci): conf = {} diff --git a/tests/test_config.py b/tests/test_config.py index abfcaea8..d169aa0d 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -104,6 +104,24 @@ class ReleaseConfigTestCase(ConfigTestCase): checks.CONFLICTS.format('release_is_layered', 'False', 'base_product_version')]) +class ImageNameConfigTestCase(ConfigTestCase): + def test_image_name_simple_string(self): + cfg = load_config( + PKGSET_REPOS, + image_name_format="foobar", + ) + + self.assertValidation(cfg, []) + + def test_image_name_variant_mapping(self): + cfg = load_config( + PKGSET_REPOS, + image_name_format={"^Server$": "foobar"}, + ) + + self.assertValidation(cfg, []) + + class RunrootConfigTestCase(ConfigTestCase): def test_runroot_without_deps(self): cfg = load_config(