<commit_before>require "set"
module Capistrano
  class Configuration
    class Server < SSHKit::Host
      extend Forwardable
      def_delegators :properties, :roles, :fetch, :set

      def self.[](host)
        host.is_a?(Server) ? host : new(host)
      end

      def add_roles(roles)
        Array(roles).each { |role| add_role(role) }
        self
      end
      alias roles= add_roles

      def add_role(role)
        roles.add role.to_sym
        self
      end

      def has_role?(role)
        roles.include? role.to_sym
      end

      def select?(options)
        options.each do |k, v|
          callable = v.respond_to?(:call) ? v : ->(server) { server.fetch(v) }
          result = \
            case k
            when :filter, :select
              callable.call(self)
            when :exclude
              !callable.call(self)
            else
              fetch(k) == v
            end
          return false unless result
        end

        true
      end

      def primary
        self if fetch(:primary)
      end

      def with(properties)
        properties.each { |key, value| add_property(key, value) }
        self
      end

      def properties
        @properties ||= Properties.new
      end

      def netssh_options
        @netssh_options ||= super.merge(fetch(:ssh_options) || {})
      end

      def roles_array
        roles.to_a
      end

      def matches?(other)
        hostname == other.hostname && port == other.port
      end

      private

      def add_property(key, value)
        if respond_to?("#{key}=")
          send("#{key}=", value)
        else
          set(key, value)
        end
      end

      class Properties
        def initialize
          @properties = {}
        end

        def set(key, value)
          pval = @properties[key]
          if pval.is_a?(Hash) && value.is_a?(Hash)
            pval.merge!(value)
          elsif pval.is_a?(Set) && value.is_a?(Set)
            pval.merge(value)
          elsif pval.is_a?(Array) && value.is_a?(Array)
            pval.concat value
          else
            @properties[key] = value
          end
        end

        def fetch(key)
          @properties[key]
        end

        def respond_to?(method, _include_all=false)
          @properties.key?(method)
        end

        def roles
          @roles ||= Set.new
        end

        def keys
          @properties.keys
        end

        def method_missing(key, value=nil)
          if value
            set(lvalue(key), value)
          else
            fetch(key)
          end
        end

        def to_h
          @properties
        end

        private<commit_msg>Define respond_to_missing? instead of respond_to?<commit_after>require "set"
module Capistrano
  class Configuration
    class Server < SSHKit::Host
      extend Forwardable
      def_delegators :properties, :roles, :fetch, :set

      def self.[](host)
        host.is_a?(Server) ? host : new(host)
      end

      def add_roles(roles)
        Array(roles).each { |role| add_role(role) }
        self
      end
      alias roles= add_roles

      def add_role(role)
        roles.add role.to_sym
        self
      end

      def has_role?(role)
        roles.include? role.to_sym
      end

      def select?(options)
        options.each do |k, v|
          callable = v.respond_to?(:call) ? v : ->(server) { server.fetch(v) }
          result = \
            case k
            when :filter, :select
              callable.call(self)
            when :exclude
              !callable.call(self)
            else
              fetch(k) == v
            end
          return false unless result
        end

        true
      end

      def primary
        self if fetch(:primary)
      end

      def with(properties)
        properties.each { |key, value| add_property(key, value) }
        self
      end

      def properties
        @properties ||= Properties.new
      end

      def netssh_options
        @netssh_options ||= super.merge(fetch(:ssh_options) || {})
      end

      def roles_array
        roles.to_a
      end

      def matches?(other)
        hostname == other.hostname && port == other.port
      end

      private

      def add_property(key, value)
        if respond_to?("#{key}=")
          send("#{key}=", value)
        else
          set(key, value)
        end
      end

      class Properties
        def initialize
          @properties = {}
        end

        def set(key, value)
          pval = @properties[key]
          if pval.is_a?(Hash) && value.is_a?(Hash)
            pval.merge!(value)
          elsif pval.is_a?(Set) && value.is_a?(Set)
            pval.merge(value)
          elsif pval.is_a?(Array) && value.is_a?(Array)
            pval.concat value
          else
            @properties[key] = value
          end
        end

        def fetch(key)
          @properties[key]
        end

        def respond_to_missing?(method, _include_all=false)
          @properties.key?(method) || super
        end

        def roles
          @roles ||= Set.new
        end

        def keys
          @properties.keys
        end

        def method_missing(key, value=nil)
          if value
            set(lvalue(key), value)
          else
            fetch(key)
          end
        end

        def to_h
          @properties
        end

        private
{'fraction_non_alphanumeric': 0.09258226436140547, 'fraction_numerical': 0.0, 'mean_word_length': 1.4093148231079267, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5435457', 'n_tokens_mistral': 1594, 'n_tokens_neox': 1570, 'n_words': 378}