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

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