<commit_before>class Build < ActiveRecord::Base
  belongs_to :project, :inverse_of => :builds
  has_one :repository, :through => :project
  has_many :build_parts, :dependent => :destroy, :inverse_of => :build_instance do
    def last_attempt_in_state(*state)
      joins(:build_attempts).joins("LEFT JOIN build_attempts AS r ON build_attempts.build_part_id = r.build_part_id AND build_attempts.id < r.id").where("build_attempts.state" => state, "r.build_part_id" => nil)
    end
    def passed
      last_attempt_in_state(:passed)
    end
    def failed
      last_attempt_in_state(:failed)
    end
    def failed_or_errored
      last_attempt_in_state(:failed, :errored)
    end
    def errored
      last_attempt_in_state(:errored)
    end
  end
  has_many :build_attempts, :through => :build_parts
  TERMINAL_STATES = [:failed, :succeeded, :errored, :aborted]
  FAILED_STATES = [:failed, :errored, :doomed]
  IN_PROGRESS_STATES = [:partitioning, :runnable, :running, :doomed]
  STATES = IN_PROGRESS_STATES + TERMINAL_STATES
  symbolize :state, :in => STATES
  symbolize :queue
  validates_presence_of :queue
  validates_presence_of :project_id
  validates_presence_of :ref
  validates_uniqueness_of :ref, :scope => :project_id
  mount_uploader :on_success_script_log_file, OnSuccessUploader
<commit_msg>a build still passes if a part has an old attempt that passed but the newest attempt failed<commit_after>class Build < ActiveRecord::Base
  belongs_to :project, :inverse_of => :builds
  has_one :repository, :through => :project
  has_many :build_parts, :dependent => :destroy, :inverse_of => :build_instance do
    def not_passed_and_last_attempt_in_state(*state)
      joins(:build_attempts).joins(<<-EOSQL).where("build_attempts.state" => state, "passed_attempt.id" => nil, "newer_attempt.id" => nil)
        LEFT JOIN build_attempts
          AS passed_attempt
          ON build_attempts.build_part_id = passed_attempt.build_part_id
            AND passed_attempt.state = 'passed'
        LEFT JOIN build_attempts
          AS newer_attempt
          ON build_attempts.build_part_id = newer_attempt.build_part_id
            AND newer_attempt.id > build_attempts.id
      EOSQL
    end
    def passed
      joins(:build_attempts).where("build_attempts.state" => :passed).group("build_parts.id")
    end
    def failed
      not_passed_and_last_attempt_in_state(:failed)
    end
    def failed_or_errored
      not_passed_and_last_attempt_in_state(:failed, :errored)
    end
    def errored
      not_passed_and_last_attempt_in_state(:errored)
    end
  end
  has_many :build_attempts, :through => :build_parts
  TERMINAL_STATES = [:failed, :succeeded, :errored, :aborted]
  FAILED_STATES = [:failed, :errored, :doomed]
  IN_PROGRESS_STATES = [:partitioning, :runnable, :running, :doomed]
  STATES = IN_PROGRESS_STATES + TERMINAL_STATES
  symbolize :state, :in => STATES
  symbolize :queue
  validates_presence_of :queue
  validates_presence_of :project_id
  validates_presence_of :ref
  validates_uniqueness_of :ref, :scope => :project_id
  mount_uploader :on_success_script_log_file, OnSuccessUploader

{'fraction_non_alphanumeric': 0.09090909090909091, 'fraction_numerical': 0.0, 'mean_word_length': 4.43455497382199, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 24, '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': '6916530', 'n_tokens_mistral': 1129, 'n_tokens_neox': 1056, 'n_words': 219}