-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6188 from dependabot/deivid-rodriguez/no-omnibus-prs
Fix dependabot not updating gemspec dependencies loaded dynamically from other gemspecs
- Loading branch information
Showing
9 changed files
with
243 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
bundler/lib/dependabot/bundler/file_parser/gemspec_declaration_finder.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# frozen_string_literal: true | ||
|
||
require "parser/current" | ||
|
||
module Dependabot | ||
module Bundler | ||
class FileParser | ||
# Checks whether a dependency is declared in a gemspec file | ||
class GemspecDeclarationFinder | ||
def initialize(gemspec:) | ||
@gemspec = gemspec | ||
@declaration_nodes = {} | ||
end | ||
|
||
def gemspec_includes_dependency?(dependency) | ||
!declaration_node(dependency).nil? | ||
end | ||
|
||
private | ||
|
||
attr_reader :gemspec | ||
|
||
def parsed_gemspec | ||
@parsed_gemspec ||= Parser::CurrentRuby.parse(gemspec.content) | ||
end | ||
|
||
def declaration_node(dependency) | ||
return @declaration_nodes[dependency] if @declaration_nodes.key?(dependency) | ||
return unless parsed_gemspec | ||
|
||
@declaration_nodes[dependency] = nil | ||
parsed_gemspec.children.any? do |node| | ||
@declaration_nodes[dependency] = deep_search_for_gem(node, dependency) | ||
end | ||
@declaration_nodes[dependency] | ||
end | ||
|
||
def deep_search_for_gem(node, dependency) | ||
return node if declares_targeted_gem?(node, dependency) | ||
return unless node.is_a?(Parser::AST::Node) | ||
|
||
declaration_node = nil | ||
node.children.find do |child_node| | ||
declaration_node = deep_search_for_gem(child_node, dependency) | ||
end | ||
declaration_node | ||
end | ||
|
||
def declares_targeted_gem?(node, dependency) | ||
return false unless node.is_a?(Parser::AST::Node) | ||
|
||
second_child = node.children[1] | ||
allowed_declarations = %i(add_dependency add_runtime_dependency add_development_dependency) | ||
return false unless allowed_declarations.include?(second_child) | ||
|
||
node.children[2].children.first == dependency.fetch("name") | ||
end | ||
end | ||
end | ||
end | ||
end |
56 changes: 56 additions & 0 deletions
56
bundler/spec/dependabot/bundler/file_parser/gemspec_declaration_finder_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# frozen_string_literal: true | ||
|
||
require "spec_helper" | ||
require "dependabot/dependency" | ||
require "dependabot/dependency_file" | ||
require "dependabot/bundler/file_parser/gemspec_declaration_finder" | ||
|
||
RSpec.describe Dependabot::Bundler::FileParser::GemspecDeclarationFinder do | ||
let(:checker) do | ||
described_class.new(gemspec: gemspec) | ||
end | ||
|
||
let(:dependency) do | ||
dep = ::Bundler::Dependency.new(dependency_name, | ||
dependency_requirement_sting) | ||
{ | ||
"name" => dep.name, | ||
"requirement" => dep.requirement.to_s | ||
} | ||
end | ||
let(:dependency_name) { "business" } | ||
let(:dependency_requirement_sting) { "~> 1" } | ||
|
||
let(:gemspec) { bundler_project_dependency_file("gemspec_loads_another", filename: "example.gemspec") } | ||
|
||
describe "#gemspec_includes_dependency?" do | ||
subject(:gemspec_includes_dependency) do | ||
checker.gemspec_includes_dependency?(dependency) | ||
end | ||
|
||
context "when the file does not include the dependency" do | ||
let(:dependency_name) { "dependabot-core" } | ||
it { is_expected.to eq(false) } | ||
end | ||
|
||
context "when the file does include the dependency as `add_dependency`" do | ||
let(:dependency_name) { "excon" } | ||
it { is_expected.to eq(true) } | ||
end | ||
|
||
context "when the file does include the dependency as `add_runtime_dependency`" do | ||
let(:dependency_name) { "bundler" } | ||
it { is_expected.to eq(true) } | ||
end | ||
|
||
context "when the file does include the dependency as `add_development_dependency`" do | ||
let(:dependency_name) { "webmock" } | ||
it { is_expected.to eq(true) } | ||
end | ||
|
||
context "when the file loads the dependency dynamically" do | ||
let(:dependency_name) { "rake" } | ||
it { is_expected.to eq(false) } | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
bundler/spec/fixtures/projects/bundler1/gemspec_loads_another/another.gemspec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# frozen_string_literal: true | ||
Gem::Specification.new do |spec| | ||
spec.name = "example" | ||
spec.version = "0.9.3" | ||
spec.summary = "Automated dependency management" | ||
spec.description = "Core logic for updating a GitHub repos dependencies" | ||
|
||
spec.author = "Dependabot" | ||
spec.email = "support@dependabot.com" | ||
spec.homepage = "https://github.com/hmarr/example" | ||
spec.license = "MIT" | ||
|
||
spec.require_path = "lib" | ||
spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", | ||
"lib/**/*", "helpers/**/*"] | ||
|
||
spec.required_ruby_version = ">= 2.4.0" | ||
spec.required_rubygems_version = ">= 2.6.11" | ||
|
||
spec.add_dependency 'business', '~> 1.0' | ||
spec.add_dependency 'statesman', '= 1.0.0' | ||
spec.add_development_dependency 'rake' | ||
end |
30 changes: 30 additions & 0 deletions
30
bundler/spec/fixtures/projects/bundler1/gemspec_loads_another/example.gemspec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# frozen_string_literal: true | ||
Gem::Specification.new do |spec| | ||
another_gemspec = Bundler.load_gemspec_uncached("another.gemspec") | ||
|
||
spec.name = "example" | ||
spec.version = "0.9.3" | ||
spec.summary = "Automated dependency management" | ||
spec.description = "Core logic for updating a GitHub repos dependencies" | ||
spec.date = "2019-08-01" | ||
|
||
spec.author = "Dependabot" | ||
spec.email = "support@dependabot.com" | ||
spec.homepage = "https://github.com/hmarr/example" | ||
spec.license = "MIT" | ||
|
||
spec.require_path = Dir["lib"] | ||
spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", | ||
"lib/**/*", "helpers/**/*"] | ||
|
||
spec.required_ruby_version = ">= 2.4.0" | ||
spec.required_rubygems_version = ">= 2.6.11" | ||
|
||
spec.add_runtime_dependency "bundler", ">= 1.12.0" | ||
spec.add_dependency "excon", "~> 0.55" | ||
spec.add_development_dependency "webmock", "~> 2.3.1" | ||
|
||
another_gemspec.development_dependencies.each do |dep| | ||
spec.add_development_dependency dep.name, *dep.requirement.as_list | ||
end | ||
end |
23 changes: 23 additions & 0 deletions
23
bundler/spec/fixtures/projects/bundler2/gemspec_loads_another/another.gemspec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# frozen_string_literal: true | ||
Gem::Specification.new do |spec| | ||
spec.name = "example" | ||
spec.version = "0.9.3" | ||
spec.summary = "Automated dependency management" | ||
spec.description = "Core logic for updating a GitHub repos dependencies" | ||
|
||
spec.author = "Dependabot" | ||
spec.email = "support@dependabot.com" | ||
spec.homepage = "https://github.com/hmarr/example" | ||
spec.license = "MIT" | ||
|
||
spec.require_path = "lib" | ||
spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", | ||
"lib/**/*", "helpers/**/*"] | ||
|
||
spec.required_ruby_version = ">= 2.4.0" | ||
spec.required_rubygems_version = ">= 2.6.11" | ||
|
||
spec.add_dependency 'business', '~> 1.0' | ||
spec.add_dependency 'statesman', '= 1.0.0' | ||
spec.add_development_dependency 'rake' | ||
end |
30 changes: 30 additions & 0 deletions
30
bundler/spec/fixtures/projects/bundler2/gemspec_loads_another/example.gemspec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# frozen_string_literal: true | ||
Gem::Specification.new do |spec| | ||
another_gemspec = Bundler.load_gemspec_uncached("another.gemspec") | ||
|
||
spec.name = "example" | ||
spec.version = "0.9.3" | ||
spec.summary = "Automated dependency management" | ||
spec.description = "Core logic for updating a GitHub repos dependencies" | ||
spec.date = "2019-08-01" | ||
|
||
spec.author = "Dependabot" | ||
spec.email = "support@dependabot.com" | ||
spec.homepage = "https://github.com/hmarr/example" | ||
spec.license = "MIT" | ||
|
||
spec.require_path = Dir["lib"] | ||
spec.files = Dir["CHANGELOG.md", "LICENSE.txt", "README.md", | ||
"lib/**/*", "helpers/**/*"] | ||
|
||
spec.required_ruby_version = ">= 2.4.0" | ||
spec.required_rubygems_version = ">= 2.6.11" | ||
|
||
spec.add_runtime_dependency "bundler", ">= 1.12.0" | ||
spec.add_dependency "excon", "~> 0.55" | ||
spec.add_development_dependency "webmock", "~> 2.3.1" | ||
|
||
another_gemspec.development_dependencies.each do |dep| | ||
spec.add_development_dependency dep.name, *dep.requirement.as_list | ||
end | ||
end |