<commit_before>module Bump
  class InvalidOptionError < StandardError; end
  class UnfoundVersionError < StandardError; end
  class TooManyVersionFilesError < StandardError; end
  class UnfoundVersionFileError < StandardError; end

  class Bump
    BUMPS         = %w(major minor patch pre)
    PRERELEASE    = ["alpha","beta","rc",nil]
    OPTIONS       = BUMPS | ["current"]
    VERSION_REGEX = /(\d+\.\d+\.\d+(?:-(?:#{PRERELEASE.compact.join('|')}))?)/

    def self.defaults
      {
        :commit => true,
        :bundle => File.exist?("Gemfile")
      }
    end

    def self.run(bump, options={})
      options = defaults.merge(options)

      case bump
      when *BUMPS
        bump(bump, options)
      when "current"
        ["Current version: #{current}", 0]
      else
        raise InvalidOptionError
      end
    rescue InvalidOptionError
      ["Invalid option. Choose between #{OPTIONS.join(',')}.", 1]
    rescue UnfoundVersionError
      ["Unable to find your gem version", 1]
    rescue UnfoundVersionFileError
      ["Unable to find a file with the gem version", 1]
    rescue TooManyVersionFilesError
      ["More than one gemspec file", 1]
    rescue Exception => e
      ["Something wrong happened: #{e.message}\n#{e.backtrace.join("\n")}", 1]
    end

    def self.current
      current_info.first
    end

    private

    def self.bump(part, options)
      current, file = current_info
      next_version = next_version(current, part)
      replace(file, current, next_version)
      system("bundle") if options[:bundle] and under_version_control?("Gemfile.lock")
      commit(next_version, file, options) if options[:commit]
      ["Bump version #{current} to #{next_version}", 0]
    end

    def self.commit(version, file, options)
      return unless File.directory?(".git")
      system("git add --update Gemfile.lock") if options[:bundle]
      system("git add --update #{file} && git commit -m 'v#{version}'")
    end

    def self.replace(file, old, new)
      content = File.read(file)
      File.open(file, "w"){|f| f.write(content.gsub(old, new)) }
    end

    def self.current_info
      version, file = (
        version_from_version_rb ||
        version_from_gemspec ||
        version_from_version ||
        version_from_lib_rb  ||
        version_from_chef  ||
        raise(UnfoundVersionFileError)
      )
      raise UnfoundVersionError unless version
      [version, file]
    end

    def self.version_from_gemspec
      return unless file    = find_version_file("*.gemspec")
      version               = File.read(file)[/\.version\s*=\s*["']#{VERSION_REGEX}["']/, 1]
      return unless version = File.read(file)[/Gem::Specification.new.+ ["']#{VERSION_REGEX}["']/, 1] if version.nil?
      [version, file]
    end

    def self.version_from_version_rb
      return unless file = find_version_file("lib/**/version.rb")
      extract_version_from_file(file)
    end

    def self.version_from_version
      return unless file = find_version_file("VERSION")
      extract_version_from_file(file)
    end

    def self.version_from_lib_rb
      files = Dir.glob("lib/**/*.rb")
      return unless file = files.detect { |file| File.readlines(file).grep(/^VERSION = (['"])#{VERSION_REGEX}['"]/i) }
      extract_version_from_file(file)
    end

    def self.version_from_chef
      file = find_version_file("metadata.rb")
      return unless file && File.read(file) =~ /^version\s+(['"])(#{VERSION_REGEX})['"]/
      [$2, file]
    end

    def self.extract_version_from_file(file)
      return unless version = File.read(file)[VERSION_REGEX]
      [version, file]<commit_msg>fix version_from_lib_rb always finding something since grep returns [] which is true<commit_after>module Bump
  class InvalidOptionError < StandardError; end
  class UnfoundVersionError < StandardError; end
  class TooManyVersionFilesError < StandardError; end
  class UnfoundVersionFileError < StandardError; end

  class Bump
    BUMPS         = %w(major minor patch pre)
    PRERELEASE    = ["alpha","beta","rc",nil]
    OPTIONS       = BUMPS | ["current"]
    VERSION_REGEX = /(\d+\.\d+\.\d+(?:-(?:#{PRERELEASE.compact.join('|')}))?)/

    def self.defaults
      {
        :commit => true,
        :bundle => File.exist?("Gemfile")
      }
    end

    def self.run(bump, options={})
      options = defaults.merge(options)

      case bump
      when *BUMPS
        bump(bump, options)
      when "current"
        ["Current version: #{current}", 0]
      else
        raise InvalidOptionError
      end
    rescue InvalidOptionError
      ["Invalid option. Choose between #{OPTIONS.join(',')}.", 1]
    rescue UnfoundVersionError
      ["Unable to find your gem version", 1]
    rescue UnfoundVersionFileError
      ["Unable to find a file with the gem version", 1]
    rescue TooManyVersionFilesError
      ["More than one gemspec file", 1]
    rescue Exception => e
      ["Something wrong happened: #{e.message}\n#{e.backtrace.join("\n")}", 1]
    end

    def self.current
      current_info.first
    end

    private

    def self.bump(part, options)
      current, file = current_info
      next_version = next_version(current, part)
      replace(file, current, next_version)
      system("bundle") if options[:bundle] and under_version_control?("Gemfile.lock")
      commit(next_version, file, options) if options[:commit]
      ["Bump version #{current} to #{next_version}", 0]
    end

    def self.commit(version, file, options)
      return unless File.directory?(".git")
      system("git add --update Gemfile.lock") if options[:bundle]
      system("git add --update #{file} && git commit -m 'v#{version}'")
    end

    def self.replace(file, old, new)
      content = File.read(file)
      File.open(file, "w"){|f| f.write(content.gsub(old, new)) }
    end

    def self.current_info
      version, file = (
        version_from_version_rb ||
        version_from_gemspec ||
        version_from_version ||
        version_from_lib_rb  ||
        version_from_chef  ||
        raise(UnfoundVersionFileError)
      )
      raise UnfoundVersionError unless version
      [version, file]
    end

    def self.version_from_gemspec
      return unless file    = find_version_file("*.gemspec")
      version               = File.read(file)[/\.version\s*=\s*["']#{VERSION_REGEX}["']/, 1]
      return unless version = File.read(file)[/Gem::Specification.new.+ ["']#{VERSION_REGEX}["']/, 1] if version.nil?
      [version, file]
    end

    def self.version_from_version_rb
      return unless file = find_version_file("lib/**/version.rb")
      extract_version_from_file(file)
    end

    def self.version_from_version
      return unless file = find_version_file("VERSION")
      extract_version_from_file(file)
    end

    def self.version_from_lib_rb
      file = find_version_file("lib/**/*.rb")
      return unless file && File.read(file) =~ /^\s+VERSION = ['"](#{VERSION_REGEX})['"]/i
      [$1, file]
    end

    def self.version_from_chef
      file = find_version_file("metadata.rb")
      return unless file && File.read(file) =~ /^version\s+(['"])(#{VERSION_REGEX})['"]/
      [$2, file]
    end

    def self.extract_version_from_file(file)
      return unless version = File.read(file)[VERSION_REGEX]
      [version, file]
{'fraction_non_alphanumeric': 0.13069741900054915, 'fraction_numerical': 0.002883031301482702, 'mean_word_length': 2.8524590163934427, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, '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': '45242', 'n_tokens_mistral': 2272, 'n_tokens_neox': 2230, 'n_words': 527}