Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions updater/lib/dependabot/dependency_group_engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,18 @@ class DependencyGroupEngine

class ConfigurationError < StandardError; end

# Package managers that support the dependency-type option in group rules.
# Update this list when adding dependency-type support to new ecosystems.
# Note: 'silent' is included to avoid modifying its integration tests.
PACKAGE_MANAGERS_SUPPORTING_DEPENDENCY_TYPE = T.let(
%w(bundler composer hex maven npm_and_yarn pip uv silent).freeze,
T::Array[String]
)

sig { params(job: Dependabot::Job).returns(Dependabot::DependencyGroupEngine) }
def self.from_job_config(job:)
validate_group_configuration!(job)

groups = job.dependency_groups.map do |group|
Dependabot::DependencyGroup.new(name: group["name"], rules: group["rules"], applies_to: group["applies-to"])
end
Expand All @@ -41,6 +51,25 @@ def self.from_job_config(job:)
new(dependency_groups: groups)
end

sig { params(job: Dependabot::Job).void }
def self.validate_group_configuration!(job)
return unless job.dependency_groups.any?

unsupported_groups = job.dependency_groups.select do |group|
rules = group["rules"] || {}
rules.key?("dependency-type") &&
!PACKAGE_MANAGERS_SUPPORTING_DEPENDENCY_TYPE.include?(job.package_manager)
end

return unless unsupported_groups.any?

group_names = unsupported_groups.map { |g| g["name"] }.join(", ")
raise ConfigurationError,
"The 'dependency-type' option is not supported for the '#{job.package_manager}' package manager. " \
"It is only supported for: #{PACKAGE_MANAGERS_SUPPORTING_DEPENDENCY_TYPE.join(', ')}. " \
"Affected groups: #{group_names}"
end

sig { returns(T::Array[Dependabot::DependencyGroup]) }
attr_reader :dependency_groups

Expand Down
137 changes: 137 additions & 0 deletions updater/spec/dependabot/dependency_group_engine_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -480,4 +480,141 @@
end
end
end

describe "::from_job_config validation" do
let(:dependency_groups_config) do
[
{
"name" => "test-group",
"rules" => {
"dependency-type" => "production"
}
}
]
end

context "when dependency-type is used with a supported package manager" do
%w(bundler composer hex maven npm_and_yarn pip uv).each do |package_manager|
context "with #{package_manager}" do
let(:job) do
instance_double(
Dependabot::Job,
dependency_groups: dependency_groups_config,
source: source,
dependencies: nil,
security_updates_only?: false,
package_manager: package_manager
)
end

it "does not raise an error" do
expect { dependency_group_engine }.not_to raise_error
end
end
end
end

context "when dependency-type is used with an unsupported package manager" do
%w(gradle go_modules cargo docker terraform).each do |package_manager|
context "with #{package_manager}" do
let(:job) do
instance_double(
Dependabot::Job,
dependency_groups: dependency_groups_config,
source: source,
dependencies: nil,
security_updates_only?: false,
package_manager: package_manager
)
end

it "raises a ConfigurationError" do
expect { dependency_group_engine }.to raise_error(
Dependabot::DependencyGroupEngine::ConfigurationError,
/The 'dependency-type' option is not supported for the '#{package_manager}' package manager/
)
end

it "includes the group name in the error message" do
expect { dependency_group_engine }.to raise_error(
Dependabot::DependencyGroupEngine::ConfigurationError,
/Affected groups: test-group/
)
end

it "lists supported package managers in the error message" do
expect { dependency_group_engine }.to raise_error(
Dependabot::DependencyGroupEngine::ConfigurationError,
/bundler, composer, hex, maven, npm_and_yarn, pip, uv/
)
end
end
end
end

context "when multiple groups use dependency-type with an unsupported package manager" do
let(:dependency_groups_config) do
[
{
"name" => "group-one",
"rules" => {
"dependency-type" => "production"
}
},
{
"name" => "group-two",
"rules" => {
"dependency-type" => "development"
}
}
]
end

let(:job) do
instance_double(
Dependabot::Job,
dependency_groups: dependency_groups_config,
source: source,
dependencies: nil,
security_updates_only?: false,
package_manager: "gradle"
)
end

it "raises an error mentioning all affected groups" do
expect { dependency_group_engine }.to raise_error(
Dependabot::DependencyGroupEngine::ConfigurationError,
/Affected groups: group-one, group-two/
)
end
end

context "when groups don't use dependency-type with an unsupported package manager" do
let(:dependency_groups_config) do
[
{
"name" => "test-group",
"rules" => {
"patterns" => ["dummy-*"]
}
}
]
end

let(:job) do
instance_double(
Dependabot::Job,
dependency_groups: dependency_groups_config,
source: source,
dependencies: nil,
security_updates_only?: false,
package_manager: "gradle"
)
end

it "does not raise an error" do
expect { dependency_group_engine }.not_to raise_error
end
end
end
end
Loading