Hello community,

here is the log from the commit of package yast2-packager for openSUSE:Factory 
checked in at 2016-05-19 12:04:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-packager (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-packager.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-packager"

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-packager/yast2-packager.changes    
2016-04-28 20:30:38.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.yast2-packager.new/yast2-packager.changes       
2016-05-19 12:04:28.000000000 +0200
@@ -1,0 +2,21 @@
+Thu May 12 11:24:25 UTC 2016 - [email protected]
+
+- Select the new default product patterns also when adding an
+  add-on from media in installed system (FATE#320199)
+- 3.1.100
+
+-------------------------------------------------------------------
+Wed May 11 15:49:26 CEST 2016 - [email protected]
+
+- Showing location of installed licenses.
+  (fate#219341)
+- 3.1.99
+
+-------------------------------------------------------------------
+Tue May 10 12:31:13 UTC 2016 - [email protected]
+
+- Local repositories are disabled at the end of the installation
+  if there is an online replacement available (FATE#320494)
+- 3.1.98
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ yast2-packager.spec ++++++
--- /var/tmp/diff_new_pack.cxu8Xh/_old  2016-05-19 12:04:29.000000000 +0200
+++ /var/tmp/diff_new_pack.cxu8Xh/_new  2016-05-19 12:04:29.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-packager
-Version:        3.1.97
+Version:        3.1.100
 Release:        0
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
@@ -33,8 +33,8 @@
 BuildRequires:  yast2_theme
 BuildRequires:  rubygem(rspec)
 
-# PackagesUI.show_update_messages; uptime call
-BuildRequires:  yast2 >= 3.1.182
+# Packages::Repository and Packages::Product classes
+BuildRequires:  yast2 >= 3.1.187
 
 # Pkg::SourceRawURL() and Pkg:ExpandedUrl()
 BuildRequires:  yast2-pkg-bindings >= 3.1.30
@@ -45,8 +45,8 @@
 # Pkg::SourceRawURL() and Pkg:ExpandedUrl()
 Requires:       yast2-pkg-bindings >= 3.1.30
 
-# Fixed .proc.cmdline agent; uptime call
-Requires:       yast2 >= 3.1.182
+# Packages::Repository and Packages::Product classes
+Requires:       yast2 >= 3.1.187
 
 # unzipping license file
 Requires:       unzip

++++++ yast2-packager-3.1.97.tar.bz2 -> yast2-packager-3.1.100.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.1.97/package/yast2-packager.changes 
new/yast2-packager-3.1.100/package/yast2-packager.changes
--- old/yast2-packager-3.1.97/package/yast2-packager.changes    2016-04-25 
11:47:26.000000000 +0200
+++ new/yast2-packager-3.1.100/package/yast2-packager.changes   2016-05-17 
09:02:08.000000000 +0200
@@ -1,4 +1,25 @@
 -------------------------------------------------------------------
+Thu May 12 11:24:25 UTC 2016 - [email protected]
+
+- Select the new default product patterns also when adding an
+  add-on from media in installed system (FATE#320199)
+- 3.1.100
+
+-------------------------------------------------------------------
+Wed May 11 15:49:26 CEST 2016 - [email protected]
+
+- Showing location of installed licenses.
+  (fate#219341)
+- 3.1.99
+
+-------------------------------------------------------------------
+Tue May 10 12:31:13 UTC 2016 - [email protected]
+
+- Local repositories are disabled at the end of the installation
+  if there is an online replacement available (FATE#320494)
+- 3.1.98
+
+-------------------------------------------------------------------
 Fri Apr 22 16:23:17 UTC 2016 - [email protected]
 
 - Move the default pattern selection to a different place to not
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.1.97/package/yast2-packager.spec 
new/yast2-packager-3.1.100/package/yast2-packager.spec
--- old/yast2-packager-3.1.97/package/yast2-packager.spec       2016-04-25 
11:47:26.000000000 +0200
+++ new/yast2-packager-3.1.100/package/yast2-packager.spec      2016-05-17 
09:02:08.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-packager
-Version:        3.1.97
+Version:        3.1.100
 Release:        0
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
@@ -32,8 +32,8 @@
 BuildRequires:  yast2_theme
 BuildRequires:  rubygem(rspec)
 
-# PackagesUI.show_update_messages; uptime call
-BuildRequires: yast2 >= 3.1.182
+# Packages::Repository and Packages::Product classes
+BuildRequires: yast2 >= 3.1.187
 
 # Pkg::SourceRawURL() and Pkg:ExpandedUrl()
 BuildRequires: yast2-pkg-bindings >= 3.1.30
@@ -44,8 +44,8 @@
 # Pkg::SourceRawURL() and Pkg:ExpandedUrl()
 Requires:      yast2-pkg-bindings >= 3.1.30
 
-# Fixed .proc.cmdline agent; uptime call
-Requires: yast2 >= 3.1.182
+# Packages::Repository and Packages::Product classes
+Requires: yast2 >= 3.1.187
 
 # unzipping license file
 Requires:      unzip
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.1.97/src/Makefile.am 
new/yast2-packager-3.1.100/src/Makefile.am
--- old/yast2-packager-3.1.97/src/Makefile.am   2016-04-25 11:47:26.000000000 
+0200
+++ new/yast2-packager-3.1.100/src/Makefile.am  2016-05-17 09:02:08.000000000 
+0200
@@ -70,6 +70,10 @@
   desktop/sw_single.desktop \
   desktop/checkmedia.desktop
 
-EXTRA_DIST = $(module_DATA) $(client_DATA) $(ynclude_DATA) $(ynclude1_DATA) 
$(scrconf_DATA) $(agent_SCRIPTS) $(desktop_DATA)
+ylibclientdir = "${yast2dir}/lib/packager/clients"
+ylibclient_DATA = \
+  lib/packager/clients/pkg_finish.rb
+
+EXTRA_DIST = $(module_DATA) $(client_DATA) $(ynclude_DATA) $(ynclude1_DATA) 
$(scrconf_DATA) $(agent_SCRIPTS) $(desktop_DATA) $(ylibclient_DATA) $(ylib_DATA)
 
 include $(top_srcdir)/Makefile.am.common
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.1.97/src/clients/pkg_finish.rb 
new/yast2-packager-3.1.100/src/clients/pkg_finish.rb
--- old/yast2-packager-3.1.97/src/clients/pkg_finish.rb 2016-04-25 
11:47:26.000000000 +0200
+++ new/yast2-packager-3.1.100/src/clients/pkg_finish.rb        2016-05-17 
09:02:08.000000000 +0200
@@ -11,187 +11,5 @@
 #
 # $Id$
 #
-module Yast
-  class PkgFinishClient < Client
-    def main
-      Yast.import "Pkg"
-
-      textdomain "packager"
-
-      Yast.import "Installation"
-      Yast.import "Mode"
-      Yast.import "Stage"
-      Yast.import "String"
-      Yast.import "FileUtils"
-      Yast.import "Packages"
-
-      @ret = nil
-      @func = ""
-      @param = {}
-
-      # Check arguments
-      if Ops.greater_than(Builtins.size(WFM.Args), 0) &&
-          Ops.is_string?(WFM.Args(0))
-        @func = Convert.to_string(WFM.Args(0))
-        if Ops.greater_than(Builtins.size(WFM.Args), 1) &&
-            Ops.is_map?(WFM.Args(1))
-          @param = Convert.to_map(WFM.Args(1))
-        end
-      end
-
-      Builtins.y2milestone("starting pkg_finish")
-      Builtins.y2debug("func=%1", @func)
-      Builtins.y2debug("param=%1", @param)
-
-      if @func == "Info"
-        return {
-          "steps" => 1,
-          # progress step title
-          "title" => _(
-            "Saving the software manager configuration..."
-          ),
-          "when"  => [:installation, :update, :autoinst]
-        }
-      elsif @func == "Write"
-        #     File "/openSUSE-release.prod" is no more on the media
-        #     but directly in the RPM. Don't create the directory
-        #     and don't copy the file manually anymore.
-        #
-        #     (since evrsion 2.17.5)
-        #
-        #     // Copy information about product (bnc#385868)
-        #     // FIXME: this is a temporary hack containing a hardcoded file 
name
-        #     string media_prod = Pkg::SourceProvideOptionalFile (
-        #      Packages::theSources[0]:0, 1,
-        #      "/openSUSE-release.prod");
-        #     if (media_prod != nil)
-        #     {
-        #      WFM::Execute (.local.bash, sformat ("test -d %1%2 || mkdir 
%1%2",
-        #                                              Installation::destdir, 
"/etc/zypp/products.d"));
-        #      WFM::Execute (.local.bash, sformat ("test -d %3%2 && /bin/cp %1 
%3%2",
-        #                                              media_prod, 
"/etc/zypp/products.d", Installation::destdir));
-        #     }
-
-        # Remove (backup) all sources not used during the update
-        # BNC #556469: Backup and remove all the old repositories before any 
Pkg::SourceSaveAll call
-        BackUpAllTargetSources() if Stage.initial && Mode.update
-
-        # See bnc #384827, #381360
-        if Mode.update
-          Builtins.y2milestone("Adding default repositories")
-          WFM.call("inst_extrasources")
-        end
-
-
-        # save all repositories and finish target
-        Pkg.SourceSaveAll
-        Pkg.TargetFinish
-
-        # save repository metadata cache to the installed system
-        # (needs to be done _after_ saving repositories, see bnc#700881)
-        Pkg.SourceCacheCopyTo(Installation.destdir)
-
-        # copy list of failed packages to installed system
-        WFM.Execute(
-          path(".local.bash"),
-          Builtins.sformat(
-            "test -f %1 && /bin/cp -a %1 '%2%1'",
-            "/var/lib/YaST2/failed_packages",
-            String.Quote(Installation.destdir)
-          )
-        )
-      else
-        Builtins.y2error("unknown function: %1", @func)
-        @ret = nil
-      end
-
-      Builtins.y2debug("ret=%1", @ret)
-      Builtins.y2milestone("pkg_finish finished")
-      deep_copy(@ret)
-    end
-
-    # During upgrade, old sources are reinitialized
-    # either as enabled or disabled.
-    # The old sources from targed should go away.
-    def BackUpAllTargetSources
-      Yast.import "Directory"
-
-      repos_dir = "/etc/zypp/repos.d"
-
-      if !FileUtils.Exists(repos_dir)
-        Builtins.y2error("Directory %1 doesn't exist!", repos_dir)
-        return
-      end
-
-      current_repos = Convert.convert(
-        SCR.Read(path(".target.dir"), repos_dir),
-        :from => "any",
-        :to   => "list <string>"
-      )
-
-      if current_repos == nil || Builtins.size(current_repos) == 0
-        Builtins.y2warning(
-          "There are currently no repos in %1 conf dir",
-          repos_dir
-        )
-        return
-      else
-        Builtins.y2milestone(
-          "These repos currently exist on a target: %1",
-          current_repos
-        )
-      end
-
-      cmd = Convert.to_map(
-        WFM.Execute(path(".local.bash_output"), "date +%Y%m%d-%H%M%S")
-      )
-      a_name_list = Builtins.splitstring(
-        Ops.get_string(cmd, "stdout", "the_latest"),
-        "\n"
-      )
-      archive_name = Ops.add(
-        Ops.add("repos_", Ops.get(a_name_list, 0, "")),
-        ".tgz"
-      )
-
-      shellcommand = Builtins.sformat(
-        "mkdir -p '%1' && cd '%1' && /bin/tar -czf '%2' '%3'",
-        String.Quote(Ops.add(Directory.vardir, "/repos.d_backup/")),
-        String.Quote(archive_name),
-        String.Quote(repos_dir)
-      )
-      cmd = Convert.to_map(
-        SCR.Execute(path(".target.bash_output"), shellcommand)
-      )
-
-      if Ops.get_integer(cmd, "exit", -1) != 0
-        Builtins.y2error(
-          "Unable to backup current repos; Command >%1< returned: %2",
-          shellcommand,
-          cmd
-        )
-      end
-
-      success = nil
-
-      Builtins.foreach(current_repos) do |one_repo|
-        one_repo = Ops.add(Ops.add(repos_dir, "/"), one_repo)
-        Builtins.y2milestone("Removing target repository %1", one_repo)
-        success = Convert.to_boolean(
-          SCR.Execute(path(".target.remove"), one_repo)
-        )
-        Builtins.y2error("Cannot remove %1 file", one_repo) if success != true
-      end
-
-      Builtins.y2milestone("All old repositories were removed from the target")
-
-      # reload the target to sync the removed repositories with libzypp 
repomanager
-      Pkg.TargetFinish
-      Pkg.TargetInitialize("/mnt")
-
-      nil
-    end
-  end
-end
-
-Yast::PkgFinishClient.new.main
+require "packager/clients/pkg_finish"
+Yast::PkgFinishClient.new.run
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-packager-3.1.97/src/lib/packager/clients/pkg_finish.rb 
new/yast2-packager-3.1.100/src/lib/packager/clients/pkg_finish.rb
--- old/yast2-packager-3.1.97/src/lib/packager/clients/pkg_finish.rb    
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-packager-3.1.100/src/lib/packager/clients/pkg_finish.rb   
2016-05-17 09:02:08.000000000 +0200
@@ -0,0 +1,198 @@
+# encoding: utf-8
+
+# 
------------------------------------------------------------------------------
+# Copyright (c) 2016 SUSE LLC
+#
+# 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.
+#
+# 
------------------------------------------------------------------------------
+
+require "installation/finish_client"
+require "packages/repository"
+
+module Yast
+  class PkgFinishClient < ::Installation::FinishClient
+    include Yast::I18n
+    include Yast::Logger
+
+    # Path to libzypp repositories
+    REPOS_DIR = "/etc/zypp/repos.d"
+    # Path to failed_packages file
+    FAILED_PKGS_PATH = "/var/lib/YaST2/failed_packages"
+    # Command to create a tar.gz to back-up old repositories
+    TAR_CMD = "mkdir -p '%<target>s' && cd '%<target>s' "\
+      "&& /bin/tar -czf '%<archive>s' '%<source>s'"
+    # Format of the timestamp to be used as repositories backup
+    BACKUP_TIMESTAMP_FORMAT = "%Y%m%d-%H%M%S"
+
+    # Constructor
+    def initialize
+      textdomain "packager"
+
+      Yast.import "Pkg"
+      Yast.import "Installation"
+      Yast.import "Mode"
+      Yast.import "Stage"
+      Yast.import "String"
+      Yast.import "FileUtils"
+      Yast.import "Packages"
+      Yast.import "Directory"
+    end
+
+    # @see Implements ::Installation::FinishClient#modes
+    def modes
+      [:installation, :update, :autoinst]
+    end
+
+    # @see Implements ::Installation::FinishClient#title
+    def title
+      _("Saving the software manager configuration...")
+    end
+
+    # @see Implements ::Installation::FinishClient#write
+    def write
+      # Remove (backup) all sources not used during the update
+      # BNC #556469: Backup and remove all the old repositories before any 
Pkg::SourceSaveAll call
+      backup_all_target_sources if Stage.initial && Mode.update
+
+      # See bnc #384827, #381360
+      if Mode.update
+        log.info("Adding default repositories")
+        WFM.call("inst_extrasources")
+      end
+
+      # If repositories weren't load during installation (for example, in 
openSUSE
+      # if online repositories were not enabled), resolvables should be loaded 
now.
+      Pkg.SourceLoad
+      disable_local_repos
+
+      # save all repositories and finish target
+      Pkg.SourceSaveAll
+      Pkg.TargetFinish
+
+      # save repository metadata cache to the installed system
+      # (needs to be done _after_ saving repositories, see bnc#700881)
+      Pkg.SourceCacheCopyTo(Installation.destdir)
+
+      # copy list of failed packages to installed system
+      if File.exist?(FAILED_PKGS_PATH)
+        ::FileUtils.cp(FAILED_PKGS_PATH, File.join(Installation.destdir, 
FAILED_PKGS_PATH),
+          preserve: true)
+      end
+    end
+
+  private
+
+    # Backup old sources
+    #
+    # During upgrade, old sources are reinitialized
+    # either as enabled or disabled.
+    # The old sources from target should go away.
+    def backup_all_target_sources
+      if !File.exist?(REPOS_DIR)
+        log.error("Directory #{REPOS_DIR} doesn't exist!")
+        return
+      end
+
+      current_repos = SCR.Read(path(".target.dir"), REPOS_DIR)
+
+      if current_repos.nil? || current_repos.empty?
+        log.warn("There are currently no repos in #{REPOS_DIR} conf dir")
+        return
+      else
+        log.info("These repos currently exist on a target: #{current_repos}")
+      end
+
+      # Backup repos.d
+      repos_backup_dir = File.join(Directory.vardir, "repos.d_backup")
+      backup_old_sources(REPOS_DIR, repos_backup_dir).nil?
+
+      # Clean old repositories
+      remove_old_sources(current_repos)
+
+      # Sync sources
+      sync_target_sources
+
+      nil
+    end
+
+    # Disable given repositories if needed
+    #
+    # Given a local repository:
+    #
+    # * if all products it contains are available through another repository,
+    #   then it will be disabled;
+    # * if some product contained is not available through another
+    #   repository, then it will be left untouched.
+    #
+    # @return [Array<Packages::Repository>] List of disabled repositories
+    def disable_local_repos
+      candidates_repos, other_repos = 
*::Packages::Repository.enabled.partition(&:local?)
+      products = other_repos.map(&:products).flatten.uniq
+      candidates_repos.each_with_object([]) do |repo, disabled|
+        if repo.products.empty?
+          log.info("Repo #{repo.repo_id} (#{repo.name}) does not have 
products; ignored")
+          next
+        end
+        uncovered = repo.products.reject { |p| products.include?(p) }
+        if uncovered.empty?
+          log.info("Repo #{repo.repo_id} (#{repo.name}) will be disabled 
because products " \
+            "are present in other repositories")
+          repo.disable!
+          disabled << repo
+        else
+          log.info("Repo #{repo.repo_id} (#{repo.name}) cannot be disabled 
because these " \
+            "products are not available through other repos: 
#{uncovered.map(&:name)}")
+        end
+      end
+    end
+
+    # Backup sources
+    #
+    # @param source [String] Path of sources to backup
+    # @param target [String] Directory to store backup
+    # @return [String,nil] Name of the backup archive (locate in the given 
target directory);
+    #                      nil if the backup failed
+    def backup_old_sources(source, target)
+      archive_name = "repos_#{Time.now.strftime(BACKUP_TIMESTAMP_FORMAT)}.tgz"
+      compress_cmd = format(TAR_CMD,
+        target: String.Quote(target),
+        archive: archive_name,
+        source: String.Quote(source))
+      cmd = SCR.Execute(path(".target.bash_output"), compress_cmd)
+      if !cmd["exit"].zero?
+        log.error("Unable to backup current repos; Command >#{compress_cmd}< 
returned: #{cmd}")
+        nil
+      else
+        archive_name
+      end
+    end
+
+    # Remove old sources
+    #
+    # @param [Array<String>] List of repositories to remove
+    def remove_old_sources(repos)
+      repos.each do |repo|
+        file = File.join(REPOS_DIR, repo)
+        log.info("Removing target repository #{file}")
+        if !SCR.Execute(path(".target.remove"), file)
+          log.error("Cannot remove #{repo} file")
+        end
+      end
+      log.info("All old repositories were removed from the target")
+    end
+
+    # Reload the target to sync the removed repositories with libzypp
+    # repomanager
+    def sync_target_sources
+      Pkg.TargetFinish
+      Pkg.TargetInitialize(Installation.destdir)
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-packager-3.1.97/src/lib/packager/product_patterns.rb 
new/yast2-packager-3.1.100/src/lib/packager/product_patterns.rb
--- old/yast2-packager-3.1.97/src/lib/packager/product_patterns.rb      
2016-04-25 11:47:26.000000000 +0200
+++ new/yast2-packager-3.1.100/src/lib/packager/product_patterns.rb     
2016-05-17 09:02:08.000000000 +0200
@@ -20,8 +20,14 @@
   class ProductPatterns
     include Yast::Logger
 
-    def initialize
+    attr_reader :src
+
+    # optionally evaluate only the products in the specified repository
+    # (by default use all repositories)
+    # @param [Integer,nil] src repository id
+    def initialize(src: nil)
       Yast.import "Pkg"
+      @src = src
     end
 
     # Find the default patterns for all selected products.
@@ -78,6 +84,7 @@
 
       resolvables = Yast::Pkg.ResolvableProperties(product, :product, "")
       remove_unselected(resolvables)
+      remove_other_repos(resolvables) if src
 
       resolvables.each do |resolvable|
         prod_pkg = resolvable["product_package"]
@@ -96,6 +103,7 @@
 
       product_dependencies
     end
+
     # Remove not selected resolvables from the list
     # @param [Array<Hash>] resolvables only the Hashes where the key "status"
     #   maps to :selected value are kept, the rest is removed
@@ -103,6 +111,13 @@
       resolvables.select! { |p| p["status"] == :selected }
     end
 
+    # Remove the resolvables from other repositories than in 'src'
+    # @param [Array<Hash>] resolvables only the Hashes where the key "status"
+    #   is equal to `src` are kept, the rest is removed
+    def remove_other_repos(resolvables)
+      resolvables.select! { |p| p["source"] == src }
+    end
+
     # Collect "provides" dependencies from the list.
     # @param [Array<Hash>] dependencies all dependencies
     # @return [Array<String>] only the "provides" dependencies
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.1.97/src/modules/AddOnProduct.rb 
new/yast2-packager-3.1.100/src/modules/AddOnProduct.rb
--- old/yast2-packager-3.1.97/src/modules/AddOnProduct.rb       2016-04-25 
11:47:26.000000000 +0200
+++ new/yast2-packager-3.1.100/src/modules/AddOnProduct.rb      2016-05-17 
09:02:08.000000000 +0200
@@ -14,6 +14,8 @@
 #      Lukas Ocilka <[email protected]>
 require "yast"
 
+require "packager/product_patterns"
+
 module Yast
   class AddOnProductClass < Module
     include Yast::Logger
@@ -990,49 +992,35 @@
     end
 
     def PackagesProposalAddonID(src_id)
-      Builtins.sformat("Add-On-Product-ID:%1", src_id)
+      "Add-On-Product-ID:#{src_id}"
     end
 
     # See also DeselectProductPatterns()
     def SelectProductPatterns(content_file, src_id)
-      if !FileUtils.Exists(content_file)
-        Builtins.y2error("No such file: %1", content_file)
-        return false
-      end
+      patterns_to_select = []
 
-      contentmap = Convert.to_map(SCR.Read(path(".content_file"), 
content_file))
+      if content_file && File.exist?(content_file)
+        contentmap = Convert.to_map(SCR.Read(path(".content_file"), 
content_file)) || {}
 
-      # no PATTERNS defined
-      if !Builtins.haskey(contentmap, "PATTERNS")
-        Builtins.y2milestone(
-          "Add-On doesn't have any required patterns (PATTERNS in content)"
-        )
-        return true
-      end
+        # no PATTERNS defined
+        if !contentmap.key?("PATTERNS")
+          log.info "Add-On doesn't have any required patterns (PATTERNS in 
content)"
+        end
 
-      # parsing PATTERNS
-      patterns_to_select = Builtins.splitstring(
-        Ops.get_string(contentmap, "PATTERNS", ""),
-        "\t "
-      )
-      patterns_to_select = Builtins.filter(patterns_to_select) do |one_pattern|
-        one_pattern != nil && one_pattern != ""
+        # parsing PATTERNS
+        patterns_to_select = contentmap.fetch("PATTERNS", "").split(/\t /)
+        patterns_to_select.reject! { |p| p.nil? || p.empty? }
       end
 
-      if Builtins.size(patterns_to_select) == 0
-        Builtins.y2error(
-          "Erroneous PATTERNS: %1",
-          Ops.get_string(contentmap, "PATTERNS", "")
-        )
-        return false
-      end
+      product_patterns = ProductPatterns.new(src: @src_id)
+      log.info "Found default product patterns: #{product_patterns.names}"
+      patterns_to_select.concat(product_patterns.names)
+      patterns_to_select.uniq!
+
+      log.info "Add-On requires these patterns: #{patterns_to_select.inspect}"
 
-      Builtins.y2milestone(
-        "Add-On requires these PATTERNS: %1",
-        patterns_to_select
-      )
       # clear/set
-      Ops.set(@patterns_preselected_by_addon, src_id, [])
+      @patterns_preselected_by_addon[src_id] = []
 
       # bnc #458297
       # Using PackagesProposal to select the patterns itself
@@ -1043,7 +1031,7 @@
       )
 
       if Stage.initial
-        Builtins.y2milestone("Using PackagesProposal to select Add-On 
patterns")
+        log.info "Using PackagesProposal to select Add-On patterns"
         return true
       end
 
@@ -1141,10 +1129,10 @@
 
       if content_file == nil
         Builtins.y2warning("Add-On %1 doesn't have a content file", srcid)
-      else
-        SelectProductPatterns(content_file, srcid)
       end
 
+      SelectProductPatterns(content_file, srcid)
+
       nil
     end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.1.97/src/modules/ProductLicense.rb 
new/yast2-packager-3.1.100/src/modules/ProductLicense.rb
--- old/yast2-packager-3.1.97/src/modules/ProductLicense.rb     2016-04-25 
11:47:26.000000000 +0200
+++ new/yast2-packager-3.1.100/src/modules/ProductLicense.rb    2016-05-17 
09:02:08.000000000 +0200
@@ -64,6 +64,8 @@
 
       # filename printed in the license dialog
       @license_file_print = nil
+      # license file is on installed system
+      @license_on_installed_system = false
 
       # BNC #448598
       # no-acceptance-needed file in license.tar.gz means the license
@@ -377,14 +379,15 @@
               ReplacePoint(
                 Id(:printing_hint),
                 Label(
-                  # TRANSLATORS: addition license information
-                  # %1 is replaced with the filename
-                  Builtins.sformat(
-                    _(
-                      "If you want to print this EULA, you can find it\non the 
first media in the file %1"
-                    ),
-                    @license_file_print
-                  )
+                  @license_on_installed_system ?
+                      # TRANSLATORS: addition license information
+                      # %s is replaced with the directory name
+                      _("This EULA can be found in the directory\n%s") % 
@license_file_print
+                    :
+                      # TRANSLATORS: addition license information
+                      # %s is replaced with the filename
+                      _("If you want to print this EULA, you can find it\non 
the first media in the file %s") %
+                        @license_file_print
                 )
               )
             ) :
@@ -638,6 +641,8 @@
 
       if FileUtils.Exists(fallback_dir)
         @license_dir = fallback_dir
+        @license_file_print = fallback_dir
+        @license_on_installed_system = true
       else
         Builtins.y2warning("Fallback dir doesn't exist %1", fallback_dir)
         @license_dir = nil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.1.97/test/Makefile.am 
new/yast2-packager-3.1.100/test/Makefile.am
--- old/yast2-packager-3.1.97/test/Makefile.am  2016-04-25 11:47:26.000000000 
+0200
+++ new/yast2-packager-3.1.100/test/Makefile.am 2016-05-17 09:02:08.000000000 
+0200
@@ -3,6 +3,7 @@
   product_patterns_test.rb \
   package_installation_test.rb \
   packages_test.rb \
+  pkg_finish_test.rb \
   source_dialogs_test.rb \
   space_calculation_test.rb
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.1.97/test/pkg_finish_test.rb 
new/yast2-packager-3.1.100/test/pkg_finish_test.rb
--- old/yast2-packager-3.1.97/test/pkg_finish_test.rb   1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-packager-3.1.100/test/pkg_finish_test.rb  2016-05-17 
09:02:08.000000000 +0200
@@ -0,0 +1,200 @@
+#!/usr/bin/env rspec
+
+require_relative "test_helper"
+require "packager/clients/pkg_finish"
+require "packages/repository"
+require "uri"
+require "tmpdir"
+require "fileutils"
+
+describe Yast::PkgFinishClient do
+  Yast.import "Pkg"
+  Yast.import "Installation"
+  Yast.import "WFM"
+
+  FAILED_PKGS_PATH = "/var/lib/YaST2/failed_packages"
+
+  subject(:client) { Yast::PkgFinishClient.new }
+  let(:repositories) { [] }
+
+  before do
+    allow(Yast::WFM).to receive(:Args).and_return(args)
+    allow(::Packages::Repository).to receive(:enabled).and_return(repositories)
+  end
+
+  describe "Info" do
+    let(:args) { ["Info"] }
+
+    it "returns a hash describing the client" do
+      allow(client).to receive(:_).and_return("title")
+      expect(client.run).to eq({
+          "steps" => 1,
+          "title" => "title",
+          "when" => [:installation, :update, :autoinst]})
+    end
+  end
+
+  describe "Write" do
+    let(:args) { ["Write"] }
+    let(:destdir) { "/mnt" }
+    let(:update) { false }
+
+    before do
+      allow(Yast::Installation).to receive(:destdir).and_return(destdir)
+      allow(Yast::Mode).to receive(:update).and_return(update)
+      allow(Yast::Stage).to receive(:initial).and_return(true)
+      allow(Yast::Pkg).to receive(:SourceLoad)
+    end
+
+    it "saves repository information" do
+      expect(Yast::Pkg).to receive(:SourceLoad)
+      expect(Yast::Pkg).to receive(:SourceSaveAll)
+      expect(Yast::Pkg).to receive(:TargetFinish)
+      expect(Yast::Pkg).to receive(:SourceCacheCopyTo).with(destdir)
+      allow(Yast::WFM).to receive(:Execute)
+      expect(client.run).to be_nil
+    end
+
+    it "copies failed_packages list under destination dir" do
+      stub_const("Yast::Pkg", double("pkg").as_null_object)
+      allow(File).to receive(:exist?).and_call_original
+      expect(File).to receive(:exist?).with(FAILED_PKGS_PATH)
+        .and_return(true)
+      expect(FileUtils).to receive(:cp)
+        .with(FAILED_PKGS_PATH, "#{destdir}#{FAILED_PKGS_PATH}", preserve: 
true)
+      client.run
+    end
+
+    context "given some local repository" do
+      let(:repositories) { [local_repo, remote_repo] }
+
+      let(:local_repo) do
+        Packages::Repository.new(repo_id: 1, name: "SLE-12-SP2-0", enabled: 
true,
+          url: URI("cd://dev/sr0"), autorefresh: false)
+      end
+
+      let(:remote_repo) do
+        Packages::Repository.new(repo_id: 2, name: "SLE-12-SP2-Pool", enabled: 
true,
+          url: URI("http://download.suse.com/sle-12-sp2";), autorefresh: true)
+      end
+
+      let(:sles_product) do
+        Packages::Product.new(name: "SLES", version: "12.2",
+          arch: "x86_64", category: "base", status: :available, vendor: "SUSE")
+      end
+
+      let(:sles_ha_product) do
+        Packages::Product.new(name: "SLESHA", version: "12.2",
+          arch: "x86_64", category: "base", status: :available, vendor: "SUSE")
+      end
+
+      before do
+        allow(local_repo).to 
receive(:products).and_return([sles_product.clone])
+      end
+
+      context "if their products are available through other repos" do
+        before do
+          allow(remote_repo).to 
receive(:products).and_return([sles_product.clone])
+        end
+
+        it "disables the local repository" do
+          expect(local_repo).to receive(:disable!)
+          client.run
+        end
+      end
+
+      context "if their products are not available through other repos" do
+        before do
+          allow(remote_repo).to 
receive(:products).and_return([sles_ha_product])
+        end
+
+        it "does not disable the local repository" do
+          expect(local_repo).to_not receive(:disable!)
+          client.run
+        end
+      end
+
+      context "if does not contain any product" do
+        before do
+          allow(local_repo).to receive(:products).and_return([])
+        end
+
+        it "does not disable the local repository" do
+          allow(client.log).to receive(:info).and_call_original
+          expect(local_repo).to_not receive(:disable!)
+          expect(client.log).to receive(:info).with(/ignored/)
+          client.run
+        end
+      end
+    end
+
+    context "during update" do
+      let(:update) { true }
+      let(:tmpdir) do
+        dir = Dir.mktmpdir
+        FileUtils.remove_entry(dir)
+        Pathname(dir)
+      end
+      let(:repos_dir) { tmpdir.join("repos.d") }
+      let(:vardir) { tmpdir.join("var") }
+
+      before do
+        allow(Yast::Directory).to receive(:vardir).and_return(vardir.to_s)
+        allow(Yast::WFM).to receive(:call)
+        stub_const("Yast::PkgFinishClient::REPOS_DIR", repos_dir.to_s)
+        stub_const("Yast::Pkg", double("pkg").as_null_object)
+      end
+
+      context "when repos.d exists and contains files" do
+        before do
+          FileUtils.mkdir_p(repos_dir)                 # Create repos.d
+          FileUtils.touch(repos_dir.join("yast.repo")) # Add a 'repo'
+        end
+
+        it "saves the repositories at /etc/repos.d" do
+          client.run
+
+          # The backup exists
+          file = Pathname.glob(vardir.join("*")).first
+          expect(file.exist?).to eq(true)
+
+          # The old repos are gone
+          expect(Pathname.glob(repos_dir.join("*"))).to be_empty
+        end
+
+        it "logs an error if compression fails" do
+          allow(Yast::SCR).to receive(:Execute).and_call_original
+          expect(Yast::SCR).to receive(:Execute).
+            with(Yast::Path.new(".target.bash_output"), /tar/).
+            and_return("exit" => -1)
+          expect(client.log).to receive(:error)
+            .with(/Unable to backup/)
+          client.run
+        end
+      end
+
+      context "when repos.d does not exist" do
+        it "logs an error" do
+          expect(client.log).to receive(:error).with(/#{repos_dir} doesn't 
exist/)
+          client.run
+        end
+      end
+
+      context "when repos.d is empty" do
+        before do
+          FileUtils.mkdir_p(repos_dir) # Create repos.d
+        end
+
+        it "logs a warning" do
+          expect(client.log).to receive(:warn).with(/no repos in #{repos_dir}/)
+          client.run
+        end
+      end
+
+      it "calls inst_extrasources client" do
+        expect(Yast::WFM).to receive(:call).with("inst_extrasources")
+        client.run
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.1.97/test/product_factory.rb 
new/yast2-packager-3.1.100/test/product_factory.rb
--- old/yast2-packager-3.1.97/test/product_factory.rb   2016-04-25 
11:47:26.000000000 +0200
+++ new/yast2-packager-3.1.100/test/product_factory.rb  2016-05-17 
09:02:08.000000000 +0200
@@ -36,6 +36,7 @@
     product["description"] = attrs["description"] || "SUSE Linux Enterprise 
#{product_name}."
     product["display_name"] = attrs["display_name"] || "SUSE Linux Enterprise 
#{product_name}"
     product["download_size"] = attrs["download_size"] || 0
+    # default: 2024-10-31
     product["eol"] = attrs["eol"] || 1730332800
     product["flags"] = attrs["flags"] || []
     product["flavor"] = attrs["flavor"] || "POOL"
@@ -70,4 +71,22 @@
 
     product
   end
+
+  # create product packages for testing
+  # @param [String] product_name name of the product_line
+  # @param [Fixnum,nil] src repository ID providing the product
+  # @return [Array] created product data: the default pattern name,
+  #   the release package name, the release package status,
+  #   the product status
+  def self.create_product_packages(product_name: "product", src: nil)
+    pattern_name = "#{product_name}_pattern"
+    package_name = "#{product_name}-release"
+    package = { "name" => package_name, "status" => :selected,
+       "deps" => [{ "requires" => "foo" }, { "provides" => "bar" },
+                  { "provides" => "defaultpattern(#{pattern_name})" }] }
+    product = ProductFactory.create_product("status" => :selected,
+      "source" => src, "product_package" => package_name)
+
+    [ pattern_name, package_name,  package, product ]
+  end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.1.97/test/product_patterns_test.rb 
new/yast2-packager-3.1.100/test/product_patterns_test.rb
--- old/yast2-packager-3.1.97/test/product_patterns_test.rb     2016-04-25 
11:47:26.000000000 +0200
+++ new/yast2-packager-3.1.100/test/product_patterns_test.rb    2016-05-17 
09:02:08.000000000 +0200
@@ -36,40 +36,25 @@
     end
 
     it "returns the default pattern name from the release package" do
-      default_pattern = "def_pattern"
-      product_package_name = "product-release"
-      product_package = { "name" => product_package_name, "status" => 
:selected,
-         "deps" => [{ "requires" => "foo" }, { "provides" => "bar" },
-                    { "provides" => "defaultpattern(#{default_pattern})" }] }
-      product = ProductFactory.create_product("status"          => :selected,
-                                              "product_package" => 
product_package_name)
+      pattern_name, package_name, package, product =
+        ProductFactory.create_product_packages(product_name: "product1")
 
       expect(Yast::Pkg).to receive(:ResolvableProperties).with("", :product, 
"")
         .and_return([product])
       expect(Yast::Pkg).to 
receive(:ResolvableProperties).with(product["name"], :product, "")
         .and_return([product])
-      expect(Yast::Pkg).to 
receive(:ResolvableDependencies).with(product_package_name, :package, "")
-        .and_return([product_package])
+      expect(Yast::Pkg).to receive(:ResolvableDependencies).with(package_name, 
:package, "")
+        .and_return([package])
 
-      expect(subject.names).to eq([default_pattern])
+      expect(subject.names).to eq([pattern_name])
     end
 
     it "returns the default patterns from all products" do
-      default_pattern1 = "def_pattern1"
-      product_package_name1 = "product-release1"
-      product_package1 = { "name" => product_package_name1, "status" => 
:selected,
-         "deps" => [{ "requires" => "foo" }, { "provides" => "bar" },
-                    { "provides" => "defaultpattern(#{default_pattern1})" }] }
-      product1 = ProductFactory.create_product("status"          => :selected,
-                                               "product_package" => 
product_package_name1)
-
-      default_pattern2 = "def_pattern2"
-      product_package_name2 = "product-release2"
-      product_package2 = { "name" => product_package_name2, "status" => 
:selected,
-         "deps" => [{ "requires" => "foo" }, { "provides" => "bar" },
-                    { "provides" => "defaultpattern(#{default_pattern2})" }] }
-      product2 = ProductFactory.create_product("status"          => :selected,
-                                               "product_package" => 
product_package_name2)
+      pattern_name1, package_name1, package1, product1 =
+        ProductFactory.create_product_packages(product_name: "product1")
+
+      pattern_name2, package_name2, package2, product2 =
+        ProductFactory.create_product_packages(product_name: "product2")
 
       expect(Yast::Pkg).to receive(:ResolvableProperties).with("", :product, 
"")
         .and_return([product1, product2])
@@ -77,12 +62,38 @@
         .and_return([product1])
       expect(Yast::Pkg).to 
receive(:ResolvableProperties).with(product2["name"], :product, "")
         .and_return([product2])
-      expect(Yast::Pkg).to 
receive(:ResolvableDependencies).with(product_package_name1, :package, "")
-        .and_return([product_package1])
-      expect(Yast::Pkg).to 
receive(:ResolvableDependencies).with(product_package_name2, :package, "")
-        .and_return([product_package2])
+      expect(Yast::Pkg).to 
receive(:ResolvableDependencies).with(package_name1, :package, "")
+        .and_return([package1])
+      expect(Yast::Pkg).to 
receive(:ResolvableDependencies).with(package_name2, :package, "")
+        .and_return([package2])
+
+      expect(subject.names.sort).to eq([pattern_name1, pattern_name2].sort)
+    end
+
+    context "repository parameter has been set" do
+      # get the default patterns only from the repository with id 2
+      subject { Yast::ProductPatterns.new(src: 2) }
+
+      it "returns the default patterns only from the selected repository" do
+        pattern_name1, package_name1, package1, product1 =
+          ProductFactory.create_product_packages(product_name: "product1", 
src: 1)
+
+        pattern_name2, package_name2, package2, product2 =
+          ProductFactory.create_product_packages(product_name: "product2", 
src: 2)
+
+        expect(Yast::Pkg).to receive(:ResolvableProperties).with("", :product, 
"")
+          .and_return([product1, product2])
+        expect(Yast::Pkg).to 
receive(:ResolvableProperties).with(product1["name"], :product, "")
+          .and_return([product1])
+        expect(Yast::Pkg).to 
receive(:ResolvableProperties).with(product2["name"], :product, "")
+          .and_return([product2])
+        # the product1 package should not be checked, it's in different repo
+        expect(Yast::Pkg).to_not 
receive(:ResolvableDependencies).with(package_name1, :package, "")
+        expect(Yast::Pkg).to 
receive(:ResolvableDependencies).with(package_name2, :package, "")
+          .and_return([package2])
 
-      expect(subject.names.sort).to eq([default_pattern1, 
default_pattern2].sort)
+        expect(subject.names).to eq([pattern_name2])
+      end
     end
   end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.1.97/test/test_helper.rb 
new/yast2-packager-3.1.100/test/test_helper.rb
--- old/yast2-packager-3.1.97/test/test_helper.rb       2016-04-25 
11:47:26.000000000 +0200
+++ new/yast2-packager-3.1.100/test/test_helper.rb      2016-05-17 
09:02:08.000000000 +0200
@@ -9,3 +9,7 @@
 
 require "yast"
 require "yast/rspec"
+require "pathname"
+
+TESTS_PATH = Pathname.new(File.dirname(__FILE__))
+FIXTURES_PATH = TESTS_PATH.join("data")


Reply via email to