Skip to content

Commit

Permalink
Create abstract Dependabot::Requirement class (#8492)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamieMagee authored Dec 19, 2023
1 parent 7255015 commit 62b63c4
Show file tree
Hide file tree
Showing 21 changed files with 143 additions and 25 deletions.
8 changes: 7 additions & 1 deletion bundler/lib/dependabot/bundler/requirement.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
# typed: true
# frozen_string_literal: true

require "sorbet-runtime"

require "dependabot/requirement"
require "dependabot/utils"

module Dependabot
module Bundler
class Requirement < Gem::Requirement
class Requirement < Dependabot::Requirement
extend T::Sig

# For consistency with other languages, we define a requirements array.
# Ruby doesn't have an `OR` separator for requirements, so it always
# contains a single element.
sig { override.params(requirement_string: T.nilable(String)).returns(T::Array[Requirement]) }
def self.requirements_array(requirement_string)
[new(requirement_string)]
end
Expand Down
8 changes: 7 additions & 1 deletion cargo/lib/dependabot/cargo/requirement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@
# - https://steveklabnik.github.io/semver/semver/index.html #
################################################################################

require "sorbet-runtime"

require "dependabot/requirement"
require "dependabot/utils"
require "dependabot/cargo/version"

module Dependabot
module Cargo
class Requirement < Gem::Requirement
class Requirement < Dependabot::Requirement
extend T::Sig

quoted = OPS.keys.map { |k| Regexp.quote(k) }.join("|")
version_pattern = Cargo::Version::VERSION_PATTERN

Expand All @@ -37,6 +42,7 @@ def self.parse(obj)
# For consistency with other languages, we define a requirements array.
# Rust doesn't have an `OR` separator for requirements, so it always
# contains a single element.
sig { override.params(requirement_string: T.nilable(String)).returns(T::Array[Requirement]) }
def self.requirements_array(requirement_string)
[new(requirement_string)]
end
Expand Down
20 changes: 20 additions & 0 deletions common/lib/dependabot/requirement.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# typed: strong
# frozen_string_literal: true

require "sorbet-runtime"

module Dependabot
class Requirement < Gem::Requirement
extend T::Sig
extend T::Helpers

abstract!

sig do
abstract
.params(requirement_string: T.nilable(String))
.returns(T::Array[Requirement])
end
def self.requirements_array(requirement_string); end
end
end
8 changes: 5 additions & 3 deletions common/lib/dependabot/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
require "tmpdir"
require "set"
require "sorbet-runtime"

require "dependabot/requirement"
require "dependabot/version"
require "dependabot/config/file"

Expand Down Expand Up @@ -33,17 +35,17 @@ def self.register_version_class(package_manager, version_class)
@version_classes[package_manager] = version_class
end

@requirement_classes = T.let({}, T::Hash[String, T.class_of(Gem::Requirement)])
@requirement_classes = T.let({}, T::Hash[String, T.class_of(Dependabot::Requirement)])

sig { params(package_manager: String).returns(T.class_of(Gem::Requirement)) }
sig { params(package_manager: String).returns(T.class_of(Dependabot::Requirement)) }
def self.requirement_class_for_package_manager(package_manager)
requirement_class = @requirement_classes[package_manager]
return requirement_class if requirement_class

raise "Unregistered package_manager #{package_manager}"
end

sig { params(package_manager: String, requirement_class: T.class_of(Gem::Requirement)).void }
sig { params(package_manager: String, requirement_class: T.class_of(Dependabot::Requirement)).void }
def self.register_requirement_class(package_manager, requirement_class)
validate_package_manager!(package_manager)

Expand Down
3 changes: 2 additions & 1 deletion common/spec/dummy_package_manager/requirement.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# typed: true
# frozen_string_literal: true

require "dependabot/requirement"
require "dependabot/utils"

module DummyPackageManager
class Requirement < Gem::Requirement
class Requirement < Dependabot::Requirement
def self.requirements_array(requirement_string)
[new(requirement_string)]
end
Expand Down
10 changes: 8 additions & 2 deletions composer/lib/dependabot/composer/requirement.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
# typed: true
# frozen_string_literal: true

require "sorbet-runtime"

require "dependabot/requirement"
require "dependabot/utils"

module Dependabot
module Composer
class Requirement < Gem::Requirement
class Requirement < Dependabot::Requirement
extend T::Sig

AND_SEPARATOR = /(?<=[a-zA-Z0-9*])(?<!\sas)[\s,]+(?![\s,]*[|-]|as)/
OR_SEPARATOR = /(?<=[a-zA-Z0-9*])[\s,]*\|\|?\s*/

Expand All @@ -18,8 +23,9 @@ def self.parse(obj)

# Returns an array of requirements. At least one requirement from the
# returned array must be satisfied for a version to be valid.
sig { override.params(requirement_string: T.nilable(String)).returns(T::Array[Requirement]) }
def self.requirements_array(requirement_string)
requirement_string.strip.split(OR_SEPARATOR).map do |req_string|
T.must(requirement_string).strip.split(OR_SEPARATOR).map do |req_string|
new(req_string)
end
end
Expand Down
8 changes: 7 additions & 1 deletion docker/lib/dependabot/docker/requirement.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
# typed: true
# frozen_string_literal: true

require "sorbet-runtime"

require "dependabot/requirement"
require "dependabot/utils"

module Dependabot
module Docker
# Lifted from the bundler package manager
class Requirement < Gem::Requirement
class Requirement < Dependabot::Requirement
extend T::Sig

# For consistency with other languages, we define a requirements array.
# Ruby doesn't have an `OR` separator for requirements, so it always
# contains a single element.
sig { override.params(requirement_string: T.nilable(String)).returns(T::Array[Requirement]) }
def self.requirements_array(requirement_string)
[new(requirement_string)]
end
Expand Down
8 changes: 7 additions & 1 deletion elm/lib/dependabot/elm/requirement.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
# typed: false
# frozen_string_literal: true

require "sorbet-runtime"

require "dependabot/requirement"
require "dependabot/utils"
require "dependabot/elm/version"

module Dependabot
module Elm
class Requirement < Gem::Requirement
class Requirement < Dependabot::Requirement
extend T::Sig

ELM_PATTERN_RAW =
"(#{Elm::Version::VERSION_PATTERN}) (<=?) v (<=?) " \
"(#{Elm::Version::VERSION_PATTERN})".freeze
Expand All @@ -15,6 +20,7 @@ class Requirement < Gem::Requirement

# Returns an array of requirements. At least one requirement from the
# returned array must be satisfied for a version to be valid.
sig { override.params(requirement_string: T.nilable(String)).returns(T::Array[Requirement]) }
def self.requirements_array(requirement_string)
[new(requirement_string)]
end
Expand Down
8 changes: 7 additions & 1 deletion git_submodules/lib/dependabot/git_submodules/requirement.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
# typed: true
# frozen_string_literal: true

require "sorbet-runtime"

require "dependabot/requirement"
require "dependabot/utils"

module Dependabot
module GitSubmodules
class Requirement < Gem::Requirement
class Requirement < Dependabot::Requirement
extend T::Sig

# For consistency with other languages, we define a requirements array.
# Ruby doesn't have an `OR` separator for requirements, so it always
# contains a single element.
sig { override.params(requirement_string: T.nilable(String)).returns(T::Array[Requirement]) }
def self.requirements_array(requirement_string)
[new(requirement_string)]
end
Expand Down
6 changes: 5 additions & 1 deletion github_actions/lib/dependabot/github_actions/requirement.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
# typed: true
# frozen_string_literal: true

require "sorbet-runtime"

require "dependabot/requirement"
require "dependabot/utils"
require "dependabot/github_actions/version"

module Dependabot
module GithubActions
# Lifted from the bundler package manager
class Requirement < Gem::Requirement
class Requirement < Dependabot::Requirement
# For consistency with other languages, we define a requirements array.
# Ruby doesn't have an `OR` separator for requirements, so it always
# contains a single element.
sig { override.params(requirement_string: T.nilable(String)).returns(T::Array[Requirement]) }
def self.requirements_array(requirement_string)
[new(requirement_string)]
end
Expand Down
8 changes: 7 additions & 1 deletion go_modules/lib/dependabot/go_modules/requirement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@
# - https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md #
################################################################################

require "sorbet-runtime"

require "dependabot/requirement"
require "dependabot/utils"
require "dependabot/go_modules/version"

module Dependabot
module GoModules
class Requirement < Gem::Requirement
class Requirement < Dependabot::Requirement
extend T::Sig

WILDCARD_REGEX = /(?:\.|^)[xX*]/
OR_SEPARATOR = /(?<=[a-zA-Z0-9*])\s*\|{2}/

Expand Down Expand Up @@ -40,6 +45,7 @@ def self.parse(obj)

# Returns an array of requirements. At least one requirement from the
# returned array must be satisfied for a version to be valid.
sig { override.params(requirement_string: T.nilable(String)).returns(T::Array[Requirement]) }
def self.requirements_array(requirement_string)
return [new(nil)] if requirement_string.nil?

Expand Down
8 changes: 7 additions & 1 deletion gradle/lib/dependabot/gradle/requirement.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
# typed: true
# frozen_string_literal: true

require "sorbet-runtime"

require "dependabot/requirement"
require "dependabot/utils"
require "dependabot/maven/requirement"
require "dependabot/gradle/version"

module Dependabot
module Gradle
class Requirement < Gem::Requirement
class Requirement < Dependabot::Requirement
extend T::Sig

quoted = OPS.keys.map { |k| Regexp.quote k }.join("|")
PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Gradle::Version::VERSION_PATTERN})\\s*".freeze
PATTERN = /\A#{PATTERN_RAW}\z/
Expand All @@ -25,6 +30,7 @@ def self.parse(obj)
[matches[1] || "=", Gradle::Version.new(matches[2])]
end

