diff options
Diffstat (limited to 'lib/bundler/yaml_serializer.rb')
-rw-r--r-- | lib/bundler/yaml_serializer.rb | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/lib/bundler/yaml_serializer.rb b/lib/bundler/yaml_serializer.rb new file mode 100644 index 0000000000..327baa4ee7 --- /dev/null +++ b/lib/bundler/yaml_serializer.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +module Bundler + # A stub yaml serializer that can handle only hashes and strings (as of now). + module YAMLSerializer + module_function + + def dump(hash) + yaml = String.new("---") + yaml << dump_hash(hash) + end + + def dump_hash(hash) + yaml = String.new("\n") + hash.each do |k, v| + yaml << k << ":" + if v.is_a?(Hash) + yaml << dump_hash(v).gsub(/^(?!$)/, " ") # indent all non-empty lines + else + yaml << " " << v.to_s.gsub(/\s+/, " ").inspect << "\n" + end + end + yaml + end + + SCAN_REGEX = / + ^ + ([ ]*) # indentations + (.*) # key + (?::(?=\s)) # : (without the lookahead the #key includes this when : is present in value) + [ ]? + (?: !\s)? # optional exclamation mark found with ruby 1.9.3 + (['"]?) # optional opening quote + (.*) # value + \3 # matching closing quote + $ + /xo + + def load(str) + res = {} + stack = [res] + str.scan(SCAN_REGEX).each do |(indent, key, _, val)| + key = convert_to_backward_compatible_key(key) + depth = indent.scan(/ /).length + if val.empty? + new_hash = {} + stack[depth][key] = new_hash + stack[depth + 1] = new_hash + else + stack[depth][key] = val + end + end + res + end + + # for settings' keys + def convert_to_backward_compatible_key(key) + key = "#{key}/" if key =~ /https?:/i && key !~ %r{/\Z} + key = key.gsub(".", "__") if key.include?(".") + key + end + + class << self + private :dump_hash, :convert_to_backward_compatible_key + end + end +end |