diff options
author | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2023-04-18 19:30:39 +0900 |
---|---|---|
committer | git <svn-admin@ruby-lang.org> | 2023-04-19 06:56:23 +0000 |
commit | 40d1a0004041f60301c8090ab8955024ebc35cc2 (patch) | |
tree | 8c5c01f2dd4c041ca2fc0e0c4ec5ccd2a649e590 /lib/rubygems | |
parent | 62e5ba537acbb439366ddfa99992c1151df55a24 (diff) | |
download | ruby-40d1a0004041f60301c8090ab8955024ebc35cc2.tar.gz |
[rubygems/rubygems] Copy YAMLSerializer from Bundler
https://github.com/rubygems/rubygems/commit/6a97346708
Diffstat (limited to 'lib/rubygems')
-rw-r--r-- | lib/rubygems/config_file.rb | 8 | ||||
-rw-r--r-- | lib/rubygems/yaml_serializer.rb | 89 |
2 files changed, 93 insertions, 4 deletions
diff --git a/lib/rubygems/config_file.rb b/lib/rubygems/config_file.rb index a0d263fba7..42e408f254 100644 --- a/lib/rubygems/config_file.rb +++ b/lib/rubygems/config_file.rb @@ -517,14 +517,14 @@ if you believe they were disclosed to a third party. k.is_a?(Symbol) ? ":#{k}" : k end - require "bundler/yaml_serializer" - Bundler::YAMLSerializer.dump(content) + require_relative "yaml_serializer" + Gem::YAMLSerializer.dump(content) end def self.load_with_rubygems_config_hash(yaml) - require "bundler/yaml_serializer" + require_relative "yaml_serializer" - content = Bundler::YAMLSerializer.load(yaml) + content = Gem::YAMLSerializer.load(yaml) content.transform_keys! do |k| if k.match?(/\A:(.*)\Z/) diff --git a/lib/rubygems/yaml_serializer.rb b/lib/rubygems/yaml_serializer.rb new file mode 100644 index 0000000000..a447709c74 --- /dev/null +++ b/lib/rubygems/yaml_serializer.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +module Gem + # 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 + 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 + + 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 + + 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 + key = convert_to_backward_compatible_key(key) + depth = indent.scan(/ /).length + 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 + + # 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 |