class DependencyBumper::Updater

Attributes

cmd_ln_opt[R]
config[R]
report[R]

Public Class Methods

new(config, cmd_ln_opt) click to toggle source
# File lib/dependency_bumper/updater.rb, line 9
def initialize(config, cmd_ln_opt)
  @config = config
  @cmd_ln_opt = cmd_ln_opt
end

Public Instance Methods

create_git_branch(report) click to toggle source
# File lib/dependency_bumper/updater.rb, line 37
    def create_git_branch(report)
      branch_name = "gem-bump-#{Time.now.strftime('%d-%m-%Y')}"
      repo_path = exec(['git', 'rev-parse', '--show-toplevel']).first.strip
      git_repo = Git.open(repo_path, log: Console.logger)

      git_config_username_email(git_repo)
      git_repo.checkout(branch_name, new_branch: true)

      output = <<~END
        Updating gems #{Time.now.strftime('%d-%m-%Y')}
        #{report}
      END

      git_repo.add(all: true)
      git_repo.commit(output)
    rescue Git::GitExecuteError => e
      Console.logger.error(e)
    end
git_config_username_email(repo) click to toggle source
# File lib/dependency_bumper/updater.rb, line 56
def git_config_username_email(repo)
  if repo.config['user.email'].nil? || repo.config['user.name'].nil?
    Console.logger.info('Setting up temporary username and email for committing please update git config')
    repo.config('user.name', 'Your name')
    repo.config('user.email', 'you@example.com')
  else
    Console.logger.info('User name and email is set, read to commit')
  end
  repo.config('commit.gpgsign', config.dig('git', 'commit', 'gpgsign').to_s)
end
major_minor_patch(old_version, new_version) click to toggle source
# File lib/dependency_bumper/updater.rb, line 95
def major_minor_patch(old_version, new_version)
  old_versions = old_version.canonical_segments
  new_versions = new_version.canonical_segments

  if new_versions[0] - old_versions[0] > 1
    return :major
  else # check cases like 1.9 to 2.0
    return :major if new_versions[1].nil? || new_versions[1].nil?

    return :minor if new_versions[1] < old_versions[1]
  end

  if new_versions[1] - old_versions[1] > 1
    return :minor
  else
    return :patch if new_versions[2].nil? || new_versions[2].nil?

    return :patch if new_versions[2] < old_versions[2]
  end

  return :patch if new_versions[2] - old_versions[2] >= 1
end
report_result() { || ... } click to toggle source
# File lib/dependency_bumper/updater.rb, line 67
def report_result
  master_lockfile = Bundler::LockfileParser.new(Bundler.read_file(current_gem_file))

  gems = {}

  master_lockfile.specs.each do |spec|
    gems[spec.name] = { from: spec.version }
  end

  yield

  updated_lockfile = Bundler::LockfileParser.new(Bundler.read_file(current_gem_file))

  updated_lockfile.specs.each do |spec|
    gems[spec.name][:to] = spec.version if gems[spec.name]
  end

  output = ''
  gems.each do |k, v|
    next if v[:from] == v[:to]

    message = "#{k} From #{v[:from]} To #{v[:to]} update level: #{major_minor_patch(v[:from], v[:to])} \n"
    output += message
  end

  output
end
run() click to toggle source
# File lib/dependency_bumper/updater.rb, line 14
def run
  gem_list = outdated_gems
  return if gem_list == []

  commands = generate_update_arguments(gem_list)
  options = { 'jobs' => Etc.nprocessors }

  @report = report_result do
    commands.each do |group, gems|
      Bundler.settings.temporary(no_install: cmd_ln_opt.fetch(:dry, false)) do
        Bundler::CLI::Update.new(options.merge({ group => true }), gems).run
      end
    end
  end

  if report.empty?
    Console.logger.info('No gem updated')
  else
    Console.logger.info(report)
    create_git_branch(report) if cmd_ln_opt.fetch(:git, false)
  end
end

Private Instance Methods

convert_outdated_level() click to toggle source
# File lib/dependency_bumper/updater.rb, line 136
def convert_outdated_level
  {
    'strict' => 'filter-strict',
    'patch' => 'filer-patch',
    'minor' => 'filter-minor',
    'major' => 'filter-major',
  }.fetch(config['outdated_level'], 'filter-strict')
end
current_gem_file() click to toggle source
# File lib/dependency_bumper/updater.rb, line 120
def current_gem_file
  Bundler::SharedHelpers.default_lockfile
end
exec(cmd) click to toggle source
# File lib/dependency_bumper/updater.rb, line 145
def exec(cmd)
  result = []
  Open3.popen3(*cmd) do |_, stdout, stderr, wait_thr|
    stdout.each_line do |x|
      Console.logger.info(x)

      next if x.match?(/^\n$/)

      result << x
    end

    stderr.each do |x|
      Console.logger.error(x)
    end

    exit_status = wait_thr.value # Process::Status object returned.
    Console.logger.debug("exit status: #{exit_status.success?}")
  end

  result
end
generate_update_arguments(gem_names) click to toggle source
# File lib/dependency_bumper/updater.rb, line 167
def generate_update_arguments(gem_names)
  grouped_gems = {
    'major' => [],
    'minor' => [],
    'patch' => [],
  }

  gem_names.each do |gem_name|
    next if config['skip'].key?(gem_name)

    placed_in_group = false

    grouped_gems.keys.each do |group_name|
      if config['update'][group_name].key?(gem_name)
        grouped_gems[group_name] << gem_name
        placed_in_group = true
      end
    end

    unless placed_in_group
      grouped_gems[config['update']['default']] << gem_name
    end
  end

  grouped_gems.reject! { |_, v| v.empty? }

  grouped_gems
end
outdated_gems() click to toggle source
# File lib/dependency_bumper/updater.rb, line 124
def outdated_gems
  bundler = Bundler::CLI::Outdated.new({ convert_outdated_level => true, parseable: true }, [])
  outdated_gems_list = bundler.run

  if outdated_gems_list == []
    Console.logger.info('No outdated gems found')
    return []
  end

  outdated_gems_list.map { |gem| gem[:current_spec].name }
end