Hello community,

here is the log from the commit of package yast2-packager for openSUSE:Factory 
checked in at 2020-03-27 21:56:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-packager (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-packager.new.3160 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-packager"

Fri Mar 27 21:56:24 2020 rev:391 rq:788545 version:4.2.60

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-packager/yast2-packager.changes    
2020-03-22 14:16:16.666022457 +0100
+++ /work/SRC/openSUSE:Factory/.yast2-packager.new.3160/yast2-packager.changes  
2020-03-27 21:56:59.402782024 +0100
@@ -1,0 +2,7 @@
+Thu Mar 26 12:25:20 UTC 2020 - David Diaz <[email protected]>
+
+- Reverts changes made in 4.2.59 to improve the addons selection,
+  keeping it as it was (bsc#1167523).
+- 4.2.60
+
+-------------------------------------------------------------------

Old:
----
  yast2-packager-4.2.59.tar.bz2

New:
----
  yast2-packager-4.2.60.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ yast2-packager.spec ++++++
--- /var/tmp/diff_new_pack.1ofYX7/_old  2020-03-27 21:56:59.890782308 +0100
+++ /var/tmp/diff_new_pack.1ofYX7/_new  2020-03-27 21:56:59.890782308 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-packager
-Version:        4.2.59
+Version:        4.2.60
 Release:        0
 Summary:        YaST2 - Package Library
 License:        GPL-2.0-or-later
@@ -35,8 +35,8 @@
 BuildRequires:  yast2-storage-ng >= 4.0.141
 # break the yast2-packager -> yast2-storage-ng -> yast2-packager build cycle
 #!BuildIgnore: yast2-packager
-# CWM::MultiStatusSelector
-BuildRequires:  yast2 >= 4.2.72
+# Y2Packager::Repositories
+BuildRequires:  yast2 >= 4.2.60
 # Pkg::Resolvables
 BuildRequires:  yast2-pkg-bindings >= 4.2.0
 # Augeas lenses
@@ -47,8 +47,8 @@
 Requires:       yast2-country-data >= 2.16.3
 # Pkg::Resolvables
 Requires:       yast2-pkg-bindings >= 4.2.0
-# CWM::MultiStatusSelector
-Requires:       yast2 >= 4.2.72
+# Y2Packager::Repositories
+Requires:       yast2 >= 4.2.60
 # unzipping license file
 Requires:       unzip
 # HTTP, FTP, HTTPS modules (inst_productsources.ycp)

++++++ yast2-packager-4.2.59.tar.bz2 -> yast2-packager-4.2.60.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-4.2.59/package/yast2-packager.changes 
new/yast2-packager-4.2.60/package/yast2-packager.changes
--- old/yast2-packager-4.2.59/package/yast2-packager.changes    2020-03-18 
15:04:45.000000000 +0100
+++ new/yast2-packager-4.2.60/package/yast2-packager.changes    2020-03-26 
14:00:39.000000000 +0100
@@ -1,4 +1,11 @@
 -------------------------------------------------------------------
+Thu Mar 26 12:25:20 UTC 2020 - David Diaz <[email protected]>
+
+- Reverts changes made in 4.2.59 to improve the addons selection,
+  keeping it as it was (bsc#1167523).
+- 4.2.60
+
+-------------------------------------------------------------------
 Thu Mar 12 23:24:18 UTC 2020 - David Diaz <[email protected]>
 
 - Improve the product selection dialog (related to bsc#1157780).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-4.2.59/package/yast2-packager.spec 
new/yast2-packager-4.2.60/package/yast2-packager.spec
--- old/yast2-packager-4.2.59/package/yast2-packager.spec       2020-03-18 
15:04:45.000000000 +0100
+++ new/yast2-packager-4.2.60/package/yast2-packager.spec       2020-03-26 
14:00:39.000000000 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-packager
-Version:        4.2.59
+Version:        4.2.60
 Release:        0
 Summary:        YaST2 - Package Library
 License:        GPL-2.0-or-later
@@ -35,8 +35,8 @@
 BuildRequires:  yast2-storage-ng >= 4.0.141
 # break the yast2-packager -> yast2-storage-ng -> yast2-packager build cycle
 #!BuildIgnore: yast2-packager
-# CWM::MultiStatusSelector
-BuildRequires:  yast2 >= 4.2.72
+# Y2Packager::Repositories
+BuildRequires:  yast2 >= 4.2.60
 # Pkg::Resolvables
 BuildRequires:  yast2-pkg-bindings >= 4.2.0
 # Augeas lenses
@@ -47,8 +47,8 @@
 Requires:       yast2-country-data >= 2.16.3
 # Pkg::Resolvables
 Requires:       yast2-pkg-bindings >= 4.2.0
-# CWM::MultiStatusSelector
-Requires:       yast2 >= 4.2.72
+# Y2Packager::Repositories
+Requires:       yast2 >= 4.2.60
 # unzipping license file
 Requires:       unzip
 # HTTP, FTP, HTTPS modules (inst_productsources.ycp)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-packager-4.2.59/src/lib/y2packager/dialogs/addon_selector.rb 
new/yast2-packager-4.2.60/src/lib/y2packager/dialogs/addon_selector.rb
--- old/yast2-packager-4.2.59/src/lib/y2packager/dialogs/addon_selector.rb      
2020-03-18 15:04:45.000000000 +0100
+++ new/yast2-packager-4.2.60/src/lib/y2packager/dialogs/addon_selector.rb      
2020-03-26 14:00:39.000000000 +0100
@@ -1,40 +1,37 @@
-# Copyright (c) [2017-2020] SUSE LLC
+# 
------------------------------------------------------------------------------
+# Copyright (c) 2017 SUSE LLC, All Rights Reserved.
 #
-# All Rights Reserved.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of version 2 of the GNU General Public License as published
-# by the Free Software Foundation.
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of version 2 of the GNU General Public License as published by the
+# Free Software Foundation.
 #
 # This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, contact SUSE LLC.
-#
-# To contact SUSE LLC about this file by physical or electronic mail, you may
-# find current contact information at www.suse.com.
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 
details.
+# 
------------------------------------------------------------------------------
 
 require "yast"
-require "cwm/dialog"
+require "erb"
+require "ui/installation_dialog"
 require "y2packager/resolvable"
-require "y2packager/widgets/addons_selector"
 
 Yast.import "AddOnProduct"
 Yast.import "Mode"
 Yast.import "ProductFeatures"
+Yast.import "Report"
 Yast.import "Stage"
+Yast.import "UI"
 Yast.import "Wizard"
 
 module Y2Packager
   module Dialogs
     # Dialog which shows the user available products on the medium
-    class AddonSelector < ::CWM::Dialog
+    class AddonSelector < ::UI::InstallationDialog
+      include Yast::Logger
+      include ERB::Util
+
       # @return [Array<Y2Packager::ProductLocation>] Products on the medium
       attr_reader :products
-
       # @return [Array<Y2Packager::ProductLocation>] User selected products
       attr_reader :selected_products
 
@@ -46,107 +43,156 @@
       #
       # @param products [Array<Y2Packager::ProductLocation>] Products on the 
medium
       def initialize(products)
+        super()
         textdomain "packager"
 
         @products = products
-        # do not offer base products, they would conflict with the already
-        # selected base product, allow a hidden way to force displaying them in
-        # some special cases
+        # do not offer base products, they would conflict with the already 
selected base product,
+        # allow a hidden way to force displaying them in some special cases
         @products.reject! { |p| p.details&.base } if 
ENV["Y2_DISPLAY_BASE_PRODUCTS"] != "1"
         @selected_products = []
       end
 
-      # The dialog entry point
-      #
-      # Display the dialog title on the left side at installation (in the first
-      # stage) to have the same layout as in the registration addons dialog.
-      #
-      # @see CWM::Dialog#run
-      def run
-        Yast::Wizard.OpenLeftTitleNextBackDialog if Yast::Stage.initial
-        super
-      ensure
-        Yast::Wizard.CloseDialog if Yast::Stage.initial
-      end
-
-      # @see CWM::Dialog#title
-      def title
-        # TODO: does it make sense also for the 3rd party addons?
-        _("Extension and Module Selection")
-      end
-
-      # @see CWM::Dialog#contents
-      def contents
-        VBox(
-          # TRANSLATORS: Product selection label (above a multi-selection box)
-          Left(Heading(_("Available Extensions and Modules"))),
-          addons_selector_widget
-        )
-      end
-
       # Handler for the :next action
       #
-      # Displays a confirmation popup if none product has been selected
-      #
-      # @return [Boolean] true when continuing; false if the action is canceled
+      # This action happens when the user clicks the 'Next' button
       def next_handler
         read_user_selection
 
-        return true unless selected_products.empty?
+        return if selected_products.empty? && 
!Yast::Popup.ContinueCancel(continue_msg)
 
-        Yast::Popup.ContinueCancel(continue_msg)
+        finish_dialog(:next)
       end
 
       # Handler for the :abort action
-      #
-      # Displays a confirmation popup when running in the initial stage 
(inst-sys)
-      #
-      # @return [Boolean] true when aborting is confirmed; false otherwise
+      # Confirm abort when running in the initial stage (inst-sys)
       def abort_handler
-        return true unless Yast::Stage.initial
+        return if Yast::Stage.initial && !Yast::Popup.ConfirmAbort(:painless)
 
-        Yast::Popup.ConfirmAbort(:painless)
+        finish_dialog(:abort)
       end
 
       # Text to display when the help button is pressed
       #
-      # @return [String] help
-      def help
-        [
-          # TRANSLATORS: Help text for the product selector dialog
-          _("<p>The selected repository contains several products in 
independent " \
-          "subdirectories. Select which products you want to install.</p>"),
-          # TRANSLATORS: Help text explaining different product selection 
statuses
-          _("<p>Bear in mind that products can have several states depending 
on " \
-            "how they were selected to be installed or not. Basically, it can 
be "\
-            "auto-selected by a pre-selection of recommended products or as a 
dependency "\
-            "of another product, manually selected by the user, or not 
selected "\
-            "(see the legend below).</p>")
-        ].join
+      # @return [String]
+      def help_text
+        # TRANSLATORS: help text
+        _("<p>The selected repository contains several products in independent 
" \
+        "subdirectories. Select which products you want to install.</p>")
+      end
+
+      # Handle changing the current item or changing the selection
+      def addon_repos_handler
+        current_product = find_current_product
+        return unless current_product
+
+        refresh_details(current_product)
+
+        select_dependent_products
+      end
+
+      # Display the the dialog title on the left side at installation
+      # (in the first stage) to have the same layout as in the registration
+      # addons dialog.
+      def run
+        Yast::Wizard.OpenLeftTitleNextBackDialog if Yast::Stage.initial
+        super()
+      ensure
+        Yast::Wizard.CloseDialog if Yast::Stage.initial
+      end
+
+      # overwrite dialog creation to always enable back/next by default
+      def create_dialog
+        res = super
+        Yast::Wizard.EnableNextButton
+        Yast::Wizard.EnableBackButton
+        Yast::UI.SetFocus(Id(:addon_repos))
+        res
       end
 
     private
 
-      # @return [Array<Y2Packager::ProductLocation>] collection of selected 
products
       attr_writer :selected_products
 
-      # Addons selector widget
+      def selection_content
+        defaults = preselected_products
+        products.map { |p| Item(Id(p.dir), p.summary || p.name, 
defaults.include?(p)) }
+      end
+
+      # Dialog content
       #
-      # @return [Y2Packager::Widgets::AddonsSelector]
-      def addons_selector_widget
-        @addons_selector_widget ||= Widgets::AddonsSelector.new(products, 
preselected_products)
+      # @see ::UI::Dialog
+      def dialog_content
+        VBox(
+          # TRANSLATORS: Product selection label (above a multi-selection box)
+          Left(Heading(_("Available Extensions and Modules"))),
+          VWeight(60, MinHeight(8,
+            MultiSelectionBox(
+              Id(:addon_repos),
+              Opt(:notify, :immediate),
+              "",
+              selection_content
+            ))),
+          VSpacing(0.4),
+          details_widget
+        )
       end
 
-      # Reads the currently selected products
-      def read_user_selection
-        selected_items = addons_selector_widget.selected_items.map(&:id)
+      # select the dependent products for the active selection
+      def select_dependent_products
+        # select the dependent products
+        new_selection = current_selection
+
+        # the selection has not changed, nothing to do
+        return if new_selection == selected_products
+
+        # add the dependent items to the selected list
+        selected_items = Yast::UI.QueryWidget(Id(:addon_repos), :SelectedItems)
+        new_items = new_selection - selected_products
+        new_items.each do |p|
+          # the dependencies contain also the transitive (indirect) 
dependencies,
+          # we do not need to recursively evaluate the list
+          dependencies = p&.details&.depends_on
+          selected_items.concat(dependencies) if dependencies
+        end
+
+        selected_items.uniq!
+
+        Yast::UI.ChangeWidget(:addon_repos, :SelectedItems, selected_items)
+      end
+
+      # refresh the details of the currently selected add-on
+      def refresh_details(current_product)
+        details = product_description(current_product)
+        Yast::UI.ChangeWidget(Id(:details), :Value, details)
+        Yast::UI.ChangeWidget(Id(:details), :Enabled, true)
+      end
 
-        self.selected_products = products.select { |p| 
selected_items.include?(p.dir) }
+      def read_user_selection
+        self.selected_products = current_selection
 
         log.info("Selected products: #{selected_products.inspect}")
       end
 
-      # A message for asking the user whether to continue without adding any 
addon
+      #
+      # The currently selected products
+      #
+      # @return [Array<Y2Packager::ProductLocation>] list of selected products
+      #
+      def current_selection
+        selected_items = Yast::UI.QueryWidget(Id(:addon_repos), :SelectedItems)
+        products.select { |p| selected_items.include?(p.dir) }
+      end
+
+      # Dialog title
+      #
+      # @see ::UI::Dialog
+      def dialog_title
+        # TODO: does it make sense also for the 3rd party addons?
+        _("Extension and Module Selection")
+      end
+
+      # A message for asking the user whether to continue without adding any 
addon.
       #
       # @return [String] translated message
       def continue_msg
@@ -155,30 +201,55 @@
           "Do you really want to continue without adding any product?")
       end
 
-      # Returns a list of the preselected products depending on the 
installation mode
-      #
-      # @see #preselected_installation_products
-      # @see #preselected_upgrade_products
-      #
-      # @return [Array<Y2Packager::ProductLocation>] preselected products
-      def preselected_products
-        if Yast::Mode.installation
-          # in installation preselect the defaults defined in the 
control.xml/installation.xml
-          preselected_installation_products
-        elsif Yast::Mode.update
-          # at upgrade preselect the installed addons
-          preselected_upgrade_products
-        else
-          # in other modes (e.g. installed system) do not preselect anything
-          []
+      # description widget
+      # @return [Yast::Term] the addon details widget
+      def details_widget
+        VWeight(
+          40,
+          RichText(Id(:details), Opt(:disabled), initial_description)
+        )
+      end
+
+      # extra help text
+      # @return [String] first product description
+      def initial_description
+        return "" if products.empty?
+
+        product_description(products.first)
+      end
+
+      def product_description(product)
+        erb_file = File.join(__dir__, "product_summary.erb")
+        log.info "Loading ERB template #{erb_file}"
+        erb = ERB.new(File.read(erb_file))
+
+        # compute the dependent products
+        dependencies = []
+        product&.details&.depends_on&.each do |p|
+          # display the human readable product name instead of the product 
directory
+          prod = @products.find { |pr| pr.dir == p }
+          dependencies << (prod.summary || prod.name) if prod
         end
+
+        # render the ERB template in the context of this object
+        erb.result(binding)
       end
 
-      # Returns a list of the preselected products at upgrade
-      #
-      # Preselect the installed products
-      #
-      # @return [Array<Y2Packager::ProductLocation>] preselected products
+      # return a list of the preselected products depending on the 
installation mode
+      # @return [Array<Y2Packager::ProductLocation>] the products
+      def preselected_products
+        # at upgrade preselect the installed addons
+        return preselected_upgrade_products if Yast::Mode.update
+        # in installation preselect the defaults defined in the 
control.xml/installation.xml
+        return preselected_installation_products if Yast::Mode.installation
+
+        # in other modes (e.g. installed system) do not preselect anything
+        []
+      end
+
+      # return a list of the preselected products at upgrade,
+      # preselect the installed products
+      # @return [Array<Y2Packager::ProductLocation>] the products
       def preselected_upgrade_products
         missing_products = Yast::AddOnProduct.missing_upgrades
         # installed but not selected yet products (to avoid duplicates)
@@ -187,12 +258,10 @@
         end
       end
 
-      # Return a list of the preselected products at installation,
-      #
-      # Preselect the default products specified in the 
control.xml/installation.xml,
-      # the already selected products are ignored.
-      #
-      # @return [Array<Y2Packager::ProductLocation>] preselected products
+      # return a list of the preselected products at installation,
+      # preselect the default products specified in the 
control.xml/installation.xml,
+      # the already selected products are ignored
+      # @return [Array<Y2Packager::ProductLocation>] the products
       def preselected_installation_products
         default_modules = Yast::ProductFeatures.GetFeature("software", 
"default_modules")
         return [] unless default_modules.is_a?(Array)
@@ -209,6 +278,14 @@
           default_modules.include?(p.details&.product)
         end
       end
+
+      # Returns the current product (the one which has the focus in the addons 
list)
+      #
+      # @return [Y2Packager::Product,nil]
+      def find_current_product
+        current_item = Yast::UI.QueryWidget(Id(:addon_repos), :CurrentItem)
+        products.find { |p| p.dir == current_item }
+      end
     end
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-packager-4.2.59/src/lib/y2packager/dialogs/product_summary.erb 
new/yast2-packager-4.2.60/src/lib/y2packager/dialogs/product_summary.erb
--- old/yast2-packager-4.2.59/src/lib/y2packager/dialogs/product_summary.erb    
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-packager-4.2.60/src/lib/y2packager/dialogs/product_summary.erb    
2020-03-26 14:00:39.000000000 +0100
@@ -0,0 +1,36 @@
+<%
+textdomain "packager"
+%>
+
+<%# TRANSLATORS: the RichText header, followed by the name of the directory %>
+<b><%= _("Directory on the Media:") %></b> <%= h(product.dir) %><br>
+<%# TRANSLATORS: the RichText header, followed by the name of the medium %>
+<b><%= _("Media Name:") %></b> <%= h(product.name) %><br>
+
+<% details = product.details %>
+<% if details %>
+  <% if details.product %>
+    <%# TRANSLATORS: the RichText header, followed by the product identifier, 
e.g. "SLES" %>
+    <b><%= _("Product ID:") %></b> <%= h(details.product) %>
+  <% end %>
+
+  <% if dependencies.nil? %>
+    <%# TRANSLATORS: error message in a RichText summary %>
+    <p><em><%= _("Cannot evaluate the product dependencies.") %></em></p>
+  <% elsif !dependencies.empty? %>
+    <%# TRANSLATORS: the RichText section header, followed by the names of the 
dependent products %>
+    <h3><%= _("Dependencies") %></h3>
+    <ul>
+      <% dependencies.each do |dep| %>
+        <li><%= h(dep) %></li>
+      <% end %>
+    </ul>
+  <% end %>
+
+  <% if !details.description.empty? %>
+    <%# TRANSLATORS: the RichText header, it is followed by an untranslated 
(English) product description %>
+    <h3><%= _("Product Description (English Only)") %></h3>
+    <%# no escaping, the description already *is* a rich text %>
+    <p><%= details.description %></p>
+  <% end %>
+<% end %>
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-packager-4.2.59/src/lib/y2packager/widgets/addons_selector.rb 
new/yast2-packager-4.2.60/src/lib/y2packager/widgets/addons_selector.rb
--- old/yast2-packager-4.2.59/src/lib/y2packager/widgets/addons_selector.rb     
2020-03-18 15:04:45.000000000 +0100
+++ new/yast2-packager-4.2.60/src/lib/y2packager/widgets/addons_selector.rb     
1970-01-01 01:00:00.000000000 +0100
@@ -1,179 +0,0 @@
-# Copyright (c) [2020] SUSE LLC
-#
-# All Rights Reserved.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of version 2 of the GNU General Public License as published
-# by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, contact SUSE LLC.
-#
-# To contact SUSE LLC about this file by physical or electronic mail, you may
-# find current contact information at www.suse.com.
-
-require "yast"
-require "forwardable"
-require "cwm/multi_status_selector"
-
-module Y2Packager
-  module Widgets
-    # A custom widget to display a multi status selector list
-    class AddonsSelector < CWM::MultiStatusSelector
-      include Yast::Logger
-      include Yast::UIShortcuts
-
-      attr_reader :items
-
-      # Constructor
-      #
-      # @param products [Array<ProductLocation>] available product locations
-      # @param preselected_products [Array<ProductLocation>] product locations 
to be selected
-      def initialize(products, preselected_products)
-        @products = products
-        @items = products.map do |product|
-          dependencies = product&.details&.depends_on || []
-          selected = preselected_products.include?(product)
-
-          Item.new(product, dependencies, selected)
-        end
-      end
-
-      def init
-        super
-
-        # Respect the behavior introduced in version 4.2.55
-        details_widget.value = items.first.description
-      end
-
-      # (see CWM::AbstractWidget#contents)
-      def contents
-        VBox(
-          VWeight(60, super),
-          VWeight(40, details_widget)
-        )
-      end
-
-      # Toggles the item
-      #
-      # Also recalculates the dependencies to perform necessary auto selections
-      #
-      # @param item [Item] the item to toggle
-      def toggle(item)
-        item.toggle
-        refresh_details(item)
-        select_dependencies
-      end
-
-      # Returns selected and auto-selected items
-      #
-      # @return [Array<Item>] a collection of selected and auto-selected items
-      def selected_items
-        items.select { |i| i.selected? || i.auto_selected? }
-      end
-
-      # (see CWM::AbstractWidget#contents)
-      def help
-        Item.help
-      end
-
-    private
-
-      # (see CWM::MultiStatusSelector#label_event_handler)
-      def label_event_handler(item)
-        refresh_details(item)
-      end
-
-      # Updates the details area with the given item description
-      #
-      # @param item [Item] selected item
-      def refresh_details(item)
-        details_widget.value = item.description
-      end
-
-      # Auto-selects needed dependencies
-      #
-      # Based in the current selection, auto selects dependencies not manually
-      # selected yet.
-      def select_dependencies
-        # Resets previous auto selection
-        @items.select(&:auto_selected?).each(&:unselect!)
-
-        # Recalculates missed dependencies
-        selected_items = @items.select(&:selected?)
-        dependencies = selected_items.flat_map(&:dependencies).uniq
-        missed_dependencies = dependencies - selected_items.map(&:id)
-
-        # Auto-selects them
-        @items.select { |i| missed_dependencies.include?(i.id) 
}.each(&:auto_select!)
-      end
-
-      # Returns the widget to display the details
-      #
-      # @return [CWM::RichText] the widget to display the details
-      def details_widget
-        @details_widget ||=
-          begin
-            w = CWM::RichText.new
-            w.widget_id = "details_area"
-            w
-          end
-      end
-
-      # Internal class to represent a {Y2Packager::ProductLocation} as 
selectable item
-      class Item < Item
-        include Yast::Logger
-        include ERB::Util
-        include Yast::I18n
-
-        # Constructor
-        #
-        # @param product [Y2Packager::ProductLocation] the product to be 
represented
-        # @param dependencies [Array<String>] a collection with the 
dependencies ids
-        # @param selected [Boolean] a flag indicating the initial status for 
the item
-        def initialize(product, dependencies, selected)
-          @product = product
-          @dependencies = dependencies
-          @status = selected ? :selected : :unselected
-        end
-
-        attr_reader :dependencies, :status
-
-        # Returns the item id
-        #
-        # @return [String] the item id
-        def id
-          product.dir
-        end
-
-        # Returns the item label
-        #
-        # @return [String] the item label
-        def label
-          product.summary || product.name
-        end
-
-        # Builds the item description
-        def description
-          @description ||=
-            begin
-              erb_file = File.join(__dir__, "product_summary.erb")
-              log.info "Loading ERB template #{erb_file}"
-              erb = ERB.new(File.read(erb_file))
-
-              erb.result(binding)
-            end
-        end
-
-      private
-
-        attr_reader :product
-      end
-    end
-  end
-end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-packager-4.2.59/src/lib/y2packager/widgets/product_summary.erb 
new/yast2-packager-4.2.60/src/lib/y2packager/widgets/product_summary.erb
--- old/yast2-packager-4.2.59/src/lib/y2packager/widgets/product_summary.erb    
2020-03-18 15:04:45.000000000 +0100
+++ new/yast2-packager-4.2.60/src/lib/y2packager/widgets/product_summary.erb    
1970-01-01 01:00:00.000000000 +0100
@@ -1,36 +0,0 @@
-<%
-textdomain "packager"
-%>
-
-<%# TRANSLATORS: the RichText header, followed by the name of the directory %>
-<b><%= _("Directory on the Media:") %></b> <%= h(product.dir) %><br>
-<%# TRANSLATORS: the RichText header, followed by the name of the medium %>
-<b><%= _("Media Name:") %></b> <%= h(product.name) %><br>
-
-<% details = product.details %>
-<% if details %>
-  <% if details.product %>
-    <%# TRANSLATORS: the RichText header, followed by the product identifier, 
e.g. "SLES" %>
-    <b><%= _("Product ID:") %></b> <%= h(details.product) %>
-  <% end %>
-
-  <% if dependencies.nil? %>
-    <%# TRANSLATORS: error message in a RichText summary %>
-    <p><em><%= _("Cannot evaluate the product dependencies.") %></em></p>
-  <% elsif !dependencies.empty? %>
-    <%# TRANSLATORS: the RichText section header, followed by the names of the 
dependent products %>
-    <h3><%= _("Dependencies") %></h3>
-    <ul>
-      <% dependencies.each do |dep| %>
-        <li><%= h(dep) %></li>
-      <% end %>
-    </ul>
-  <% end %>
-
-  <% if !details.description.empty? %>
-    <%# TRANSLATORS: the RichText header, it is followed by an untranslated 
(English) product description %>
-    <h3><%= _("Product Description (English Only)") %></h3>
-    <%# no escaping, the description already *is* a rich text %>
-    <p><%= details.description %></p>
-  <% end %>
-<% end %>
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-4.2.59/test/addon_selector_test.rb 
new/yast2-packager-4.2.60/test/addon_selector_test.rb
--- old/yast2-packager-4.2.59/test/addon_selector_test.rb       1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-packager-4.2.60/test/addon_selector_test.rb       2020-03-26 
14:00:39.000000000 +0100
@@ -0,0 +1,136 @@
+#! /usr/bin/env rspec
+
+require_relative "./test_helper"
+
+require "y2packager/product_location"
+require "y2packager/product_location_details"
+require "y2packager/dialogs/addon_selector"
+
+describe Y2Packager::Dialogs::AddonSelector do
+  let(:media_products) do
+    prods = [
+      [
+        "SLE-15-Module-Basesystem 15.0-0",
+        "/Basesystem",
+        Y2Packager::ProductLocationDetails.new(product: 
"sle-module-basesystem")
+      ],
+      [
+        "SLE-15-Module-Legacy 15.0-0",
+        "/Legacy",
+        Y2Packager::ProductLocationDetails.new(product: "sle-module-legacy")
+      ]
+    ]
+    prods.map { |r| Y2Packager::ProductLocation.new(r[0], r[1], product: r[2]) 
}
+  end
+
+  subject { described_class.new(media_products) }
+
+  describe "#help_text" do
+    it "returns a String" do
+      expect(subject.help_text).to be_a(String)
+    end
+  end
+
+  describe "#abort_handler" do
+    it "returns :abort" do
+      allow(Yast::Stage).to receive(:initial).and_return(false)
+      expect(subject.abort_handler).to eq(:abort)
+    end
+
+    context "in installation" do
+      before do
+        expect(Yast::Stage).to receive(:initial).and_return(true)
+      end
+
+      it "asks for confirmation" do
+        expect(Yast::Popup).to receive(:ConfirmAbort).and_return(true)
+        subject.abort_handler
+      end
+
+      it "returns :abort when confirmed" do
+        expect(Yast::Popup).to receive(:ConfirmAbort).and_return(true)
+        expect(subject.abort_handler).to eq(:abort)
+      end
+
+      it "returns nil when not confirmed" do
+        expect(Yast::Popup).to receive(:ConfirmAbort).and_return(false)
+        expect(subject.abort_handler).to be_nil
+      end
+    end
+  end
+
+  describe "#next_handler" do
+    context "an addon is selected" do
+      before do
+        expect(Yast::UI).to receive(:QueryWidget).with(Id(:addon_repos), 
:SelectedItems)
+          .and_return(["/Basesystem"])
+      end
+
+      it "returns :next if an addon is selected" do
+        expect(subject.next_handler).to eq(:next)
+      end
+
+      it "does not display any popup" do
+        expect(Yast::Popup).to_not receive(:anything)
+        subject.next_handler
+      end
+    end
+
+    context "no addon is selected" do
+      before do
+        expect(Yast::UI).to receive(:QueryWidget).with(Id(:addon_repos), 
:SelectedItems)
+          .and_return([])
+      end
+
+      it "displays a popup asking for confirmation" do
+        expect(Yast::Popup).to receive(:ContinueCancel).with(/no product/i)
+        subject.next_handler
+      end
+
+      it "returns :next if the popup is confirmed" do
+        expect(Yast::Popup).to receive(:ContinueCancel).with(/no 
product/i).and_return(true)
+        expect(subject.next_handler).to eq(:next)
+      end
+
+      it "returns nil if the popup is not confirmed" do
+        expect(Yast::Popup).to receive(:ContinueCancel).with(/no 
product/i).and_return(false)
+        expect(subject.next_handler).to be_nil
+      end
+    end
+  end
+
+  describe "#create_dialog" do
+    context "in installation" do
+      before do
+        allow(Yast::Stage).to receive(:initial).and_return(true)
+        allow(Yast::Mode).to receive(:installation).and_return(true)
+      end
+
+      it "preselects the default products from control.xml" do
+        # mock the control.xml default
+        expect(Yast::ProductFeatures).to receive(:GetFeature)
+          .with("software", 
"default_modules").and_return(["sle-module-basesystem"])
+
+        allow(Y2Packager::Resolvable).to receive(:find)
+          .with(kind: :product, status: :selected).and_return([])
+
+        expect(Yast::Wizard).to receive(:SetContents) do |_title, content, 
_help, _back, _next|
+          # find the MultiSelectionBox term in the UI definition
+          term = content.nested_find do |t|
+            t.respond_to?(:value) && t.value == :MultiSelectionBox
+          end
+
+          # verify that the Basesystem module is preselected
+          expect(term.params[3][0].params[1]).to eq("SLE-15-Module-Basesystem 
15.0-0")
+          expect(term.params[3][0].params[2]).to eq(true)
+
+          # verify that the Legacy module is NOT preselected
+          expect(term.params[3][1].params[1]).to eq("SLE-15-Module-Legacy 
15.0-0")
+          expect(term.params[3][1].params[2]).to eq(false)
+        end
+
+        subject.create_dialog
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-packager-4.2.59/test/lib/dialogs/addon_selector_test.rb 
new/yast2-packager-4.2.60/test/lib/dialogs/addon_selector_test.rb
--- old/yast2-packager-4.2.59/test/lib/dialogs/addon_selector_test.rb   
2020-03-18 15:04:45.000000000 +0100
+++ new/yast2-packager-4.2.60/test/lib/dialogs/addon_selector_test.rb   
1970-01-01 01:00:00.000000000 +0100
@@ -1,176 +0,0 @@
-# Copyright (c) [2017-2020] SUSE LLC
-#
-# All Rights Reserved.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of version 2 of the GNU General Public License as published
-# by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, contact SUSE LLC.
-#
-# To contact SUSE LLC about this file by physical or electronic mail, you may
-# find current contact information at www.suse.com.
-#
-require_relative "../../test_helper"
-
-require "cwm/rspec"
-require "y2packager/product_location"
-require "y2packager/product_location_details"
-require "y2packager/dialogs/addon_selector"
-
-describe Y2Packager::Dialogs::AddonSelector do
-  subject { described_class.new(products) }
-
-  include_examples "CWM::Dialog"
-
-  let(:basesystem) do
-    Y2Packager::ProductLocation.new(
-      "SLE-15-Module-Basesystem 15.0-0",
-      "/Basesystem",
-      product: Y2Packager::ProductLocationDetails.new(product: 
"sle-module-basesystem")
-    )
-  end
-
-  let(:desktop_applications) do
-    Y2Packager::ProductLocation.new(
-      "Desktop-Applications-Module 15-0",
-      "/Desktop-Applications",
-      product: Y2Packager::ProductLocationDetails.new(
-        depends_on: ["SLE-15-Module-Basesystem 15.0-0"]
-      )
-    )
-  end
-
-  let(:legacy_product) do
-    Y2Packager::ProductLocation.new(
-      "SLE-15-Module-Legacy 15.0-0",
-      "/Legacy",
-      product: Y2Packager::ProductLocationDetails.new(product: 
"sle-module-legacy")
-    )
-  end
-
-  let(:products) { [basesystem, desktop_applications, legacy_product] }
-
-  describe "#contents" do
-    context "during installation" do
-      before do
-        allow(Yast::Stage).to receive(:initial).and_return(true)
-        allow(Yast::Mode).to receive(:installation).and_return(true)
-        allow(Yast::UI).to receive(:UserInput).and_return(:next)
-
-        # mock the control.xml default
-        allow(Yast::ProductFeatures).to receive(:GetFeature)
-          .with("software", "default_modules")
-          .and_return(["sle-module-basesystem"])
-        allow(Y2Packager::Resolvable).to receive(:find)
-          .with(kind: :product, status: :selected)
-          .and_return([])
-      end
-
-      it "preselects the default products from control.xml" do
-        expect(Y2Packager::Widgets::AddonsSelector).to receive(:new)
-          .with(anything, [products.first])
-
-        subject.contents
-      end
-    end
-  end
-
-  describe "#abort_handler" do
-    it "returns :abort" do
-      allow(Yast::Stage).to receive(:initial).and_return(false)
-    end
-
-    context "during installation" do
-      let(:confirm_abort) { false }
-
-      before do
-        allow(Yast::Stage).to receive(:initial).and_return(true)
-        allow(Yast::Popup).to receive(:ConfirmAbort).and_return(confirm_abort)
-      end
-
-      it "asks for confirmation" do
-        expect(Yast::Popup).to receive(:ConfirmAbort).and_return(true)
-
-        subject.abort_handler
-      end
-
-      context "when confirmed" do
-        let(:confirm_abort) { true }
-
-        it "returns true" do
-          expect(subject.abort_handler).to eq(true)
-        end
-      end
-
-      context "when rejected" do
-        let(:confirm_abort) { false }
-
-        it "returns false" do
-          expect(subject.abort_handler).to eq(false)
-        end
-      end
-    end
-  end
-
-  describe "#next_handler" do
-    let(:addons_selector) { Y2Packager::Widgets::AddonsSelector.new(products, 
[]) }
-
-    before do
-      allow(Y2Packager::Widgets::AddonsSelector).to 
receive(:new).and_return(addons_selector)
-    end
-
-    context "when a product is selected" do
-      before do
-        addons_selector.items.each(&:select!)
-      end
-
-      it "does not display a popup" do
-        expect(Yast::Popup).to_not receive(:ContinueCancel)
-
-        subject.next_handler
-      end
-
-      it "returns true" do
-        expect(subject.next_handler).to eq(true)
-      end
-    end
-
-    context "when none product is selected" do
-      let(:confirm_continue) { false }
-
-      before do
-        addons_selector.items.each(&:unselect!)
-        allow(Yast::Popup).to 
receive(:ContinueCancel).and_return(confirm_continue)
-      end
-
-      it "displays a popup asking for confirmation" do
-        expect(Yast::Popup).to receive(:ContinueCancel).with(/no product/i)
-
-        subject.next_handler
-      end
-
-      context "and the user decides to continue" do
-        let(:confirm_continue) { true }
-
-        it "returns true" do
-          expect(subject.next_handler).to eq(true)
-        end
-      end
-
-      context "but the user decides to cancel" do
-        let(:confirm_continue) { false }
-
-        it "returns false" do
-          expect(subject.next_handler).to eq(false)
-        end
-      end
-    end
-  end
-end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-packager-4.2.59/test/lib/widgets/addons_selector_test.rb 
new/yast2-packager-4.2.60/test/lib/widgets/addons_selector_test.rb
--- old/yast2-packager-4.2.59/test/lib/widgets/addons_selector_test.rb  
2020-03-18 15:04:45.000000000 +0100
+++ new/yast2-packager-4.2.60/test/lib/widgets/addons_selector_test.rb  
1970-01-01 01:00:00.000000000 +0100
@@ -1,183 +0,0 @@
-# Copyright (c) [2020] SUSE LLC
-#
-# All Rights Reserved.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of version 2 of the GNU General Public License as published
-# by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, contact SUSE LLC.
-#
-# To contact SUSE LLC about this file by physical or electronic mail, you may
-# find current contact information at www.suse.com.
-
-require_relative "../../test_helper"
-
-require "cwm/rspec"
-require "y2packager/product_location"
-require "y2packager/product_location_details"
-require "y2packager/widgets/addons_selector"
-
-describe Y2Packager::Widgets::AddonsSelector do
-  subject(:addons_selector) { described_class.new(products, 
preselected_products) }
-
-  include_examples "CWM::CustomWidget"
-
-  let(:details_area) do
-    subject.contents.nested_find { |i| i.is_a?(CWM::RichText) && i.widget_id 
== "details_area" }
-  end
-
-  let(:basesystem) do
-    Y2Packager::ProductLocation.new(
-      "SLE-15-Module-Basesystem 15.0-0",
-      "/Basesystem",
-      product: Y2Packager::ProductLocationDetails.new(product: 
"sle-module-basesystem")
-    )
-  end
-
-  let(:desktop_applications) do
-    Y2Packager::ProductLocation.new(
-      "Desktop-Applications-Module 15-0",
-      "/Desktop-Applications",
-      product: Y2Packager::ProductLocationDetails.new(
-        depends_on: ["/Basesystem"]
-      )
-    )
-  end
-
-  let(:legacy_product) do
-    Y2Packager::ProductLocation.new(
-      "SLE-15-Module-Legacy 15.0-0",
-      "/Legacy",
-      product: Y2Packager::ProductLocationDetails.new(product: 
"sle-module-legacy")
-    )
-  end
-
-  let(:products) { [basesystem, desktop_applications, legacy_product] }
-  let(:preselected_products) { [legacy_product] }
-
-  describe "#initialize" do
-    it "selects preselected products" do
-      expect(subject.selected_items.map(&:id)).to 
eq(preselected_products.map(&:dir))
-    end
-  end
-
-  describe "#init" do
-    let(:first_item) { subject.items.first }
-
-    # Behavior introduced in version 4.2.55 
(https://github.com/yast/yast-packager/pull/511)
-    it "displays the first item description" do
-      expect(details_area).to receive(:value=).with(first_item.description)
-
-      subject.init
-    end
-  end
-
-  describe "#items" do
-    it "returns a collection of items representing available products" do
-      expect(subject.items.map(&:id)).to eq(products.map(&:dir))
-    end
-  end
-
-  describe "#toggle" do
-    let(:item) { subject.items.first }
-
-    it "toggles given item" do
-      expect(item).to receive(:toggle)
-
-      subject.toggle(item)
-    end
-
-    it "displays the item details" do
-      expect(details_area).to receive(:value=).with(item.description)
-
-      subject.toggle(item)
-    end
-
-    context "when selected item has dependencies" do
-      let(:basesystem_item) { subject.items.find { |i| i.id == "/Basesystem" } 
}
-      let(:desktop_apps_item) { subject.items.find { |i| i.id == 
"/Desktop-Applications" } }
-
-      context "and they are not selected yet" do
-        it "auto-selects them" do
-          expect(basesystem_item).to receive(:auto_select!)
-
-          subject.toggle(desktop_apps_item)
-        end
-      end
-
-      context "but they are already selected" do
-        before do
-          basesystem_item.select!
-        end
-
-        it "does nothing" do
-          expect(basesystem_item).to_not receive(:auto_select!)
-          expect(basesystem_item).to_not receive(:unselect!)
-          expect(basesystem_item).to_not receive(:select!)
-
-          subject.toggle(desktop_apps_item)
-        end
-      end
-    end
-  end
-end
-
-describe Y2Packager::Widgets::AddonsSelector::Item do
-  subject(:item) { described_class.new(product, dependencies, selected) }
-
-  let(:product) do
-    Y2Packager::ProductLocation.new(
-      "SLE-15-Module-Basesystem 15.0-0",
-      "/Basesystem",
-      product: Y2Packager::ProductLocationDetails.new(product: 
"sle-module-basesystem")
-    )
-  end
-
-  let(:dependencies) { nil }
-  let(:selected) { false }
-
-  describe "#id" do
-    it "returns a String" do
-      expect(subject.id).to be_a(String)
-    end
-
-    it "returns the product dir" do
-      expect(subject.id).to eq(product.dir)
-    end
-  end
-
-  describe "#label" do
-    let(:product_summary) { "A product summary" }
-    let(:product_name) { "A product name" }
-
-    before do
-      allow(product).to receive(:summary).and_return(product_summary)
-      allow(product).to receive(:name).and_return(product_name)
-    end
-
-    it "returns a String" do
-      expect(subject.id).to be_a(String)
-    end
-
-    context "when product has a summary" do
-      it "returns the product summary" do
-        expect(subject.label).to eq(product_summary)
-      end
-    end
-
-    context "when product has not a summary" do
-      let(:product_summary) { nil }
-
-      it "returns the product name" do
-        expect(subject.label).to eq(product_name)
-      end
-    end
-  end
-end


Reply via email to