Blame SOURCES/0004-boom-fix-precedence-and-handle-conflicts-when-mergin.patch

0228ad
 boom/command.py | 84 ++++++++++++++++++++++++++++++++++++++++++---------------
0228ad
 1 file changed, 63 insertions(+), 21 deletions(-)
0228ad
0228ad
diff --git a/boom/command.py b/boom/command.py
0228ad
index dc9abae..8900457 100644
0228ad
--- a/boom/command.py
0228ad
+++ b/boom/command.py
0228ad
@@ -482,24 +482,72 @@ def _do_print_type(report_fields, selected, output_fields=None,
0228ad
     return br.report_output()
0228ad
 
0228ad
 
0228ad
-def _merge_add_del_opts(orig_opts, opts):
0228ad
+def _merge_add_del_opts(bp, add_opts, del_opts):
0228ad
     """Merge a set of existing bootparams option alterations with
0228ad
         a set of command-line provided values to produce a single
0228ad
         set of options to add or remove from a cloned or edited
0228ad
         ``BootEntry``.
0228ad
-        :param orig_opts: A list of original option modifications
0228ad
-        :param opts: A space-separated string containing a list of
0228ad
-                     command line option modifications
0228ad
-        :returns: A single list containing the merged options
0228ad
-    """
0228ad
-    # Merge new and cloned kernel options
0228ad
-    all_opts = set()
0228ad
-    if opts:
0228ad
-        all_opts.update(opts.split())
0228ad
-    if orig_opts:
0228ad
-        all_opts.update(orig_opts)
0228ad
 
0228ad
-    return list(all_opts)
0228ad
+        The sets are merged giving precedence to alterations on the
0228ad
+        current command line: i.e. if an option is present in both
0228ad
+        ``bp.del_opts`` and ``add_opts`` (or vice versa) then the
0228ad
+        option taken from the current command line will be effective.
0228ad
+
0228ad
+        :param bp: A ``BootParams`` object with the original ``add_opts``
0228ad
+                   and ``del_opts`` values.
0228ad
+        :param add_opts: A space-separated string containing a list of
0228ad
+                         additional options taken from the current
0228ad
+                         command line.
0228ad
+        :param del_opts: A space-separated string containing a list of
0228ad
+                         options to delete taken from the current
0228ad
+                         command line.
0228ad
+        :returns: A tuple ``(effective_add_opts, effective_del_opts)``
0228ad
+                  giving the final effective values as a list of
0228ad
+                  strings, one per option word.
0228ad
+    """
0228ad
+    def _merge_opts(orig_opts, opts, r_opts):
0228ad
+        # Merge new and cloned kernel options
0228ad
+        all_opts = set()
0228ad
+        if opts:
0228ad
+            all_opts.update(opts)
0228ad
+        if orig_opts:
0228ad
+            all_opts.update(orig_opts)
0228ad
+        all_opts = list(all_opts)
0228ad
+        return [o for o in all_opts if o not in r_opts]
0228ad
+
0228ad
+    _log_debug_cmd("Add opts: %s" % add_opts)
0228ad
+    _log_debug_cmd("Del opts: %s" % del_opts)
0228ad
+    _log_debug_cmd("Original add_opts: %s" % bp.add_opts)
0228ad
+    _log_debug_cmd("Original del_opts: %s" % bp.del_opts)
0228ad
+
0228ad
+    r_del_opts = []
0228ad
+    r_add_opts = []
0228ad
+
0228ad
+    add_opts = add_opts.split() if add_opts else []
0228ad
+    del_opts = del_opts.split() if del_opts else []
0228ad
+
0228ad
+    for add_opt in list(add_opts):
0228ad
+        # Do not allow conflicting command line add/del opts
0228ad
+        if add_opt in del_opts:
0228ad
+            raise ValueError("Conflicting --add-opts %s and --del-opts %s" %
0228ad
+                             (add_opt, add_opt))
0228ad
+
0228ad
+        if add_opt in bp.del_opts:
0228ad
+            r_del_opts.append(add_opt)
0228ad
+            add_opts.remove(add_opt)
0228ad
+
0228ad
+    for del_opt in list(del_opts):
0228ad
+        if del_opt in bp.add_opts:
0228ad
+            r_add_opts.append(del_opt)
0228ad
+            del_opts.remove(del_opt)
0228ad
+
0228ad
+    add_opts = _merge_opts(bp.add_opts, add_opts, r_add_opts)
0228ad
+    del_opts = _merge_opts(bp.del_opts, del_opts, r_del_opts)
0228ad
+
0228ad
+    _log_debug_cmd("Effective add options: %s" % add_opts)
0228ad
+    _log_debug_cmd("Effective del options: %s" % del_opts)
0228ad
+
0228ad
+    return (add_opts, del_opts)
0228ad
 
0228ad
 
0228ad
 #
0228ad
@@ -759,10 +807,7 @@ def clone_entry(selection=None, title=None, version=None, machine_id=None,
0228ad
                        else be.bp.btrfs_subvol_id)
0228ad
     profile = profile if profile else be._osp
0228ad
 
0228ad
-    add_opts = _merge_add_del_opts(be.bp.add_opts, add_opts)
0228ad
-    del_opts = _merge_add_del_opts(be.bp.del_opts, del_opts)
0228ad
-    _log_debug_cmd("Effective add options: %s" % add_opts)
0228ad
-    _log_debug_cmd("Effective del options: %s" % del_opts)
0228ad
+    (add_opts, del_opts) = _merge_add_del_opts(be.bp, add_opts, del_opts)
0228ad
 
0228ad
     bp = BootParams(version, root_device, lvm_root_lv=lvm_root_lv,
0228ad
                     btrfs_subvol_path=btrfs_subvol_path,
0228ad
@@ -864,10 +909,7 @@ def edit_entry(selection=None, title=None, version=None, machine_id=None,
0228ad
     machine_id = machine_id or be.machine_id
0228ad
     version = version or be.version
0228ad
 
0228ad
-    add_opts = _merge_add_del_opts(be.bp.add_opts, add_opts)
0228ad
-    del_opts = _merge_add_del_opts(be.bp.del_opts, del_opts)
0228ad
-    _log_debug_cmd("Effective add options: %s" % add_opts)
0228ad
-    _log_debug_cmd("Effective del options: %s" % del_opts)
0228ad
+    (add_opts, del_opts) = _merge_add_del_opts(be.bp, add_opts, del_opts)
0228ad
 
0228ad
     be._osp = profile or be._osp
0228ad
     be.title = title or be.title