Hello community,

here is the log from the commit of package yast2-packager for openSUSE:Factory 
checked in at 2017-01-27 10:39:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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    
2017-01-23 11:26:27.398891076 +0100
+++ /work/SRC/openSUSE:Factory/.yast2-packager.new/yast2-packager.changes       
2017-02-03 20:07:50.943207726 +0100
@@ -1,0 +2,7 @@
+Thu Jan 19 15:11:48 UTC 2017 - [email protected]
+
+- Use information provided by libzypp to evaluate product
+  renames (FATE#321751)
+- 3.2.12
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ yast2-packager.spec ++++++
--- /var/tmp/diff_new_pack.Zb5RHj/_old  2017-02-03 20:07:51.603114839 +0100
+++ /var/tmp/diff_new_pack.Zb5RHj/_new  2017-02-03 20:07:51.607114276 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-packager
-Version:        3.2.11
+Version:        3.2.12
 Release:        0
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build

++++++ yast2-packager-3.2.11.tar.bz2 -> yast2-packager-3.2.12.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.2.11/package/yast2-packager.changes 
new/yast2-packager-3.2.12/package/yast2-packager.changes
--- old/yast2-packager-3.2.11/package/yast2-packager.changes    2017-01-17 
12:06:11.423301000 +0100
+++ new/yast2-packager-3.2.12/package/yast2-packager.changes    2017-01-24 
13:27:16.628000000 +0100
@@ -1,4 +1,11 @@
 -------------------------------------------------------------------
+Thu Jan 19 15:11:48 UTC 2017 - [email protected]
+
+- Use information provided by libzypp to evaluate product
+  renames (FATE#321751)
+- 3.2.12
+
+-------------------------------------------------------------------
 Wed Dec 21 15:06:31 CET 2016 - [email protected]
 
 - Adjust /etc/zypp/zypp.conf in the installed system when
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.2.11/package/yast2-packager.spec 
new/yast2-packager-3.2.12/package/yast2-packager.spec
--- old/yast2-packager-3.2.11/package/yast2-packager.spec       2017-01-17 
12:06:11.423301000 +0100
+++ new/yast2-packager-3.2.12/package/yast2-packager.spec       2017-01-24 
13:27:16.628000000 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-packager
-Version:        3.2.11
+Version:        3.2.12
 Release:        0
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.2.11/src/modules/AddOnProduct.rb 
new/yast2-packager-3.2.12/src/modules/AddOnProduct.rb
--- old/yast2-packager-3.2.11/src/modules/AddOnProduct.rb       2017-01-17 
12:06:11.443301000 +0100
+++ new/yast2-packager-3.2.12/src/modules/AddOnProduct.rb       2017-01-24 
13:27:17.192000000 +0100
@@ -20,6 +20,23 @@
   class AddOnProductClass < Module
     include Yast::Logger
 
+    # @return [Hash] Product renames default map. Used when information is not
+    #                found elsewhere.
+    DEFAULT_PRODUCT_RENAMES = {
+      "SUSE_SLES"     => [ "SLES" ],
+      # SLED or Workstation extension
+      "SUSE_SLED"     => [ "SLED", "sle-we" ],
+      "sle-haegeo"    => [ "sle-ha-geo" ],
+      "sle-hae"       => [ "sle-ha" ],
+      "SUSE_SLES_SAP" => [ "SLES_SAP" ],
+      # SMT is now integrated into the base SLES
+      "sle-smt"       => [ "SLES" ]
+    }
+
+    # @return [Hash] Product renames added externally through the #add_rename 
method
+    attr_accessor :external_product_renames
+    private :external_product_renames, :external_product_renames=
+
     def main
       Yast.import "UI"
       Yast.import "Pkg"
@@ -132,21 +149,9 @@
       #      ]
       @patterns_preselected_by_addon = {}
 
-      # product renames needed for detecting the product update
-      # this mapping can be updated by SCC registration server,
-      # this is the static default for offline updates
-      # mapping: <old_name> => [ <new_name> ]
-      @product_renames = {
-        "SUSE_SLES"     => [ "SLES" ],
-        # SLED or Workstation extension
-        "SUSE_SLED"     => [ "SLED", "sle-we" ],
-        "sle-haegeo"    => [ "sle-ha-geo" ],
-        "sle-hae"       => [ "sle-ha" ],
-        "SUSE_SLES_SAP" => [ "SLES_SAP" ],
-        # SMT is now integrated into the base SLES
-        "sle-smt"       => [ "SLES" ]
-      }
-
+      # additional product renames needed for detecting the product update
+      # @see #add_rename
+      @external_product_renames = {}
     end
 
     # Downloads a requested file, caches it and returns path to that cached 
file.
@@ -2155,18 +2160,29 @@
       nil
     end
 
+    # Determine whether a product has been renamed
+    #
+    # @param old_name [String] Old product's name
+    # @param new_name [String] New product's name
+    # @return [Boolean] +true+ if the product was renamed; otherwise, +false+.
     def renamed?(old_name, new_name)
-      return false unless @product_renames[old_name]
-      @product_renames[old_name].include?(new_name)
+      renamed_externally?(old_name, new_name) ||
+        renamed_by_libzypp?(old_name, new_name) ||
+        renamed_by_default?(old_name, new_name)
     end
 
+    # Add a product's rename
+    #
+    # This method won't try to update the rename if it already exists.
+    # Renames added will be tracked in order to not loose information.
+    #
+    # @param old_name [String] Old product's name
+    # @param old_name [String] New product's name
     def add_rename(old_name, new_name)
       # already known
-      return if renamed?(old_name, new_name)
-
+      return if renamed_externally?(old_name, new_name)
       log.info "Adding product rename: '#{old_name}' => '#{new_name}'"
-      @product_renames[old_name] = [] unless @product_renames[old_name]
-      @product_renames[old_name] << new_name
+      self.external_product_renames = 
add_rename_to_hash(external_product_renames, old_name, new_name)
     end
 
     publish :variable => :add_on_products, :type => "list <map <string, any>>"
@@ -2209,6 +2225,131 @@
 
   private
 
+    # Determine whether a rename for a product was added
+    #
+    # This method will return true if a rename was added through
+    # the #add_rename method (for example, a rename taken from
+    # SCC).
+    #
+    # @param old_name [String] Old product's name
+    # @param new_name [String] New product's name
+    # @return [Boolean] +true+ if the product was renamed; otherwise, +false+.
+    #
+    # @see #renamed_at?
+    def renamed_externally?(old_name, new_name)
+      log.info "Search #{old_name} -> #{new_name} rename in added renames map: 
" \
+        "#{external_product_renames.inspect}"
+      renamed_at?(external_product_renames, old_name, new_name)
+    end
+
+    # Determine whether a product was renamed using libzypp
+    #
+    # libzypp (through #ResolvableProperties and #ResolvableDependencies 
method) is used
+    # to determine whether the product was renamed or not.
+    #
+    # @param old_name [String] Old product's name
+    # @param new_name [String] New product's name
+    # @return [Boolean] +true+ if the product was renamed; otherwise, +false+.
+    #
+    # @see #renamed_at?
+    def renamed_by_libzypp?(old_name, new_name)
+      renames = product_renames_from_libzypp
+      log.info "Search #{old_name} -> #{new_name} rename in libzypp: " \
+        "#{renames.inspect}"
+      renamed_at?(renames, old_name, new_name)
+    end
+
+    # Determine whether a product rename is included in the fallback map
+    #
+    # @see DEFAULT_PRODUCT_RENAMES
+    # @see #renamed_at?
+    def renamed_by_default?(old_name, new_name)
+      log.info "Search #{old_name} -> #{new_name} rename in default map: " \
+        "#{DEFAULT_PRODUCT_RENAMES.inspect}"
+      renamed_at?(DEFAULT_PRODUCT_RENAMES, old_name, new_name)
+    end
+
+    # Determine whether a product rename is present on a given hash
+    #
+    # @param renames  [Hash] Product renames in form old_name => [new_name1, 
new_name2, ...]
+    # @param old_name [String] Old product's name
+    # @param new_name [String] New product's name
+    # @return [Boolean] +true+ if the product was renamed; otherwise, +false+.
+    def renamed_at?(renames, old_name, new_name)
+      return false unless renames[old_name]
+      renames[old_name].include?(new_name)
+    end
+
+    # Get product renames from libzypp
+    #
+    # @see names_from_product_package
+    # @see add_rename_to_hash
+    def product_renames_from_libzypp
+      renames = {}
+      products = Pkg.ResolvableProperties("", :product, "") # Dependencies are 
not included in this call
+      products.each do |product|
+        renames = 
names_from_product_packages(product["product_package"]).reduce(renames) do 
|hash, rename|
+          add_rename_to_hash(hash, rename, product["name"])
+        end
+      end
+      renames
+    end
+
+    # Regular expresion to extract the product name. It supports two different
+    # formats: "product:NAME" and "product(NAME)"
+    # @see product_name_from_dep
+    PRODUCTS_REGEXP = /\Aproduct(?::|\()([^\)\b]+)/
+
+    # Extracts product's name from dependency
+    #
+    #
+    # @see renamed_by_libzypp?
+    def product_name_from_dep(dependency)
+      matches = PRODUCTS_REGEXP.match(dependency)
+      matches.nil? ? nil : matches[1]
+    end
+
+    # Add a product's rename to a given hash
+    #
+    # It will be ignored if:
+    #
+    # * old and new names are the same or
+    # * the rename it's already included
+    #
+    # @param renames  [Hash]   Renames following the format <old_name> => [ 
<new_name> ]
+    # @param old_name [String] Old product's name
+    # @param new_name [String] New product's name
+    # @return [Hash] Product renames hash adding the new rename if needed
+    #
+    # @see #add_rename
+    def add_rename_to_hash(renames, old_name, new_name)
+      return renames if old_name == new_name || renamed_at?(renames, old_name, 
new_name)
+      log.info "Adding product rename: '#{old_name}' => '#{new_name}'"
+      renames.merge(old_name => new_name) do |key, old_val, new_val|
+        old_val.nil? ? [new_val] : old_val + [new_val]
+      end
+    end
+
+    # Determines the products for a product package
+    #
+    # The renames are extracted from the "obsoletes" and "provides" 
dependencies
+    # (renames like 'SUSE_SLES' to 'SLES' are defined in the "provides"
+    # dependencies only).
+    #
+    # @return [Array<String>] Old names
+    def names_from_product_packages(package_name)
+      # Get package dependencies (not retrieved when using 
Pkg.ResolvableProperties)
+      packages = Pkg.ResolvableDependencies(package_name, :package, "")
+      return [] if packages.nil? || packages.empty?
+      names = packages.each_with_object([]) do |package, names|
+        next names unless package.key?("deps")
+        # Get information from 'obsoletes' and 'provides' keys
+        relevant_deps = package["deps"].map { |d| d["obsoletes"] || 
d["provides"] }.compact
+        names.concat(relevant_deps.map { |d| product_name_from_dep(d) })
+      end
+      names.compact.uniq
+    end
+
     # Adds a product from a CD/DVD
     #
     # To add the product, the name should match +prodname+ argument.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-packager-3.2.11/test/addon_product_test.rb 
