Class: Dependabot::Julia::Requirement
- Inherits:
-
Requirement
- Object
- Requirement
- Dependabot::Julia::Requirement
- Defined in:
- lib/dependabot/julia/requirement.rb
Constant Summary collapse
- HYPHEN_RANGE_PATTERN =
Julia hyphen ranges require whitespace around the hyphen ("1.2 - 3.4"); without spaces the hyphen introduces a prerelease tag instead.
T.let(/^(\d+(?:\.\d+)*)\s+-\s+(\d+(?:\.\d+)*)$/, Regexp)
Class Method Summary collapse
- .compound_constraint?(constraints) ⇒ Boolean
- .normalize_julia_constraint(constraint) ⇒ Object
- .normalize_version(version) ⇒ Object
- .parse_compound_constraint(constraints) ⇒ Object
- .parse_requirements(requirement_string) ⇒ Object
- .parse_separate_constraints(constraints) ⇒ Object
- .requirements_array(requirement_string) ⇒ Object
Class Method Details
.compound_constraint?(constraints) ⇒ Boolean
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/dependabot/julia/requirement.rb', line 32 def self.compound_constraint?(constraints) # Compound constraints (e.g., ">= 1.0, < 2.0") are when explicit comparison operators # (>=, <=, <, >, =) work together to define a single range. # Separate constraints (e.g., "^1.10, 2" or "0.34, 0.35") use version specs # (with or without ^/~) as OR conditions - any matching spec is acceptable. # Only treat as compound if ALL constraints use explicit comparison operators. # # NOTE: Julia's Pkg unions *all* comma-separated compat specs, including # operator-style ones, so ">= 1.0, < 2.0" is `*` to the resolver. We keep # intersection semantics for operator-style lists anyway because this # method also parses Dependabot ignore conditions (e.g. ">= 2.a, < 3"), # which are always intersections; treating those as unions would make # every ignore condition match all versions. return false if constraints.length <= 1 constraints.all? { |c| c.match?(/^[<>=]/) } end |
.normalize_julia_constraint(constraint) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/dependabot/julia/requirement.rb', line 80 def self.normalize_julia_constraint(constraint) return normalize_caret_constraint(constraint) if constraint.match?(/^\^(\d+(?:\.\d+)*)/) return normalize_tilde_constraint(constraint) if constraint.match?(/^~(\d+(?:\.\d+)*)/) return normalize_range_constraint(constraint) if constraint.match?(HYPHEN_RANGE_PATTERN) # Julia treats plain version numbers as caret constraints (implicit ^) # e.g., "1.2.3" is equivalent to "^1.2.3" which means ">= 1.2.3, < 2.0.0" # See: https://pkgdocs.julialang.org/v1/compatibility/ return normalize_caret_constraint("^#{constraint}") if constraint.match?(/^(\d+(?:\.\d+)*)$/) # Return as-is for standard gem requirements (>=, <=, ==, etc.) [constraint] end |
.normalize_version(version) ⇒ Object
69 70 71 72 73 |
# File 'lib/dependabot/julia/requirement.rb', line 69 def self.normalize_version(version) # Remove 'v' prefix if present (common in Julia) version = version.sub(/^v/, "") if version.match?(/^v\d/) version end |
.parse_compound_constraint(constraints) ⇒ Object
51 52 53 54 55 |
# File 'lib/dependabot/julia/requirement.rb', line 51 def self.parse_compound_constraint(constraints) # Handle compound constraints (e.g., ">= 1.0, < 2.0") as a single requirement normalized_constraints = constraints.flat_map { |c| normalize_julia_constraint(c) } [new(normalized_constraints)] end |
.parse_requirements(requirement_string) ⇒ Object
64 65 66 |
# File 'lib/dependabot/julia/requirement.rb', line 64 def self.parse_requirements(requirement_string) requirements_array(requirement_string) end |
.parse_separate_constraints(constraints) ⇒ Object
58 59 60 61 |
# File 'lib/dependabot/julia/requirement.rb', line 58 def self.parse_separate_constraints(constraints) # Handle separate version specs (e.g., "0.34, 0.35") as multiple requirements constraints.map { |constraint| new(normalize_julia_constraint(constraint)) } end |
.requirements_array(requirement_string) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/dependabot/julia/requirement.rb', line 11 def self.requirements_array(requirement_string) # Julia version specifiers can be: # - Exact: "1.2.3" # - Range: "1.2 - 1.3", ">=1.0, <2.0" # - Caret: "^1.2" (compatible within major version) # - Tilde: "~1.2.3" (compatible within minor version) # Note: Missing compat entry (nil/empty) means any version is acceptable return [new(">= 0")] if requirement_string.nil? || requirement_string.empty? constraints = requirement_string.split(",").map(&:strip) if compound_constraint?(constraints) parse_compound_constraint(constraints) else parse_separate_constraints(constraints) end rescue Gem::Requirement::BadRequirementError [new(">= 0")] end |