class Gem::YAMLSerializer::Builder - Documentation for Ruby 4.1
Description: Documentation for the Gem::YAMLSerializer::Builder class
Keywords: ruby,class,Gem::YAMLSerializer::Builder

🔍

No recent searches

# class Gem::YAMLSerializer::Builder

### Constants

ARRAY_FIELDS
MAX_ALIAS_RESOLUTIONS
PLATFORM_ALLOWED_IVARS
PLATFORM_FIELDS
VALID_OPS

### Public Class Methods

new (permitted_classes: [], permitted_symbols: [], aliases: true)
Source

    # File lib/rubygems/yaml_serializer.rb, line 425
    def initialize(permitted_classes: [], permitted_symbols: [], aliases: true)
      @permitted_classes = permitted_classes.map {|c| "!ruby/object:#{c}" }
      @permitted_symbols = permitted_symbols
      @aliases = aliases
      @anchor_values = {}
      @alias_count = 0
    end

### Public Instance Methods

build (node)
Source

    # File lib/rubygems/yaml_serializer.rb, line 433
    def build(node)
      return nil if node.nil?

      result = build_node(node)

      if result.is_a?(Hash) &&
         (result[:tag] == "!ruby/object:Gem::Specification" ||
          result["tag"] == "!ruby/object:Gem::Specification")
        build_specification(result)
      else
        result
      end
    end

### Private Instance Methods

build_dependency (node)
Source

    # File lib/rubygems/yaml_serializer.rb, line 569
    def build_dependency(node)
      hash = pairs_to_hash(node)
      d = Gem::Dependency.allocate
      d.instance_variable_set(:@name, hash["name"])

      d.instance_variable_set(:@requirement, hash["requirement"] || hash["version_requirements"])

      type = hash["type"]
      type = type ? type.to_s.sub(/^:/, "").to_sym : :runtime
      validate_symbol!(type)
      d.instance_variable_set(:@type, type)

      d.instance_variable_set(:@prerelease, ["true", true].include?(hash["prerelease"]))
      d.instance_variable_set(:@version_requirements, d.instance_variable_get(:@requirement))
      d
    end

build_hash (node)
Source

    # File lib/rubygems/yaml_serializer.rb, line 500
    def build_hash(node)
      result = {}
      node.pairs.each do |key_node, value_node|
        key = key_node.is_a?(Scalar) ? key_node.value.to_s : build_node(key_node).to_s
        value = build_node(value_node)

        if ARRAY_FIELDS.include?(key)
          value = normalize_array_field(value)
        end

        result[key] = value
      end
      result
    end

build_mapping (node)
Source

    # File lib/rubygems/yaml_serializer.rb, line 474
    def build_mapping(node)
      check_anchor!(node)
      validate_tag!(node.tag) if node.tag

      result = case node.tag
               when "!ruby/object:Gem::Version"
                 build_version(node)
               when "!ruby/object:Gem::Platform"
                 build_platform(node)
               when "!ruby/object:Gem::Requirement", "!ruby/object:Gem::Version::Requirement"
                 build_requirement(node)
               when "!ruby/object:Gem::Dependency"
                 build_dependency(node)
               when nil
                 build_hash(node)
               when "!ruby/object:Gem::Specification"
                 hash = build_hash(node)
                 hash[:tag] = node.tag
                 hash
               else
                 raise ArgumentError, "undefined class/module #{node.tag.sub("!ruby/object:", "")}"
      end

      store_anchor(node.anchor, result)
    end

build_node (node)
Source

    # File lib/rubygems/yaml_serializer.rb, line 449
    def build_node(node)
      case node
      when nil then nil
      when AliasRef then resolve_alias(node)
      when Scalar then store_anchor(node.anchor, node.value)
      when Mapping then build_mapping(node)
      when Sequence then store_anchor(node.anchor, node.items.map {|item| build_node(item) })
      else node # already a Ruby object
      end
    end

build_platform (node)
Source

    # File lib/rubygems/yaml_serializer.rb, line 523
    def build_platform(node)
      hash = pairs_to_hash(node)
      if (hash.keys & PLATFORM_FIELDS).any?
        Gem::Platform.new([hash["cpu"], hash["os"], hash["version"]])
      elsif hash["value"].is_a?(Array)
        # Malformed platform (e.g. sequence instead of mapping).
        # Return the raw value so yaml_initialize handles it like Psych does.
        hash["value"]
      else
        plat = Gem::Platform.allocate
        hash.each do |k, v|
          plat.instance_variable_set(:"@#{k}", v) if PLATFORM_ALLOWED_IVARS.include?(k)
        end
        plat
      end
    end

