diff --git a/library/packages/src/lib/y2packager/license.rb b/library/packages/src/lib/y2packager/license.rb index 9bb6c3949..74c3b1cce 100644 --- a/library/packages/src/lib/y2packager/license.rb +++ b/library/packages/src/lib/y2packager/license.rb @@ -13,6 +13,7 @@ require "yast" require "digest" require "y2packager/licenses_fetchers" +require "y2packager/licenses_handlers" module Y2Packager # Represent a License which could be the same for multiple products. @@ -30,6 +31,12 @@ class License # @return [Hash] language -> content attr_reader :translations + # @return [Yast::LicenseHandler] + attr_reader :handler + + # @return [Yast::LicenseFetcher] + attr_reader :fetcher + alias_method :accepted?, :accepted class << self @@ -47,17 +54,22 @@ def find(product_name, content: nil) log.info "Searching for a license for product #{product_name}" return cache[product_name] if cache[product_name] - new_license = License.new(product_name: product_name, content: content) - return unless new_license.id + fetcher = LicensesFetchers.for(product_name) + handler = LicensesHandlers.for(fetcher, product_name) - eq_license = cache.values.find { |l| l.id == new_license.id } - if eq_license - log.info "Found cached license: #{eq_license.id}" + license = License.new(product_name: product_name, fetcher: fetcher, + handler: handler, content: content) + return unless license.id + + cached_license = cache.values.find { |l| l.id == license.id } + if cached_license + log.info "Found cached license: #{cached_license.id}" else - log.info "Caching license: #{new_license.id}" + log.info "Caching license: #{license.id}" + cache[product_name] = license end - cache[product_name] = eq_license || new_license + cache[product_name] end # Clean licenses cache @@ -88,10 +100,12 @@ def cache # @param product_name [String] Product name to retrieve license information # @param content [String] License content. If this argument is given, this # string is used as the license's content (and `product_name` is ignored). - def initialize(product_name: nil, content: nil) + def initialize(product_name: nil, fetcher: nil, handler: nil, content: nil) @accepted = false @translations = {} @product_name = product_name + @fetcher = fetcher + @handler = handler add_content_for(DEFAULT_LANG, content) if content end @@ -115,15 +129,10 @@ def id # @return [String, nil] the license translated content or nil if not found def content_for(lang = DEFAULT_LANG) return @translations[lang] if @translations[lang] + return unless @fetcher - [:libzypp, :rpm].each do |source| - log.info "Trying to get the license for #{product_name} from #{source}" - content = LicensesFetchers.for(source, product_name).content(lang) - - return add_content_for(lang, content) unless content.to_s.empty? - end - - nil + content = @fetcher.content(lang) + add_content_for(lang, content) end # Add the license translated content for the given language @@ -169,9 +178,11 @@ def reject! @accepted = false end + attr_accessor :source, :handler, :fetcher private # @return [String] Product name attr_reader :product_name + end end diff --git a/library/packages/src/lib/y2packager/licenses_fetchers.rb b/library/packages/src/lib/y2packager/licenses_fetchers.rb index e7c2780bf..591a7ae6d 100644 --- a/library/packages/src/lib/y2packager/licenses_fetchers.rb +++ b/library/packages/src/lib/y2packager/licenses_fetchers.rb @@ -20,13 +20,24 @@ module Y2Packager # Licenses can be retrieved from different places (libzypp, URLs, etc.). The classes # defined in this module are able to retrieve licenses contents. module LicensesFetchers + include Yast::Logger + + DEFAULT_LANGUAGE = "en_US".freeze + KNOWN_SOURCES = [:libzypp, :rpm].freeze + # Return the licenses proper fetcher for a given source # # @param source [:libzypp,nil] Source to fetch license from (only :rpm is supported) # @param product_name [String] Product's name - def self.for(source, product_name) - klass = const_get(source.to_s.capitalize) - klass.new(product_name) + def self.for(product_name) + log.info "Finding a license source for #{product_name}" + + KNOWN_SOURCES.each do |source| + klass = const_get(source.to_s.capitalize) + fetcher = klass.new(product_name) + + return fetcher if fetcher.valid? + end end end end diff --git a/library/packages/src/lib/y2packager/licenses_fetchers/libzypp.rb b/library/packages/src/lib/y2packager/licenses_fetchers/libzypp.rb index 0f446936c..f89e12678 100644 --- a/library/packages/src/lib/y2packager/licenses_fetchers/libzypp.rb +++ b/library/packages/src/lib/y2packager/licenses_fetchers/libzypp.rb @@ -20,10 +20,30 @@ class Libzypp < Base # Return the license text to be confirmed # # @param lang [String] Language - # @return [String,nil] Product's license; nil if the product or the license were not found. + # + # @return [String, nil] Product's license; nil if the product or the license were not found. def content(lang) + return @default_content if lang == DEFAULT_LANG && @default_content + Yast::Pkg.PrdGetLicenseToConfirm(product_name, lang) end + + # Check if is a valid fecher based on content for default language + # + # @return [Booelan] true if there is content for the default language; false otherwise. + # TODO: found? + def valid? + default_content.empty? + end + + private + + # Return the content found for the default language + # + # @return [String] the license content for the default language; empty if nothing was found. + def default_content + @default_content = content(DEFAULT_LANGUAGE).to_s + end end end end diff --git a/library/packages/src/lib/y2packager/licenses_fetchers/rpm.rb b/library/packages/src/lib/y2packager/licenses_fetchers/rpm.rb index 62d3d774a..1f57f66a3 100644 --- a/library/packages/src/lib/y2packager/licenses_fetchers/rpm.rb +++ b/library/packages/src/lib/y2packager/licenses_fetchers/rpm.rb @@ -23,6 +23,8 @@ class Rpm < Base # # @return [String, nil] Product's license; nil if the product or the license were not found def content(lang) + return @default_content if @default_content + package = find_package if package.nil? @@ -34,8 +36,23 @@ def content(lang) license_content(package, lang) end + + # Check if is a valid fecher based on content for default language + # + # @return [Booelan] true if there is content for the default language; false otherwise. + def valid? + default_content.empty? + end + private + # Return the content found for the default language + # + # @return [String] the license content for the default language; empty if nothing was found. + def default_content + @default_content = content(DEFAULT_LANGUAGE).to_s + end + # Return the license content for a package and language # # Package is extracted to a work directory. When a license for a language "xx_XX" is not diff --git a/library/packages/src/lib/y2packager/licenses_handlers.rb b/library/packages/src/lib/y2packager/licenses_handlers.rb index afa762ed1..25cbe125c 100644 --- a/library/packages/src/lib/y2packager/licenses_handlers.rb +++ b/library/packages/src/lib/y2packager/licenses_handlers.rb @@ -24,8 +24,10 @@ module LicensesHandlers # @param source [:libzypp,nil] Source to fetch license from (only :libzypp is supported) # @param product_name [String] Product's name # @return [Object] - def self.for(source, product_name) - klass = const_get(source.to_s.capitalize) + def self.for(fetcher, product_name) + type = fetcher.class.name.split("::").last + klass = const_get(type.to_s.capitalize) + klass.new(product_name) end end diff --git a/library/packages/src/lib/y2packager/product_license.rb b/library/packages/src/lib/y2packager/product_license.rb index 468f712b8..49c27a954 100644 --- a/library/packages/src/lib/y2packager/product_license.rb +++ b/library/packages/src/lib/y2packager/product_license.rb @@ -13,7 +13,6 @@ require "yast" require "forwardable" require "y2packager/license" -require "y2packager/licenses_handlers" module Y2Packager # This class holds the license stuff for a given product @@ -58,7 +57,7 @@ def find(product_name, handler: nil, content: nil) return cache[product_name] if cache[product_name] license = License.find(product_name, content: content) return nil unless license - cache[product_name] = ProductLicense.new(product_name, license, handler: handler) + cache[product_name] = ProductLicense.new(product_name, license) end # Clear product licenses cache @@ -73,13 +72,12 @@ def clear_cache # Constructor # - # @param product_name [String] Product name to get licenses for - # @param handler [Symbol] Backend to use when syncing the licenses acceptance status - # (only :libzypp is supported) - def initialize(product_name, license, handler: nil) + # @param product_name [String] + # @param license [Yast::License] + def initialize(product_name, license) @product_name = product_name @license = license - @handler = Y2Packager::LicensesHandlers.for(handler, product_name) if handler + @handler = license.handler end # Determine whether the license have been accepted or not diff --git a/library/packages/test/y2packager/license_test.rb b/library/packages/test/y2packager/license_test.rb index c9bc956d0..cb04df388 100755 --- a/library/packages/test/y2packager/license_test.rb +++ b/library/packages/test/y2packager/license_test.rb @@ -16,15 +16,19 @@ require "y2packager/license" describe Y2Packager::License do - subject(:license) { Y2Packager::License.new(product_name: "SLES") } + subject(:license) { Y2Packager::License.new(product_name: "SLES", fetcher: fetcher) } let(:content) { "Some license content" } let(:fetcher) do - instance_double(Y2Packager::LicensesFetchers::Libzypp, content: "license") + instance_double(Y2Packager::LicensesFetchers::Libzypp, content: "license", valid?: true) + end + let(:handler) do + instance_double(Y2Packager::LicensesHandlers::Libzypp) end before do described_class.clear_cache + allow(Y2Packager::LicensesHandlers).to receive(:for).and_return(handler) allow(Y2Packager::LicensesFetchers::Libzypp).to receive(:new).and_return(fetcher) end @@ -32,7 +36,7 @@ context "when some content is given" do before do allow(Y2Packager::License).to receive(:new) - .with(product_name: "SLES", content: content) + .with(product_name: "SLES", fetcher: fetcher, content: content) .and_return(license) end @@ -92,7 +96,7 @@ let(:fetcher) { instance_double(Y2Packager::LicensesFetchers::Libzypp) } - subject(:license) { Y2Packager::License.new(product_name: "SLES") } + subject(:license) { Y2Packager::License.new(product_name: "SLES", fetcher: fetcher) } before do allow(fetcher).to receive(:content)