new/yast2-packager-3.2.12/test/addon_product_test.rb
--- old/yast2-packager-3.2.11/test/addon_product_test.rb        2017-01-17 
12:06:11.459301000 +0100
+++ new/yast2-packager-3.2.12/test/addon_product_test.rb        2017-01-24 
13:27:17.824000000 +0100
@@ -1,6 +1,7 @@
 #! /usr/bin/env rspec
 
 require_relative "./test_helper"
+require_relative "product_factory"
 
 Yast.import "AddOnProduct"
 
@@ -8,12 +9,58 @@
   subject { Yast::AddOnProduct }
 
   describe "#renamed?" do
-    it "returns true if product has been renamed" do
-      expect(Yast::AddOnProduct.renamed?("SUSE_SLES", "SLES")).to eq(true)
+    let(:other_product) { ProductFactory.create_product }
+    let(:products) { [other_product] }
+
+    before do
+      subject.main
+      allow(Yast::Pkg).to receive(:ResolvableProperties).with("", :product, "")
+        .and_return(products)
+    end
+
+    context "when rename is included in the fallback list" do
+      it "returns true" do
+        expect(Yast::AddOnProduct.renamed?("SUSE_SLES", "SLES")).to eq(true)
+      end
+    end
+
+    context "when product rename is not known" do
+      it "returns false" do
+        expect(Yast::AddOnProduct.renamed?("foo", "bar")).to eq(false)
+      end
     end
 