build_requirement (node)
Source

    # File lib/rubygems/yaml_serializer.rb, line 540
    def build_requirement(node)
      r = Gem::Requirement.allocate
      hash = pairs_to_hash(node)
      reqs = hash["requirements"] || hash["value"]

      if reqs.is_a?(Array) && !reqs.empty?
        safe_reqs = []
        reqs.each do |item|
          if item.is_a?(Array) && item.size == 2
            op = item[0].to_s
            ver = item[1]
            if VALID_OPS.include?(op)
              version_obj = ver.is_a?(Gem::Version) ? ver : Gem::Version.new(ver.to_s)
              safe_reqs << [op, version_obj]
            end
          elsif item.is_a?(String)
            parsed = Gem::Requirement.parse(item)
            safe_reqs << parsed
          end
        rescue Gem::Requirement::BadRequirementError, Gem::Version::BadVersionError
          # Skip malformed items silently
        end
        reqs = safe_reqs unless safe_reqs.empty?
      end

      r.instance_variable_set(:@requirements, reqs)
      r
    end

build_specification (hash)
Source

    # File lib/rubygems/yaml_serializer.rb, line 586
    def build_specification(hash)
      spec = Gem::Specification.allocate

      normalize_specification_version!(hash)
      normalize_array_fields!(hash)

      spec.yaml_initialize("!ruby/object:Gem::Specification", hash)
      spec
    end

build_version (node)
Source

    # File lib/rubygems/yaml_serializer.rb, line 515
    def build_version(node)
      hash = pairs_to_hash(node)
      Gem::Version.new((hash["version"] || hash["value"]).to_s)
    end

check_anchor! (node)
Source

    # File lib/rubygems/yaml_serializer.rb, line 628
    def check_anchor!(node)
      if node.anchor
        raise Psych::AliasesNotEnabled unless @aliases
      end
    end

normalize_array_field (value)
Source

    # File lib/rubygems/yaml_serializer.rb, line 646
    def normalize_array_field(value)
      if value.is_a?(Hash)
        value.values.flatten.compact
      elsif !value.is_a?(Array) && value
        [value].flatten.compact
      else
        value
      end
    end

normalize_array_fields! (hash)
Source

    # File lib/rubygems/yaml_serializer.rb, line 640
    def normalize_array_fields!(hash)
      ARRAY_FIELDS.each do |field|
        hash[field] = normalize_array_field(hash[field]) if hash[field]
      end
    end

normalize_specification_version! (hash)
Source

    # File lib/rubygems/yaml_serializer.rb, line 634
    def normalize_specification_version!(hash)
      val = hash["specification_version"]
      return unless val && !val.is_a?(Integer)
      hash["specification_version"] = val.to_i if val.is_a?(String) && /\A\d+\z/.match?(val)
    end

pairs_to_hash (node)
Source

    # File lib/rubygems/yaml_serializer.rb, line 596
    def pairs_to_hash(node)
      result = {}
      node.pairs.each do |key_node, value_node|
        key = key_node.is_a?(Scalar) ? key_node.value.to_s : build_node(key_node).to_s
        result[key] = build_node(value_node)
      end
      result
    end

raise_disallowed_class! (tag)
Source

    # File lib/rubygems/yaml_serializer.rb, line 610
    def raise_disallowed_class!(tag)
      if defined?(Psych::VERSION)
        raise Psych::DisallowedClass.new("load", tag)
      else
        raise Psych::DisallowedClass, "Tried to load unspecified class: #{tag}"
      end
    end

resolve_alias (node)
Source

    # File lib/rubygems/yaml_serializer.rb, line 460
    def resolve_alias(node)
      raise Psych::AliasesNotEnabled unless @aliases
      @alias_count += 1
      if @alias_count > MAX_ALIAS_RESOLUTIONS
        raise Psych::BadAlias, "exceeded maximum alias resolutions (#{MAX_ALIAS_RESOLUTIONS})"
      end
      @anchor_values.fetch(node.name, nil)
    end

store_anchor (name, value)
Source

    # File lib/rubygems/yaml_serializer.rb, line 469
    def store_anchor(name, value)
      @anchor_values[name] = value if name
      value
    end

validate_symbol! (sym)
Source

    # File lib/rubygems/yaml_serializer.rb, line 618
    def validate_symbol!(sym)
      if @permitted_symbols.any? && !@permitted_symbols.include?(sym.to_s)
        if defined?(Psych::VERSION)
          raise Psych::DisallowedClass.new("load", sym.inspect)
        else
          raise Psych::DisallowedClass, "Tried to load unspecified class: #{sym.inspect}"
        end
      end
    end

validate_tag! (tag)
Source

    # File lib/rubygems/yaml_serializer.rb, line 605
    def validate_tag!(tag)
      return if @permitted_classes.include?(tag)
      raise_disallowed_class!(tag)
    end