sig { override.params(requirement_string: T.nilable(String)).returns(T::Array[Requirement]) }
def self.requirements_array(requirement_string)
split_java_requirement(requirement_string).map do |str|
new(str)
Expand Down
10 changes: 8 additions & 2 deletions hex/lib/dependabot/hex/requirement.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
# typed: true
# frozen_string_literal: true

require "sorbet-runtime"

require "dependabot/requirement"
require "dependabot/utils"
require "dependabot/hex/version"

module Dependabot
module Hex
class Requirement < Gem::Requirement
class Requirement < Dependabot::Requirement
extend T::Sig

AND_SEPARATOR = /\s+and\s+/
OR_SEPARATOR = /\s+or\s+/

Expand All @@ -20,8 +25,9 @@ class Requirement < Gem::Requirement

# Returns an array of requirements. At least one requirement from the
# returned array must be satisfied for a version to be valid.
sig { override.params(requirement_string: T.nilable(String)).returns(T::Array[Requirement]) }
def self.requirements_array(requirement_string)
requirement_string.strip.split(OR_SEPARATOR).map do |req_string|
T.must(requirement_string).strip.split(OR_SEPARATOR).map do |req_string|
requirements = req_string.strip.split(AND_SEPARATOR)
new(requirements)
end
Expand Down
8 changes: 7 additions & 1 deletion maven/lib/dependabot/maven/requirement.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
# typed: true
# frozen_string_literal: true

