diff options
author | Claire McQuin <claire@getchef.com> | 2014-10-15 13:30:28 -0700 |
---|---|---|
committer | Claire McQuin <claire@getchef.com> | 2014-10-15 13:30:28 -0700 |
commit | 9af87953f6b4fe40c84e902d19b880138465044d (patch) | |
tree | 84c79955f187d79e8a9fa745386fc09a02eb3530 | |
parent | 6186f4793517311b3c6aade8c8ca0ae1acc6f3e8 (diff) | |
download | chef-9af87953f6b4fe40c84e902d19b880138465044d.tar.gz |
Use shell_out to get locales
-rw-r--r-- | lib/chef/config.rb | 24 | ||||
-rw-r--r-- | spec/unit/config_spec.rb | 89 |
2 files changed, 102 insertions, 11 deletions
diff --git a/lib/chef/config.rb b/lib/chef/config.rb index 5213acf866..9a8117d2c2 100644 --- a/lib/chef/config.rb +++ b/lib/chef/config.rb @@ -31,6 +31,7 @@ class Chef class Config extend Mixlib::Config + extend Chef::Mixin::ShellOut PathHelper = Chef::Util::PathHelper @@ -611,24 +612,25 @@ class Chef # # For example, on CentOS 6 with ENV['LANG'] = "en_US.UTF-8", # `locale -a`.split fails with ArgumentError invalid UTF-8 encoding. - output = `locale -a` - locales = output.encode(output.encoding, :invalid => :replace).split + locales = shell_out_with_systems_locale("locale -a").stdout.split case when locales.include?('C.UTF-8') 'C.UTF-8' - when locales.include?('en_US.UTF-8') || locales.include?('en_US.utf8') + when locales.include?('en_US.UTF-8'), locales.include?('en_US.utf8') 'en_US.UTF-8' when locales.include?('en.UTF-8') 'en.UTF-8' - when guesses = locales.select { |l| l =~ /^en_.*UTF-?8$/i } - # Will match en_ZZ.UTF-8, en_ZZ.utf-8, en_ZZ.UTF8, en_ZZ.utf8 - guessed_locale = guesses.first - # Transform into the form en_ZZ.UTF-8 - guessed_locale.gsub(/UTF-?8$/i, "UTF-8") - guessed_locale else - Chef::Log.warn "Please install an English UTF-8 locale for Chef to use, falling back to C locale and disabling UTF-8 support." - 'C' + # Will match en_ZZ.UTF-8, en_ZZ.utf-8, en_ZZ.UTF8, en_ZZ.utf8 + guesses = locales.select { |l| l =~ /^en_.*UTF-?8$/i } + unless guesses.empty? + guessed_locale = guesses.first + # Transform into the form en_ZZ.UTF-8 + guessed_locale.gsub(/UTF-?8$/i, "UTF-8") + else + Chef::Log.warn "Please install an English UTF-8 locale for Chef to use, falling back to C locale and disabling UTF-8 support." + 'C' + end end rescue if Chef::Platform.windows? diff --git a/spec/unit/config_spec.rb b/spec/unit/config_spec.rb index 41411669e6..cc83ca3c45 100644 --- a/spec/unit/config_spec.rb +++ b/spec/unit/config_spec.rb @@ -417,6 +417,95 @@ describe Chef::Config do end end end + + describe "Chef::Config[:internal_locale]" do + let(:shell_out) do + double("Chef::Mixin::ShellOut double", :exitstatus => 0, :stdout => locales) + end + + let(:locales) { locale_array.join("\n") } + + before do + allow(Chef::Config).to receive(:shell_out_with_systems_locale).with("locale -a").and_return(shell_out) + end + + shared_examples_for "a suitable locale" do + it "returns an English UTF-8 locale" do + expect(Chef::Log).to_not receive(:warn).with(/Please install an English UTF-8 locale for Chef to use/) + expect(Chef::Log).to_not receive(:debug).with(/Defaulting to locale en_US.UTF-8 on Windows/) + expect(Chef::Log).to_not receive(:debug).with(/No usable locale -a command found/) + expect(Chef::Config[:internal_locale]).to eq expected_locale + end + end + + context "when the result includes 'C.UTF-8'" do + include_examples "a suitable locale" do + let(:locale_array) { [expected_locale, "en_US.UTF-8"] } + let(:expected_locale) { "C.UTF-8" } + end + end + + context "when the result includes 'en_US.UTF-8'" do + include_examples "a suitable locale" do + let(:locale_array) { ["en_CA.UTF-8", expected_locale, "en_NZ.UTF-8"] } + let(:expected_locale) { "en_US.UTF-8" } + end + end + + context "when the result includes 'en_US.utf8'" do + include_examples "a suitable locale" do + let(:locale_array) { ["en_CA.utf8", "en_US.utf8", "en_NZ.utf8"] } + let(:expected_locale) { "en_US.UTF-8" } + end + end + + context "when the result includes 'en.UTF-8'" do + include_examples "a suitable locale" do + let(:locale_array) { ["en.ISO8859-1", expected_locale] } + let(:expected_locale) { "en.UTF-8" } + end + end + + context "when the result includes 'en_*.UTF-8'" do + include_examples "a suitable locale" do + let(:locale_array) { [expected_locale, "en_CA.UTF-8", "en_GB.UTF-8"] } + let(:expected_locale) { "en_AU.UTF-8" } + end + end + + context "when the result includes 'en_*.utf8'" do + include_examples "a suitable locale" do + let(:locale_array) { ["en_AU.utf8", "en_CA.utf8", "en_GB.utf8"] } + let(:expected_locale) { "en_AU.UTF-8" } + end + end + + context "when the result does not include 'en_*.UTF-8'" do + let(:locale_array) { ["af_ZA", "af_ZA.ISO8859-1", "af_ZA.ISO8859-15", "af_ZA.UTF-8"] } + + it "should fall back to C locale" do + expect(Chef::Log).to receive(:warn).with("Please install an English UTF-8 locale for Chef to use, falling back to C locale and disabling UTF-8 support.") + expect(Chef::Config[:internal_locale]).to eq 'C' + end + end + + context "on error" do + let(:locale_array) { [] } + + before do + allow(Chef::Config).to receive(:shell_out_with_systems_locale).and_raise("THIS IS AN ERROR") + end + + it "should default to 'en_US.UTF-8'" do + if is_windows + expect(Chef::Log).to receive(:debug).with("Defaulting to locale en_US.UTF-8 on Windows, until it matters that we do something else.") + else + expect(Chef::Log).to receive(:debug).with("No usable locale -a command found, assuming you have en_US.UTF-8 installed.") + end + expect(Chef::Config[:internal_locale]).to eq "en_US.UTF-8" + end + end + end end end end |