<commit_before>require 'net/ssh'
require 'net/sftp'

class Ssh
  class ResultProxy < Array
    def initialize(results)
      push *results
      first.respond_to?(:successful?) || map! { |c| Result.new(c.properties) }
    end

    def successful?
      all? { |r| r.successful? }
    end

    def failures
      reject { |r| r.successful? }
    end
  end

  class Result
    attr_reader :host, :exit_code

    def initialize(properties)
      @host      = properties[:host]
      @exit_code = properties[:exit_status]
    end

    def successful?
      exit_code == 0
    end
  end

  # leaving this untested, because testing it was just a big
  # jumble of mocks that were going to be super brittle
  #
  class Upload < Thread
    attr_reader :sftp, :failure, :error_message, :host

    def initialize(session, path, data)
      super do
        begin
          @sftp = Net::SFTP::Session.new(session.session || session.session(true))
          @host = [session.user, session.host].join("@")
          sftp.connect!
          sftp.file.open(path, "w") { |f| f.puts data }
        rescue Net::SFTP::StatusException => e
          @failure       = true
          @error_message = e.description
        ensure
          sftp.close_channel
        end
      end
    end

    def successful?
      !failure
    end
  end

  attr_reader :ssh, :hosts, :servers

  def initialize(*hosts)
    @ssh     = Net::SSH::Multi.start
    @hosts   = hosts<commit_msg>only close channel if ssh isn't nil<commit_after>require 'net/ssh'
require 'net/sftp'

class Ssh
  class ResultProxy < Array
    def initialize(results)
      push *results
      first.respond_to?(:successful?) || map! { |c| Result.new(c.properties) }
    end

    def successful?
      all? { |r| r.successful? }
    end

    def failures
      reject { |r| r.successful? }
    end
  end

  class Result
    attr_reader :host, :exit_code

    def initialize(properties)
      @host      = properties[:host]
      @exit_code = properties[:exit_status]
    end

    def successful?
      exit_code == 0
    end
  end

  # leaving this untested, because testing it was just a big
  # jumble of mocks that were going to be super brittle
  #
  class Upload < Thread
    attr_reader :sftp, :failure, :error_message, :host

    def initialize(session, path, data)
      super do
        begin
          @sftp = Net::SFTP::Session.new(session.session || session.session(true))
          @host = [session.user, session.host].join("@")
          sftp.connect!
          sftp.file.open(path, "w") { |f| f.puts data }
        rescue Net::SFTP::StatusException => e
          @failure       = true
          @error_message = e.description
        ensure
          sftp && sftp.close_channel
        end
      end
    end

    def successful?
      !failure
    end
  end

  attr_reader :ssh, :hosts, :servers

  def initialize(*hosts)
    @ssh     = Net::SSH::Multi.start
    @hosts   = hosts
{'fraction_non_alphanumeric': 0.10409556313993173, 'fraction_numerical': 0.0006825938566552901, 'mean_word_length': 2.217343578485181, 'pattern_counts': {'":': 0, '<': 7, '<?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': '1600616', 'n_tokens_mistral': 946, 'n_tokens_neox': 910, 'n_words': 252}