class Filex::Filex
ファイル操作用クラス
Public Class Methods
eRubyスクリプトファイルの存在チェック、ハッシュを用いてを置換後に1個の文字列に変換
@param fname [String] eRubyスクリプトファイル @param objx [Hash] eRubyスクリプト置換用ハッシュ @param mes [Messagex] Messagexクラスのインスタンス @return [String] eRubyスクリプトファイルの変換結果
# File lib/filex.rb, line 162 def self.check_and_expand_file(fname, objx, mes) strdata = check_and_load_file(fname, mes) mes.output_info("fname=#{fname}") mes.output_info("strdata=#{strdata}") mes.output_info("objx=#{objx}") strdata2 = expand_str(strdata, objx, mes, fname: fname) strdata2 end
eRubyスクリプトの存在チェック、ハッシュを用いて置換したものを行の配列として得る
@param fname [String] eRubyスクリプト名 @param data [Hash] eRubyスクリプト置換用ハッシュ @param mes [Messagex] Messagexクラスのインスタンス @return [Array<String>] eRubyスクリプトの変換結果
# File lib/filex.rb, line 86 def self.check_and_expand_file_lines(fname, data, mes) check_and_expand_file(fname, data, mes).split("\n") end
YAML形式ファイルの存在チェック、(eRubyスクリプトとしての)YAMLファイルをハッシュを用いて置換した後にRubyのオブジェクトに変換
@param yamlfname [String] yamlファイル名(eRubyスクリプトでもある) @param objx [Hash] eRubyスクリプト置換用ハッシュ @param mes [Messagex] Messagexクラスのインスタンス @return [Hash] YAMLの変換結果
# File lib/filex.rb, line 71 def self.check_and_expand_yamlfile(yamlfname, objx, mes) lines = Filex.check_and_expand_file_lines(yamlfname, objx, mes) str = escape_by_single_quote_with_lines_in_yamlformat(lines, mes).join("\n") mes.output_debug("=str") mes.output_debug(str) load_yaml(str, mes) end
テキストファイルの存在チェック、ファイルの内容を1個の文字列に変換
@param fname [String] ファイル名 @param mes [Messagex] Messagexクラスのインスタンス @return [String] ファイルの内容
# File lib/filex.rb, line 96 def self.check_and_load_file(fname, mes) size = File.size?(fname) if size && (size > 0) begin strdata = File.read(fname) rescue IOError => e mesg = "Can't read #{fname}" mes.output_fatal(mesg) mes.output_exception(e) exit(mes.ec("EXIT_CODE_CANNOT_READ_FILE")) rescue SystemCallError => e mesg = "Can't write #{fname}" mes.output_fatal(mesg) mes.output_exception(e) exit(mes.ec("EXIT_CODE_CANNOT_READ_FILE")) end else mesg = %Q(Can not find #{fname} or is empty| size=|#{size}|) mes.output_error(mesg) exit(mes.ec("EXIT_CODE_CANNOT_FIND_FILE_OR_EMPTY")) end if strdata.strip.empty? mesg = %Q(#{fname} is empty) mes.output_fatal(mesg) exit(mes.ec("EXIT_CODE_FILE_IS_EMPTY")) else digest = Digest::MD5.hexdigest(strdata) mes.output_info(digest) end strdata end
YAML形式ファイルをRubyのオブジェクトに変換
@param yamlfname [String] yamlファイル名 @param mes [Messagex] Messagexクラスのインスタンス @return [Hash] YAMLの変換結果
# File lib/filex.rb, line 59 def self.check_and_load_yamlfile(yamlfname, mes) str = Filex.check_and_load_file(yamlfname, mes) load_yaml(str, mes) end
YAML形式の文字列に、シングルクォーテーションでのエスケープが必要かを調べる(第2段階)
@param right [String] 対象文字列の分割右側部分 @param state [Hash] 状態 @option state [Messagex] :mes Messagexクラスのインスタンス @option state [Booleand] :has_quoto true: 対象文字列がエスケープされている false: 対象文字列はエスケープされていない @return [Array<String>] 第0要素 分割文字列の左側部分、第1要素 分割文字列の右側部分
# File lib/filex.rb, line 278 def self.check_colon_in_right(right, state) left3, right3 = colon_not_space(right) state[:mes].output_info("52|left3=#{left3}|right3=#{right3}") state[:need_quoto] = true return [nil, nil] if left3 left2, right2 = colon(right) state[:mes].output_info("53|left2=#{left2}|right2=#{right2}") state[:need_quoto] = true [left2, right2] end
最初に現れる「:」を区切り文字として、文字列を2つに分割する
@param str [String] 分割対象文字列 @return [Array<String>] 第0要素 分割文字列の左側部分、第1要素 分割文字列の右側部分
# File lib/filex.rb, line 204 def self.colon(str) if (m = /^(\s*([^\s]+):)(.*)$/.match(str)) left = m[1] right = m[3] end [left, right] end
最初に現れる「:」と空白文字以外の文字の組み合わせを区切り文字列として、文字列を2つに分割する
@param str [String] 分割対象文字列 @return [Array<String>] 第0要素 分割文字列の左側部分、第1要素 分割文字列の右側部分
# File lib/filex.rb, line 190 def self.colon_not_space(str) if (m = /^(\s*([^\s]+):[^\s])(.*)$/.match(str)) left = m[1] right = m[3] end [left, right] end
最初に現れる「:」と空白文字の組み合わせを区切り文字列として、文字列を2つに分割する
@param str [String] 分割対象文字列 @return [Array<String>] 第0要素 分割文字列の左側部分、第1要素 分割文字列の右側部分
# File lib/filex.rb, line 176 def self.colon_space(str) if (m = /^(\s*([^\s]+):\s)(.*)$/.match(str)) left = m[1] right = m[3] end [left, right] end
YAML形式の文字列の配列に(必要であれば)シングルクォーテーションでのエスケープを追加
@param lines [Array<String>] 対象行の配列 @param mes [Messagex] :mes Messagexクラスのインスタンス @return [Array<String>] 必要なエスケープがされた対象文字列
# File lib/filex.rb, line 362 def self.escape_by_single_quote_with_lines_in_yamlformat(lines, mes) state = { mes: mes } lines.map do |line| state[:need_quoto] = false state[:has_quoto] = false left, right = escape_single_quote_yaml_first(line, state) left, right = escape_single_quote_yaml_second(line, state, left, right) if left escape_single_quote_yaml_third(line, state, left, right) end if state[:need_quoto] && !state[:has_quoto] state[:mes].output_info("2 need_quoto") left + %q(') + right + %q(') else line end end end
YAML形式の文字列に、シングルクォーテーションでのエスケープが必要かを調べる(第1段階)
@param line [String] 対象文字列 @param state [Hash] 状態 @return [Array<String>] 第0要素 分割文字列の左側部分、第1要素 分割文字列の右側部分
# File lib/filex.rb, line 233 def self.escape_single_quote_yaml_first(line, state) # lineに対して": "での分割を試みる left, right = colon_space(line) state[:mes].output_info("F1|left=#{left}|right=#{right}") # 分割できなければ、lineに対して":"での分割を試みる left, right = colon(line) unless left state[:mes].output_info("F2|left=#{left}|right=#{right}") # 右側部分に"-"が含まれていれば、"- "で区切れるか調べる if right&.index("-") left, right = hyphen_space(line) state[:mes].output_info("F3|left=#{left}") if left state[:need_quoto] = true state[:mes].output_info("NQ|1|need_quoto=#{state[:need_quoto]}") end end # lineが":"が分割できなければ、lineに対して"- "での分割を試みる unless left left, right = hyphen_space(line) state[:mes].output_info("F4|left=#{left}|right=#{right}") if right&.index("-") == 0 state[:mes].output_info("F-X|index=0|right.size=#{right.size}") if right.size == 1 left += right right = nil else state[:need_quoto] = true end end end state[:mes].output_info("FE|left=#{left}|right=#{right}") [left, right] end
YAML形式の文字列に、シングルクォーテーションでのエスケープが必要かを調べる(第2段階)
@param line [String] 対象文字列 @param state [Hash] 状態 @option state [Messagex] :mes Messagexクラスのインスタンス @option state [Booleand] :has_quoto true: 対象文字列がエスケープされている false: 対象文字列はエスケープされていない @param left [String] 対象文字列の分割左側部分 @param right [String] 対象文字列の分割右側部分 @return [Array<String>] 第0要素 分割された文字列の左側部分、第1要素 分割された文字列の右側部分
# File lib/filex.rb, line 300 def self.escape_single_quote_yaml_second(line, state, left, right) return [left, right] if right.nil? || right.strip.empty? state[:mes].output_info("S1|left=#{left}|right=#{right}") state[:has_quoto] = true if right.index("'") if right.index(":") state[:mes].output_info("S2|left=#{left}|right=#{right}") return([left, right]) if /\d:/.match?(right) state[:mes].output_info("S3|left=#{left}|right=#{right}") end left2, right2 = colon_space(right) state[:mes].output_info("S4|left2=#{left2}|right2=#{right2}") unless left2 left2, right2 = check_colon_in_right(right, state) end if left2 left += left2 right = right2 state[:mes].output_info("S5|left=#{left}|right=#{right}") end state[:mes].output_info("S6|left=#{left}|right=#{right}") [left, right] end
YAML形式の文字列に、シングルクォーテーションでのエスケープが必要かを調べる(第3段階)
@param line [String] 対象文字列 @param state [Hash] 状態 @option state [Messagex] :mes Messagexクラスのインスタンス @option state [Booleand] :has_quoto true: 対象文字列がエスケープされている false: 対象文字列はエスケープされていない @param left [String] 対象文字列の分割左側部分 @param right [String] 対象文字列の分割右側部分 @return [void]
# File lib/filex.rb, line 338 def self.escape_single_quote_yaml_third(line, state, left, right) return if right.nil? || right.strip.empty? state[:mes].output_info("T1|left=#{left}|right=#{right}") return if state[:need_quoto] state[:mes].output_info("T2|left=#{left}|right=#{right}") return unless (right.index(":") || right.index("*")) state[:mes].output_info("T3|left=#{left}|right=#{right}") state[:mes].output_info("T4 not need_quoto") unless right.index("-") state[:need_quoto] = true state[:mes].output_info("NQ|T5|need_quoto=#{state[:need_quoto]}") end state[:mes].output_info("T6 need_quoto=#{state[:need_quoto]}") end
eRubyスクリプト文字列を、ハッシュを用いて置換した内容を、1個の文字列に変換
@param eruby_str [String] eRubyスクリプト文字列 @param data [Hash] eRubyスクリプト置換用ハッシュ @param mes [Messagex] Messagexクラスのインスタンス @param fnames [Hash] 入力ファイル名群 @return [String] eRubyスクリプトの変換結果
# File lib/filex.rb, line 138 def self.expand_str(eruby_str, data, mes, fnames={}) begin mes.output_info("eruby_str=|#{eruby_str}|") mes.output_info("data=#{data}") strdata = Erubis::Eruby.new(eruby_str).result(data) rescue NameError => e mes.output_exception(e) fnames.map {|x| mes.output_fatal(%Q(#{x[0]}=#{x[1]})) } exit(mes.ec("EXIT_CODE_NAME_ERROR_EXCEPTION_IN_ERUBY")) rescue Error => e mes.output_exception(e) fnames.map {|x| mes.output_fatal(%Q(#{x[0]}=#{x[1]})) } exit(mes.ec("EXIT_CODE_ERROR_EXCEPTION_IN_ERUBY")) end strdata end
最初に現れる「-」と空白文字の組み合わせを区切り文字列として、文字列を2つに分割する
@param str [String] 分割対象文字列 @return [Array<String>] 第0要素 分割文字列の左側部分、第1要素 分割文字列の右側部分
# File lib/filex.rb, line 218 def self.hyphen_space(str) if (m = /^(\s*((\-\s+)+))(.*)$/.match(str)) left = m[1] right = m[4] end [left, right] end
YAML形式文字列をRubyのオブジェクトに変換 @param str [String] YAML形式の文字列 @param mes [Messagex] Messagexクラスのインスタンス @return [Hash] YAMLの変換結果
# File lib/filex.rb, line 40 def self.load_yaml(str, mes) yamlhs = {} begin yamlhs = YAML.safe_load(str, [Date, Symbol]) rescue Error => e mes.output_exception(e) mes.output_fatal("str=#{str}") exit(mes.ec("EXIT_CODE_CANNOT_ANALYZE_YAMLFILE")) end yamlhs end
Filexクラスで利用する終了ステータスの登録
@param mes [Messagex] Messagexクラスのインスタンス @return [void]
# File lib/filex.rb, line 28 def self.setup(mes) mes.add_exitcode("EXIT_CODE_CANNOT_ANALYZE_YAMLFILE") mes.add_exitcode("EXIT_CODE_NAME_ERROR_EXCEPTION_IN_ERUBY") mes.add_exitcode("EXIT_CODE_ERROR_EXCEPTION_IN_ERUBY") mes.add_exitcode("EXIT_CODE_FILE_IS_EMPTY") end