class Dependabot::PullRequestCreator::BranchNamer

Attributes

dependencies[R]
files[R]
prefix[R]
separator[R]
target_branch[R]

Public Class Methods

new(dependencies:, files:, target_branch:, separator: "/", prefix: "dependabot") click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 11
def initialize(dependencies:, files:, target_branch:, separator: "/",
               prefix: "dependabot")
  @dependencies  = dependencies
  @files         = files
  @target_branch = target_branch
  @separator     = separator
  @prefix        = prefix
end

Public Instance Methods

new_branch_name() click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 20
def new_branch_name
  @name ||=
    begin
      dependency_name_part =
        if dependencies.count > 1 && updating_a_property?
          property_name
        elsif dependencies.count > 1 && updating_a_dependency_set?
          dependency_set.fetch(:group)
        else
          dependencies.
            map(&:name).
            join("-and-").
            tr(":[]", "-").
            tr("@", "")
        end

      "#{dependency_name_part}-#{branch_version_suffix}"
    end

  # Some users need branch names without slashes
  sanitize_ref(File.join(prefixes, @name).gsub("/", separator))
end

Private Instance Methods

branch_version_suffix() click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 90
def branch_version_suffix
  dep = dependencies.first

  if library? && ref_changed?(dep) && new_ref(dep)
    new_ref(dep)
  elsif library?
    sanitized_requirement(dep)
  else
    new_version(dep)
  end
end
dependency_set() click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 80
def dependency_set
  @dependency_set ||= dependencies.first.requirements.
                      find { |r| r.dig(:metadata, :dependency_set) }&.
                      dig(:metadata, :dependency_set)

  raise "No dependency set!" unless @dependency_set

  @dependency_set
end
library?() click to toggle source

TODO: Bring this in line with existing library checks that we do in the update checkers, which are also overriden by passing an explicit `requirements_update_strategy`.

TODO re-use in MessageBuilder

# File lib/dependabot/pull_request_creator/branch_namer.rb, line 172
def library?
  dependencies.any? { |d| !d.appears_in_lockfile? }
end
new_library_requirement(dependency) click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 156
def new_library_requirement(dependency)
  updated_reqs =
    dependency.requirements - dependency.previous_requirements

  gemspec =
    updated_reqs.find { |r| r[:file].match?(%r{^[^/]*\.gemspec$}) }
  return gemspec[:requirement] if gemspec

  updated_reqs.first[:requirement]
end
new_ref(dependency) click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 144
def new_ref(dependency)
  new_refs = dependency.requirements.map do |r|
    r.dig(:source, "ref") || r.dig(:source, :ref)
  end.compact.uniq
  return new_refs.first if new_refs.count == 1
end
new_version(dependency) click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 120
def new_version(dependency)
  # Version looks like a git SHA and we could be updating to a specific
  # ref in which case we return that otherwise we return a shorthand sha
  if dependency.version.match?(/^[0-9a-f]{40}$/)
    return new_ref(dependency) if ref_changed?(dependency) && new_ref(dependency)

    dependency.version[0..6]
  elsif dependency.version == dependency.previous_version &&
        package_manager == "docker"
    dependency.requirements.
      map { |r| r.dig(:source, "digest") || r.dig(:source, :digest) }.
      compact.first.split(":").last[0..6]
  else
    dependency.version
  end
end
package_manager() click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 54
def package_manager
  dependencies.first.package_manager
end
prefixes() click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 45
def prefixes
  [
    prefix,
    package_manager,
    files.first.directory.tr(" ", "-"),
    target_branch
  ].compact
end
previous_ref(dependency) click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 137
def previous_ref(dependency)
  previous_refs = dependency.previous_requirements.map do |r|
    r.dig(:source, "ref") || r.dig(:source, :ref)
  end.compact.uniq
  return previous_refs.first if previous_refs.count == 1
end
property_name() click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 70
def property_name
  @property_name ||= dependencies.first.requirements.
                     find { |r| r.dig(:metadata, :property_name) }&.
                     dig(:metadata, :property_name)

  raise "No property name!" unless @property_name

  @property_name
end
ref_changed?(dependency) click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 151
def ref_changed?(dependency)
  # We could go from multiple previous refs (nil) to a single new ref
  previous_ref(dependency) != new_ref(dependency)
end
requirements_changed?(dependency) click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 176
def requirements_changed?(dependency)
  (dependency.requirements - dependency.previous_requirements).any?
end
sanitize_ref(ref) click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 180
def sanitize_ref(ref)
  # This isn't a complete implementation of git's ref validation, but it
  # covers most cases that crop up. Its list of allowed charactersr is a
  # bit stricter than git's, but that's for cosmetic reasons.
  ref.
    # Remove forbidden characters (those not already replaced elsewhere)
    gsub(%r{[^A-Za-z0-9/\-_.(){}]}, "").
    # Slashes can't be followed by periods
    gsub(%r{/\.}, "/dot-").
    # Two or more sequential periods are forbidden
    gsub(/\.+/, ".").
    # Two or more sequential slashes are forbidden
    gsub(%r{/+}, "/").
    # Trailing periods are forbidden
    sub(/\.$/, "")
end
sanitized_requirement(dependency) click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 102
def sanitized_requirement(dependency)
  new_library_requirement(dependency).
    delete(" ").
    gsub("!=", "neq-").
    gsub(">=", "gte-").
    gsub("<=", "lte-").
    gsub("~>", "tw-").
    gsub("^", "tw-").
    gsub("||", "or-").
    gsub("~", "approx-").
    gsub("~=", "tw-").
    gsub(/==*/, "eq-").
    gsub(">", "gt-").
    gsub("<", "lt-").
    gsub("*", "star").
    gsub(",", "-and-")
end
updating_a_dependency_set?() click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 64
def updating_a_dependency_set?
  dependencies.first.
    requirements.
    any? { |r| r.dig(:metadata, :dependency_set) }
end
updating_a_property?() click to toggle source
# File lib/dependabot/pull_request_creator/branch_namer.rb, line 58
def updating_a_property?
  dependencies.first.
    requirements.
    any? { |r| r.dig(:metadata, :property_name) }
end