require "sorbet-runtime"

require "dependabot/requirement"
require "dependabot/utils"
require "dependabot/maven/version"

module Dependabot
module Maven
class Requirement < Gem::Requirement
class Requirement < Dependabot::Requirement
extend T::Sig

quoted = OPS.keys.map { |k| Regexp.quote k }.join("|")
OR_SYNTAX = /(?<=\]|\)),/
PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{Maven::Version::VERSION_PATTERN})\\s*".freeze
Expand All @@ -25,6 +30,7 @@ def self.parse(obj)
[matches[1] || "=", Maven::Version.new(matches[2])]
end

sig { override.params(requirement_string: T.nilable(String)).returns(T::Array[Requirement]) }
def self.requirements_array(requirement_string)
split_java_requirement(requirement_string).map do |str|
new(str)
Expand Down
8 changes: 7 additions & 1 deletion npm_and_yarn/lib/dependabot/npm_and_yarn/requirement.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
# typed: true
# frozen_string_literal: true

require "sorbet-runtime"

require "dependabot/requirement"
require "dependabot/utils"
require "dependabot/npm_and_yarn/version"

module Dependabot
module NpmAndYarn
class Requirement < Gem::Requirement
class Requirement < Dependabot::Requirement
extend T::Sig

AND_SEPARATOR = /(?<=[a-zA-Z0-9*])\s+(?:&+\s+)?(?!\s*[|-])/
OR_SEPARATOR = /(?<=[a-zA-Z0-9*])\s*\|+/
LATEST_REQUIREMENT = "latest"
Expand Down Expand Up @@ -34,6 +39,7 @@ def self.parse(obj)

# Returns an array of requirements. At least one requirement from the
# returned array must be satisfied for a version to be valid.
sig { override.params(requirement_string: T.nilable(String)).returns(T::Array[Requirement]) }
def self.requirements_array(requirement_string)
return [new(nil)] if requirement_string.nil?

Expand Down
Loading

0 comments on commit 62b63c4

Please sign in to comment.