Skip to content
Snippets Groups Projects
Commit 9ea1dcf4 authored by Markus Reiter's avatar Markus Reiter
Browse files

Fix auditing of cask languages.

parent 3e5ff1ff
No related branches found
No related tags found
No related merge requests found
......@@ -330,14 +330,11 @@ module Cask
end
def check_languages
invalid = []
@cask.languages.each do |language|
invalid << language.to_s unless language.match?(/^[a-z]{2}$/) || language.match?(/^[a-z]{2}-[A-Z]{2}$/)
Locale.parse(language)
rescue Locale::ParserError
add_error "Locale '#{language}' is invalid."
end
return if invalid.empty?
add_error "locale #{invalid.join(", ")} are invalid"
end
def check_token_conflicts
......
......@@ -136,7 +136,7 @@ module Cask
end
def language_eval
return @language if instance_variable_defined?(:@language)
return @language if defined?(@language)
return @language = nil if @language_blocks.nil? || @language_blocks.empty?
......
# frozen_string_literal: true
# Representation of a system locale.
#
# Used to compare the system language and languages defined using cask `language` stanza.
#
# @api private
class Locale
# Error when a string cannot be parsed to a `Locale`.
class ParserError < StandardError
end
LANGUAGE_REGEX = /(?:[a-z]{2,3})/.freeze # ISO 639-1 or ISO 639-2
REGION_REGEX = /(?:[A-Z]{2}|\d{3})/.freeze # ISO 3166-1 or UN M.49
SCRIPT_REGEX = /(?:[A-Z][a-z]{3})/.freeze # ISO 15924
# ISO 639-1 or ISO 639-2
LANGUAGE_REGEX = /(?:[a-z]{2,3})/.freeze
private_constant :LANGUAGE_REGEX
# ISO 3166-1 or UN M.49
REGION_REGEX = /(?:[A-Z]{2}|\d{3})/.freeze
private_constant :REGION_REGEX
# ISO 15924
SCRIPT_REGEX = /(?:[A-Z][a-z]{3})/.freeze
private_constant :SCRIPT_REGEX
LOCALE_REGEX = /\A((?:#{LANGUAGE_REGEX}|#{REGION_REGEX}|#{SCRIPT_REGEX})(?:-|$)){1,3}\Z/.freeze
private_constant :LOCALE_REGEX
def self.parse(string)
string = string.to_s
if locale = try_parse(string)
return locale
end
raise ParserError, "'#{string}' cannot be parsed to a #{self}"
end
def self.try_parse(string)
return if string.blank?
raise ParserError, "'#{string}' cannot be parsed to a #{self}" unless string.match?(LOCALE_REGEX)
scanner = StringScanner.new(string)
scan = proc do |regex|
string.scan(/(?:-|^)(#{regex})(?:-|$)/).flatten.first
if language = scanner.scan(LANGUAGE_REGEX)
sep = scanner.scan(/-/)
return if (sep && scanner.eos?) || (sep.nil? && !scanner.eos?)
end
language = scan.call(LANGUAGE_REGEX)
region = scan.call(REGION_REGEX)
script = scan.call(SCRIPT_REGEX)
if region = scanner.scan(REGION_REGEX)
sep = scanner.scan(/-/)
return if (sep && scanner.eos?) || (sep.nil? && !scanner.eos?)
end
script = scanner.scan(SCRIPT_REGEX)
return unless scanner.eos?
new(language, region, script)
end
......@@ -46,7 +75,10 @@ class Locale
end
def include?(other)
other = self.class.parse(other) unless other.is_a?(self.class)
unless other.is_a?(self.class)
other = self.class.try_parse(other)
return false if other.nil?
end
[:language, :region, :script].all? do |var|
if other.public_send(var).nil?
......@@ -58,12 +90,14 @@ class Locale
end
def eql?(other)
other = self.class.parse(other) unless other.is_a?(self.class)
unless other.is_a?(self.class)
other = self.class.try_parse(other)
return false if other.nil?
end
[:language, :region, :script].all? do |var|
public_send(var) == other.public_send(var)
end
rescue ParserError
false
end
alias == eql?
......
......@@ -278,7 +278,6 @@ describe Cask::Audit, :cask do
end
describe "locale validation" do
let(:strict) { true }
let(:cask) do
tmp_cask "locale-cask-test", <<~RUBY
cask 'locale-cask-test' do
......@@ -318,7 +317,9 @@ describe Cask::Audit, :cask do
context "when cask locale is invalid" do
it "error with invalid locale" do
expect(subject).to fail_with(/locale ZH-CN, zh-, zh-cn are invalid/)
expect(subject).to fail_with(/Locale 'ZH-CN' is invalid\./)
expect(subject).to fail_with(/Locale 'zh-' is invalid\./)
expect(subject).to fail_with(/Locale 'zh-cn' is invalid\./)
end
end
end
......
......@@ -26,6 +26,9 @@ describe Locale do
expect { described_class.parse("zh-CN_Hans") }.to raise_error(Locale::ParserError)
expect { described_class.parse("zhCN") }.to raise_error(Locale::ParserError)
expect { described_class.parse("zh_Hans") }.to raise_error(Locale::ParserError)
expect { described_class.parse("zh-") }.to raise_error(Locale::ParserError)
expect { described_class.parse("ZH-CN") }.to raise_error(Locale::ParserError)
expect { described_class.parse("zh-cn") }.to raise_error(Locale::ParserError)
end
end
end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment