module Apstrings require 'apstrings/reader' require 'apstrings/strings_parser' require 'apstrings/logger' class ValidateResult attr_accessor :master_special_character_error attr_accessor :file_special_character_errors attr_accessor :missing_keys attr_accessor :dup_keys attr_accessor :file_format_errors attr_accessor :valid_file_format def initialize(file,masterFile, file_special_character_errors=[], master_special_character_error=[], missing_keys=[], dup_keys=[],file_format_errors=[], valid_file_format=true) @file = file @masterFile = masterFile @file_special_character_errors = file_special_character_errors @master_special_character_error = master_special_character_error @missing_keys = missing_keys @dup_keys = dup_keys @file_format_errors = file_format_errors @valid_file_format = valid_file_format end def to_hash { :file=> File.basename(@file), :masterFile => File.basename(@masterFile), :master_special_character_error => @master_special_character_error, :file_special_character_errors => @file_special_character_errors , :missing_keys => @missing_keys , :dup_keys => @dup_keys, :file_format_errors => @file_format_errors, :valid_file_format => @valid_file_format } end end class Validator class << self; attr_accessor :result end def self.validate(file,masterFile) @result = ValidateResult.new(file,masterFile); @file = file @master = nil puts "-----------------------------------------\n\n" puts "-----------------------------------------" puts "apstrings: start validate strings file : #{@file} ..." if nil == masterFile Log::warn("No master file provided, validating file format only ...") else @master = Validator::paredFile(masterFile) end valid_master, valid_file , no_missing_key = true,true,true begin @string_file = Validator::paredFile(file); rescue Exception => e Log::error(e) @result.valid_file_format = false @result.file_format_errors << e return false,@result.to_hash end valid_file = Validator::validate_format(@string_file) if masterFile != nil valid_master = Validator::validate_format(@master) no_missing_key = Validator::validate_missing(@string_file,@master) end if valid_master && valid_file && no_missing_key # Log::info("Yeah! 🍻 🍻 ") return true,@result.to_hash else if valid_master && valid_file && !no_missing_key # Log::warn("Missing keys found.") return true,@result.to_hash else # Log::error("Invalid file.") return false,@result.to_hash end end end def self.validate_format(sf) is_valid = true # puts "apstrings: start validate format for #{file} ..." dup_keys_in_file = Validator::validate_duplicates(sf) mismatchs_in_file = Validator::validate_special_characters(sf) @result.dup_keys = dup_keys_in_file if sf == @master @result.master_special_character_error = @result.master_special_character_error + mismatchs_in_file else @result.file_special_character_errors = @result.file_special_character_errors + mismatchs_in_file end if nil != dup_keys_in_file && !dup_keys_in_file.empty? Log::warn("Dup-keys found in #{sf.raw_file}: \n `#{dup_keys_in_file}`.") else # Log::info("OK . .") end if !mismatchs_in_file.empty? is_valid = false @result.valid_file_format = false mismatchs_in_file.each { |e| e.each_pair { |key,value| Log::error("Mismatch format found in `#{sf.raw_file}`: \n `#{key}` ====> `#{value}`") } } else # Log::info("OK ... \n ") end is_valid end def self.validate_missing(sf,sf_masterFile) # puts "apstrings: checking missing keys for #{file}..." no_missing = true missing_keys = sf_masterFile.keys - sf.keys @result.missing_keys = missing_keys; if !missing_keys.empty? no_missing =false Log::warn("#{missing_keys.count.to_s} missing keys found in #{sf.raw_file} comparing to master file: #{sf_masterFile.raw_file} : \n #{missing_keys.to_s}") else # Log::info("OK...") end no_missing end def self.validate_duplicates(sf) # puts "apstrings: checking dup-keys for #{file}..." sf.keys.detect { |e| sf.keys.count(e) > 1 } end def self.validate_special_characters(sf) # puts "apstrings: checking syntax for #{file}..." variables_regex = /%[hlqLztj]?[@%dDuUxXoOfeEgGcCsSpaAF]/ mismatchs = [] sf.key_values.each { |e| e.each_pair { |key,value| fixed_key = Validator::value_in_master(key) if fixed_key != nil striped_key = fixed_key.gsub(/%\d\$/,'%') # Strip numbered format placeholders , e.g. %1$@ --> %@ striped_value = value.gsub(/%\d\$/,'%') key_variables = striped_key.scan(variables_regex) value_variables = striped_value.scan(variables_regex) if !(key_variables.sort == value_variables.sort) mismatchs << {key => value} end else # key in slavor file but does not exist in master file . Log.warn("There is missing key in master file comparing to slavor. As we only check missing keys in slavor file, just ignore. \n "); end } } mismatchs end def self.paredFile(file) read_file = Reader.read(file) StringsParser.new(read_file,DotStringFile.new(file)).parse_file end def self.value_in_master(key) if @master value_comment = @master.to_hash[key] # if value_comment == nil return key else return value_comment.keys[0] end else key end end end end