Class: Dependabot::Helm::Requirement

Inherits:
Requirement
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/dependabot/helm/requirement.rb

Overview

Parses Helm Chart.yaml SemVer range constraints (^, ~, x-ranges, hyphen ranges, || OR, space-AND and comma-AND). Adapted from Dependabot::NpmAndYarn::Requirement: Helm uses the same SemVer family (Masterminds), unlike the Gem-style Docker::Requirement registered for the docker-image path.

NOTE: this class is intentionally NOT registered as the requirement class for "helm" (that remains Docker::Requirement, used by the docker-image path and ignore conditions). It is used explicitly by the range-preserving requirements updater.

Constant Summary collapse

AND_SEPARATOR =
T.let(/(?<=[a-zA-Z0-9*])\s+(?:&+\s+)?(?!\s*[|-])/, Regexp)
OR_SEPARATOR =
T.let(/(?<=[a-zA-Z0-9*])\s*\|+/, Regexp)
PATTERN_RAW =
T.let("\\s*(#{quoted})?\\s*(#{version_pattern})\\s*".freeze, String)
PATTERN =
T.let(/\A#{PATTERN_RAW}\z/, Regexp)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*requirements) ⇒ Requirement

Returns a new instance of Requirement.



70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/dependabot/helm/requirement.rb', line 70

def initialize(*requirements)
  requirements = requirements.flatten.compact
  # `new(nil)` (from `requirements_array(nil)`) means "match anything".
  # Use a literal ">= 0" so it flows through our `parse` and is backed by a
  # Helm::Version — Gem's DefaultRequirement uses a plain Gem::Version, which
  # Helm::Version#<=>'s strict sig would reject.
  requirements = [">= 0"] if requirements.empty?

  requirements = requirements.flat_map { |req_string| req_string.split(",").map(&:strip) }
                             .flat_map { |req_string| convert_helm_constraint_to_ruby_constraint(req_string) }

  super
end

Class Method Details

.parse(obj) ⇒ Object



46
47
48
49
50
51
52
53
54
# File 'lib/dependabot/helm/requirement.rb', line 46

def self.parse(obj)
  return ["=", Helm::Version.new(obj.to_s)] if obj.is_a?(Gem::Version)

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

  [matches[1] || "=", Helm::Version.new(T.must(matches[2]))]
end

.requirements_array(requirement_string) ⇒ Object



59
60
61
62
63
64
65
66
67
# File 'lib/dependabot/helm/requirement.rb', line 59

def self.requirements_array(requirement_string)
  return [new(nil)] if requirement_string.nil?

  # Parentheses are extremely rare in Helm constraints; strip them.
  requirement_string = requirement_string.gsub(/[()]/, "")
  requirement_string.strip.split(OR_SEPARATOR).map do |req_string|
    new(req_string.strip.split(AND_SEPARATOR))
  end
end