import libmodulemd-2.8.2-1.el8
This commit is contained in:
parent
f1c27fa518
commit
d123d4c82c
3
.gitignore
vendored
3
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
SOURCES/modulemd-2.5.0.tar.xz
|
SOURCES/modulemd-1.8.16.tar.xz
|
||||||
|
SOURCES/modulemd-2.8.2.tar.xz
|
||||||
|
@ -1 +1,2 @@
|
|||||||
2b6c3443a36ec821fd289ae6605e9dea4c5dbcda SOURCES/modulemd-2.5.0.tar.xz
|
6e55eddb35afc4cd28b6d8cb248f821af5f49dd7 SOURCES/modulemd-1.8.16.tar.xz
|
||||||
|
9846728616cff38995764e9b4315889ecb3d4637 SOURCES/modulemd-2.8.2.tar.xz
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
From 1a7bf143761ff8e3f4f6585b82c0be4dbd511fca Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
Date: Thu, 23 May 2019 14:00:36 -0400
|
|
||||||
Subject: [PATCH 1/8] Double valgrind timeout
|
|
||||||
|
|
||||||
On some architectures under heavy load, the valgrind check on v2
|
|
||||||
is taking a long time.
|
|
||||||
|
|
||||||
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
---
|
|
||||||
modulemd/meson.build | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/modulemd/meson.build b/modulemd/meson.build
|
|
||||||
index 47bd1f58e6401d2634d8ff737c2b347f5ebc6bf5..e49c7a9df76dcf37a18ddeba3150d6c914aa4e25 100644
|
|
||||||
--- a/modulemd/meson.build
|
|
||||||
+++ b/modulemd/meson.build
|
|
||||||
@@ -315,5 +315,5 @@ if valgrind.found()
|
|
||||||
test ('valgrind', python3,
|
|
||||||
env : test_env,
|
|
||||||
args : modulemd_valgrind_scripts,
|
|
||||||
- timeout : 600)
|
|
||||||
+ timeout : 1200)
|
|
||||||
endif
|
|
||||||
--
|
|
||||||
2.23.0
|
|
||||||
|
|
@ -1,125 +0,0 @@
|
|||||||
From d9b41f72d4b2d545b2600aff7bd8a27ed0093750 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
Date: Wed, 29 May 2019 11:33:57 -0400
|
|
||||||
Subject: [PATCH 2/8] Parallelize the valgrind tests
|
|
||||||
|
|
||||||
This considerably reduces the time needed to perform the valgrind
|
|
||||||
memory tests on systems with multiple available processors. In the
|
|
||||||
case of my laptop, the duration was reduced from ~200s to 90s.
|
|
||||||
|
|
||||||
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
---
|
|
||||||
modulemd/common/tests/test-valgrind.py | 74 ++++++++++++++------------
|
|
||||||
1 file changed, 41 insertions(+), 33 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/modulemd/common/tests/test-valgrind.py b/modulemd/common/tests/test-valgrind.py
|
|
||||||
index 9be72c705fde79aa305d831eaa4f31f7e2cc663f..9349749658ccca0529776f3d534664d614c1cb4d 100644
|
|
||||||
--- a/modulemd/common/tests/test-valgrind.py
|
|
||||||
+++ b/modulemd/common/tests/test-valgrind.py
|
|
||||||
@@ -18,9 +18,12 @@ import subprocess
|
|
||||||
import tempfile
|
|
||||||
import xml.etree.ElementTree as ET
|
|
||||||
|
|
||||||
+from multiprocessing import Pool, TimeoutError
|
|
||||||
+
|
|
||||||
if os.getenv('MMD_SKIP_VALGRIND'):
|
|
||||||
sys.exit(77)
|
|
||||||
|
|
||||||
+
|
|
||||||
failed = False
|
|
||||||
|
|
||||||
# Get the list of tests to run
|
|
||||||
@@ -49,9 +52,9 @@ for test in unfiltered_tests:
|
|
||||||
continue
|
|
||||||
tests.append(test)
|
|
||||||
|
|
||||||
+
|
|
||||||
with tempfile.TemporaryDirectory(prefix="libmodulemd_valgrind_") as tmpdirname:
|
|
||||||
- for test in tests:
|
|
||||||
- # TODO: auto-detect the location of the suppression file
|
|
||||||
+ def exec_valgrind(test):
|
|
||||||
valgrind_command = "/usr/bin/valgrind " \
|
|
||||||
"--leak-check=full " \
|
|
||||||
"--suppressions=/usr/share/glib-2.0/valgrind/glib.supp " \
|
|
||||||
@@ -66,42 +69,47 @@ with tempfile.TemporaryDirectory(prefix="libmodulemd_valgrind_") as tmpdirname:
|
|
||||||
'--wrap=%s' % valgrind_command,
|
|
||||||
test])
|
|
||||||
|
|
||||||
- if proc_result.returncode != 0:
|
|
||||||
- print("Valgrind exited with an error on %s" % test,
|
|
||||||
- file=sys.stderr)
|
|
||||||
- failed = True
|
|
||||||
- continue
|
|
||||||
+ return proc_result.returncode, test
|
|
||||||
|
|
||||||
- # Process the XML for leaks
|
|
||||||
- tree = ET.parse('%s/%s.xml' % (tmpdirname, test))
|
|
||||||
- root = tree.getroot()
|
|
||||||
+ with Pool() as pool:
|
|
||||||
+ for returncode, test in pool.map(exec_valgrind, tests):
|
|
||||||
+ if returncode != 0:
|
|
||||||
+ print("Valgrind exited with an error on %s" % test,
|
|
||||||
+ file=sys.stderr)
|
|
||||||
+ failed = True
|
|
||||||
+ continue
|
|
||||||
|
|
||||||
- for root_child in root:
|
|
||||||
- if (root_child.tag == "error"):
|
|
||||||
- for error_child in root_child:
|
|
||||||
- if error_child.tag == 'kind':
|
|
||||||
- if error_child.text == 'Leak_DefinitelyLost':
|
|
||||||
- print("Memory leak detected in %s" % test,
|
|
||||||
- file=sys.stderr)
|
|
||||||
- failed = True
|
|
||||||
+ # Process the XML for leaks
|
|
||||||
+ tree = ET.parse('%s/%s.xml' % (tmpdirname, test))
|
|
||||||
+ root = tree.getroot()
|
|
||||||
|
|
||||||
- elif error_child.text == 'InvalidFree':
|
|
||||||
- print("Invalid free() detected in %s" % test,
|
|
||||||
- file=sys.stderr)
|
|
||||||
- failed = True
|
|
||||||
+ for root_child in root:
|
|
||||||
+ if (root_child.tag == "error"):
|
|
||||||
+ for error_child in root_child:
|
|
||||||
+ if error_child.tag == 'kind':
|
|
||||||
+ if error_child.text == 'Leak_DefinitelyLost':
|
|
||||||
+ print("Memory leak detected in %s" % test,
|
|
||||||
+ file=sys.stderr)
|
|
||||||
+ failed = True
|
|
||||||
|
|
||||||
- elif error_child.text == 'InvalidRead':
|
|
||||||
- print("Invalid read detected in %s" % test,
|
|
||||||
- file=sys.stderr)
|
|
||||||
- failed = True
|
|
||||||
+ elif error_child.text == 'InvalidFree':
|
|
||||||
+ print("Invalid free() detected in %s" % test,
|
|
||||||
+ file=sys.stderr)
|
|
||||||
+ failed = True
|
|
||||||
|
|
||||||
- elif error_child.text == 'UninitCondition':
|
|
||||||
- print("Uninitialized usage detected in %s" % test,
|
|
||||||
- file=sys.stderr)
|
|
||||||
- failed = True
|
|
||||||
- if failed:
|
|
||||||
- with open('%s/%s.xml' % (tmpdirname, test), 'r') as xml:
|
|
||||||
- print(xml.read())
|
|
||||||
+ elif error_child.text == 'InvalidRead':
|
|
||||||
+ print("Invalid read detected in %s" % test,
|
|
||||||
+ file=sys.stderr)
|
|
||||||
+ failed = True
|
|
||||||
+
|
|
||||||
+ elif error_child.text == 'UninitCondition':
|
|
||||||
+ print(
|
|
||||||
+ "Uninitialized usage detected in %s" %
|
|
||||||
+ test, file=sys.stderr)
|
|
||||||
+ failed = True
|
|
||||||
+ if failed:
|
|
||||||
+ with open('%s/%s.xml' % (tmpdirname, test), 'r') as xml:
|
|
||||||
+ print(xml.read())
|
|
||||||
|
|
||||||
|
|
||||||
if failed:
|
|
||||||
--
|
|
||||||
2.23.0
|
|
||||||
|
|
@ -1,136 +0,0 @@
|
|||||||
From 340e316bd6384562086b4e381c8cd42b1ccd0781 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
Date: Tue, 28 May 2019 14:28:30 -0400
|
|
||||||
Subject: [PATCH 3/8] Fix transfer type for Module.search_streams()
|
|
||||||
|
|
||||||
Technically this is an API-breaking change, but no one is using it
|
|
||||||
yet and it was always expected to be managed this way.
|
|
||||||
|
|
||||||
Fixes: https://github.com/fedora-modularity/libmodulemd/issues/308
|
|
||||||
|
|
||||||
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
---
|
|
||||||
modulemd/meson.build | 1 +
|
|
||||||
.../v2/include/modulemd-2.0/modulemd-module.h | 4 +-
|
|
||||||
modulemd/v2/meson.build | 17 ++++++-
|
|
||||||
modulemd/v2/tests/ModulemdTests/module.py | 46 +++++++++++++++++++
|
|
||||||
4 files changed, 65 insertions(+), 3 deletions(-)
|
|
||||||
create mode 100644 modulemd/v2/tests/ModulemdTests/module.py
|
|
||||||
|
|
||||||
diff --git a/modulemd/meson.build b/modulemd/meson.build
|
|
||||||
index e49c7a9df76dcf37a18ddeba3150d6c914aa4e25..e5912d4041ba3e427d13b98c0eeca5217d48244b 100644
|
|
||||||
--- a/modulemd/meson.build
|
|
||||||
+++ b/modulemd/meson.build
|
|
||||||
@@ -231,6 +231,7 @@ test_v2_python_scripts = files(
|
|
||||||
'v2/tests/ModulemdTests/defaultsv1.py',
|
|
||||||
'v2/tests/ModulemdTests/dependencies.py',
|
|
||||||
'v2/tests/ModulemdTests/merger.py',
|
|
||||||
+ 'v2/tests/ModulemdTests/module.py',
|
|
||||||
'v2/tests/ModulemdTests/moduleindex.py',
|
|
||||||
'v2/tests/ModulemdTests/modulestream.py',
|
|
||||||
'v2/tests/ModulemdTests/profile.py',
|
|
||||||
diff --git a/modulemd/v2/include/modulemd-2.0/modulemd-module.h b/modulemd/v2/include/modulemd-2.0/modulemd-module.h
|
|
||||||
index 45be9c0ae96e203707da61d84f18c71c4a826035..0219cfe227652813d20bdf736f9033782084c5ad 100644
|
|
||||||
--- a/modulemd/v2/include/modulemd-2.0/modulemd-module.h
|
|
||||||
+++ b/modulemd/v2/include/modulemd-2.0/modulemd-module.h
|
|
||||||
@@ -131,8 +131,8 @@ modulemd_module_get_stream_by_NSVC (ModulemdModule *self,
|
|
||||||
* @arch: (nullable): The processor architecture of the stream to retrieve. If
|
|
||||||
* NULL, the architecture is not included in the search.
|
|
||||||
*
|
|
||||||
- * Returns: (transfer full) (element-type ModulemdModuleStream): The list of
|
|
||||||
- * stream objects matching the requested parameters. This function cannot
|
|
||||||
+ * Returns: (transfer container) (element-type ModulemdModuleStream): The list
|
|
||||||
+ * of stream objects matching the requested parameters. This function cannot
|
|
||||||
* fail, but it may return a zero-length list if no matches were found. The
|
|
||||||
* returned streams will be in a predictable order, sorted first by stream
|
|
||||||
* name, then by version (highest to lowest), then by context and finally by
|
|
||||||
diff --git a/modulemd/v2/meson.build b/modulemd/v2/meson.build
|
|
||||||
index 3f45db2c4e0e9a8996c74dffd949d5276082dc6f..e8a5a38f0528c4f860f0b84ef63609ff5fd89caa 100644
|
|
||||||
--- a/modulemd/v2/meson.build
|
|
||||||
+++ b/modulemd/v2/meson.build
|
|
||||||
@@ -392,6 +392,22 @@ test ('dependencies_python2_release', python2,
|
|
||||||
env : py_test_release_env,
|
|
||||||
args : dependencies_python_script)
|
|
||||||
|
|
||||||
+# -- Test Modulemd.Module (Python) -- #
|
|
||||||
+module_python_script = files('tests/ModulemdTests/module.py')
|
|
||||||
+test ('module_python3_debug', python3,
|
|
||||||
+ env : py_test_env,
|
|
||||||
+ args : module_python_script)
|
|
||||||
+test ('module_python3_release', python3,
|
|
||||||
+ env : py_test_release_env,
|
|
||||||
+ args : module_python_script)
|
|
||||||
+
|
|
||||||
+test ('module_python2_debug', python2,
|
|
||||||
+ env : py_test_env,
|
|
||||||
+ args : module_python_script)
|
|
||||||
+test ('module_python2_release', python2,
|
|
||||||
+ env : py_test_release_env,
|
|
||||||
+ args : module_python_script)
|
|
||||||
+
|
|
||||||
# -- Test Modulemd.ModuleIndex (Python) -- #
|
|
||||||
moduleindex_python_script = files('tests/ModulemdTests/moduleindex.py')
|
|
||||||
test ('moduleindex_python3_debug', python3,
|
|
||||||
@@ -401,7 +417,6 @@ test ('moduleindex_python3_release', python3,
|
|
||||||
env : py_test_release_env,
|
|
||||||
args : moduleindex_python_script)
|
|
||||||
|
|
||||||
-moduleindex_python_script = files('tests/ModulemdTests/moduleindex.py')
|
|
||||||
test ('moduleindex_python2_debug', python2,
|
|
||||||
env : py_test_env,
|
|
||||||
args : moduleindex_python_script)
|
|
||||||
diff --git a/modulemd/v2/tests/ModulemdTests/module.py b/modulemd/v2/tests/ModulemdTests/module.py
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..b604d9c9b357c4a5211d3ba5b4d0aba08c3a42bd
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/modulemd/v2/tests/ModulemdTests/module.py
|
|
||||||
@@ -0,0 +1,46 @@
|
|
||||||
+#!/usr/bin/python3
|
|
||||||
+
|
|
||||||
+# This file is part of libmodulemd
|
|
||||||
+# Copyright (C) 2017-2018 Stephen Gallagher
|
|
||||||
+#
|
|
||||||
+# Fedora-License-Identifier: MIT
|
|
||||||
+# SPDX-2.0-License-Identifier: MIT
|
|
||||||
+# SPDX-3.0-License-Identifier: MIT
|
|
||||||
+#
|
|
||||||
+# This program is free software.
|
|
||||||
+# For more information on the license, see COPYING.
|
|
||||||
+# For more information on free software, see
|
|
||||||
+# <https://www.gnu.org/philosophy/free-sw.en.html>.
|
|
||||||
+
|
|
||||||
+from os import path
|
|
||||||
+import sys
|
|
||||||
+try:
|
|
||||||
+ import unittest
|
|
||||||
+ import gi
|
|
||||||
+ gi.require_version('Modulemd', '2.0')
|
|
||||||
+ from gi.repository import Modulemd
|
|
||||||
+ from gi.repository.Modulemd import ModuleIndex
|
|
||||||
+ from gi.repository import GLib
|
|
||||||
+except ImportError:
|
|
||||||
+ # Return error 77 to skip this test on platforms without the necessary
|
|
||||||
+ # python modules
|
|
||||||
+ sys.exit(77)
|
|
||||||
+
|
|
||||||
+from base import TestBase
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+class TestModule(TestBase):
|
|
||||||
+
|
|
||||||
+ def test_search_streams(self):
|
|
||||||
+ idx = Modulemd.ModuleIndex.new()
|
|
||||||
+ idx.update_from_file(path.join(self.source_root,
|
|
||||||
+ "modulemd/v2/tests/test_data/f29.yaml"),
|
|
||||||
+ True)
|
|
||||||
+ module = idx.get_module('nodejs')
|
|
||||||
+
|
|
||||||
+ self.assertEquals(len(module.search_streams('8', 0)), 1)
|
|
||||||
+ self.assertEquals(len(module.search_streams('10', 0)), 1)
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+if __name__ == '__main__':
|
|
||||||
+ unittest.main()
|
|
||||||
--
|
|
||||||
2.23.0
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
From 82e56d78e46504aab5917b606eae67e1a3b54603 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
Date: Wed, 29 May 2019 16:18:30 -0400
|
|
||||||
Subject: [PATCH 4/8] Extend timeout for header test
|
|
||||||
|
|
||||||
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
---
|
|
||||||
modulemd/meson.build | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/modulemd/meson.build b/modulemd/meson.build
|
|
||||||
index e5912d4041ba3e427d13b98c0eeca5217d48244b..0741736a12b4457559ade0a5372ff4b25743fce3 100644
|
|
||||||
--- a/modulemd/meson.build
|
|
||||||
+++ b/modulemd/meson.build
|
|
||||||
@@ -308,7 +308,8 @@ if build_api_v2
|
|
||||||
import_header_script = find_program('common/tests/test-import-headers.sh')
|
|
||||||
test ('test_v2_import_headers', import_header_script,
|
|
||||||
env : test_env,
|
|
||||||
- args : modulemd_v2_hdrs)
|
|
||||||
+ args : modulemd_v2_hdrs,
|
|
||||||
+ timeout : 300)
|
|
||||||
endif
|
|
||||||
|
|
||||||
if valgrind.found()
|
|
||||||
--
|
|
||||||
2.23.0
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
|||||||
From b338dee563932c44bed50b54a1ce00c8e83c0465 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
Date: Wed, 23 Oct 2019 11:13:55 -0400
|
|
||||||
Subject: [PATCH 5/8] Add test_data_path env var for Python tests
|
|
||||||
|
|
||||||
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
---
|
|
||||||
modulemd/v2/meson.build | 1 +
|
|
||||||
modulemd/v2/tests/ModulemdTests/base.py | 4 ++++
|
|
||||||
2 files changed, 5 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/modulemd/v2/meson.build b/modulemd/v2/meson.build
|
|
||||||
index e8a5a38f0528c4f860f0b84ef63609ff5fd89caa..5137b7d23ec66e39a56cf022974da6570c8e4822 100644
|
|
||||||
--- a/modulemd/v2/meson.build
|
|
||||||
+++ b/modulemd/v2/meson.build
|
|
||||||
@@ -93,6 +93,7 @@ install_headers(
|
|
||||||
test_release_env = environment()
|
|
||||||
test_release_env.set('LC_ALL', 'C')
|
|
||||||
test_release_env.set ('MESON_SOURCE_ROOT', meson.source_root())
|
|
||||||
+test_release_env.set ('TEST_DATA_PATH', meson.source_root() + '/modulemd/tests/test_data')
|
|
||||||
|
|
||||||
# Test env with fatal warnings and criticals
|
|
||||||
test_env = test_release_env
|
|
||||||
diff --git a/modulemd/v2/tests/ModulemdTests/base.py b/modulemd/v2/tests/ModulemdTests/base.py
|
|
||||||
index 831309634100f25533c9a7dafe7f96bf7e100cd7..5f396958fd7a20e6567cfe69f99eaeb95825663a 100644
|
|
||||||
--- a/modulemd/v2/tests/ModulemdTests/base.py
|
|
||||||
+++ b/modulemd/v2/tests/ModulemdTests/base.py
|
|
||||||
@@ -28,6 +28,10 @@ class TestBase(unittest.TestCase):
|
|
||||||
def source_root(self):
|
|
||||||
return os.getenv("MESON_SOURCE_ROOT")
|
|
||||||
|
|
||||||
+ @property
|
|
||||||
+ def test_data_path(self):
|
|
||||||
+ return os.getenv("TEST_DATA_PATH")
|
|
||||||
+
|
|
||||||
def _catch_signal(self, *sigargs):
|
|
||||||
if self._caught_signal:
|
|
||||||
raise AssertionError("Multiple signals were caught")
|
|
||||||
--
|
|
||||||
2.23.0
|
|
||||||
|
|
@ -1,272 +0,0 @@
|
|||||||
From 200838c96b48cbe849af652cbb7ece98205cbf9d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
Date: Wed, 3 Jul 2019 08:05:25 -0400
|
|
||||||
Subject: [PATCH 6/8] Add ModuleIndexMerger.resolve_ext()
|
|
||||||
|
|
||||||
This will allow us to handle default streams strictly when merging. In most end-user
|
|
||||||
cases, we want default stream conflicts to simply drop the default stream (this is
|
|
||||||
fail-safe). But when we are creating a repo with defaults, we want to be stricter and
|
|
||||||
ensure that we aren't producing a repo with inconsistent data.
|
|
||||||
|
|
||||||
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
---
|
|
||||||
.../modulemd-module-index-merger.h | 33 +++++++++++++++++++
|
|
||||||
.../private/modulemd-defaults-private.h | 3 ++
|
|
||||||
.../private/modulemd-defaults-v1-private.h | 1 +
|
|
||||||
.../private/modulemd-module-index-private.h | 4 +++
|
|
||||||
modulemd/v2/modulemd-defaults-v1.c | 12 +++++++
|
|
||||||
modulemd/v2/modulemd-defaults.c | 2 ++
|
|
||||||
modulemd/v2/modulemd-module-index-merger.c | 12 ++++++-
|
|
||||||
modulemd/v2/modulemd-module-index.c | 5 +--
|
|
||||||
modulemd/v2/tests/ModulemdTests/merger.py | 21 ++++++++++++
|
|
||||||
9 files changed, 90 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h b/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h
|
|
||||||
index b019f0ed856684a003e9c2f6abefc70e1448246a..97ca7ebb3824ef62aabbafee391b25d56bac43c3 100644
|
|
||||||
--- a/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h
|
|
||||||
+++ b/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h
|
|
||||||
@@ -161,6 +161,10 @@ modulemd_module_index_merger_associate_index (ModulemdModuleIndexMerger *self,
|
|
||||||
* #ModulemdModuleIndexMerger is undefined. The only valid action on it after
|
|
||||||
* that point is g_object_unref().
|
|
||||||
*
|
|
||||||
+ * This function is equivalent to calling
|
|
||||||
+ * modulemd_module_index_merger_resolve_ext() with
|
|
||||||
+ * `strict_default_streams=FALSE`.
|
|
||||||
+ *
|
|
||||||
* Returns: (transfer full): A newly-allocated #ModulemdModuleIndex containing
|
|
||||||
* the merged results. If this function encounters an unresolvable merge
|
|
||||||
* conflict, it will return NULL and set @error appropriately.
|
|
||||||
@@ -171,4 +175,33 @@ ModulemdModuleIndex *
|
|
||||||
modulemd_module_index_merger_resolve (ModulemdModuleIndexMerger *self,
|
|
||||||
GError **error);
|
|
||||||
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * modulemd_module_index_merger_resolve_ext:
|
|
||||||
+ * @self: (in): This #ModulemdModuleIndexMerger object.
|
|
||||||
+ * @strict_default_streams: (in): If TRUE, merging two #ModulemdDefaults with
|
|
||||||
+ * conflicting default streams will raise an error. If FALSE, the module will
|
|
||||||
+ * have its default stream blocked.
|
|
||||||
+ * @error: (out): A #GError containing the reason for a failure to resolve the
|
|
||||||
+ * merges.
|
|
||||||
+ *
|
|
||||||
+ * Merges all added #ModulemdModuleIndex objects according to their priority.
|
|
||||||
+ * The logic of this merge is described in the Description of
|
|
||||||
+ * #ModulemdModuleIndexMerger.
|
|
||||||
+ *
|
|
||||||
+ * Once this function has been called, the internal state of the
|
|
||||||
+ * #ModulemdModuleIndexMerger is undefined. The only valid action on it after
|
|
||||||
+ * that point is g_object_unref().
|
|
||||||
+ *
|
|
||||||
+ * Returns: (transfer full): A newly-allocated #ModulemdModuleIndex containing
|
|
||||||
+ * the merged results. If this function encounters an unresolvable merge
|
|
||||||
+ * conflict, it will return NULL and set @error appropriately.
|
|
||||||
+ *
|
|
||||||
+ * Since: 2.6
|
|
||||||
+ */
|
|
||||||
+ModulemdModuleIndex *
|
|
||||||
+modulemd_module_index_merger_resolve_ext (ModulemdModuleIndexMerger *self,
|
|
||||||
+ gboolean strict_default_streams,
|
|
||||||
+ GError **error);
|
|
||||||
+
|
|
||||||
G_END_DECLS
|
|
||||||
diff --git a/modulemd/v2/include/private/modulemd-defaults-private.h b/modulemd/v2/include/private/modulemd-defaults-private.h
|
|
||||||
index 1863cf6365e769b184478ba5435c664ac05a0b2f..6ea3a54ff992890e88badfdaefa1483b9ba52429 100644
|
|
||||||
--- a/modulemd/v2/include/private/modulemd-defaults-private.h
|
|
||||||
+++ b/modulemd/v2/include/private/modulemd-defaults-private.h
|
|
||||||
@@ -38,6 +38,8 @@ modulemd_defaults_set_module_name (ModulemdDefaults *self,
|
|
||||||
* modulemd_defaults_merge:
|
|
||||||
* @from: (in): A #ModulemdDefaults object to merge from
|
|
||||||
* @into: (in): A #ModulemdDefaults object being merged into
|
|
||||||
+ * @strict_default_streams: (in): Whether a stream conflict should throw an
|
|
||||||
+ * error or just unset the default stream.
|
|
||||||
* @error: (out): A #GError containing the reason for an unresolvable merge
|
|
||||||
* conflict
|
|
||||||
*
|
|
||||||
@@ -52,6 +54,7 @@ modulemd_defaults_set_module_name (ModulemdDefaults *self,
|
|
||||||
ModulemdDefaults *
|
|
||||||
modulemd_defaults_merge (ModulemdDefaults *from,
|
|
||||||
ModulemdDefaults *into,
|
|
||||||
+ gboolean strict_default_streams,
|
|
||||||
GError **error);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
diff --git a/modulemd/v2/include/private/modulemd-defaults-v1-private.h b/modulemd/v2/include/private/modulemd-defaults-v1-private.h
|
|
||||||
index de2ede98e6fb49bfd792b5f2913868fad6ff27db..9144a7ef90853a28eee8345a3b814fdc6478be7b 100644
|
|
||||||
--- a/modulemd/v2/include/private/modulemd-defaults-v1-private.h
|
|
||||||
+++ b/modulemd/v2/include/private/modulemd-defaults-v1-private.h
|
|
||||||
@@ -74,6 +74,7 @@ ModulemdDefaults *
|
|
||||||
modulemd_defaults_v1_merge (const gchar *module_name,
|
|
||||||
ModulemdDefaultsV1 *from,
|
|
||||||
ModulemdDefaultsV1 *into,
|
|
||||||
+ gboolean strict_default_streams,
|
|
||||||
GError **error);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
diff --git a/modulemd/v2/include/private/modulemd-module-index-private.h b/modulemd/v2/include/private/modulemd-module-index-private.h
|
|
||||||
index fd37ab30dffa99f81b2762cb4e23546fe990b2f6..62fc71844f3a58030f79e7da628656b3ffcba5ae 100644
|
|
||||||
--- a/modulemd/v2/include/private/modulemd-module-index-private.h
|
|
||||||
+++ b/modulemd/v2/include/private/modulemd-module-index-private.h
|
|
||||||
@@ -72,6 +72,9 @@ modulemd_module_index_update_from_parser (ModulemdModuleIndex *self,
|
|
||||||
* argument specifies whether the contents of @from will supersede those from
|
|
||||||
* @into. For specifics of how this works, see the Description section for
|
|
||||||
* #ModulemdIndexMerger.
|
|
||||||
+ * @strict_default_streams: (in): When merging #ModulemdDefaults, treat
|
|
||||||
+ * conflicting stream defaults as an error if this is True. Otherwise, on a
|
|
||||||
+ * conflict, the default stream will be unset.
|
|
||||||
* @error: (out): If the merge fails, this will return a #GError explaining the
|
|
||||||
* reason for it.
|
|
||||||
*
|
|
||||||
@@ -84,6 +87,7 @@ gboolean
|
|
||||||
modulemd_module_index_merge (ModulemdModuleIndex *from,
|
|
||||||
ModulemdModuleIndex *into,
|
|
||||||
gboolean override,
|
|
||||||
+ gboolean strict_default_streams,
|
|
||||||
GError **error);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
diff --git a/modulemd/v2/modulemd-defaults-v1.c b/modulemd/v2/modulemd-defaults-v1.c
|
|
||||||
index 55f899b530ef59e0d60de982db76440c7a493325..f51e79d9b0a9fb0395077cd1c3be16529dd53f92 100644
|
|
||||||
--- a/modulemd/v2/modulemd-defaults-v1.c
|
|
||||||
+++ b/modulemd/v2/modulemd-defaults-v1.c
|
|
||||||
@@ -1204,6 +1204,7 @@ ModulemdDefaults *
|
|
||||||
modulemd_defaults_v1_merge (const gchar *module_name,
|
|
||||||
ModulemdDefaultsV1 *from,
|
|
||||||
ModulemdDefaultsV1 *into,
|
|
||||||
+ gboolean strict_default_streams,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
g_autoptr (ModulemdDefaultsV1) merged = NULL;
|
|
||||||
@@ -1246,6 +1247,17 @@ modulemd_defaults_v1_merge (const gchar *module_name,
|
|
||||||
g_info ("Module stream mismatch in merge: %s != %s",
|
|
||||||
into->default_stream,
|
|
||||||
from->default_stream);
|
|
||||||
+ if (strict_default_streams)
|
|
||||||
+ {
|
|
||||||
+ g_set_error (error,
|
|
||||||
+ MODULEMD_ERROR,
|
|
||||||
+ MODULEMD_ERROR_VALIDATE,
|
|
||||||
+ "Default stream mismatch in module %s: %s != %s",
|
|
||||||
+ module_name,
|
|
||||||
+ into->default_stream,
|
|
||||||
+ from->default_stream);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
modulemd_defaults_v1_set_default_stream (
|
|
||||||
merged, DEFAULT_MERGE_CONFLICT, NULL);
|
|
||||||
}
|
|
||||||
diff --git a/modulemd/v2/modulemd-defaults.c b/modulemd/v2/modulemd-defaults.c
|
|
||||||
index 9711fbdbd267570d01d8df4962a2c4e2a7d25c6e..2157f21fd4079ee096baee2a3a3552df5c273d06 100644
|
|
||||||
--- a/modulemd/v2/modulemd-defaults.c
|
|
||||||
+++ b/modulemd/v2/modulemd-defaults.c
|
|
||||||
@@ -391,6 +391,7 @@ modulemd_defaults_init (ModulemdDefaults *self)
|
|
||||||
ModulemdDefaults *
|
|
||||||
modulemd_defaults_merge (ModulemdDefaults *from,
|
|
||||||
ModulemdDefaults *into,
|
|
||||||
+ gboolean strict_default_streams,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
g_autoptr (ModulemdDefaults) merged_defaults = NULL;
|
|
||||||
@@ -446,6 +447,7 @@ modulemd_defaults_merge (ModulemdDefaults *from,
|
|
||||||
merged_defaults = modulemd_defaults_v1_merge (module_name,
|
|
||||||
MODULEMD_DEFAULTS_V1 (from),
|
|
||||||
MODULEMD_DEFAULTS_V1 (into),
|
|
||||||
+ strict_default_streams,
|
|
||||||
&nested_error);
|
|
||||||
if (!merged_defaults)
|
|
||||||
{
|
|
||||||
diff --git a/modulemd/v2/modulemd-module-index-merger.c b/modulemd/v2/modulemd-module-index-merger.c
|
|
||||||
index b8abda8eef91d88538d617b2e15fc77970110ba6..c3502f5c95f7b3227ed772db302d1cc67ca16c7c 100644
|
|
||||||
--- a/modulemd/v2/modulemd-module-index-merger.c
|
|
||||||
+++ b/modulemd/v2/modulemd-module-index-merger.c
|
|
||||||
@@ -170,6 +170,14 @@ modulemd_module_index_merger_associate_index (ModulemdModuleIndexMerger *self,
|
|
||||||
ModulemdModuleIndex *
|
|
||||||
modulemd_module_index_merger_resolve (ModulemdModuleIndexMerger *self,
|
|
||||||
GError **error)
|
|
||||||
+{
|
|
||||||
+ return modulemd_module_index_merger_resolve_ext (self, FALSE, error);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+ModulemdModuleIndex *
|
|
||||||
+modulemd_module_index_merger_resolve_ext (ModulemdModuleIndexMerger *self,
|
|
||||||
+ gboolean strict_default_streams,
|
|
||||||
+ GError **error)
|
|
||||||
{
|
|
||||||
MODULEMD_INIT_TRACE ();
|
|
||||||
g_autoptr (ModulemdModuleIndex) thislevel = NULL;
|
|
||||||
@@ -200,6 +208,7 @@ modulemd_module_index_merger_resolve (ModulemdModuleIndexMerger *self,
|
|
||||||
if (!modulemd_module_index_merge (g_ptr_array_index (indexes, j),
|
|
||||||
thislevel,
|
|
||||||
FALSE,
|
|
||||||
+ strict_default_streams,
|
|
||||||
&nested_error))
|
|
||||||
{
|
|
||||||
g_propagate_error (error, g_steal_pointer (&nested_error));
|
|
||||||
@@ -209,7 +218,8 @@ modulemd_module_index_merger_resolve (ModulemdModuleIndexMerger *self,
|
|
||||||
|
|
||||||
|
|
||||||
/* Merge 'thislevel' into 'final' with override=True */
|
|
||||||
- if (!modulemd_module_index_merge (thislevel, final, TRUE, &nested_error))
|
|
||||||
+ if (!modulemd_module_index_merge (
|
|
||||||
+ thislevel, final, TRUE, strict_default_streams, &nested_error))
|
|
||||||
{
|
|
||||||
g_propagate_error (error, g_steal_pointer (&nested_error));
|
|
||||||
return NULL;
|
|
||||||
diff --git a/modulemd/v2/modulemd-module-index.c b/modulemd/v2/modulemd-module-index.c
|
|
||||||
index e67f91ec9ba7e0b629f871c85024fd76b6ef3c4d..61878d5b1cbf060b11729328c38027a7ba526b42 100644
|
|
||||||
--- a/modulemd/v2/modulemd-module-index.c
|
|
||||||
+++ b/modulemd/v2/modulemd-module-index.c
|
|
||||||
@@ -908,6 +908,7 @@ gboolean
|
|
||||||
modulemd_module_index_merge (ModulemdModuleIndex *from,
|
|
||||||
ModulemdModuleIndex *into,
|
|
||||||
gboolean override,
|
|
||||||
+ gboolean strict_default_streams,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
MODULEMD_INIT_TRACE ();
|
|
||||||
@@ -996,8 +997,8 @@ modulemd_module_index_merge (ModulemdModuleIndex *from,
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
- merged_defaults =
|
|
||||||
- modulemd_defaults_merge (defaults, into_defaults, &nested_error);
|
|
||||||
+ merged_defaults = modulemd_defaults_merge (
|
|
||||||
+ defaults, into_defaults, strict_default_streams, &nested_error);
|
|
||||||
if (!merged_defaults)
|
|
||||||
{
|
|
||||||
g_propagate_error (error, g_steal_pointer (&nested_error));
|
|
||||||
diff --git a/modulemd/v2/tests/ModulemdTests/merger.py b/modulemd/v2/tests/ModulemdTests/merger.py
|
|
||||||
index b87c05798af98d93dfcf67c8b0be629dd94efe4f..92c90d185f55b8a7d5f856aa16cdce5ff32f30d8 100644
|
|
||||||
--- a/modulemd/v2/tests/ModulemdTests/merger.py
|
|
||||||
+++ b/modulemd/v2/tests/ModulemdTests/merger.py
|
|
||||||
@@ -210,6 +210,27 @@ class TestModuleIndexMerger(TestBase):
|
|
||||||
def test_merger_with_modified(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
+ def test_strict_default_streams(self):
|
|
||||||
+ merger = Modulemd.ModuleIndexMerger.new()
|
|
||||||
+
|
|
||||||
+ for stream in ("27", "38"):
|
|
||||||
+ default = """
|
|
||||||
+---
|
|
||||||
+document: modulemd-defaults
|
|
||||||
+version: 1
|
|
||||||
+data:
|
|
||||||
+ module: python
|
|
||||||
+ stream: %s
|
|
||||||
+...
|
|
||||||
+""" % (stream)
|
|
||||||
+
|
|
||||||
+ index = Modulemd.ModuleIndex()
|
|
||||||
+ index.update_from_string(default, strict=True)
|
|
||||||
+ merger.associate_index(index, 0)
|
|
||||||
+
|
|
||||||
+ with self.assertRaisesRegexp(gi.repository.GLib.GError, "Default stream mismatch in module python"):
|
|
||||||
+ merger.resolve_ext(True)
|
|
||||||
+
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
unittest.main()
|
|
||||||
--
|
|
||||||
2.23.0
|
|
||||||
|
|
@ -1,949 +0,0 @@
|
|||||||
From de49d4386cf3c842ce63d2005a624bdfc369c247 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
Date: Fri, 27 Sep 2019 15:21:27 -0400
|
|
||||||
Subject: [PATCH 7/8] Rework defaults merging logic
|
|
||||||
|
|
||||||
Updates documentation of ModuleIndexMerger with the new algorithm.
|
|
||||||
|
|
||||||
Also fixes a memory leak in DefaultsV1.set_default_stream()
|
|
||||||
|
|
||||||
Fixes: https://github.com/fedora-modularity/libmodulemd/issues/368
|
|
||||||
|
|
||||||
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
---
|
|
||||||
.../merger/add_conflicting_profile.yaml | 7 +
|
|
||||||
.../merger/add_conflicting_stream.yaml | 9 +
|
|
||||||
...nflicting_stream_and_profile_modified.yaml | 11 +
|
|
||||||
modulemd/tests/test_data/merger/add_only.yaml | 8 +
|
|
||||||
modulemd/tests/test_data/merger/base.yaml | 34 +++
|
|
||||||
.../modulemd-module-index-merger.h | 67 +++---
|
|
||||||
.../private/modulemd-defaults-v1-private.h | 23 +-
|
|
||||||
modulemd/v2/modulemd-defaults-v1.c | 207 ++++++++++--------
|
|
||||||
modulemd/v2/modulemd-defaults.c | 28 +--
|
|
||||||
modulemd/v2/tests/ModulemdTests/merger.py | 119 ++++++++++
|
|
||||||
modulemd/v2/tests/test-modulemd-merger.c | 147 +++++++++++++
|
|
||||||
11 files changed, 510 insertions(+), 150 deletions(-)
|
|
||||||
create mode 100644 modulemd/tests/test_data/merger/add_conflicting_profile.yaml
|
|
||||||
create mode 100644 modulemd/tests/test_data/merger/add_conflicting_stream.yaml
|
|
||||||
create mode 100644 modulemd/tests/test_data/merger/add_conflicting_stream_and_profile_modified.yaml
|
|
||||||
create mode 100644 modulemd/tests/test_data/merger/add_only.yaml
|
|
||||||
create mode 100644 modulemd/tests/test_data/merger/base.yaml
|
|
||||||
|
|
||||||
diff --git a/modulemd/tests/test_data/merger/add_conflicting_profile.yaml b/modulemd/tests/test_data/merger/add_conflicting_profile.yaml
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..29b0dd0d41f61b8e83f6adde3334ee1a1f65893a
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/modulemd/tests/test_data/merger/add_conflicting_profile.yaml
|
|
||||||
@@ -0,0 +1,7 @@
|
|
||||||
+document: modulemd-defaults
|
|
||||||
+version: 1
|
|
||||||
+data:
|
|
||||||
+ module: postgresql
|
|
||||||
+ stream: '8.1'
|
|
||||||
+ profiles:
|
|
||||||
+ '8.1': [client, server]
|
|
||||||
diff --git a/modulemd/tests/test_data/merger/add_conflicting_stream.yaml b/modulemd/tests/test_data/merger/add_conflicting_stream.yaml
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..615ca8746f8c880f220bdb01275c1ef37104185d
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/modulemd/tests/test_data/merger/add_conflicting_stream.yaml
|
|
||||||
@@ -0,0 +1,9 @@
|
|
||||||
+---
|
|
||||||
+document: modulemd-defaults
|
|
||||||
+version: 1
|
|
||||||
+data:
|
|
||||||
+ module: postgresql
|
|
||||||
+ stream: '8.2'
|
|
||||||
+ profiles:
|
|
||||||
+ '8.2': [client, server, foo]
|
|
||||||
+
|
|
||||||
diff --git a/modulemd/tests/test_data/merger/add_conflicting_stream_and_profile_modified.yaml b/modulemd/tests/test_data/merger/add_conflicting_stream_and_profile_modified.yaml
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..db4bf38515502316d667a48d41a64a9f4a2937c3
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/modulemd/tests/test_data/merger/add_conflicting_stream_and_profile_modified.yaml
|
|
||||||
@@ -0,0 +1,11 @@
|
|
||||||
+---
|
|
||||||
+document: modulemd-defaults
|
|
||||||
+version: 1
|
|
||||||
+data:
|
|
||||||
+ module: postgresql
|
|
||||||
+ stream: '8.2'
|
|
||||||
+ modified: 201909270000
|
|
||||||
+ profiles:
|
|
||||||
+ '8.1': [client, server]
|
|
||||||
+ '8.2': [client, server, foo]
|
|
||||||
+
|
|
||||||
diff --git a/modulemd/tests/test_data/merger/add_only.yaml b/modulemd/tests/test_data/merger/add_only.yaml
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..4a717807f928435ada8f3cf6fcdbd4c86927062e
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/modulemd/tests/test_data/merger/add_only.yaml
|
|
||||||
@@ -0,0 +1,8 @@
|
|
||||||
+---
|
|
||||||
+document: modulemd-defaults
|
|
||||||
+version: 1
|
|
||||||
+data:
|
|
||||||
+ module: httpd
|
|
||||||
+ stream: 2.8
|
|
||||||
+ profiles:
|
|
||||||
+ '2.10': [notreal]
|
|
||||||
diff --git a/modulemd/tests/test_data/merger/base.yaml b/modulemd/tests/test_data/merger/base.yaml
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..12fbc7142040e4edbcba34b17a1dff341beaf1a4
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/modulemd/tests/test_data/merger/base.yaml
|
|
||||||
@@ -0,0 +1,34 @@
|
|
||||||
+---
|
|
||||||
+# Intents optional:
|
|
||||||
+document: modulemd-defaults
|
|
||||||
+version: 1
|
|
||||||
+data:
|
|
||||||
+ module: httpd
|
|
||||||
+ profiles:
|
|
||||||
+ '2.2': [client, server]
|
|
||||||
+ '2.8': [notreal]
|
|
||||||
+ intents:
|
|
||||||
+ workstation:
|
|
||||||
+ stream: '2.4'
|
|
||||||
+ profiles:
|
|
||||||
+ '2.4': [client]
|
|
||||||
+ '2.6': [client, server, bindings]
|
|
||||||
+---
|
|
||||||
+document: modulemd-defaults
|
|
||||||
+version: 1
|
|
||||||
+data:
|
|
||||||
+ module: postgresql
|
|
||||||
+ stream: '8.1'
|
|
||||||
+ profiles:
|
|
||||||
+ '8.1': [client, server, foo]
|
|
||||||
+ '8.3': [client, server]
|
|
||||||
+---
|
|
||||||
+document: modulemd-defaults
|
|
||||||
+version: 1
|
|
||||||
+data:
|
|
||||||
+ module: nodejs
|
|
||||||
+ stream: '8.0'
|
|
||||||
+ modified: 201909270000
|
|
||||||
+ profiles:
|
|
||||||
+ '6.0': [default]
|
|
||||||
+ '8.0': [super]
|
|
||||||
diff --git a/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h b/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h
|
|
||||||
index 97ca7ebb3824ef62aabbafee391b25d56bac43c3..ad7c02ca5ec236d75e9d3ad51af8e2f6afab54c4 100644
|
|
||||||
--- a/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h
|
|
||||||
+++ b/modulemd/v2/include/modulemd-2.0/modulemd-module-index-merger.h
|
|
||||||
@@ -51,35 +51,48 @@ G_BEGIN_DECLS
|
|
||||||
* there exists two #ModulemdModuleStream entries that have different content
|
|
||||||
* for the same NSVC, the behavior is undefined.
|
|
||||||
*
|
|
||||||
- * Merging #ModulemdDefaults entries behaves as follows:
|
|
||||||
+ * Merging #ModulemdDefaults entries behaves as follows (note that this
|
|
||||||
+ * behavior has changed slightly as of 2.8.1):
|
|
||||||
*
|
|
||||||
- * - Within a ModuleIndex, if two or more default entries reference the same
|
|
||||||
- * module, the one with the highest modified field will be used and the
|
|
||||||
- * others discarded.
|
|
||||||
- * - When merging ModuleIndexes, if two or more indexes contain Defaults for
|
|
||||||
- * the same module, but different modified values, the one with the highest
|
|
||||||
- * modified value will be used and the others discarded.
|
|
||||||
- * - Any module default that is provided by a single repository is
|
|
||||||
- * authoritative.
|
|
||||||
- * - If the repos have different priorities (not common), then the default for
|
|
||||||
- * this module and stream name coming from the repo of higher priority will
|
|
||||||
- * be used and the default from the lower-priority repo will not be included
|
|
||||||
- * even if it has a higher modified value.
|
|
||||||
+ * - Any module defaults object that is provided by a single
|
|
||||||
+ * #ModulemdModuleIndex will be the defaults object in the resulting merged
|
|
||||||
+ * #ModulemdModuleIndex.
|
|
||||||
+ * - If the #ModulemdModuleIndex inputs have different priorities (not common),
|
|
||||||
+ * then the defaults from the highest priority #ModulemdModuleIndex will be
|
|
||||||
+ * used and the others entirely discarded. The `modified` value will not be
|
|
||||||
+ * considered at all. (Priority is intended for providing a total override,
|
|
||||||
+ * including an on-disk configuration).
|
|
||||||
* - If the repos have the same priority (such as "fedora" and "updates" in the
|
|
||||||
- * Fedora Project) and modified value, the entries will be merged as follows:
|
|
||||||
- * - If both repositories specify the same default stream for the module, use
|
|
||||||
- * it.
|
|
||||||
- * - If either repository specifies a default stream for the module and the
|
|
||||||
- * other does not, use the one specified.
|
|
||||||
- * - If both repositories specify different default streams, the merge will
|
|
||||||
- * unset the default stream and proceed with the merge.
|
|
||||||
- * - If both repositories specify a set of default profiles for a stream and
|
|
||||||
- * the sets are equivalent, use that set.
|
|
||||||
- * - If one repository specifies a set of default profiles for a stream and
|
|
||||||
- * the other does not, use the one specified.
|
|
||||||
- * - If both repositories specify a set of default profiles for a stream and
|
|
||||||
- * each are providing a different set, this is an unresolvable merge
|
|
||||||
- * conflict and the merge resolution will fail and report an error.
|
|
||||||
+ * Fedora Project) and `modified` value, the entries will be merged as
|
|
||||||
+ * follows for default streams:
|
|
||||||
+ * - If both #ModulemdModuleIndex objects specify the same default stream for
|
|
||||||
+ * the module, that one will be used.
|
|
||||||
+ * - If either #ModulemdModuleIndex specifies a default stream for the module
|
|
||||||
+ * and the other does not, the provided one will be used.
|
|
||||||
+ * - If both #ModulemdModuleIndex objects specify different default streams
|
|
||||||
+ * and have different `modified` values, the default stream from the
|
|
||||||
+ * #ModulemdDefaults object with the higher `modified` value will be used.
|
|
||||||
+ * - If both #ModulemdModuleIndex objects specify different default streams
|
|
||||||
+ * and have the same `modified` value, the merge will unset the default
|
|
||||||
+ * stream and leave no default stream in the resulting merged
|
|
||||||
+ * #ModulemdModuleIndex. This behavior can be controlled by using
|
|
||||||
+ * modulemd_module_index_merger_resolve_ext() and setting
|
|
||||||
+ * `strict_default_streams` to #TRUE. In that case, an error will be
|
|
||||||
+ * returned if conflicting default streams have been provided.
|
|
||||||
+ * - and for profile defaults:
|
|
||||||
+ * - If both #ModulemdModuleIndex objects specify a set of default profiles
|
|
||||||
+ * for a particular module and stream and the sets are equivalent, use that
|
|
||||||
+ * set.
|
|
||||||
+ * - If one #ModulemdModuleIndex object specifies a set of default profiles
|
|
||||||
+ * for a module and stream and the other does not, use the provided set.
|
|
||||||
+ * - If both #ModulemdModuleIndex objects specify a set of default profiles
|
|
||||||
+ * for a stream, each are providing a different set and the `modified`
|
|
||||||
+ * value differs, the set from the object with the higher `modified` value
|
|
||||||
+ * will be used.
|
|
||||||
+ * - If both #ModulemdModuleIndex objects specify a set of default profiles
|
|
||||||
+ * for a stream, each are providing a different set and the `modified`
|
|
||||||
+ * value is the same, this is an unresolvable merge conflict and the merge
|
|
||||||
+ * resolution will fail and return an error.
|
|
||||||
* - Intents behave in exactly the same manner as described for the top-level
|
|
||||||
* defaults, except that they merge beneath each intent name.
|
|
||||||
*
|
|
||||||
diff --git a/modulemd/v2/include/private/modulemd-defaults-v1-private.h b/modulemd/v2/include/private/modulemd-defaults-v1-private.h
|
|
||||||
index 9144a7ef90853a28eee8345a3b814fdc6478be7b..437bab1afa8c50c4a13924c8bc825ddb0bb211d4 100644
|
|
||||||
--- a/modulemd/v2/include/private/modulemd-defaults-v1-private.h
|
|
||||||
+++ b/modulemd/v2/include/private/modulemd-defaults-v1-private.h
|
|
||||||
@@ -70,9 +70,28 @@ modulemd_defaults_v1_emit_yaml (ModulemdDefaultsV1 *self,
|
|
||||||
GError **error);
|
|
||||||
|
|
||||||
|
|
||||||
+/**
|
|
||||||
+ * modulemd_defaults_v1_merge:
|
|
||||||
+ * @from: (in): A #ModulemdDefaultsV1 object to merge from.
|
|
||||||
+ * @into: (in): A #ModulemdDefaultsV1 object being merged into.
|
|
||||||
+ * @strict_default_streams: (in): Whether a stream conflict should throw an
|
|
||||||
+ * error or just unset the default stream.
|
|
||||||
+ * @error: (out): A #GError containing the reason for an unresolvable merge
|
|
||||||
+ * conflict.
|
|
||||||
+ *
|
|
||||||
+ * Performs a merge of two #ModulemdDefaultsV1 objects representing the
|
|
||||||
+ * defaults for a single module name. See the documentation for
|
|
||||||
+ * #ModulemdModuleIndexMerger for details on the merge algorithm used.
|
|
||||||
+ *
|
|
||||||
+ * Returns: (transfer full): A newly-allocated #ModulemdDefaultsV1 object
|
|
||||||
+ * containing the merged values of @from and @into. If this function encounters
|
|
||||||
+ * an unresolvable merge conflict, it will return NULL and set @error
|
|
||||||
+ * appropriately.
|
|
||||||
+ *
|
|
||||||
+ * Since: 2.0
|
|
||||||
+ */
|
|
||||||
ModulemdDefaults *
|
|
||||||
-modulemd_defaults_v1_merge (const gchar *module_name,
|
|
||||||
- ModulemdDefaultsV1 *from,
|
|
||||||
+modulemd_defaults_v1_merge (ModulemdDefaultsV1 *from,
|
|
||||||
ModulemdDefaultsV1 *into,
|
|
||||||
gboolean strict_default_streams,
|
|
||||||
GError **error);
|
|
||||||
diff --git a/modulemd/v2/modulemd-defaults-v1.c b/modulemd/v2/modulemd-defaults-v1.c
|
|
||||||
index f51e79d9b0a9fb0395077cd1c3be16529dd53f92..8a18d645de5d95a96e3cc862f78eeedc74595a9e 100644
|
|
||||||
--- a/modulemd/v2/modulemd-defaults-v1.c
|
|
||||||
+++ b/modulemd/v2/modulemd-defaults-v1.c
|
|
||||||
@@ -204,6 +204,7 @@ modulemd_defaults_v1_set_default_stream (ModulemdDefaultsV1 *self,
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* This is the fallback default for non-specific intents */
|
|
||||||
+ g_clear_pointer (&self->default_stream, g_free);
|
|
||||||
self->default_stream = g_strdup (default_stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1192,17 +1193,18 @@ modulemd_defaults_v1_emit_intents (ModulemdDefaultsV1 *self,
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
-modulemd_defaults_v1_merge_intent_profiles (
|
|
||||||
+modulemd_defaults_v1_merge_default_profiles (
|
|
||||||
GHashTable *from_profile_defaults,
|
|
||||||
GHashTable *merged_profile_defaults,
|
|
||||||
+ guint64 from_modified,
|
|
||||||
+ guint64 into_modified,
|
|
||||||
GError **error);
|
|
||||||
static GHashTable *
|
|
||||||
modulemd_defaults_v1_copy_intent_profiles (GHashTable *intent_profiles);
|
|
||||||
|
|
||||||
|
|
||||||
ModulemdDefaults *
|
|
||||||
-modulemd_defaults_v1_merge (const gchar *module_name,
|
|
||||||
- ModulemdDefaultsV1 *from,
|
|
||||||
+modulemd_defaults_v1_merge (ModulemdDefaultsV1 *from,
|
|
||||||
ModulemdDefaultsV1 *into,
|
|
||||||
gboolean strict_default_streams,
|
|
||||||
GError **error)
|
|
||||||
@@ -1212,83 +1214,85 @@ modulemd_defaults_v1_merge (const gchar *module_name,
|
|
||||||
gpointer key, value;
|
|
||||||
GHashTable *intent_profiles = NULL;
|
|
||||||
GHashTable *merged_intent_profiles = NULL;
|
|
||||||
+ guint64 from_modified;
|
|
||||||
+ guint64 into_modified;
|
|
||||||
g_autoptr (GHashTable) intent_profile_defaults = NULL;
|
|
||||||
gchar *intent_name = NULL;
|
|
||||||
gchar *intent_default_stream = NULL;
|
|
||||||
gchar *merged_default_stream = NULL;
|
|
||||||
g_autoptr (GError) nested_error = NULL;
|
|
||||||
+ const gchar *module_name =
|
|
||||||
+ modulemd_defaults_get_module_name (MODULEMD_DEFAULTS (into));
|
|
||||||
|
|
||||||
- merged = modulemd_defaults_v1_new (module_name);
|
|
||||||
+ from_modified = modulemd_defaults_get_modified (MODULEMD_DEFAULTS (from));
|
|
||||||
+ into_modified = modulemd_defaults_get_modified (MODULEMD_DEFAULTS (into));
|
|
||||||
+
|
|
||||||
+ /* Start from a copy of "into" */
|
|
||||||
+ merged =
|
|
||||||
+ MODULEMD_DEFAULTS_V1 (modulemd_defaults_copy (MODULEMD_DEFAULTS (into)));
|
|
||||||
|
|
||||||
/* Merge the default streams */
|
|
||||||
- if (into->default_stream && !from->default_stream)
|
|
||||||
- {
|
|
||||||
- modulemd_defaults_v1_set_default_stream (
|
|
||||||
- merged, into->default_stream, NULL);
|
|
||||||
- }
|
|
||||||
- else if (from->default_stream && !into->default_stream)
|
|
||||||
+ if (from->default_stream && !merged->default_stream)
|
|
||||||
{
|
|
||||||
modulemd_defaults_v1_set_default_stream (
|
|
||||||
merged, from->default_stream, NULL);
|
|
||||||
}
|
|
||||||
- else if (into->default_stream && from->default_stream)
|
|
||||||
+ else if (merged->default_stream && from->default_stream)
|
|
||||||
{
|
|
||||||
- if (g_str_equal (into->default_stream, DEFAULT_MERGE_CONFLICT))
|
|
||||||
+ if (g_str_equal (merged->default_stream, DEFAULT_MERGE_CONFLICT))
|
|
||||||
{
|
|
||||||
/* A previous pass over this same module encountered a merge
|
|
||||||
- * conflict, so we need to propagate that.
|
|
||||||
+ * conflict, so keep it.
|
|
||||||
*/
|
|
||||||
- modulemd_defaults_v1_set_default_stream (
|
|
||||||
- merged, DEFAULT_MERGE_CONFLICT, NULL);
|
|
||||||
}
|
|
||||||
- else if (!g_str_equal (into->default_stream, from->default_stream))
|
|
||||||
+ else if (!g_str_equal (merged->default_stream, from->default_stream))
|
|
||||||
{
|
|
||||||
- /* They have conflicting default streams */
|
|
||||||
- g_info ("Module stream mismatch in merge: %s != %s",
|
|
||||||
- into->default_stream,
|
|
||||||
- from->default_stream);
|
|
||||||
- if (strict_default_streams)
|
|
||||||
+ if (from_modified > into_modified)
|
|
||||||
{
|
|
||||||
- g_set_error (error,
|
|
||||||
- MODULEMD_ERROR,
|
|
||||||
- MODULEMD_ERROR_VALIDATE,
|
|
||||||
- "Default stream mismatch in module %s: %s != %s",
|
|
||||||
- module_name,
|
|
||||||
- into->default_stream,
|
|
||||||
- from->default_stream);
|
|
||||||
- return NULL;
|
|
||||||
+ modulemd_defaults_v1_set_default_stream (
|
|
||||||
+ merged, from->default_stream, NULL);
|
|
||||||
+ }
|
|
||||||
+ else if (from_modified == into_modified)
|
|
||||||
+ {
|
|
||||||
+ /* They have conflicting default streams */
|
|
||||||
+ g_info ("Module stream mismatch in merge: %s != %s",
|
|
||||||
+ into->default_stream,
|
|
||||||
+ from->default_stream);
|
|
||||||
+ if (strict_default_streams)
|
|
||||||
+ {
|
|
||||||
+ g_set_error (
|
|
||||||
+ error,
|
|
||||||
+ MODULEMD_ERROR,
|
|
||||||
+ MODULEMD_ERROR_VALIDATE,
|
|
||||||
+ "Default stream mismatch in module %s: %s != %s",
|
|
||||||
+ module_name,
|
|
||||||
+ into->default_stream,
|
|
||||||
+ from->default_stream);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ modulemd_defaults_v1_set_default_stream (
|
|
||||||
+ merged, DEFAULT_MERGE_CONFLICT, NULL);
|
|
||||||
}
|
|
||||||
- modulemd_defaults_v1_set_default_stream (
|
|
||||||
- merged, DEFAULT_MERGE_CONFLICT, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
- /* They're the same, so store that */
|
|
||||||
- modulemd_defaults_v1_set_default_stream (
|
|
||||||
- merged, into->default_stream, NULL);
|
|
||||||
+ /* They're the same, so change nothing */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
- /* Both values were NULL.
|
|
||||||
- * Nothing to do, leave it blank.
|
|
||||||
- */
|
|
||||||
+ /* The 'from' default stream was NULL. Make no changes. */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* == Merge profile defaults == */
|
|
||||||
|
|
||||||
- /* Iterate through 'into' and add them to merged_defaults */
|
|
||||||
- if (!modulemd_defaults_v1_merge_intent_profiles (
|
|
||||||
- into->profile_defaults, merged->profile_defaults, &nested_error))
|
|
||||||
- {
|
|
||||||
- g_propagate_error (error, g_steal_pointer (&nested_error));
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
/* Iterate through 'from' and see if there are additions or conflicts */
|
|
||||||
- if (!modulemd_defaults_v1_merge_intent_profiles (
|
|
||||||
- from->profile_defaults, merged->profile_defaults, &nested_error))
|
|
||||||
+ if (!modulemd_defaults_v1_merge_default_profiles (from->profile_defaults,
|
|
||||||
+ merged->profile_defaults,
|
|
||||||
+ from_modified,
|
|
||||||
+ into_modified,
|
|
||||||
+ &nested_error))
|
|
||||||
{
|
|
||||||
g_propagate_error (error, g_steal_pointer (&nested_error));
|
|
||||||
return NULL;
|
|
||||||
@@ -1298,18 +1302,6 @@ modulemd_defaults_v1_merge (const gchar *module_name,
|
|
||||||
|
|
||||||
/* Merge intent default stream values */
|
|
||||||
|
|
||||||
- /* Iterate through 'into' and add them to merged_defaults */
|
|
||||||
- g_hash_table_iter_init (&iter, into->intent_default_streams);
|
|
||||||
- while (g_hash_table_iter_next (&iter, &key, &value))
|
|
||||||
- {
|
|
||||||
- intent_name = (gchar *)key;
|
|
||||||
- intent_default_stream = (gchar *)value;
|
|
||||||
-
|
|
||||||
- g_hash_table_insert (merged->intent_default_streams,
|
|
||||||
- g_strdup (intent_name),
|
|
||||||
- g_strdup (intent_default_stream));
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
/* Iterate through 'from', adding any new values and checking the existing
|
|
||||||
* ones for equivalence.
|
|
||||||
*/
|
|
||||||
@@ -1321,46 +1313,44 @@ modulemd_defaults_v1_merge (const gchar *module_name,
|
|
||||||
merged_default_stream =
|
|
||||||
g_hash_table_lookup (merged->intent_default_streams, intent_name);
|
|
||||||
|
|
||||||
+ /* If there is no new default stream, just jump to the next item */
|
|
||||||
+ if (!intent_default_stream)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
if (!merged_default_stream)
|
|
||||||
{
|
|
||||||
/* New entry, just add it */
|
|
||||||
g_hash_table_insert (merged->intent_default_streams,
|
|
||||||
g_strdup (intent_name),
|
|
||||||
g_strdup (intent_default_stream));
|
|
||||||
- continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (!g_str_equal (intent_default_stream, merged_default_stream))
|
|
||||||
+ else if (!g_str_equal (intent_default_stream, merged_default_stream))
|
|
||||||
{
|
|
||||||
- g_set_error (error,
|
|
||||||
- MODULEMD_ERROR,
|
|
||||||
- MODULEMD_ERROR_VALIDATE,
|
|
||||||
- "Profile default stream mismatch in intents: %s != %s",
|
|
||||||
- intent_default_stream,
|
|
||||||
- merged_default_stream);
|
|
||||||
- return NULL;
|
|
||||||
+ if (from_modified > into_modified)
|
|
||||||
+ {
|
|
||||||
+ g_hash_table_replace (merged->intent_default_streams,
|
|
||||||
+ g_strdup (intent_name),
|
|
||||||
+ g_strdup (intent_default_stream));
|
|
||||||
+ }
|
|
||||||
+ else if (into_modified == from_modified)
|
|
||||||
+ {
|
|
||||||
+ g_set_error (
|
|
||||||
+ error,
|
|
||||||
+ MODULEMD_ERROR,
|
|
||||||
+ MODULEMD_ERROR_VALIDATE,
|
|
||||||
+ "Profile default stream mismatch in intents: %s != %s",
|
|
||||||
+ intent_default_stream,
|
|
||||||
+ merged_default_stream);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Merge intent default profile values */
|
|
||||||
|
|
||||||
- /* First copy 'into' to 'merged' */
|
|
||||||
- g_hash_table_iter_init (&iter, into->intent_default_profiles);
|
|
||||||
- while (g_hash_table_iter_next (&iter, &key, &value))
|
|
||||||
- {
|
|
||||||
- intent_name = (gchar *)key;
|
|
||||||
- intent_profiles = (GHashTable *)value;
|
|
||||||
-
|
|
||||||
- intent_profile_defaults =
|
|
||||||
- modulemd_defaults_v1_copy_intent_profiles (intent_profiles);
|
|
||||||
-
|
|
||||||
- g_hash_table_insert (merged->intent_default_profiles,
|
|
||||||
- g_strdup (intent_name),
|
|
||||||
- g_steal_pointer (&intent_profile_defaults));
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* Now copy 'from" into merged, checking for conflicts */
|
|
||||||
+ /* Now copy 'from' into merged, checking for conflicts */
|
|
||||||
g_hash_table_iter_init (&iter, from->intent_default_profiles);
|
|
||||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
|
||||||
{
|
|
||||||
@@ -1374,7 +1364,7 @@ modulemd_defaults_v1_merge (const gchar *module_name,
|
|
||||||
intent_profile_defaults =
|
|
||||||
modulemd_defaults_v1_copy_intent_profiles (intent_profiles);
|
|
||||||
|
|
||||||
- /* This wasn't in 'into', so just add it */
|
|
||||||
+ /* This wasn't in 'merged', so just add it */
|
|
||||||
g_hash_table_insert (merged->intent_default_profiles,
|
|
||||||
g_strdup (intent_name),
|
|
||||||
g_steal_pointer (&intent_profile_defaults));
|
|
||||||
@@ -1384,14 +1374,20 @@ modulemd_defaults_v1_merge (const gchar *module_name,
|
|
||||||
/* Go through each of the profile defaults and see if they're additive or
|
|
||||||
* conflicting
|
|
||||||
*/
|
|
||||||
- if (!modulemd_defaults_v1_merge_intent_profiles (
|
|
||||||
- intent_profiles, merged_intent_profiles, &nested_error))
|
|
||||||
+ if (!modulemd_defaults_v1_merge_default_profiles (intent_profiles,
|
|
||||||
+ merged_intent_profiles,
|
|
||||||
+ from_modified,
|
|
||||||
+ into_modified,
|
|
||||||
+ &nested_error))
|
|
||||||
{
|
|
||||||
g_propagate_error (error, g_steal_pointer (&nested_error));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* Set the modified value to the higher of the two provided */
|
|
||||||
+ if (from_modified > into_modified)
|
|
||||||
+ modulemd_defaults_set_modified (MODULEMD_DEFAULTS (merged), from_modified);
|
|
||||||
|
|
||||||
return MODULEMD_DEFAULTS (g_steal_pointer (&merged));
|
|
||||||
}
|
|
||||||
@@ -1427,9 +1423,11 @@ modulemd_defaults_v1_copy_intent_profiles (GHashTable *intent_profiles)
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
-modulemd_defaults_v1_merge_intent_profiles (
|
|
||||||
+modulemd_defaults_v1_merge_default_profiles (
|
|
||||||
GHashTable *from_profile_defaults,
|
|
||||||
GHashTable *merged_profile_defaults,
|
|
||||||
+ guint64 from_modified,
|
|
||||||
+ guint64 into_modified,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
GHashTableIter iter;
|
|
||||||
@@ -1459,15 +1457,30 @@ modulemd_defaults_v1_merge_intent_profiles (
|
|
||||||
/* Check to see if they match */
|
|
||||||
if (!modulemd_hash_table_sets_are_equal (from_profiles, merged_profiles))
|
|
||||||
{
|
|
||||||
- /* The profile sets differed. This is an unresolvable merge
|
|
||||||
- * conflict
|
|
||||||
- */
|
|
||||||
- g_set_error (error,
|
|
||||||
- MODULEMD_ERROR,
|
|
||||||
- MODULEMD_ERROR_VALIDATE,
|
|
||||||
- "Profile default mismatch in stream: %s",
|
|
||||||
- stream_name);
|
|
||||||
- return FALSE;
|
|
||||||
+ if (from_modified > into_modified)
|
|
||||||
+ {
|
|
||||||
+ g_hash_table_replace (
|
|
||||||
+ merged_profile_defaults,
|
|
||||||
+ g_strdup (stream_name),
|
|
||||||
+ modulemd_hash_table_deep_set_copy (from_profiles));
|
|
||||||
+ }
|
|
||||||
+ else if (into_modified > from_modified)
|
|
||||||
+ {
|
|
||||||
+ /* Already there, so just continue */
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ /* The profile sets differed. This is an unresolvable merge
|
|
||||||
+ * conflict
|
|
||||||
+ */
|
|
||||||
+ g_set_error (error,
|
|
||||||
+ MODULEMD_ERROR,
|
|
||||||
+ MODULEMD_ERROR_VALIDATE,
|
|
||||||
+ "Profile default mismatch in stream: %s",
|
|
||||||
+ stream_name);
|
|
||||||
+ return FALSE;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* They were a complete match, so no need to add it a second time */
|
|
||||||
diff --git a/modulemd/v2/modulemd-defaults.c b/modulemd/v2/modulemd-defaults.c
|
|
||||||
index 2157f21fd4079ee096baee2a3a3552df5c273d06..b551c578fda68a8a1ae7532696548e8c18501e68 100644
|
|
||||||
--- a/modulemd/v2/modulemd-defaults.c
|
|
||||||
+++ b/modulemd/v2/modulemd-defaults.c
|
|
||||||
@@ -396,9 +396,6 @@ modulemd_defaults_merge (ModulemdDefaults *from,
|
|
||||||
{
|
|
||||||
g_autoptr (ModulemdDefaults) merged_defaults = NULL;
|
|
||||||
guint64 mdversion;
|
|
||||||
- const gchar *module_name = NULL;
|
|
||||||
- guint64 from_modified;
|
|
||||||
- guint64 into_modified;
|
|
||||||
g_autoptr (GError) nested_error = NULL;
|
|
||||||
|
|
||||||
g_return_val_if_fail (MODULEMD_IS_DEFAULTS (from), NULL);
|
|
||||||
@@ -416,36 +413,19 @@ modulemd_defaults_merge (ModulemdDefaults *from,
|
|
||||||
NULL);
|
|
||||||
g_return_val_if_fail (mdversion == MD_DEFAULTS_VERSION_ONE, NULL);
|
|
||||||
|
|
||||||
- from_modified = modulemd_defaults_get_modified (from);
|
|
||||||
- into_modified = modulemd_defaults_get_modified (into);
|
|
||||||
-
|
|
||||||
- if (from_modified > into_modified)
|
|
||||||
- {
|
|
||||||
- /* Just return 'from' if it has a higher modified value */
|
|
||||||
- return modulemd_defaults_copy (from);
|
|
||||||
- }
|
|
||||||
- else if (into_modified > from_modified)
|
|
||||||
- {
|
|
||||||
- /* Just return 'into' if it has a higher modified value */
|
|
||||||
- return modulemd_defaults_copy (into);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* Modified value is the same, so we need to merge */
|
|
||||||
-
|
|
||||||
- module_name = modulemd_defaults_get_module_name (into);
|
|
||||||
- if (!g_str_equal (module_name, modulemd_defaults_get_module_name (from)))
|
|
||||||
+ if (!g_str_equal (modulemd_defaults_get_module_name (into),
|
|
||||||
+ modulemd_defaults_get_module_name (from)))
|
|
||||||
{
|
|
||||||
g_set_error (error,
|
|
||||||
MODULEMD_ERROR,
|
|
||||||
MODULEMD_ERROR_VALIDATE,
|
|
||||||
"Module name mismatch in merge: %s != %s",
|
|
||||||
- module_name,
|
|
||||||
+ modulemd_defaults_get_module_name (into),
|
|
||||||
modulemd_defaults_get_module_name (from));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- merged_defaults = modulemd_defaults_v1_merge (module_name,
|
|
||||||
- MODULEMD_DEFAULTS_V1 (from),
|
|
||||||
+ merged_defaults = modulemd_defaults_v1_merge (MODULEMD_DEFAULTS_V1 (from),
|
|
||||||
MODULEMD_DEFAULTS_V1 (into),
|
|
||||||
strict_default_streams,
|
|
||||||
&nested_error);
|
|
||||||
diff --git a/modulemd/v2/tests/ModulemdTests/merger.py b/modulemd/v2/tests/ModulemdTests/merger.py
|
|
||||||
index 92c90d185f55b8a7d5f856aa16cdce5ff32f30d8..72bd43f9d775923abf6a456c70b01bf3d0a912fc 100644
|
|
||||||
--- a/modulemd/v2/tests/ModulemdTests/merger.py
|
|
||||||
+++ b/modulemd/v2/tests/ModulemdTests/merger.py
|
|
||||||
@@ -14,6 +14,7 @@
|
|
||||||
|
|
||||||
from os import path
|
|
||||||
import sys
|
|
||||||
+import logging
|
|
||||||
try:
|
|
||||||
import unittest
|
|
||||||
import gi
|
|
||||||
@@ -231,6 +232,124 @@ data:
|
|
||||||
with self.assertRaisesRegexp(gi.repository.GLib.GError, "Default stream mismatch in module python"):
|
|
||||||
merger.resolve_ext(True)
|
|
||||||
|
|
||||||
+ def test_merge_add_only(self):
|
|
||||||
+ base_idx = Modulemd.ModuleIndex()
|
|
||||||
+ self.assertTrue(base_idx.update_from_file(
|
|
||||||
+ path.join(
|
|
||||||
+ self.test_data_path,
|
|
||||||
+ "merger",
|
|
||||||
+ "base.yaml"), True))
|
|
||||||
+
|
|
||||||
+ add_only_idx = Modulemd.ModuleIndex()
|
|
||||||
+ self.assertTrue(add_only_idx.update_from_file(
|
|
||||||
+ path.join(
|
|
||||||
+ self.test_data_path,
|
|
||||||
+ "merger",
|
|
||||||
+ "add_only.yaml"), True))
|
|
||||||
+
|
|
||||||
+ merger = Modulemd.ModuleIndexMerger()
|
|
||||||
+ merger.associate_index(base_idx, 0)
|
|
||||||
+ merger.associate_index(add_only_idx, 0)
|
|
||||||
+
|
|
||||||
+ merged_idx = merger.resolve()
|
|
||||||
+ self.assertIsNotNone(merged_idx)
|
|
||||||
+
|
|
||||||
+ httpd = merged_idx.get_module('httpd')
|
|
||||||
+ self.assertIsNotNone(httpd)
|
|
||||||
+ httpd_defs = httpd.get_defaults()
|
|
||||||
+
|
|
||||||
+ self.assertEqual(httpd_defs.get_default_stream(), "2.8")
|
|
||||||
+ expected_profile_defs = {
|
|
||||||
+ '2.2': set(['client', 'server']),
|
|
||||||
+ '2.8': set(['notreal', ]),
|
|
||||||
+ '2.10': set(['notreal', ])
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for stream in expected_profile_defs.keys():
|
|
||||||
+ self.assertEqual(set(httpd_defs.get_default_profiles_for_stream(
|
|
||||||
+ stream)), expected_profile_defs[stream])
|
|
||||||
+
|
|
||||||
+ self.assertEqual(httpd_defs.get_default_stream("workstation"), "2.4")
|
|
||||||
+
|
|
||||||
+ def test_merge_add_conflicting_stream(self):
|
|
||||||
+ base_idx = Modulemd.ModuleIndex()
|
|
||||||
+ self.assertTrue(base_idx.update_from_file(
|
|
||||||
+ path.join(
|
|
||||||
+ self.test_data_path,
|
|
||||||
+ "merger",
|
|
||||||
+ "base.yaml"), True))
|
|
||||||
+
|
|
||||||
+ add_only_idx = Modulemd.ModuleIndex()
|
|
||||||
+ self.assertTrue(add_only_idx.update_from_file(
|
|
||||||
+ path.join(
|
|
||||||
+ self.test_data_path,
|
|
||||||
+ "merger",
|
|
||||||
+ "add_conflicting_stream.yaml"), True))
|
|
||||||
+
|
|
||||||
+ merger = Modulemd.ModuleIndexMerger()
|
|
||||||
+ merger.associate_index(base_idx, 0)
|
|
||||||
+ merger.associate_index(add_only_idx, 0)
|
|
||||||
+
|
|
||||||
+ merged_idx = merger.resolve()
|
|
||||||
+ self.assertIsNotNone(merged_idx)
|
|
||||||
+
|
|
||||||
+ psql = merged_idx.get_module('postgresql')
|
|
||||||
+ self.assertIsNotNone(psql)
|
|
||||||
+
|
|
||||||
+ psql_defs = psql.get_defaults()
|
|
||||||
+ self.assertIsNotNone(psql_defs)
|
|
||||||
+
|
|
||||||
+ self.assertIsNone(psql_defs.get_default_stream())
|
|
||||||
+
|
|
||||||
+ expected_profile_defs = {
|
|
||||||
+ '8.1': set(['client', 'server', 'foo']),
|
|
||||||
+ '8.2': set(['client', 'server', 'foo']),
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for stream in expected_profile_defs.keys():
|
|
||||||
+ self.assertEqual(set(psql_defs.get_default_profiles_for_stream(
|
|
||||||
+ stream)), expected_profile_defs[stream])
|
|
||||||
+
|
|
||||||
+ def test_merge_add_conflicting_stream_and_profile_modified(self):
|
|
||||||
+ base_idx = Modulemd.ModuleIndex()
|
|
||||||
+ self.assertTrue(base_idx.update_from_file(
|
|
||||||
+ path.join(
|
|
||||||
+ self.test_data_path,
|
|
||||||
+ "merger",
|
|
||||||
+ "base.yaml"), True))
|
|
||||||
+
|
|
||||||
+ add_conflicting_idx = Modulemd.ModuleIndex()
|
|
||||||
+ self.assertTrue(add_conflicting_idx.update_from_file(
|
|
||||||
+ path.join(
|
|
||||||
+ self.test_data_path,
|
|
||||||
+ "merger",
|
|
||||||
+ "add_conflicting_stream_and_profile_modified.yaml"), True))
|
|
||||||
+
|
|
||||||
+ merger = Modulemd.ModuleIndexMerger()
|
|
||||||
+ merger.associate_index(base_idx, 0)
|
|
||||||
+ merger.associate_index(add_conflicting_idx, 0)
|
|
||||||
+
|
|
||||||
+ merged_idx = merger.resolve()
|
|
||||||
+ self.assertIsNotNone(merged_idx)
|
|
||||||
+
|
|
||||||
+ psql = merged_idx.get_module('postgresql')
|
|
||||||
+ self.assertIsNotNone(psql)
|
|
||||||
+
|
|
||||||
+ psql_defs = psql.get_defaults()
|
|
||||||
+ self.assertIsNotNone(psql_defs)
|
|
||||||
+
|
|
||||||
+ self.assertEqual(psql_defs.get_default_stream(), '8.2')
|
|
||||||
+
|
|
||||||
+ expected_profile_defs = {
|
|
||||||
+ '8.1': set(['client', 'server']),
|
|
||||||
+ '8.2': set(['client', 'server', 'foo']),
|
|
||||||
+ '8.3': set(['client', 'server']),
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for stream in expected_profile_defs:
|
|
||||||
+ self.assertEqual(set(psql_defs.get_default_profiles_for_stream(
|
|
||||||
+ stream)), expected_profile_defs[stream])
|
|
||||||
+
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
unittest.main()
|
|
||||||
diff --git a/modulemd/v2/tests/test-modulemd-merger.c b/modulemd/v2/tests/test-modulemd-merger.c
|
|
||||||
index e46b4d84441528310c2d4e5b5990f23e3719090e..967e2cc902a5708905e9762e4d4631ab2eb4e4eb 100644
|
|
||||||
--- a/modulemd/v2/tests/test-modulemd-merger.c
|
|
||||||
+++ b/modulemd/v2/tests/test-modulemd-merger.c
|
|
||||||
@@ -14,6 +14,8 @@
|
|
||||||
#include <glib.h>
|
|
||||||
#include <yaml.h>
|
|
||||||
|
|
||||||
+#include "modulemd-defaults.h"
|
|
||||||
+#include "modulemd-defaults-v1.h"
|
|
||||||
#include "modulemd-module-index.h"
|
|
||||||
#include "modulemd-module-index-merger.h"
|
|
||||||
#include "private/test-utils.h"
|
|
||||||
@@ -101,6 +103,142 @@ merger_test_deduplicate (CommonMmdTestFixture *fixture,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
+static void
|
|
||||||
+merger_test_add_only (void)
|
|
||||||
+{
|
|
||||||
+ g_autoptr (GPtrArray) failures = NULL;
|
|
||||||
+ g_autoptr (GError) error = NULL;
|
|
||||||
+ g_autoptr (ModulemdModuleIndex) base_idx = modulemd_module_index_new ();
|
|
||||||
+ g_autoptr (ModulemdModuleIndex) add_only_idx = modulemd_module_index_new ();
|
|
||||||
+ g_autoptr (ModulemdModuleIndex) merged_idx = NULL;
|
|
||||||
+ g_autoptr (ModulemdModuleIndexMerger) merger =
|
|
||||||
+ modulemd_module_index_merger_new ();
|
|
||||||
+ ModulemdModule *httpd = NULL;
|
|
||||||
+ ModulemdDefaults *httpd_defs = NULL;
|
|
||||||
+ g_autofree gchar *base_yaml =
|
|
||||||
+ g_strdup_printf ("%s/merger/base.yaml", g_getenv ("TEST_DATA_PATH"));
|
|
||||||
+ g_autofree gchar *add_only_yaml =
|
|
||||||
+ g_strdup_printf ("%s/merger/add_only.yaml", g_getenv ("TEST_DATA_PATH"));
|
|
||||||
+
|
|
||||||
+ g_assert_true (modulemd_module_index_update_from_file (
|
|
||||||
+ base_idx, base_yaml, TRUE, &failures, &error));
|
|
||||||
+ g_assert_true (modulemd_module_index_update_from_file (
|
|
||||||
+ add_only_idx, add_only_yaml, TRUE, &failures, &error));
|
|
||||||
+
|
|
||||||
+ modulemd_module_index_merger_associate_index (merger, base_idx, 0);
|
|
||||||
+ modulemd_module_index_merger_associate_index (merger, add_only_idx, 0);
|
|
||||||
+
|
|
||||||
+ merged_idx = modulemd_module_index_merger_resolve_ext (merger, TRUE, &error);
|
|
||||||
+ g_assert_no_error (error);
|
|
||||||
+ g_assert_nonnull (merged_idx);
|
|
||||||
+
|
|
||||||
+ httpd = modulemd_module_index_get_module (merged_idx, "httpd");
|
|
||||||
+ g_assert_nonnull (httpd);
|
|
||||||
+
|
|
||||||
+ httpd_defs = modulemd_module_get_defaults (httpd);
|
|
||||||
+ g_assert_nonnull (httpd_defs);
|
|
||||||
+
|
|
||||||
+ g_assert_cmpstr (modulemd_defaults_v1_get_default_stream (
|
|
||||||
+ MODULEMD_DEFAULTS_V1 (httpd_defs), NULL),
|
|
||||||
+ ==,
|
|
||||||
+ "2.8");
|
|
||||||
+
|
|
||||||
+ g_assert_cmpstr (modulemd_defaults_v1_get_default_stream (
|
|
||||||
+ MODULEMD_DEFAULTS_V1 (httpd_defs), "workstation"),
|
|
||||||
+ ==,
|
|
||||||
+ "2.4");
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+merger_test_add_conflicting_stream (void)
|
|
||||||
+{
|
|
||||||
+ g_autoptr (GPtrArray) failures = NULL;
|
|
||||||
+ g_autoptr (GError) error = NULL;
|
|
||||||
+ g_autoptr (ModulemdModuleIndex) base_idx = modulemd_module_index_new ();
|
|
||||||
+ g_autoptr (ModulemdModuleIndex) add_conflicting_idx =
|
|
||||||
+ modulemd_module_index_new ();
|
|
||||||
+ g_autoptr (ModulemdModuleIndex) merged_idx = NULL;
|
|
||||||
+ g_autoptr (ModulemdModuleIndexMerger) merger =
|
|
||||||
+ modulemd_module_index_merger_new ();
|
|
||||||
+ ModulemdModule *psql = NULL;
|
|
||||||
+ ModulemdDefaults *psql_defs = NULL;
|
|
||||||
+ g_autofree gchar *base_yaml =
|
|
||||||
+ g_strdup_printf ("%s/merger/base.yaml", g_getenv ("TEST_DATA_PATH"));
|
|
||||||
+ g_autofree gchar *add_conflicting_yaml = g_strdup_printf (
|
|
||||||
+ "%s/merger/add_conflicting_stream.yaml", g_getenv ("TEST_DATA_PATH"));
|
|
||||||
+
|
|
||||||
+ g_assert_true (modulemd_module_index_update_from_file (
|
|
||||||
+ base_idx, base_yaml, TRUE, &failures, &error));
|
|
||||||
+ g_assert_true (modulemd_module_index_update_from_file (
|
|
||||||
+ add_conflicting_idx, add_conflicting_yaml, TRUE, &failures, &error));
|
|
||||||
+
|
|
||||||
+ modulemd_module_index_merger_associate_index (merger, base_idx, 0);
|
|
||||||
+ modulemd_module_index_merger_associate_index (
|
|
||||||
+ merger, add_conflicting_idx, 0);
|
|
||||||
+
|
|
||||||
+ merged_idx =
|
|
||||||
+ modulemd_module_index_merger_resolve_ext (merger, FALSE, &error);
|
|
||||||
+ g_assert_no_error (error);
|
|
||||||
+ g_assert_nonnull (merged_idx);
|
|
||||||
+
|
|
||||||
+ psql = modulemd_module_index_get_module (merged_idx, "postgresql");
|
|
||||||
+ g_assert_nonnull (psql);
|
|
||||||
+
|
|
||||||
+ psql_defs = modulemd_module_get_defaults (psql);
|
|
||||||
+ g_assert_nonnull (psql_defs);
|
|
||||||
+
|
|
||||||
+ g_assert_null (modulemd_defaults_v1_get_default_stream (
|
|
||||||
+ MODULEMD_DEFAULTS_V1 (psql_defs), NULL));
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+merger_test_add_conflicting_stream_and_profile_modified (void)
|
|
||||||
+{
|
|
||||||
+ g_autoptr (GPtrArray) failures = NULL;
|
|
||||||
+ g_autoptr (GError) error = NULL;
|
|
||||||
+ g_autoptr (ModulemdModuleIndex) base_idx = modulemd_module_index_new ();
|
|
||||||
+ g_autoptr (ModulemdModuleIndex) add_conflicting_idx =
|
|
||||||
+ modulemd_module_index_new ();
|
|
||||||
+ g_autoptr (ModulemdModuleIndex) merged_idx = NULL;
|
|
||||||
+ g_autoptr (ModulemdModuleIndexMerger) merger =
|
|
||||||
+ modulemd_module_index_merger_new ();
|
|
||||||
+ ModulemdModule *psql = NULL;
|
|
||||||
+ ModulemdDefaults *psql_defs = NULL;
|
|
||||||
+ g_autofree gchar *base_yaml =
|
|
||||||
+ g_strdup_printf ("%s/merger/base.yaml", g_getenv ("TEST_DATA_PATH"));
|
|
||||||
+ g_autofree gchar *add_conflicting_yaml = g_strdup_printf (
|
|
||||||
+ "%s/merger/add_conflicting_stream_and_profile_modified.yaml",
|
|
||||||
+ g_getenv ("TEST_DATA_PATH"));
|
|
||||||
+
|
|
||||||
+ g_assert_true (modulemd_module_index_update_from_file (
|
|
||||||
+ base_idx, base_yaml, TRUE, &failures, &error));
|
|
||||||
+ g_assert_true (modulemd_module_index_update_from_file (
|
|
||||||
+ add_conflicting_idx, add_conflicting_yaml, TRUE, &failures, &error));
|
|
||||||
+
|
|
||||||
+ modulemd_module_index_merger_associate_index (merger, base_idx, 0);
|
|
||||||
+ modulemd_module_index_merger_associate_index (
|
|
||||||
+ merger, add_conflicting_idx, 0);
|
|
||||||
+
|
|
||||||
+ merged_idx =
|
|
||||||
+ modulemd_module_index_merger_resolve_ext (merger, FALSE, &error);
|
|
||||||
+ g_assert_no_error (error);
|
|
||||||
+ g_assert_nonnull (merged_idx);
|
|
||||||
+
|
|
||||||
+ psql = modulemd_module_index_get_module (merged_idx, "postgresql");
|
|
||||||
+ g_assert_nonnull (psql);
|
|
||||||
+
|
|
||||||
+ psql_defs = modulemd_module_get_defaults (psql);
|
|
||||||
+ g_assert_nonnull (psql_defs);
|
|
||||||
+
|
|
||||||
+ g_assert_cmpstr (modulemd_defaults_v1_get_default_stream (
|
|
||||||
+ MODULEMD_DEFAULTS_V1 (psql_defs), NULL),
|
|
||||||
+ ==,
|
|
||||||
+ "8.2");
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
int
|
|
||||||
main (int argc, char *argv[])
|
|
||||||
{
|
|
||||||
@@ -125,5 +263,14 @@ main (int argc, char *argv[])
|
|
||||||
merger_test_deduplicate,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
+ g_test_add_func ("/modulemd/module/index/merger/add_only",
|
|
||||||
+ merger_test_add_only);
|
|
||||||
+
|
|
||||||
+ g_test_add_func ("/modulemd/module/index/merger/add_conflicting_stream",
|
|
||||||
+ merger_test_add_conflicting_stream);
|
|
||||||
+
|
|
||||||
+ g_test_add_func ("/modulemd/module/index/merger/add_conflicting_both",
|
|
||||||
+ merger_test_add_conflicting_stream_and_profile_modified);
|
|
||||||
+
|
|
||||||
return g_test_run ();
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.23.0
|
|
||||||
|
|
@ -1,503 +0,0 @@
|
|||||||
From a16e69a71778bc81e5bb35ab98048a650cd4edcc Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
Date: Tue, 8 Oct 2019 16:05:13 -0400
|
|
||||||
Subject: [PATCH 8/8] Rework defaults merging logic
|
|
||||||
|
|
||||||
Fixes: https://github.com/fedora-modularity/libmodulemd/issues/378
|
|
||||||
|
|
||||||
Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
|
|
||||||
---
|
|
||||||
modulemd/v1/modulemd-defaults.c | 347 +++++++++++++-------
|
|
||||||
modulemd/v1/tests/test-modulemd-defaults.c | 18 +-
|
|
||||||
test_data/defaults/overriding-modified.yaml | 5 +-
|
|
||||||
3 files changed, 242 insertions(+), 128 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/modulemd/v1/modulemd-defaults.c b/modulemd/v1/modulemd-defaults.c
|
|
||||||
index d44076eef0ac3bffae05f74b852fb6b51c2aee64..9fa00f4104938f83e023070e6971608b0d27ddfa 100644
|
|
||||||
--- a/modulemd/v1/modulemd-defaults.c
|
|
||||||
+++ b/modulemd/v1/modulemd-defaults.c
|
|
||||||
@@ -725,27 +725,36 @@ modulemd_defaults_copy (ModulemdDefaults *self)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
+static gboolean
|
|
||||||
+modulemd_defaults_merge_default_profiles (GHashTable *from_profile_defaults,
|
|
||||||
+ GHashTable *merged_profile_defaults,
|
|
||||||
+ guint64 from_modified,
|
|
||||||
+ guint64 into_modified,
|
|
||||||
+ GError **error);
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+modulemd_defaults_merge_intent_default_streams (ModulemdIntent *from_intent,
|
|
||||||
+ ModulemdIntent *into_intent,
|
|
||||||
+ const gchar *intent_name,
|
|
||||||
+ guint64 from_modified,
|
|
||||||
+ guint64 into_modified);
|
|
||||||
+
|
|
||||||
ModulemdDefaults *
|
|
||||||
modulemd_defaults_merge (ModulemdDefaults *first,
|
|
||||||
ModulemdDefaults *second,
|
|
||||||
gboolean override,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
- g_autoptr (ModulemdDefaults) defaults = NULL;
|
|
||||||
- GHashTable *profile_defaults = NULL;
|
|
||||||
- g_autoptr (GHashTable) intents = NULL;
|
|
||||||
- ModulemdIntent *base_intent = NULL;
|
|
||||||
- ModulemdIntent *merge_intent = NULL;
|
|
||||||
- g_autoptr (ModulemdIntent) new_intent = NULL;
|
|
||||||
- g_autoptr (GHashTable) base_profiles = NULL;
|
|
||||||
- GHashTable *merge_profiles = NULL;
|
|
||||||
+ g_autoptr (ModulemdDefaults) merged = NULL;
|
|
||||||
+ ModulemdIntent *from_intent = NULL;
|
|
||||||
+ ModulemdIntent *merged_intent = NULL;
|
|
||||||
const gchar *intent_name = NULL;
|
|
||||||
- ModulemdSimpleSet *profile = NULL;
|
|
||||||
- GHashTableIter iter, profile_iter;
|
|
||||||
- gpointer key, value, orig_value, prof_key, prof_value;
|
|
||||||
+ GHashTableIter iter;
|
|
||||||
+ gpointer key, value;
|
|
||||||
|
|
||||||
- g_return_val_if_fail (MODULEMD_IS_DEFAULTS (first), NULL);
|
|
||||||
- g_return_val_if_fail (MODULEMD_IS_DEFAULTS (second), NULL);
|
|
||||||
+
|
|
||||||
+ g_return_val_if_fail (first && MODULEMD_IS_DEFAULTS (first), NULL);
|
|
||||||
+ g_return_val_if_fail (second && MODULEMD_IS_DEFAULTS (second), NULL);
|
|
||||||
|
|
||||||
if (override)
|
|
||||||
{
|
|
||||||
@@ -755,156 +764,250 @@ modulemd_defaults_merge (ModulemdDefaults *first,
|
|
||||||
return modulemd_defaults_copy (second);
|
|
||||||
}
|
|
||||||
|
|
||||||
- /* Compare modified values */
|
|
||||||
- if (modulemd_defaults_get_modified (first) >
|
|
||||||
- modulemd_defaults_get_modified (second))
|
|
||||||
+ /* Start from a copy of the base */
|
|
||||||
+ merged = modulemd_defaults_copy (first);
|
|
||||||
+
|
|
||||||
+ /* == Merge default streams == */
|
|
||||||
+ if (second->default_stream && !merged->default_stream)
|
|
||||||
{
|
|
||||||
- /* If first has a higher modified value, return a copy of it */
|
|
||||||
- return modulemd_defaults_copy (first);
|
|
||||||
+ /* Only the second Defaults had a default stream, so set that */
|
|
||||||
+ modulemd_defaults_set_default_stream (merged, second->default_stream);
|
|
||||||
}
|
|
||||||
- else if (modulemd_defaults_get_modified (second) >
|
|
||||||
- modulemd_defaults_get_modified (first))
|
|
||||||
+ else if (merged->default_stream && second->default_stream)
|
|
||||||
{
|
|
||||||
- /* If second has a higher modified value, return a copy of it */
|
|
||||||
- return modulemd_defaults_copy (second);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
+ /* Both of them had a defaults set */
|
|
||||||
|
|
||||||
- /* They had the same 'modified' value (such as both zero, for
|
|
||||||
- * backwards-compatibility with 1.7.x and older.
|
|
||||||
- * Merge them as best we can.
|
|
||||||
- */
|
|
||||||
-
|
|
||||||
- defaults = modulemd_defaults_copy (first);
|
|
||||||
-
|
|
||||||
- /* First check for incompatibilities with the streams */
|
|
||||||
- if (g_strcmp0 (first->default_stream, second->default_stream))
|
|
||||||
- {
|
|
||||||
- /* Default streams don't match and override is not set.
|
|
||||||
- * Return an error
|
|
||||||
+ /* Shortcut past if we already know there are conflicts in this
|
|
||||||
+ * default stream.
|
|
||||||
*/
|
|
||||||
- /* They have conflicting default streams */
|
|
||||||
- g_info ("Module stream mismatch in merge: %s != %s",
|
|
||||||
- first->default_stream,
|
|
||||||
- second->default_stream);
|
|
||||||
- modulemd_defaults_set_default_stream (defaults, DEFAULT_MERGE_CONFLICT);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* Merge the profile defaults */
|
|
||||||
- profile_defaults = modulemd_defaults_peek_profile_defaults (defaults);
|
|
||||||
-
|
|
||||||
- g_hash_table_iter_init (&iter,
|
|
||||||
- modulemd_defaults_peek_profile_defaults (second));
|
|
||||||
- while (g_hash_table_iter_next (&iter, &key, &value))
|
|
||||||
- {
|
|
||||||
- orig_value = g_hash_table_lookup (profile_defaults, key);
|
|
||||||
- if (orig_value)
|
|
||||||
+ if (!g_str_equal (merged->default_stream, DEFAULT_MERGE_CONFLICT))
|
|
||||||
{
|
|
||||||
- /* This key already exists in the first defaults object.
|
|
||||||
- * Check whether they have identical values
|
|
||||||
+ /* If second has a higher modified value, use its value.
|
|
||||||
+ * If first has a higher modified value, it's already saved in
|
|
||||||
+ * merged from the copy()
|
|
||||||
*/
|
|
||||||
- if (!modulemd_simpleset_is_equal (orig_value, value))
|
|
||||||
+ if (second->modified > first->modified)
|
|
||||||
{
|
|
||||||
- g_set_error (error,
|
|
||||||
- MODULEMD_DEFAULTS_ERROR,
|
|
||||||
- MODULEMD_DEFAULTS_ERROR_CONFLICTING_PROFILES,
|
|
||||||
- "Conflicting profile defaults when merging "
|
|
||||||
- "defaults for module %s",
|
|
||||||
- modulemd_defaults_peek_module_name (first));
|
|
||||||
- return NULL;
|
|
||||||
+ modulemd_defaults_set_default_stream (merged,
|
|
||||||
+ second->default_stream);
|
|
||||||
+ }
|
|
||||||
+ else if (first->modified == second->modified)
|
|
||||||
+ {
|
|
||||||
+ if (!g_str_equal (first->default_stream, second->default_stream))
|
|
||||||
+ {
|
|
||||||
+ /* They have conflicting default streams */
|
|
||||||
+ g_info ("Module stream mismatch in merge: %s != %s",
|
|
||||||
+ first->default_stream,
|
|
||||||
+ second->default_stream);
|
|
||||||
+
|
|
||||||
+ /* Set the special conflicting value */
|
|
||||||
+ modulemd_defaults_set_default_stream (
|
|
||||||
+ merged, DEFAULT_MERGE_CONFLICT);
|
|
||||||
+ }
|
|
||||||
+ /* Otherwise, they are the same and merged will have the correct
|
|
||||||
+ * value from the copy()
|
|
||||||
+ */
|
|
||||||
}
|
|
||||||
- }
|
|
||||||
- else
|
|
||||||
- {
|
|
||||||
- /* This key is new. Add it */
|
|
||||||
- g_hash_table_replace (profile_defaults,
|
|
||||||
- g_strdup (key),
|
|
||||||
- g_object_ref (MODULEMD_SIMPLESET (value)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+ /* If neither of the above matched, both first and second had NULL for the
|
|
||||||
+ * default stream, so nothing to do
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ /* == Merge profile defaults == */
|
|
||||||
+ if (!modulemd_defaults_merge_default_profiles (second->profile_defaults,
|
|
||||||
+ merged->profile_defaults,
|
|
||||||
+ second->modified,
|
|
||||||
+ first->modified,
|
|
||||||
+ error))
|
|
||||||
+ {
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ /* == Merge intent defaults == */
|
|
||||||
|
|
||||||
+ /* --- Merge intent default stream values --- */
|
|
||||||
|
|
||||||
- /* Merge intents */
|
|
||||||
- intents = modulemd_defaults_dup_intents (defaults);
|
|
||||||
+ /* Iterate through 'second', adding any new values and checking the existing
|
|
||||||
+ * ones for equivalence.
|
|
||||||
+ */
|
|
||||||
g_hash_table_iter_init (&iter, modulemd_defaults_peek_intents (second));
|
|
||||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
|
||||||
{
|
|
||||||
- merge_intent = MODULEMD_INTENT (value);
|
|
||||||
- /* Check if this module name exists in the current table */
|
|
||||||
- intent_name = modulemd_intent_peek_intent_name (merge_intent);
|
|
||||||
- base_intent = g_hash_table_lookup (
|
|
||||||
- intents, modulemd_intent_peek_intent_name (merge_intent));
|
|
||||||
+ g_return_val_if_fail (value && MODULEMD_IS_INTENT (value), FALSE);
|
|
||||||
|
|
||||||
- if (!base_intent)
|
|
||||||
+ intent_name = (gchar *)key;
|
|
||||||
+ from_intent = MODULEMD_INTENT (value);
|
|
||||||
+
|
|
||||||
+ merged_intent = g_hash_table_lookup (merged->intents, intent_name);
|
|
||||||
+ if (!merged_intent)
|
|
||||||
{
|
|
||||||
/* This intent doesn't exist yet, so just add it completely. */
|
|
||||||
- g_hash_table_insert (intents,
|
|
||||||
+ g_hash_table_insert (merged->intents,
|
|
||||||
g_strdup (intent_name),
|
|
||||||
- modulemd_intent_copy (merge_intent));
|
|
||||||
+ modulemd_intent_copy (from_intent));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
- /* Compare the default stream for this intent */
|
|
||||||
- if (g_strcmp0 (modulemd_intent_peek_default_stream (base_intent),
|
|
||||||
- modulemd_intent_peek_default_stream (merge_intent)))
|
|
||||||
+ /* Merge the intent default streams */
|
|
||||||
+ modulemd_defaults_merge_intent_default_streams (from_intent,
|
|
||||||
+ merged_intent,
|
|
||||||
+ intent_name,
|
|
||||||
+ second->modified,
|
|
||||||
+ first->modified);
|
|
||||||
+
|
|
||||||
+ /* Merge the intent default profiles */
|
|
||||||
+ if (!modulemd_defaults_merge_default_profiles (
|
|
||||||
+ modulemd_intent_peek_profile_defaults (from_intent),
|
|
||||||
+ modulemd_intent_peek_profile_defaults (merged_intent),
|
|
||||||
+ second->modified,
|
|
||||||
+ first->modified,
|
|
||||||
+ error))
|
|
||||||
{
|
|
||||||
- /* The streams didn't match, so bail out */
|
|
||||||
- g_set_error (error,
|
|
||||||
- MODULEMD_DEFAULTS_ERROR,
|
|
||||||
- MODULEMD_DEFAULTS_ERROR_CONFLICTING_INTENT_STREAM,
|
|
||||||
- "Conflicting default stream for intent profile [%s]"
|
|
||||||
- "when merging defaults for module %s",
|
|
||||||
- (const gchar *)intent_name,
|
|
||||||
- modulemd_defaults_peek_module_name (first));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- /* Construct a new Intent with the merged values which will replace
|
|
||||||
- * the existing one at the end */
|
|
||||||
- new_intent = modulemd_intent_copy (base_intent);
|
|
||||||
+ /* Set the modified value to the higher of the two provided */
|
|
||||||
+ if (second->modified > first->modified)
|
|
||||||
+ modulemd_defaults_set_modified (merged, second->modified);
|
|
||||||
|
|
||||||
- /* Merge the profile definitions for this intent */
|
|
||||||
- base_profiles = modulemd_intent_dup_profile_defaults (new_intent);
|
|
||||||
+ return g_steal_pointer (&merged);
|
|
||||||
+}
|
|
||||||
|
|
||||||
- merge_profiles = modulemd_intent_peek_profile_defaults (merge_intent);
|
|
||||||
- g_hash_table_iter_init (&profile_iter, merge_profiles);
|
|
||||||
- while (g_hash_table_iter_next (&profile_iter, &prof_key, &prof_value))
|
|
||||||
+
|
|
||||||
+static gboolean
|
|
||||||
+modulemd_defaults_merge_default_profiles (GHashTable *from_profile_defaults,
|
|
||||||
+ GHashTable *merged_profile_defaults,
|
|
||||||
+ guint64 from_modified,
|
|
||||||
+ guint64 into_modified,
|
|
||||||
+ GError **error)
|
|
||||||
+{
|
|
||||||
+ GHashTableIter iter;
|
|
||||||
+ gpointer key, value;
|
|
||||||
+ gchar *stream_name = NULL;
|
|
||||||
+ ModulemdSimpleSet *from_profiles = NULL;
|
|
||||||
+ ModulemdSimpleSet *merged_profiles = NULL;
|
|
||||||
+ ModulemdSimpleSet *copied_profiles = NULL;
|
|
||||||
+
|
|
||||||
+ g_hash_table_iter_init (&iter, from_profile_defaults);
|
|
||||||
+ while (g_hash_table_iter_next (&iter, &key, &value))
|
|
||||||
+ {
|
|
||||||
+ stream_name = (gchar *)key;
|
|
||||||
+ from_profiles = (ModulemdSimpleSet *)value;
|
|
||||||
+ merged_profiles =
|
|
||||||
+ g_hash_table_lookup (merged_profile_defaults, stream_name);
|
|
||||||
+
|
|
||||||
+ if (!merged_profiles)
|
|
||||||
{
|
|
||||||
- /* Check if this profile exists in this intent */
|
|
||||||
- profile = g_hash_table_lookup (base_profiles, prof_key);
|
|
||||||
+ /* Didn't appear in the profiles list, so just add it to merged */
|
|
||||||
+ modulemd_simpleset_copy (from_profiles, &copied_profiles);
|
|
||||||
+ g_hash_table_insert (
|
|
||||||
+ merged_profile_defaults, g_strdup (stream_name), copied_profiles);
|
|
||||||
+ copied_profiles = NULL;
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- if (!profile)
|
|
||||||
+ /* Check to see if they match */
|
|
||||||
+ if (!modulemd_simpleset_is_equal (from_profiles, merged_profiles))
|
|
||||||
+ {
|
|
||||||
+ if (from_modified > into_modified)
|
|
||||||
+ {
|
|
||||||
+ modulemd_simpleset_copy (from_profiles, &copied_profiles);
|
|
||||||
+ g_hash_table_insert (merged_profile_defaults,
|
|
||||||
+ g_strdup (stream_name),
|
|
||||||
+ copied_profiles);
|
|
||||||
+ copied_profiles = NULL;
|
|
||||||
+ }
|
|
||||||
+ else if (into_modified > from_modified)
|
|
||||||
{
|
|
||||||
- /* Add this profile to the intent */
|
|
||||||
- modulemd_simpleset_copy (prof_value, &profile);
|
|
||||||
- g_hash_table_insert (
|
|
||||||
- base_profiles, g_strdup ((const gchar *)prof_key), profile);
|
|
||||||
+ /* Already there, so just continue */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
-
|
|
||||||
- if (!modulemd_simpleset_is_equal (profile, prof_value))
|
|
||||||
+ else
|
|
||||||
{
|
|
||||||
- /* If we get here, the sets were unequal, so we need to fail */
|
|
||||||
+ /* The profile sets differed. This is an unresolvable merge
|
|
||||||
+ * conflict
|
|
||||||
+ */
|
|
||||||
g_set_error (error,
|
|
||||||
MODULEMD_DEFAULTS_ERROR,
|
|
||||||
- MODULEMD_DEFAULTS_ERROR_CONFLICTING_INTENT_PROFILE,
|
|
||||||
- "Conflicting intent profile [%s:%s] when merging "
|
|
||||||
- "defaults for module %s",
|
|
||||||
- (const gchar *)intent_name,
|
|
||||||
- (const gchar *)prof_key,
|
|
||||||
- modulemd_defaults_peek_module_name (first));
|
|
||||||
- return NULL;
|
|
||||||
+ MODULEMD_DEFAULTS_ERROR_CONFLICTING_PROFILES,
|
|
||||||
+ "Profile default mismatch in stream: %s",
|
|
||||||
+ stream_name);
|
|
||||||
+ return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- modulemd_intent_set_profile_defaults (new_intent, base_profiles);
|
|
||||||
- g_clear_pointer (&base_profiles, g_hash_table_unref);
|
|
||||||
- g_hash_table_replace (
|
|
||||||
- intents, g_strdup (intent_name), g_object_ref (new_intent));
|
|
||||||
- g_clear_pointer (&new_intent, g_object_unref);
|
|
||||||
+ /* They were a complete match, so no need to add it a second time */
|
|
||||||
}
|
|
||||||
|
|
||||||
- modulemd_defaults_set_intents (defaults, intents);
|
|
||||||
+ return TRUE;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+modulemd_defaults_merge_intent_default_streams (ModulemdIntent *from_intent,
|
|
||||||
+ ModulemdIntent *into_intent,
|
|
||||||
+ const gchar *intent_name,
|
|
||||||
+ guint64 from_modified,
|
|
||||||
+ guint64 into_modified)
|
|
||||||
+{
|
|
||||||
+ const gchar *from_default_stream = NULL;
|
|
||||||
+ const gchar *into_default_stream = NULL;
|
|
||||||
+
|
|
||||||
+ g_return_if_fail (from_intent && MODULEMD_IS_INTENT (from_intent));
|
|
||||||
+ g_return_if_fail (into_intent && MODULEMD_IS_INTENT (into_intent));
|
|
||||||
+ g_return_if_fail (intent_name);
|
|
||||||
+
|
|
||||||
+ from_default_stream = modulemd_intent_peek_default_stream (from_intent);
|
|
||||||
+
|
|
||||||
+ /* If there is no new default stream, just jump to the next item */
|
|
||||||
+ if (!from_default_stream)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ into_default_stream = modulemd_intent_peek_default_stream (into_intent);
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ /* If a previous merge has already marked this as conflicting, just bail
|
|
||||||
+ * out here and move on to the next intent
|
|
||||||
+ */
|
|
||||||
+ if (g_str_equal (into_default_stream, DEFAULT_MERGE_CONFLICT))
|
|
||||||
+ return;
|
|
||||||
|
|
||||||
- return g_object_ref (defaults);
|
|
||||||
+
|
|
||||||
+ if (into_default_stream)
|
|
||||||
+ {
|
|
||||||
+ /* Both default stream names are present.
|
|
||||||
+ * If they are equal, there's nothing to do.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+ if (!g_str_equal (into_default_stream, from_default_stream))
|
|
||||||
+ {
|
|
||||||
+ if (from_modified > into_modified)
|
|
||||||
+ {
|
|
||||||
+ /* Set the default stream of from as the merged value */
|
|
||||||
+ modulemd_intent_set_default_stream (into_intent,
|
|
||||||
+ from_default_stream);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ else if (into_modified == from_modified)
|
|
||||||
+ {
|
|
||||||
+ g_info (
|
|
||||||
+ "Module stream mismatch in merge: %s != %s for intent %s",
|
|
||||||
+ into_default_stream,
|
|
||||||
+ from_default_stream,
|
|
||||||
+ intent_name);
|
|
||||||
+ modulemd_intent_set_default_stream (into_intent,
|
|
||||||
+ DEFAULT_MERGE_CONFLICT);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ /* Otherwise into is already set, so do nothing */
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ else /* !into_default_stream */
|
|
||||||
+ {
|
|
||||||
+ /* There was no default stream set yet, so just add the new one */
|
|
||||||
+ modulemd_intent_set_default_stream (into_intent, from_default_stream);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
diff --git a/modulemd/v1/tests/test-modulemd-defaults.c b/modulemd/v1/tests/test-modulemd-defaults.c
|
|
||||||
index 35142b885b3ec30f5109d53befe17be3e08d7b5a..c088e87b442af37e69845216db33afa8361785cc 100644
|
|
||||||
--- a/modulemd/v1/tests/test-modulemd-defaults.c
|
|
||||||
+++ b/modulemd/v1/tests/test-modulemd-defaults.c
|
|
||||||
@@ -913,7 +913,7 @@ modulemd_defaults_test_prioritizer_modified (DefaultsFixture *fixture,
|
|
||||||
g_assert_cmpstr (
|
|
||||||
modulemd_defaults_peek_default_stream (defaults), ==, "2.4");
|
|
||||||
htable = modulemd_defaults_peek_profile_defaults (defaults);
|
|
||||||
- g_assert_cmpint (g_hash_table_size (htable), ==, 2);
|
|
||||||
+ g_assert_cmpint (g_hash_table_size (htable), ==, 3);
|
|
||||||
g_assert_true (g_hash_table_contains (htable, "2.2"));
|
|
||||||
g_assert_true (modulemd_simpleset_contains (
|
|
||||||
g_hash_table_lookup (htable, "2.2"), "client"));
|
|
||||||
@@ -924,7 +924,10 @@ modulemd_defaults_test_prioritizer_modified (DefaultsFixture *fixture,
|
|
||||||
g_hash_table_lookup (htable, "2.2"), "client"));
|
|
||||||
g_assert_true (modulemd_simpleset_contains (
|
|
||||||
g_hash_table_lookup (htable, "2.4"), "server"));
|
|
||||||
- g_assert_false (g_hash_table_contains (htable, "2.8"));
|
|
||||||
+ g_assert_true (g_hash_table_contains (htable, "2.8"));
|
|
||||||
+ g_assert_true (modulemd_simpleset_contains (
|
|
||||||
+ g_hash_table_lookup (htable, "2.8"), "notreal"));
|
|
||||||
+
|
|
||||||
|
|
||||||
/* NODEJS */
|
|
||||||
defaults = MODULEMD_DEFAULTS (g_ptr_array_index (merged_objects, 1));
|
|
||||||
@@ -956,14 +959,21 @@ modulemd_defaults_test_prioritizer_modified (DefaultsFixture *fixture,
|
|
||||||
g_assert_cmpstr (
|
|
||||||
modulemd_defaults_peek_default_stream (defaults), ==, "8.1");
|
|
||||||
htable = modulemd_defaults_peek_profile_defaults (defaults);
|
|
||||||
- g_assert_cmpint (g_hash_table_size (htable), ==, 1);
|
|
||||||
+ g_assert_cmpint (g_hash_table_size (htable), ==, 2);
|
|
||||||
g_assert_true (g_hash_table_contains (htable, "8.1"));
|
|
||||||
g_assert_true (modulemd_simpleset_contains (
|
|
||||||
g_hash_table_lookup (htable, "8.1"), "client"));
|
|
||||||
g_assert_true (modulemd_simpleset_contains (
|
|
||||||
g_hash_table_lookup (htable, "8.1"), "server"));
|
|
||||||
- g_assert_true (
|
|
||||||
+ g_assert_false (
|
|
||||||
modulemd_simpleset_contains (g_hash_table_lookup (htable, "8.1"), "foo"));
|
|
||||||
+ g_assert_true (g_hash_table_contains (htable, "8.2"));
|
|
||||||
+ g_assert_true (modulemd_simpleset_contains (
|
|
||||||
+ g_hash_table_lookup (htable, "8.2"), "client"));
|
|
||||||
+ g_assert_true (modulemd_simpleset_contains (
|
|
||||||
+ g_hash_table_lookup (htable, "8.2"), "server"));
|
|
||||||
+ g_assert_true (
|
|
||||||
+ modulemd_simpleset_contains (g_hash_table_lookup (htable, "8.2"), "foo"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
diff --git a/test_data/defaults/overriding-modified.yaml b/test_data/defaults/overriding-modified.yaml
|
|
||||||
index 719892ee0e999e4c48a9c69f6d4fdf84b0c5d89d..b87ba98ca99da128f78f8c560af3a7d928e8fde9 100644
|
|
||||||
--- a/test_data/defaults/overriding-modified.yaml
|
|
||||||
+++ b/test_data/defaults/overriding-modified.yaml
|
|
||||||
@@ -17,7 +17,7 @@ data:
|
|
||||||
'2.6': [client, server, bindings]
|
|
||||||
'2.8': [client, server, bindings, new]
|
|
||||||
---
|
|
||||||
-# Reduce the number of profile defaults
|
|
||||||
+# Drop one profile from a stream and add it to another
|
|
||||||
document: modulemd-defaults
|
|
||||||
version: 1
|
|
||||||
data:
|
|
||||||
@@ -25,7 +25,8 @@ data:
|
|
||||||
modified: 201812061200
|
|
||||||
stream: '8.1'
|
|
||||||
profiles:
|
|
||||||
- '8.1': [client, server, foo]
|
|
||||||
+ '8.1': [client, server]
|
|
||||||
+ '8.2': [client, server, foo]
|
|
||||||
---
|
|
||||||
# Override the default stream
|
|
||||||
document: modulemd-defaults
|
|
||||||
--
|
|
||||||
2.23.0
|
|
||||||
|
|
@ -1,14 +1,25 @@
|
|||||||
%global libmodulemd_version 2.5.0
|
%global baserelease 1
|
||||||
%global libmodulemd_v1_version 1.8.11
|
%global v2_epoch 0
|
||||||
|
%global v2_major 2
|
||||||
|
%global v2_minor 8
|
||||||
|
%global v2_patch 2
|
||||||
|
%global v2_release %{baserelease}
|
||||||
|
%global libmodulemd_v2_version %{v2_major}.%{v2_minor}.%{v2_patch}
|
||||||
|
%global libmodulemd_v1_version 1.8.16
|
||||||
|
# This is trickery to ensure that the upgrade path for libmodulemd1 is always
|
||||||
|
# clean and associated with the appropriate v2 build
|
||||||
|
%global libmodulemd_v1_release %{v2_epoch}.%{v2_major}.%{v2_minor}.%{v2_patch}.%{v2_release}
|
||||||
|
|
||||||
Name: libmodulemd
|
Name: libmodulemd
|
||||||
Version: %{libmodulemd_version}
|
Version: %{libmodulemd_v2_version}
|
||||||
Release: 4%{?dist}
|
Release: %{baserelease}%{?dist}
|
||||||
Summary: Module metadata manipulation library
|
Summary: Module metadata manipulation library
|
||||||
|
|
||||||
License: MIT
|
License: MIT
|
||||||
URL: https://github.com/fedora-modularity/libmodulemd
|
URL: https://github.com/fedora-modularity/libmodulemd
|
||||||
Source0: %{url}/releases/download/%{name}-%{version}/modulemd-%{version}.tar.xz
|
Source0: %{url}/releases/download/%{name}-%{version}/modulemd-%{version}.tar.xz
|
||||||
|
Source1: %{url}/releases/download/%{name}-%{libmodulemd_v1_version}/modulemd-%{libmodulemd_v1_version}.tar.xz
|
||||||
|
|
||||||
|
|
||||||
BuildRequires: meson >= 0.47
|
BuildRequires: meson >= 0.47
|
||||||
BuildRequires: pkgconfig
|
BuildRequires: pkgconfig
|
||||||
@ -18,27 +29,16 @@ BuildRequires: pkgconfig(gobject-2.0)
|
|||||||
BuildRequires: pkgconfig(gobject-introspection-1.0)
|
BuildRequires: pkgconfig(gobject-introspection-1.0)
|
||||||
BuildRequires: pkgconfig(yaml-0.1)
|
BuildRequires: pkgconfig(yaml-0.1)
|
||||||
BuildRequires: pkgconfig(gtk-doc)
|
BuildRequires: pkgconfig(gtk-doc)
|
||||||
|
BuildRequires: glib2-doc
|
||||||
|
BuildRequires: rpm-devel
|
||||||
|
BuildRequires: file-devel
|
||||||
BuildRequires: python3-devel
|
BuildRequires: python3-devel
|
||||||
BuildRequires: python3-gobject-base
|
BuildRequires: python3-gobject-base
|
||||||
%ifarch %{valgrind_arches}
|
%ifarch %{valgrind_arches}
|
||||||
BuildRequires: valgrind
|
BuildRequires: valgrind
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
# Make sure we upgrade libmodulemd1 to match
|
|
||||||
Conflicts: libmodulemd1 < %{libmodulemd_v1_version}-%{release}
|
|
||||||
|
|
||||||
|
|
||||||
# Patches
|
# Patches
|
||||||
Patch0001: 0001-Double-valgrind-timeout.patch
|
|
||||||
Patch0002: 0002-Parallelize-the-valgrind-tests.patch
|
|
||||||
Patch0003: 0003-Fix-transfer-type-for-Module.search_streams.patch
|
|
||||||
Patch0004: 0004-Extend-timeout-for-header-test.patch
|
|
||||||
|
|
||||||
#RHBZ #1763779- Merging defaults from third-party repositories
|
|
||||||
Patch0005: 0005-Add-test_data_path-env-var-for-Python-tests.patch
|
|
||||||
Patch0006: 0006-Add-ModuleIndexMerger.resolve_ext.patch
|
|
||||||
Patch0007: 0007-Rework-defaults-merging-logic-2x.patch
|
|
||||||
Patch0008: 0008-Rework-defaults-merging-logic-1x.patch
|
|
||||||
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@ -70,6 +70,7 @@ Development files for libmodulemd.
|
|||||||
%package -n libmodulemd1
|
%package -n libmodulemd1
|
||||||
Summary: Compatibility package for libmodulemd 1.x
|
Summary: Compatibility package for libmodulemd 1.x
|
||||||
Version: %{libmodulemd_v1_version}
|
Version: %{libmodulemd_v1_version}
|
||||||
|
Release: %{libmodulemd_v1_release}
|
||||||
Obsoletes: libmodulemd < 2
|
Obsoletes: libmodulemd < 2
|
||||||
Provides: libmodulemd = %{libmodulemd_v1_version}-%{release}
|
Provides: libmodulemd = %{libmodulemd_v1_version}-%{release}
|
||||||
Provides: libmodulemd%{?_isa} = %{libmodulemd_v1_version}-%{release}
|
Provides: libmodulemd%{?_isa} = %{libmodulemd_v1_version}-%{release}
|
||||||
@ -81,6 +82,7 @@ Compatibility library for libmodulemd 1.x
|
|||||||
%package -n libmodulemd1-devel
|
%package -n libmodulemd1-devel
|
||||||
Summary: Compatibility development package for libmodulemd 1.x
|
Summary: Compatibility development package for libmodulemd 1.x
|
||||||
Version: %{libmodulemd_v1_version}
|
Version: %{libmodulemd_v1_version}
|
||||||
|
Release: %{libmodulemd_v1_release}
|
||||||
Requires: libmodulemd1%{?_isa} = %{libmodulemd_v1_version}-%{release}
|
Requires: libmodulemd1%{?_isa} = %{libmodulemd_v1_version}-%{release}
|
||||||
Conflicts: %{name}-devel
|
Conflicts: %{name}-devel
|
||||||
Obsoletes: libmodulemd-devel < 2
|
Obsoletes: libmodulemd-devel < 2
|
||||||
@ -106,26 +108,28 @@ Python 3 bindings for libmodulemd1
|
|||||||
|
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%autosetup -p1 -n modulemd-%{libmodulemd_version}
|
%setup -c
|
||||||
|
%setup -c -T -D -a 1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
|
# Build the v1 API first
|
||||||
|
pushd modulemd-%{libmodulemd_v1_version}
|
||||||
%define _vpath_builddir api1
|
%define _vpath_builddir api1
|
||||||
%meson -Ddeveloper_build=false -Dbuild_api_v1=true -Dbuild_api_v2=false
|
%meson -Ddeveloper_build=false
|
||||||
%meson_build
|
%meson_build
|
||||||
|
popd
|
||||||
|
|
||||||
|
# Build the v2 API
|
||||||
|
pushd modulemd-%{libmodulemd_v2_version}
|
||||||
%define _vpath_builddir api2
|
%define _vpath_builddir api2
|
||||||
|
|
||||||
%ifarch aarch64
|
%ifarch aarch64
|
||||||
# aarch64 builders have I/O issues that often causes the valgrind tests to
|
# aarch64 builders have I/O issues that often causes the valgrind tests to
|
||||||
# time out. Skip them from the RPM build
|
# time out. Skip them from the RPM build
|
||||||
export MMD_SKIP_VALGRIND=True
|
export MMD_SKIP_VALGRIND=True
|
||||||
%endif
|
%endif
|
||||||
%meson -Ddeveloper_build=false -Dbuild_api_v1=false -Dbuild_api_v2=true -Dwith_py3_overrides=true -Dwith_py2_overrides=false
|
%meson -Ddeveloper_build=false -Dskip_formatters=true -Dwith_py3_overrides=true -Dwith_py2_overrides=false
|
||||||
|
|
||||||
|
|
||||||
%meson_build
|
%meson_build
|
||||||
|
popd
|
||||||
|
|
||||||
%check
|
%check
|
||||||
|
|
||||||
@ -140,27 +144,36 @@ export MMD_SKIP_VALGRIND=1
|
|||||||
export MMD_SKIP_VALGRIND=1
|
export MMD_SKIP_VALGRIND=1
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
pushd modulemd-%{libmodulemd_v1_version}
|
||||||
%define _vpath_builddir api1
|
%define _vpath_builddir api1
|
||||||
%{__meson} test -C %{_vpath_builddir} %{?_smp_mesonflags} --print-errorlogs -t 10
|
%{__meson} test -C %{_vpath_builddir} %{?_smp_mesonflags} --print-errorlogs -t 10
|
||||||
|
popd
|
||||||
|
|
||||||
|
pushd modulemd-%{libmodulemd_v2_version}
|
||||||
%define _vpath_builddir api2
|
%define _vpath_builddir api2
|
||||||
%{__meson} test -C %{_vpath_builddir} %{?_smp_mesonflags} --print-errorlogs -t 10
|
%{__meson} test -C %{_vpath_builddir} %{?_smp_mesonflags} --print-errorlogs -t 10
|
||||||
|
popd
|
||||||
|
|
||||||
|
|
||||||
%install
|
%install
|
||||||
|
pushd modulemd-%{libmodulemd_v1_version}
|
||||||
%define _vpath_builddir api1
|
%define _vpath_builddir api1
|
||||||
%meson_install
|
%meson_install
|
||||||
|
popd
|
||||||
|
|
||||||
|
pushd modulemd-%{libmodulemd_v2_version}
|
||||||
%define _vpath_builddir api2
|
%define _vpath_builddir api2
|
||||||
%meson_install
|
%meson_install
|
||||||
|
popd
|
||||||
|
|
||||||
|
# Create a symlink for the libmodulemd1-devel package
|
||||||
ln -s libmodulemd.so.%{libmodulemd_v1_version} \
|
ln -s libmodulemd.so.%{libmodulemd_v1_version} \
|
||||||
%{buildroot}%{_libdir}/%{name}.so.compat
|
%{buildroot}%{_libdir}/%{name}.so.compat
|
||||||
|
|
||||||
|
|
||||||
%files
|
%files
|
||||||
%license COPYING
|
%license modulemd-%{libmodulemd_v2_version}/COPYING
|
||||||
%doc README.md
|
%doc modulemd-%{libmodulemd_v2_version}/README.md
|
||||||
%{_bindir}/modulemd-validator
|
%{_bindir}/modulemd-validator
|
||||||
%{_libdir}/%{name}.so.2*
|
%{_libdir}/%{name}.so.2*
|
||||||
%dir %{_libdir}/girepository-1.0
|
%dir %{_libdir}/girepository-1.0
|
||||||
@ -186,8 +199,8 @@ ln -s libmodulemd.so.%{libmodulemd_v1_version} \
|
|||||||
|
|
||||||
|
|
||||||
%files -n libmodulemd1
|
%files -n libmodulemd1
|
||||||
%license COPYING
|
%license modulemd-%{libmodulemd_v1_version}/COPYING
|
||||||
%doc README.md
|
%doc modulemd-%{libmodulemd_v1_version}/README.md
|
||||||
%{_bindir}/modulemd-validator-v1
|
%{_bindir}/modulemd-validator-v1
|
||||||
%{_libdir}/%{name}.so.1*
|
%{_libdir}/%{name}.so.1*
|
||||||
%dir %{_libdir}/girepository-1.0
|
%dir %{_libdir}/girepository-1.0
|
||||||
@ -206,9 +219,13 @@ ln -s libmodulemd.so.%{libmodulemd_v1_version} \
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Oct 29 2019 Stephen Gallagher <sgallagh@redhat.com> - 2.8.2-1
|
||||||
|
- Update to versions 2.8.2 and 1.8.16
|
||||||
|
- Resolves: rhbz#1752511
|
||||||
|
|
||||||
* Wed Oct 23 2019 Stephen Gallagher <sgallagh@redhat.com> - 2.5.0-4
|
* Wed Oct 23 2019 Stephen Gallagher <sgallagh@redhat.com> - 2.5.0-4
|
||||||
- Improve default merging logic when dealing with third-party repos
|
- Improve default merging logic when dealing with third-party repos
|
||||||
- Resolves: rhbz#1763779
|
- Resolves: rhbz#1761805
|
||||||
|
|
||||||
* Wed May 29 2019 Stephen Gallagher <sgallagh@redhat.com> - 2.5.0-2
|
* Wed May 29 2019 Stephen Gallagher <sgallagh@redhat.com> - 2.5.0-2
|
||||||
- Fix memory corruption error using Module.search_rpms() from python
|
- Fix memory corruption error using Module.search_rpms() from python
|
||||||
|
Loading…
Reference in New Issue
Block a user