-    it "returns false if the product rename is not known" do
-      expect(Yast::AddOnProduct.renamed?("foo", "bar")).to eq(false)
+    context "when according to libzypp a product is renamed" do
+      let(:deps) do
+        [
+          {"obsoletes" => "product:old_product1"},
+          {"obsoletes" => "product(old_product2)"},
+          {"provides" => "product:new_product"},
+          {"provides" => "product(old_name)"}
+        ]
+      end
+
+      let(:new_product) do
+        ProductFactory.create_product("name" => "new_product", 
"product_package" => "new_product-release")
+      end
+
+      let(:new_product_package) do
+        { "name" => "new_product-release", "deps" => deps }
+      end
+
+      let(:installed_product_package) do
+        { "name" => "installed_product-release" }
+      end
+
+      let(:products) { [new_product] }
+
+      it "returns true" do
+        allow(Yast::Pkg).to 
receive(:ResolvableDependencies).with(new_product["product_package"], :package, 
"")
+          .and_return([installed_product_package, new_product_package])
+        expect(subject.renamed?("old_product1", new_product["name"])).to 
eq(true)
+        expect(subject.renamed?("old_product2", new_product["name"])).to 
eq(true)
+        expect(subject.renamed?("old_name", new_product["name"])).to eq(true)
+      end
     end
   end
 


Reply via email to