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
