From 01c56c61e7f377ae3bfabdd8298039efed35b5a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20D=C3=ADaz=20Gonz=C3=A1lez?= Date: Wed, 22 May 2019 15:25:58 +0100 Subject: [PATCH 01/18] Do not allow to select a different language when not running on fbiterm --- .../widgets/product_license_translations.rb | 14 ++++++++++++-- .../widgets/product_license_translations_test.rb | 9 ++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/lib/y2packager/widgets/product_license_translations.rb b/src/lib/y2packager/widgets/product_license_translations.rb index 915fb004f..f2a4f1614 100644 --- a/src/lib/y2packager/widgets/product_license_translations.rb +++ b/src/lib/y2packager/widgets/product_license_translations.rb @@ -90,7 +90,7 @@ def product_license # @return [Array] Locale codes of the available translations # @see #default_language def available_locales - Yast::UI.TextMode ? [default_language] : product.license_locales + supported_language? ? product.license_locales : [default_language] end # License translation language @@ -101,7 +101,7 @@ def available_locales # @return [String] License content language # @see #default_language def content_language - Yast::UI.TextMode ? default_language : language + supported_language? ? language : default_language end # @return [String] Fallback language @@ -126,6 +126,16 @@ def default_language return candidate_lang if translated DEFAULT_FALLBACK_LANGUAGE end + + # Whether the preselected language is supported + # + # It should not allow to change the language if it is a not fbiterm supported language. + # + # @return [Boolean] + # @see Yast::Language.supported_language? + def supported_language? + Yast::Language.supported_language?(Yast::Language.preselected) + end end end end diff --git a/test/lib/widgets/product_license_translations_test.rb b/test/lib/widgets/product_license_translations_test.rb index 149856c96..181e4d64f 100644 --- a/test/lib/widgets/product_license_translations_test.rb +++ b/test/lib/widgets/product_license_translations_test.rb @@ -23,10 +23,17 @@ subject(:widget) { described_class.new(product, language) } let(:language) { "de_DE" } + let(:preselected) { "de_DE" } + let(:supported_language) { true } let(:product) do instance_double(Y2Packager::Product, license_locales: ["en_US", "ja"], license: "content") end + before do + allow(Yast::Language).to receive(:supported_language?).and_return(supported_language) + allow(Yast::Language).to receive(:preselected).and_return(preselected) + end + describe "#contents" do it "includes a language selector" do expect(Y2Packager::Widgets::SimpleLanguageSelection).to receive(:new) @@ -42,10 +49,10 @@ context "when running on textmode" do let(:preselected) { "ja_JP" } + let(:supported_language) { false } before do allow(Yast::UI).to receive(:TextMode).and_return(true) - allow(Yast::Language).to receive(:preselected).and_return(preselected) allow(Yast::Stage).to receive(:initial).and_return(initial) end From ff41d167d2475cad3753bd016d7105eb2e7bb2b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20D=C3=ADaz=20Gonz=C3=A1lez?= Date: Wed, 22 May 2019 15:36:36 +0100 Subject: [PATCH 02/18] Update version and changelog --- package/yast2-packager.changes | 6 ++++++ package/yast2-packager.spec | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/package/yast2-packager.changes b/package/yast2-packager.changes index 24308a492..ea294ce3f 100644 --- a/package/yast2-packager.changes +++ b/package/yast2-packager.changes @@ -1,4 +1,10 @@ ------------------------------------------------------------------- +Wed May 22 14:33:54 UTC 2019 - David Diaz + +- Allow to select the license language when running in textmode + (bsc#1135901) +- 4.1.44 +------------------------------------------------------------------- Tue May 21 15:19:38 CEST 2019 - schubi@suse.de - List of Online Repositories: Overwrite already existing repos in diff --git a/package/yast2-packager.spec b/package/yast2-packager.spec index e023f9bc8..fc914c3d4 100644 --- a/package/yast2-packager.spec +++ b/package/yast2-packager.spec @@ -17,7 +17,7 @@ Name: yast2-packager -Version: 4.1.43 +Version: 4.1.44 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build From c067f5ddf17c68d9369fea39734812f1d4f43292 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Thu, 23 May 2019 14:46:44 +0200 Subject: [PATCH 03/18] WIP: selectable languages are a subset of displayable ones --- .../widgets/product_license_translations.rb | 48 +++++-------------- 1 file changed, 13 insertions(+), 35 deletions(-) diff --git a/src/lib/y2packager/widgets/product_license_translations.rb b/src/lib/y2packager/widgets/product_license_translations.rb index f2a4f1614..4912a2a1a 100644 --- a/src/lib/y2packager/widgets/product_license_translations.rb +++ b/src/lib/y2packager/widgets/product_license_translations.rb @@ -71,7 +71,7 @@ def handle(event) # @return [Y2Packager::Widgets::SimpleLanguageSelection] def language_selection @language_selection ||= - Y2Packager::Widgets::SimpleLanguageSelection.new(available_locales, content_language) + Y2Packager::Widgets::SimpleLanguageSelection.new(selectable_locales, content_language) end # Product selection widget @@ -82,59 +82,37 @@ def product_license Y2Packager::Widgets::ProductLicenseContent.new(product, content_language) end - # Available license translations + # Selectable license translations # - # When running on textmode, only the preselected/given language is considered. + # When running on textmode, the terminal is not able to display *some* languages # see #default_language for further details. # # @return [Array] Locale codes of the available translations - # @see #default_language - def available_locales - supported_language? ? product.license_locales : [default_language] + def selectable_locales + product.license_locales.find_all { |loc| displayable_language?(loc) } end # License translation language # - # When running on textmode, it returns the preselected/default language. - # see #default_language for further details. + # If the wanted language is presant among those displayable, use it, + # otherwise use the default # # @return [String] License content language - # @see #default_language def content_language - supported_language? ? language : default_language + l = selectable_locales.find { |loc| language.start_with?(loc) } + l || DEFAULT_FALLBACK_LANGUAGE end # @return [String] Fallback language DEFAULT_FALLBACK_LANGUAGE = "en_US".freeze - # Default language - # - # For some languages (like Japanese, Chinese or Korean) YaST needs to use a fbiterm in order - # to display symbols correctly when running on textmode. However, if none of those languages - # is selected on boot, this special terminal won't be used. - # - # So during 1st stage and when running in textmode, it returns the preselected language (from - # install.inf). - # - # On an installed system, it prefers the given language. Finally, if the license translation - # is not available, the fallback language is returned. - # - # @return [String] Language code - def default_language - candidate_lang = Yast::Stage.initial ? Yast::Language.preselected : language - translated = product.license_locales.any? { |l| candidate_lang.start_with?(l) } - return candidate_lang if translated - DEFAULT_FALLBACK_LANGUAGE - end - - # Whether the preselected language is supported - # - # It should not allow to change the language if it is a not fbiterm supported language. + # Whether a language is displayable # + # @param lang [String] "cs" or "cs_CZ" # @return [Boolean] # @see Yast::Language.supported_language? - def supported_language? - Yast::Language.supported_language?(Yast::Language.preselected) + def displayable_language?(lang) + Yast::Language.supported_language?(lang) end end end From 9607f7225e0dbd9450d881cf1566ecf077944c48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20D=C3=ADaz=20Gonz=C3=A1lez?= Date: Tue, 28 May 2019 09:03:35 +0100 Subject: [PATCH 04/18] Fix typo --- src/lib/y2packager/widgets/product_license_translations.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/y2packager/widgets/product_license_translations.rb b/src/lib/y2packager/widgets/product_license_translations.rb index 4912a2a1a..9b9b3d353 100644 --- a/src/lib/y2packager/widgets/product_license_translations.rb +++ b/src/lib/y2packager/widgets/product_license_translations.rb @@ -94,7 +94,7 @@ def selectable_locales # License translation language # - # If the wanted language is presant among those displayable, use it, + # If the wanted language is present among those displayable, use it, # otherwise use the default # # @return [String] License content language From 7d46d65c2a10fa957970900a555410a8624cc8b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20D=C3=ADaz=20Gonz=C3=A1lez?= Date: Tue, 28 May 2019 09:04:27 +0100 Subject: [PATCH 05/18] Update unit tests The product license translations widget is not in charge to check if is being used in the TextMode anymore. Instead, now simply relies on the Yast::Language#supported_language? to know whether a specific language is "displayable" or not. --- .../product_license_translations_test.rb | 100 ++++++++---------- 1 file changed, 42 insertions(+), 58 deletions(-) diff --git a/test/lib/widgets/product_license_translations_test.rb b/test/lib/widgets/product_license_translations_test.rb index 181e4d64f..00264235c 100644 --- a/test/lib/widgets/product_license_translations_test.rb +++ b/test/lib/widgets/product_license_translations_test.rb @@ -17,92 +17,76 @@ require "y2packager/widgets/product_license_translations" require "y2packager/product" +RSpec::Matchers.define :array_not_including do |x| + match do |actual| + return false unless actual.is_a?(Array) + return false if actual.include?(x) + + true + end +end + describe Y2Packager::Widgets::ProductLicenseTranslations do include_examples "CWM::CustomWidget" subject(:widget) { described_class.new(product, language) } let(:language) { "de_DE" } - let(:preselected) { "de_DE" } - let(:supported_language) { true } let(:product) do - instance_double(Y2Packager::Product, license_locales: ["en_US", "ja"], license: "content") + instance_double( + Y2Packager::Product, + license_locales: ["en_US", "de_DE", "ja_JP"], + license: "content" + ) end before do - allow(Yast::Language).to receive(:supported_language?).and_return(supported_language) - allow(Yast::Language).to receive(:preselected).and_return(preselected) + allow(Yast::Language).to receive(:supported_language?).and_return(true) end describe "#contents" do it "includes a language selector" do expect(Y2Packager::Widgets::SimpleLanguageSelection).to receive(:new) - .with(product.license_locales, language) widget.contents end it "includes the product license text" do expect(Y2Packager::Widgets::ProductLicenseContent).to receive(:new) - .with(product, language) widget.contents end - context "when running on textmode" do - let(:preselected) { "ja_JP" } - let(:supported_language) { false } - + context "when selected language cannot be displayed" do before do - allow(Yast::UI).to receive(:TextMode).and_return(true) - allow(Yast::Stage).to receive(:initial).and_return(initial) + allow(Yast::Language).to receive(:supported_language?) + .with(language).and_return(false) end - context "on installation" do - let(:initial) { true } - - it "the language selector includes only the preselected language" do - expect(Y2Packager::Widgets::SimpleLanguageSelection).to receive(:new) - .with([preselected], preselected) - widget.contents - end - - it "shows the product license in the preselected language" do - expect(Y2Packager::Widgets::ProductLicenseContent).to receive(:new) - .with(product, preselected) - widget.contents - end - - context "when there is no translation for the preselected language" do - let(:preselected) { "hu_HU" } - - it "the language selector includes only 'english'" do - expect(Y2Packager::Widgets::SimpleLanguageSelection).to receive(:new) - .with(["en_US"], "en_US") - widget.contents - end - - it "shows the product license in 'english'" do - expect(Y2Packager::Widgets::ProductLicenseContent).to receive(:new) - .with(product, "en_US") - widget.contents - end - end + it "does not include it in the language selector" do + expect(Y2Packager::Widgets::SimpleLanguageSelection).to receive(:new) + .with(array_not_including("de_DE"), anything) + widget.contents + end + + it "shows the product license in the default language (AmE)" do + expect(Y2Packager::Widgets::ProductLicenseContent).to receive(:new) + .with(product, "en_US") + widget.contents + end + end + + context "when there is no translation for the given language" do + let(:language) { "hu_HU" } + + it "does not include it in the language selector" do + expect(Y2Packager::Widgets::SimpleLanguageSelection).to receive(:new) + .with(array_not_including("hu_HU"), anything) + widget.contents end - context "on the installed system" do - let(:initial) { false } - let(:language) { "ja_JP" } - - it "the language selector includes only the default language" do - expect(Y2Packager::Widgets::SimpleLanguageSelection).to receive(:new) - .with([language], language) - widget.contents - end - - it "shows the product license in the default language" do - expect(Y2Packager::Widgets::ProductLicenseContent).to receive(:new) - .with(product, language) - widget.contents - end + it "shows the product license in the default language (AmE)" do + expect(Y2Packager::Widgets::ProductLicenseContent).to receive(:new) + .with(product, "en_US") + widget.contents end end end From a2292d4d955089f5d5675bf4b6b969b7a595e700 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Thu, 6 Jun 2019 16:54:25 +0200 Subject: [PATCH 06/18] Help editors with indentation style using https://EditorConfig.org --- .editorconfig | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..cf5b4ad59 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +# 2 space indentation +[*.rb] +indent_style = space +indent_size = 2 \ No newline at end of file From 15a6a979a9d19acc06c0cd609dfc03c0cd3e47c3 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Mon, 10 Jun 2019 13:48:41 +0200 Subject: [PATCH 07/18] fixup changelog: empty line --- package/yast2-packager.changes | 1 + 1 file changed, 1 insertion(+) diff --git a/package/yast2-packager.changes b/package/yast2-packager.changes index ea294ce3f..46d328eda 100644 --- a/package/yast2-packager.changes +++ b/package/yast2-packager.changes @@ -4,6 +4,7 @@ Wed May 22 14:33:54 UTC 2019 - David Diaz - Allow to select the license language when running in textmode (bsc#1135901) - 4.1.44 + ------------------------------------------------------------------- Tue May 21 15:19:38 CEST 2019 - schubi@suse.de From 4392a1460d5019450b845fbd77e5f07d5a30ab5f Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Thu, 6 Jun 2019 16:50:33 +0200 Subject: [PATCH 08/18] WIP introduce LanguageTag see also https://tools.ietf.org/html/rfc4647 Matching of Language Tags --- .../widgets/simple_language_selection.rb | 77 +++++++++++++++---- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/src/lib/y2packager/widgets/simple_language_selection.rb b/src/lib/y2packager/widgets/simple_language_selection.rb index b6ea0e741..7940ef64f 100644 --- a/src/lib/y2packager/widgets/simple_language_selection.rb +++ b/src/lib/y2packager/widgets/simple_language_selection.rb @@ -72,7 +72,7 @@ def init new_value = if languages.include?(default) default - elsif default.include?("_") + elsif default.include?("_") # LC#generalize ??? short_code = default.split("_").first languages.include?(short_code) ? short_code : nil end @@ -92,22 +92,73 @@ def help # @return [Array>] Array of languages in form [code, description] def items return @items if @items - languages_map = Yast::Language.GetLanguagesMap(false) - @items = languages.each_with_object([]) do |code, langs| - attrs = languages_map.key?(code) ? languages_map[code] : nil - lang, attrs = languages_map.find { |k, _v| k.start_with?(code) } if attrs.nil? - - if attrs.nil? - log.warn "Not valid language '#{lang}'" - next - end - - log.debug "Using language '#{lang}' instead of '#{code}'" if lang != code - langs << [code, attrs[4]] + lmap = Yast::Language.GetLanguagesMap(false) + @items = languages.map do |lang| + [lang, LanguageTag.new(lang).name(lang_map_cache: lmap)] end + @items.reject! { |_lang, name| name.nil? } @items.uniq! @items.sort_by!(&:last) end end + + # {::Comparable} enforces a total ordering, contrary to its + # documentation, WTF. + module PartiallyComparable + def <(other) + cmp = self.<=>(other) + return nil if cmp.nil? + cmp < 0 + end + + def >(other) + cmp = self.<=>(other) + return nil if cmp.nil? + cmp > 0 + end + end + + # Language tags like "cs" "cs_CZ" "cs_CZ.UTF-8". + # + # FIXME: improve the simplistic string comparisons + class LanguageTag + include Yast::Logger + + # @param s [String] + def initialize(s) + @tag = s + end + + def to_s + @tag + end + + include PartiallyComparable + + # Like with classes (where Special < General) "en_US" < "en" + # Mnemonics: number of speakers + def <=>(other) + return 0 if to_s == other.to_s + return -1 if to_s.start_with?(other.to_s) + return 1 if other.to_s.start_with?(to_s) + nil + end + + # @return [String,nil] + def name(lang_map_cache: nil) + lang_map_cache ||= Yast::Language.GetLanguagesMap(false) + attrs = lang_map_cache[@tag] + if attrs.nil? + # we're en, find en_US + _tag, attrs = lang_map_cache.find { |k, _v| self > LanguageTag.new(k) } + end + if attrs.nil? + log.warn "Could not find name for language '#{@tag}'" + return nil + end + + attrs[4] + end + end end end From 9a4e4a08770bd734801af580c5b053bff4a7d9cf Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Mon, 10 Jun 2019 13:47:17 +0200 Subject: [PATCH 09/18] LanguageTag.generalize --- .../widgets/simple_language_selection.rb | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/lib/y2packager/widgets/simple_language_selection.rb b/src/lib/y2packager/widgets/simple_language_selection.rb index 7940ef64f..b9bec0958 100644 --- a/src/lib/y2packager/widgets/simple_language_selection.rb +++ b/src/lib/y2packager/widgets/simple_language_selection.rb @@ -69,14 +69,11 @@ def opt # initial value will be set to "en_US". def init languages = items.map(&:first) - new_value = - if languages.include?(default) - default - elsif default.include?("_") # LC#generalize ??? - short_code = default.split("_").first - languages.include?(short_code) ? short_code : nil - end - + candidates = [ + default, + LanguageTag.new(default).generalize.to_s + ] + new_value = candidates.compact.find { |c| languages.include?(c) } self.value = new_value || DEFAULT_LICENSE_LANG end @@ -144,6 +141,14 @@ def <=>(other) nil end + # A more general tag: "en_US" -> "en" (-> nil) + # @return [LanguageTag,nil] + def generalize + self.class.new(@tag.split("_").first) if @tag.include? "_" + # else nil + # FIXME: or self, find out what makes more sense + end + # @return [String,nil] def name(lang_map_cache: nil) lang_map_cache ||= Yast::Language.GetLanguagesMap(false) From 06e2a85ff4bc4ee4f4490d3ae1f96ec24b4f5efd Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Mon, 10 Jun 2019 14:59:26 +0200 Subject: [PATCH 10/18] Split out LanguageTag in its own file. TODO: tests! --- src/lib/language_tag.rb | 99 +++++++++++++++++++ .../widgets/simple_language_selection.rb | 68 +------------ 2 files changed, 100 insertions(+), 67 deletions(-) create mode 100644 src/lib/language_tag.rb diff --git a/src/lib/language_tag.rb b/src/lib/language_tag.rb new file mode 100644 index 000000000..1d58b3158 --- /dev/null +++ b/src/lib/language_tag.rb @@ -0,0 +1,99 @@ +# ------------------------------------------------------------------------------ +# Copyright (c) 2019 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. +# ------------------------------------------------------------------------------ + +require "yast" + +# {::Comparable} enforces a total ordering, contrary to its +# documentation, WTF. +module PartiallyComparable + def <(other) + cmp = self.<=>(other) + return nil if cmp.nil? + cmp < 0 + end + + def >(other) + cmp = self.<=>(other) + return nil if cmp.nil? + cmp > 0 + end + + def <=(other) + cmp = self.<=>(other) + return nil if cmp.nil? + cmp <= 0 + end + + def >=(other) + cmp = self.<=>(other) + return nil if cmp.nil? + cmp >= 0 + end + + def ==(other) + return true if equal?(other) # object identity + cmp = self.<=>(other) + return nil if cmp.nil? + cmp == 0 + end +end + +# Language tags like "cs" "cs_CZ" "cs_CZ.UTF-8". +# +# FIXME: improve the simplistic string comparisons +class LanguageTag + include Yast::Logger + + # @param s [String] + def initialize(s) + @tag = s + end + + def to_s + @tag + end + + include PartiallyComparable + + # Like with classes (where Special < General) "en_US" < "en" + # Mnemonics: number of speakers + def <=>(other) + return 0 if to_s == other.to_s + return -1 if to_s.start_with?(other.to_s) + return 1 if other.to_s.start_with?(to_s) + nil + end + + # A more general tag: "en_US" -> "en" (-> nil) + # @return [LanguageTag,nil] + def generalize + self.class.new(@tag.split("_").first) if @tag.include? "_" + # else nil + # FIXME: or self, find out what makes more sense + end + + # @return [String,nil] + def name(lang_map_cache: nil) + lang_map_cache ||= Yast::Language.GetLanguagesMap(false) + attrs = lang_map_cache[@tag] + if attrs.nil? + # we're en, find en_US + _tag, attrs = lang_map_cache.find { |k, _v| self > LanguageTag.new(k) } + end + if attrs.nil? + log.warn "Could not find name for language '#{@tag}'" + return nil + end + + attrs[4] + end +end diff --git a/src/lib/y2packager/widgets/simple_language_selection.rb b/src/lib/y2packager/widgets/simple_language_selection.rb index b9bec0958..1ef2a66f4 100644 --- a/src/lib/y2packager/widgets/simple_language_selection.rb +++ b/src/lib/y2packager/widgets/simple_language_selection.rb @@ -19,6 +19,7 @@ require "yast" require "cwm/widget" +require "language_tag" Yast.import "Language" @@ -98,72 +99,5 @@ def items @items.sort_by!(&:last) end end - - # {::Comparable} enforces a total ordering, contrary to its - # documentation, WTF. - module PartiallyComparable - def <(other) - cmp = self.<=>(other) - return nil if cmp.nil? - cmp < 0 - end - - def >(other) - cmp = self.<=>(other) - return nil if cmp.nil? - cmp > 0 - end - end - - # Language tags like "cs" "cs_CZ" "cs_CZ.UTF-8". - # - # FIXME: improve the simplistic string comparisons - class LanguageTag - include Yast::Logger - - # @param s [String] - def initialize(s) - @tag = s - end - - def to_s - @tag - end - - include PartiallyComparable - - # Like with classes (where Special < General) "en_US" < "en" - # Mnemonics: number of speakers - def <=>(other) - return 0 if to_s == other.to_s - return -1 if to_s.start_with?(other.to_s) - return 1 if other.to_s.start_with?(to_s) - nil - end - - # A more general tag: "en_US" -> "en" (-> nil) - # @return [LanguageTag,nil] - def generalize - self.class.new(@tag.split("_").first) if @tag.include? "_" - # else nil - # FIXME: or self, find out what makes more sense - end - - # @return [String,nil] - def name(lang_map_cache: nil) - lang_map_cache ||= Yast::Language.GetLanguagesMap(false) - attrs = lang_map_cache[@tag] - if attrs.nil? - # we're en, find en_US - _tag, attrs = lang_map_cache.find { |k, _v| self > LanguageTag.new(k) } - end - if attrs.nil? - log.warn "Could not find name for language '#{@tag}'" - return nil - end - - attrs[4] - end - end end end From 4cfc611a2e56545d461792d2a2c9ecc215affb3f Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Mon, 10 Jun 2019 15:00:20 +0200 Subject: [PATCH 11/18] Use LanguageTag in ProductLicenseTranslations --- src/lib/y2packager/widgets/product_license_translations.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/y2packager/widgets/product_license_translations.rb b/src/lib/y2packager/widgets/product_license_translations.rb index 9b9b3d353..cee4b9786 100644 --- a/src/lib/y2packager/widgets/product_license_translations.rb +++ b/src/lib/y2packager/widgets/product_license_translations.rb @@ -12,6 +12,7 @@ require "yast" require "cwm" +require "language_tag" require "y2packager/widgets/simple_language_selection" require "y2packager/widgets/product_license" @@ -99,7 +100,8 @@ def selectable_locales # # @return [String] License content language def content_language - l = selectable_locales.find { |loc| language.start_with?(loc) } + # this selects "en" if we want "en_US" + l = selectable_locales.find { |loc| LanguageTag.new(loc) >= language } l || DEFAULT_FALLBACK_LANGUAGE end From d3a7e1b2ed69a8d3b3a1e576bc1663a7ea4a9be5 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Tue, 11 Jun 2019 11:11:27 +0200 Subject: [PATCH 12/18] package LanguageTag --- package/yast2-packager.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/package/yast2-packager.spec b/package/yast2-packager.spec index fc914c3d4..4a314d4fd 100644 --- a/package/yast2-packager.spec +++ b/package/yast2-packager.spec @@ -137,6 +137,7 @@ rake install DESTDIR="%{buildroot}" %{yast_ybindir}/* %{yast_yncludedir}/checkmedia/* %{yast_yncludedir}/packager/* +%{yast_libdir}/language_tag.rb %{yast_libdir}/packager/* %{yast_libdir}/packager/cfa/* %{yast_libdir}/y2packager/* From 4a95b7468c3383a9a0312b6f804a81d1aa621d03 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Tue, 11 Jun 2019 11:11:52 +0200 Subject: [PATCH 13/18] document GetLicenseDialog --- src/modules/ProductLicense.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/modules/ProductLicense.rb b/src/modules/ProductLicense.rb index 7638b0c1f..842382b63 100644 --- a/src/modules/ProductLicense.rb +++ b/src/modules/ProductLicense.rb @@ -1083,6 +1083,11 @@ def base_product_id current_sources.any? ? current_sources.first : 0 end + # @param [Array] languages list of license translations + # @param [String] license_language default license language + # @param [Ref>] licenses licenses (mapping "language_code" => "license") + # @param [String] id unique license ID + # @param [Boolean] spare_space def GetLicenseDialog(languages, license_language, licenses, id, spare_space) space = UI.TextMode ? 1 : 3 From b7a1318e23eb5ec0321168ff9b9731412b9caba3 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Thu, 13 Jun 2019 14:23:19 +0200 Subject: [PATCH 14/18] Filter displayable languages in ProductLicense --- src/modules/ProductLicense.rb | 20 ++++----- test/product_license_test.rb | 78 +++++++---------------------------- 2 files changed, 23 insertions(+), 75 deletions(-) diff --git a/src/modules/ProductLicense.rb b/src/modules/ProductLicense.rb index 842382b63..6c590147d 100644 --- a/src/modules/ProductLicense.rb +++ b/src/modules/ProductLicense.rb @@ -661,6 +661,12 @@ def HandleLicenseDialogRet(licenses, base_product, action) # @return [Array] Fallback languages DEFAULT_FALLBACK_LANGUAGES = ["en_US", "en"].freeze + def displayable_language?(lang) + return true if lang.empty? # zypp means English here + Yast::Language.supported_language?(lang) + end + private :displayable_language? + # FIXME: this is needed only by yast2-registration, fix it later # and make this method private # @@ -672,19 +678,9 @@ def HandleLicenseDialogRet(licenses, base_product, action) # @param [String] id unique license ID # @param [String] caption dialog title def DisplayLicenseDialogWithTitle(languages, back, license_language, licenses, id, caption) - languages = deep_copy(languages) + languages = languages.find_all { |lang| displayable_language?(lang) } + log.info "Displayable languages: #{languages}, wanted: #{license_language}" - # For some languages (like Japanese, Chinese or Korean) YaST needs to use a fbiterm in order - # to display symbols correctly when running on textmode. To avoid such problems, consider only - # the preselected (on installation) or the default language (on running system). This will - # setup fbiterm correctly. See bsc#1094793 for further information. - if Yast::UI.TextMode - lang = default_language - candidate_languages = [lang, lang[0..1]] + DEFAULT_FALLBACK_LANGUAGES - license_language = (candidate_languages & languages).first || "" - languages = [license_language] - log.info "Adjusted license language to #{license_language}" - end contents = ( licenses_ref = arg_ref(licenses.value) diff --git a/test/product_license_test.rb b/test/product_license_test.rb index d000f5906..a8f7ccc3f 100755 --- a/test/product_license_test.rb +++ b/test/product_license_test.rb @@ -13,71 +13,23 @@ subject { Yast::ProductLicense } describe "#DisplayLicenseDialogWithTitle (partial test)" do - context "when running in text mode" do - let(:langs) { ["en_US", "ja"] } - let(:lang) { "es_ES" } - let(:licenses) { Yast.arg_ref("en_US" => "en_US license") } - let(:license_id) { "id" } - let(:preselected) { "ja_JP" } + let(:langs) { ["en_US", "ja"] } + let(:lang) { "en_US" } + let(:licenses) { Yast.arg_ref("en_US" => "en_US license") } + let(:license_id) { "id" } - before do - allow(Yast::Language).to receive(:GetLanguagesMap).and_return({}) - allow(Yast::UI).to receive(:TextMode).and_return(true) - allow(Yast::Language).to receive(:preselected).and_return(preselected) - allow(Yast::Stage).to receive(:initial).and_return(initial) - allow(Yast::Language).to receive(:language).and_return(lang) - end - - context "on the installation" do - let(:initial) { true } - - it "uses the preselected language" do - expect(subject).to receive(:GetLicenseDialog) - .with(["ja"], "ja", anything, license_id, false) - .and_call_original - subject.DisplayLicenseDialogWithTitle( - langs, "Back", lang, licenses, license_id, "License" - ) - end - - context "when there is no translation for the preselected language" do - let(:preselected) { "es_ES" } - - it "falls back to 'english'" do - expect(subject).to receive(:GetLicenseDialog) - .with(["en_US"], "en_US", anything, license_id, false) - .and_call_original - subject.DisplayLicenseDialogWithTitle( - langs, "Back", lang, licenses, license_id, "License" - ) - end - end - end - - context "on the installed system" do - let(:initial) { false } - let(:lang) { "ja_JP" } - - it "uses the default language" do - expect(subject).to receive(:GetLicenseDialog) - .with(["ja"], "ja", anything, license_id, false) - subject.DisplayLicenseDialogWithTitle( - langs, "Back", lang, licenses, license_id, "License" - ) - end - - context "when there is no translation for the default language" do - let(:lang) { "es_ES" } + before do + allow(Yast::Language).to receive(:GetLanguagesMap).and_return({}) + allow(Yast::Language).to receive(:supported_language?).and_return(true) + end - it "falls back to 'english'" do - expect(subject).to receive(:GetLicenseDialog) - .with(["en_US"], "en_US", anything, license_id, false) - subject.DisplayLicenseDialogWithTitle( - langs, "Back", lang, licenses, license_id, "License" - ) - end - end - end + it "works" do + expect(subject).to receive(:GetLicenseDialog) + .with(["en_US", "ja"], "en_US", anything, license_id, false) + .and_call_original + subject.DisplayLicenseDialogWithTitle( + langs, "Back", lang, licenses, license_id, "License" + ) end end From 3f9332c90caf14bea0bb048d7274b6bc8c357a98 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Thu, 13 Jun 2019 16:11:20 +0200 Subject: [PATCH 15/18] documented the licenses argument --- src/modules/ProductLicense.rb | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/modules/ProductLicense.rb b/src/modules/ProductLicense.rb index 6c590147d..18c8d7055 100644 --- a/src/modules/ProductLicense.rb +++ b/src/modules/ProductLicense.rb @@ -569,6 +569,7 @@ def AskInstalledLicensesAgreement(directories, action) # FIXME: this is needed only by yast2-registration, fix it later # and make this method private + # @param licenses [ArgRef] a map $[ lang_code : filename ] def HandleLicenseDialogRet(licenses, base_product, action) ret = nil @@ -674,7 +675,7 @@ def displayable_language?(lang) # @param [Array] languages list of license translations # @param [Boolean] back enable "Back" button # @param [String] license_language default license language - # @param [Hash] licenses licenses (mapping "language_code" => "license") + # @param licenses [ArgRef] a map $[ lang_code : filename ] # @param [String] id unique license ID # @param [String] caption dialog title def DisplayLicenseDialogWithTitle(languages, back, license_language, licenses, id, caption) @@ -766,7 +767,7 @@ def license_download_label(display_url) # update license location displayed in the dialog (e.g. after license translation # is changed) # @param [String] lang language of the currently displayed license - # @param [Yast::ArgRef] licenses reference to the list of licenses + # @param licenses [ArgRef] a map $[ lang_code : filename ] def update_license_location(lang, licenses) return if !location_is_url?(license_file_print) || !UI.WidgetExists(:printing_hint) @@ -845,6 +846,7 @@ def repository_product(src_id) Y2Packager::Product.from_h(product_h) end + # @param licenses [ArgRef] a map $[ lang_code : filename ] def GetLicenseContent(lic_lang, licenses, id) license_file = ( licenses_ref = arg_ref(licenses.value) @@ -932,6 +934,7 @@ def LicenseHasBeenAccepted(license_ident) nil end + # @param licenses [ArgRef] a map $[ lang_code : filename ] def WhichLicenceFile(license_language, licenses) license_file = Ops.get(licenses.value, license_language, "") @@ -948,6 +951,7 @@ def WhichLicenceFile(license_language, licenses) license_file end + # @param licenses [ArgRef] a map $[ lang_code : filename ] def GetLicenseDialogTerm(languages, license_language, licenses, id) languages = deep_copy(languages) rt = ( @@ -1081,7 +1085,7 @@ def base_product_id # @param [Array] languages list of license translations # @param [String] license_language default license language - # @param [Ref>] licenses licenses (mapping "language_code" => "license") + # @param licenses [ArgRef] a map $[ lang_code : filename ] # @param [String] id unique license ID # @param [Boolean] spare_space def GetLicenseDialog(languages, license_language, licenses, id, spare_space) @@ -1144,6 +1148,7 @@ def GetLicenseDialog(languages, license_language, licenses, id, spare_space) end # Displays License dialog + # @param licenses [ArgRef] a map $[ lang_code : filename ] def DisplayLicenseDialog(languages, back, license_language, licenses, id) # dialog title DisplayLicenseDialogWithTitle(languages, back, license_language, licenses, id, @@ -1167,7 +1172,7 @@ def CleanUpLicense(tmpdir) # @param [String] dir string directory to look into # @param [Array] patterns a list of patterns for the files, regular expressions # with %1 for the language - # @return a map $[ lang_code : filename ] + # @return [Hash{String, String}] a map $[ lang_code : filename ] def LicenseFiles(dir, patterns) patterns = deep_copy(patterns) ret = {} @@ -1495,6 +1500,8 @@ def cache_license_acceptance_needed(id, license_dir) SetAcceptanceNeeded(id, license_acceptance_needed) end + # @param licenses [ArgRef] a map $[ lang_code : filename ] + # @return [:cont,:auto] def InitLicenseData(src_id, dir, licenses, available_langs, _require_agreement, _license_ident, id) # Downloads and unpacks all licenses for a given source ID @@ -1595,6 +1602,7 @@ def InitLicenseData(src_id, dir, licenses, available_langs, end # Should have been named 'UpdateLicenseContentBasedOnSelectedLanguage' :-> + # @param licenses [ArgRef] a map $[ lang_code : filename ] def UpdateLicenseContent(licenses, id) # read the selected language @lic_lang = Convert.to_string( From b5248b5f284b4fb2978edd9a3a25bcfa363b7f86 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Thu, 13 Jun 2019 16:21:41 +0200 Subject: [PATCH 16/18] simplified the ArgRef code --- src/modules/ProductLicense.rb | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/modules/ProductLicense.rb b/src/modules/ProductLicense.rb index 18c8d7055..089af4820 100644 --- a/src/modules/ProductLicense.rb +++ b/src/modules/ProductLicense.rb @@ -682,18 +682,12 @@ def DisplayLicenseDialogWithTitle(languages, back, license_language, licenses, i languages = languages.find_all { |lang| displayable_language?(lang) } log.info "Displayable languages: #{languages}, wanted: #{license_language}" - - contents = ( - licenses_ref = arg_ref(licenses.value) - result = GetLicenseDialog( - languages, - license_language, - licenses_ref, - id, - false - ) - licenses.value = licenses_ref.value - result + contents = GetLicenseDialog( + languages, + license_language, + licenses, + id, + false ) Wizard.SetContents( From 5ee71ae4eddd03d554db497c5e89ebfbf668ce2d Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Thu, 13 Jun 2019 16:25:33 +0200 Subject: [PATCH 17/18] Don't download the wrong license --- src/modules/ProductLicense.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/modules/ProductLicense.rb b/src/modules/ProductLicense.rb index 089af4820..680a2604f 100644 --- a/src/modules/ProductLicense.rb +++ b/src/modules/ProductLicense.rb @@ -1713,8 +1713,7 @@ def product_license(id, tmpdir) log.info("License locales for product #{product_name.inspect}: #{locales.inspect}") locales.each do |locale| - license_locale = (Yast::UI.TextMode && locale.empty?) ? default_language : locale - license = Pkg.PrdGetLicenseToConfirm(product_name, license_locale) + license = Pkg.PrdGetLicenseToConfirm(product_name, locale) next if license.nil? || license.empty? found_license = true From ff85e2cf2dcee453b16252294e1a96f0bb4e4849 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Fri, 14 Jun 2019 14:40:36 +0200 Subject: [PATCH 18/18] simplified the rspec matcher --- test/lib/widgets/product_license_translations_test.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/lib/widgets/product_license_translations_test.rb b/test/lib/widgets/product_license_translations_test.rb index 00264235c..772750ba2 100644 --- a/test/lib/widgets/product_license_translations_test.rb +++ b/test/lib/widgets/product_license_translations_test.rb @@ -20,9 +20,7 @@ RSpec::Matchers.define :array_not_including do |x| match do |actual| return false unless actual.is_a?(Array) - return false if actual.include?(x) - - true + !actual.include?(x) end end