Module: Bundler::YAMLSerializer

Defined in:
lib/bundler/yaml_serializer.rb

Overview

A stub yaml serializer that can handle only hashes and strings (as of now).

Constant Summary collapse

ARRAY_REGEX =
/
  ^
  (?:[ ]*-[ ]) # '- ' before array items
  (['"]?) # optional opening quote
  (.*) # value
  \1 # matching closing quote
  $
/xo.freeze
HASH_REGEX =
/
  ^
  ([ ]*) # indentations
  (.+) # key
  (?::(?=(?:\s|$))) # :  (without the lookahead the #key includes this when : is present in value)
  [ ]?
  (['"]?) # optional opening quote
  (.*) # value
  \3 # matching closing quote
  $
/xo.freeze

Class Method Summary collapse

Class Method Details

.convert_to_backward_compatible_key!(key) ⇒ Object

for settings’ keys



79
80
81
82
# File 'lib/bundler/yaml_serializer.rb', line 79

def convert_to_backward_compatible_key!(key)
  key << "/" if /https?:/i.match?(key) && !%r{/\Z}.match?(key)
  key.gsub!(".", "__")
end

.dump(hash) ⇒ Object



8
9
10
11
# File 'lib/bundler/yaml_serializer.rb', line 8

def dump(hash)
  yaml = String.new("---")
  yaml << dump_hash(hash)
end

.dump_hash(hash) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/bundler/yaml_serializer.rb', line 13

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
    elsif v.is_a?(Array) # Expected to be array of strings
      yaml << "\n- " << v.map {|s| s.to_s.gsub(/\s+/, " ").inspect }.join("\n- ") << "\n"
    else
      yaml << " " << v.to_s.gsub(/\s+/, " ").inspect << "\n"
    end
  end
  yaml
end

.load(str) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/bundler/yaml_serializer.rb', line 49

def load(str)
  res = {}
  stack = [res]
  last_hash = nil
  last_empty_key = nil
  str.split(/\r?\n/).each do |line|
    if match = HASH_REGEX.match(line)
      indent, key, quote, val = match.captures
      convert_to_backward_compatible_key!(key)
      depth = indent.size / 2
      if quote.empty? && val.empty?
        new_hash = {}
        stack[depth][key] = new_hash
        stack[depth + 1] = new_hash
        last_empty_key = key
        last_hash = stack[depth]
      else
        stack[depth][key] = val
      end
    elsif match = ARRAY_REGEX.match(line)
      _, val = match.captures
      last_hash[last_empty_key] = [] unless last_hash[last_empty_key].is_a?(Array)

      last_hash[last_empty_key].push(val)
    end
  end
  res
end