require "yaml" module HerokuAppInfo class Parser # # simple app list # # @param [String] apps # @return [Array] # def apps(apps) apps.lines(chomp: true).grep_v(/\A===/).map { |e| /\A([^ ]+)/ =~ e $1 }.compact end # # @param [String] text # @return [Hash] # def parse(text) info = {} last_item = nil title = nil text.lines(chomp: true).each { |line| next if line.size < 1 data = parse_line(line.rstrip) case data[:item] when :continuation info[last_item] << data[:content] when :title title = data[:content] else multi_item = app_multi_items.select { |item, type| item == data[:item] } if multi_item.size > 0 case multi_item.values.first.to_s when "Array" info[data[:item]] = [data[:content]] when "Hash" info[data[:item]] = parse_hash_item(data[:content]) end else info[data[:item]] = data[:content] end end last_item = data[:item] unless data[:item] == :continuation } info end # # @param [String] line # @return [Hash] # def parse_line(line) case line # title line when /\A=== (.+)\z/ { item: :title, content: $1 } # data line when /\A(?:([A-Z][^:]+):)?(?: +(.+))?\z/ if !$1 && $2 # continuation { item: :continuation, content: $2 } else # normal { item: $1, content: $2 } end end end # # @param [String, nil] item # @return [Hash] # def parse_hash_item(item) if item.nil? {} else YAML.safe_load(item.split(",").map(&:strip).join("\n")) end end # # @return [Hash] # def app_multi_items { "Addons" => Array, "Collaborators" => Array, "Dynos" => Hash } end end end