class Dependabot::GoModules::Requirement

Constants

OR_SEPARATOR
PATTERN
PATTERN_RAW
WILDCARD_REGEX

Public Class Methods

new(*requirements) click to toggle source
Calls superclass method
# File lib/dependabot/go_modules/requirement.rb, line 50
def initialize(*requirements)
  requirements = requirements.flatten.flat_map do |req_string|
    req_string.split(",").map(&:strip).map do |r|
      convert_go_constraint_to_ruby_constraint(r.strip)
    end
  end

  super(requirements)
end
parse(obj) click to toggle source

Use GoModules::Version rather than Gem::Version to ensure that pre-release versions aren't transformed.

# File lib/dependabot/go_modules/requirement.rb, line 27
def self.parse(obj)
  return ["=", Version.new(obj.to_s)] if obj.is_a?(Gem::Version)

  unless (matches = PATTERN.match(obj.to_s))
    msg = "Illformed requirement [#{obj.inspect}]"
    raise BadRequirementError, msg
  end

  return DefaultRequirement if matches[1] == ">=" && matches[2] == "0"

  [matches[1] || "=", Version.new(matches[2])]
end
requirements_array(requirement_string) click to toggle source

Returns an array of requirements. At least one requirement from the returned array must be satisfied for a version to be valid.

# File lib/dependabot/go_modules/requirement.rb, line 42
def self.requirements_array(requirement_string)
  return [new(nil)] if requirement_string.nil?

  requirement_string.strip.split(OR_SEPARATOR).map do |req_string|
    new(req_string)
  end
end

Private Instance Methods

convert_caret_req(req_string) click to toggle source

NOTE: Dep's caret notation implementation doesn't distinguish between pre and post-1.0.0 requirements (unlike in JS)

# File lib/dependabot/go_modules/requirement.rb, line 137
def convert_caret_req(req_string)
  version = req_string.gsub(/^\^?v?/, "")
  parts = version.split(".")
  upper_bound = [parts.first.to_i + 1, 0, 0, "a"].map(&:to_s).join(".")

  [">= #{version}", "< #{upper_bound}"]
end
convert_go_constraint_to_ruby_constraint(req_string) click to toggle source
# File lib/dependabot/go_modules/requirement.rb, line 62
def convert_go_constraint_to_ruby_constraint(req_string)
  req_string = convert_wildcard_characters(req_string)

  if req_string.match?(WILDCARD_REGEX)
    ruby_range(req_string.gsub(WILDCARD_REGEX, "").gsub(/^[^\d]/, ""))
  elsif req_string.match?(/^~[^>]/) then convert_tilde_req(req_string)
  elsif req_string.include?(" - ") then convert_hyphen_req(req_string)
  elsif req_string.match?(/^[\dv^]/) then convert_caret_req(req_string)
  elsif req_string.match?(/[<=>]/) then req_string
  else ruby_range(req_string)
  end
end
convert_hyphen_req(req_string) click to toggle source
# File lib/dependabot/go_modules/requirement.rb, line 116
def convert_hyphen_req(req_string)
  lower_bound, upper_bound = req_string.split(/\s+-\s+/)
  [">= #{lower_bound}", "<= #{upper_bound}"]
end
convert_tilde_req(req_string) click to toggle source
# File lib/dependabot/go_modules/requirement.rb, line 109
def convert_tilde_req(req_string)
  version = req_string.gsub(/^~/, "")
  parts = version.split(".")
  parts << "0" if parts.count < 3
  "~> #{parts.join('.')}"
end
convert_wildcard_characters(req_string) click to toggle source
# File lib/dependabot/go_modules/requirement.rb, line 75
def convert_wildcard_characters(req_string)
  if req_string.match?(/^[\dv^>~]/)
    replace_wildcard_in_lower_bound(req_string)
  elsif req_string.start_with?("<")
    parts = req_string.split(".")
    parts.map.with_index do |part, index|
      next "0" if part.match?(WILDCARD_REGEX)
      next part.to_i + 1 if parts[index + 1]&.match?(WILDCARD_REGEX)

      part
    end.join(".")
  else
    req_string
  end
end
replace_wildcard_in_lower_bound(req_string) click to toggle source
# File lib/dependabot/go_modules/requirement.rb, line 91
def replace_wildcard_in_lower_bound(req_string)
  after_wildcard = false

  req_string = req_string.gsub(/(?:(?:\.|^)[xX*])(\.[xX*])+/, "") if req_string.start_with?("~")

  req_string.split(".").
    map do |part|
      part.split("-").map.with_index do |p, i|
        # Before we hit a wildcard we just return the existing part
        next p unless p.match?(WILDCARD_REGEX) || after_wildcard

        # On or after a wildcard we replace the version part with zero
        after_wildcard = true
        i.zero? ? "0" : "a"
      end.join("-")
    end.join(".")
end
ruby_range(req_string) click to toggle source
# File lib/dependabot/go_modules/requirement.rb, line 121
def ruby_range(req_string)
  parts = req_string.split(".")

  # If we have three or more parts then this is an exact match
  return req_string if parts.count >= 3

  # If we have no parts then the version is completely unlocked
  return ">= 0" if parts.count.zero?

  # If we have fewer than three parts we do a partial match
  parts << "0"
  "~> #{parts.join('.')}"
end