Skip to content

Commit

Permalink
Merge pull request #7649 from ggawryal/5864-fix-rust-cargo-workspace-…
Browse files Browse the repository at this point in the history
…dep-discovery

cd: correctly find workspace.dependencies-declared dependencies and their Cargo.toml
  • Loading branch information
Nishnha committed Jul 27, 2023
2 parents 8c3b7e2 + b7603a1 commit ef7e872
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 14 deletions.
40 changes: 26 additions & 14 deletions cargo/lib/dependabot/cargo/file_fetcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,30 +152,32 @@ def fetch_path_dependency_files(file:, previously_fetched_files:)
unfetchable_required_path_deps
end

# rubocop:enable Metrics/PerceivedComplexity
def collect_path_dependencies_paths(dependencies)
paths = []
dependencies.each do |_, details|
next unless details.is_a?(Hash) && details["path"]

paths << File.join(details["path"], "Cargo.toml").delete_prefix("/")
end
paths
end

# rubocop:enable Metrics/PerceivedComplexity
def path_dependency_paths_from_file(file)
paths = []

# Paths specified in dependency declaration
workspace = parsed_file(file).fetch("workspace", {})
Cargo::FileParser::DEPENDENCY_TYPES.each do |type|
parsed_file(file).fetch(type, {}).each do |_, details|
next unless details.is_a?(Hash)
next unless details["path"]

paths << File.join(details["path"], "Cargo.toml").delete_prefix("/")
end
# Paths specified in dependency declaration
paths += collect_path_dependencies_paths(parsed_file(file).fetch(type, {}))
# Paths specified as workspace dependencies in workspace root
paths += collect_path_dependencies_paths(workspace.fetch(type, {}))
end

# Paths specified for target-specific dependencies
parsed_file(file).fetch("target", {}).each do |_, t_details|
Cargo::FileParser::DEPENDENCY_TYPES.each do |type|
t_details.fetch(type, {}).each do |_, details|
next unless details.is_a?(Hash)
next unless details["path"]

paths << File.join(details["path"], "Cargo.toml").delete_prefix("/")
end
paths += collect_path_dependencies_paths(t_details.fetch(type, {}))
end
end

Expand Down Expand Up @@ -263,6 +265,16 @@ def required_path?(file, path)
end
end

# Paths specified for workspace-wide dependencies
workspace = parsed_file(file).fetch("workspace", {})
workspace.fetch("dependencies", {}).each do |_, details|
next unless details.is_a?(Hash)
next unless details["path"]
next unless path == File.join(details["path"], "Cargo.toml")

return true if details["git"].nil?
end

# Paths specified as replacements
parsed_file(file).fetch("replace", {}).each do |_, details|
next unless details.is_a?(Hash)
Expand Down
39 changes: 39 additions & 0 deletions cargo/spec/dependabot/cargo/file_fetcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,45 @@
end
end

context "with another workspace that uses excluded dependency" do
before do
stub_request(:get, url + "?ref=sha").
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_cargo_without_lockfile.json"),
headers: json_header
)
stub_request(:get, url + "Cargo.toml?ref=sha").
with(headers: { "Authorization" => "token token" }).
to_return(status: 200, body: parent_fixture, headers: json_header)

stub_request(:get, url + "member/Cargo.toml?ref=sha").
with(headers: { "Authorization" => "token token" }).
to_return(status: 200, body: member_fixture, headers: json_header)

stub_request(:get, url + "excluded/Cargo.toml?ref=sha").
with(headers: { "Authorization" => "token token" }).
to_return(status: 200, body: member_fixture, headers: json_header)
end
let(:parent_fixture) do
fixture("github", "contents_cargo_manifest_workspace_excluded_dependencies_root.json")
end
let(:member_fixture) do
fixture("github", "contents_cargo_manifest_workspace_excluded_dependencies_member.json")
end
let(:excluded_fixture) do
fixture("github", "contents_cargo_manifest_workspace_excluded_dependencies_excluded.json")
end

it "uses excluded dependency as a support file" do
expect(file_fetcher_instance.files.map(&:name)).
to match_array(%w(Cargo.toml member/Cargo.toml excluded/Cargo.toml))
expect(file_fetcher_instance.files.map(&:support_file?)).
to match_array([false, false, true])
end
end

context "with a Cargo.toml that is unparseable" do
before do
stub_request(:get, url + "?ref=sha").
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "Cargo.toml",
"path": "excluded/Cargo.toml",
"sha": "051e2034b8a01e834993e0252af26789829bbf1d",
"size": 115,
"url": "https://api.github.com/repos/ggawryal/test-cargo-inherited-excluded-dependency/contents/excluded/Cargo.toml?ref=main",
"html_url": "https://github.com/ggawryal/test-cargo-inherited-excluded-dependency/blob/main/excluded/Cargo.toml",
"git_url": "https://api.github.com/repos/ggawryal/test-cargo-inherited-excluded-dependency/git/blobs/051e2034b8a01e834993e0252af26789829bbf1d",
"download_url": "https://raw.githubusercontent.com/ggawryal/test-cargo-inherited-excluded-dependency/main/excluded/Cargo.toml",
"type": "file",
"content": "W3BhY2thZ2VdCm5hbWUgPSAiZXhjbHVkZWQiCnZlcnNpb24gPSAiMC4xLjAi\nCmVkaXRpb24gPSAiMjAyMSIKCltkZXBlbmRlbmNpZXNdCmhleC1saXRlcmFs\nID0geyB2ZXJzaW9uID0gIjAuMy40IiB9Cg==\n",
"encoding": "base64",
"_links": {
"self": "https://api.github.com/repos/ggawryal/test-cargo-inherited-excluded-dependency/contents/excluded/Cargo.toml?ref=main",
"git": "https://api.github.com/repos/ggawryal/test-cargo-inherited-excluded-dependency/git/blobs/051e2034b8a01e834993e0252af26789829bbf1d",
"html": "https://github.com/ggawryal/test-cargo-inherited-excluded-dependency/blob/main/excluded/Cargo.toml"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "Cargo.toml",
"path": "member/Cargo.toml",
"sha": "808c974349f211292687c550431634373b72df74",
"size": 143,
"url": "https://api.github.com/repos/ggawryal/test-cargo-inherited-excluded-dependency/contents/member/Cargo.toml?ref=main",
"html_url": "https://github.com/ggawryal/test-cargo-inherited-excluded-dependency/blob/main/member/Cargo.toml",
"git_url": "https://api.github.com/repos/ggawryal/test-cargo-inherited-excluded-dependency/git/blobs/808c974349f211292687c550431634373b72df74",
"download_url": "https://raw.githubusercontent.com/ggawryal/test-cargo-inherited-excluded-dependency/main/member/Cargo.toml",
"type": "file",
"content": "W3BhY2thZ2VdCm5hbWUgPSAibWVtYmVyIgp2ZXJzaW9uID0gIjAuMS4wIgpl\nZGl0aW9uID0gIjIwMjEiCgpbZGVwZW5kZW5jaWVzXQpleGNsdWRlZCA9IHsg\nd29ya3NwYWNlID0gdHJ1ZSB9CmhleC1saXRlcmFsID0geyB3b3Jrc3BhY2Ug\nPSB0cnVlIH0=\n",
"encoding": "base64",
"_links": {
"self": "https://api.github.com/repos/ggawryal/test-cargo-inherited-excluded-dependency/contents/member/Cargo.toml?ref=main",
"git": "https://api.github.com/repos/ggawryal/test-cargo-inherited-excluded-dependency/git/blobs/808c974349f211292687c550431634373b72df74",
"html": "https://github.com/ggawryal/test-cargo-inherited-excluded-dependency/blob/main/member/Cargo.toml"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "Cargo.toml",
"path": "Cargo.toml",
"sha": "db652f42a677b4686ee668d1d2af9b4266daa15d",
"size": 219,
"url": "https://api.github.com/repos/ggawryal/test-cargo-inherited-excluded-dependency/contents/Cargo.toml?ref=main",
"html_url": "https://github.com/ggawryal/test-cargo-inherited-excluded-dependency/blob/main/Cargo.toml",
"git_url": "https://api.github.com/repos/ggawryal/test-cargo-inherited-excluded-dependency/git/blobs/db652f42a677b4686ee668d1d2af9b4266daa15d",
"download_url": "https://raw.githubusercontent.com/ggawryal/test-cargo-inherited-excluded-dependency/main/Cargo.toml",
"type": "file",
"content": "W3dvcmtzcGFjZS5wYWNrYWdlXQp2ZXJzaW9uID0gIjAuMS4wIgoKW3dvcmtz\ncGFjZV0KCm1lbWJlcnMgPSBbIm1lbWJlciJdCmV4Y2x1ZGUgPSBbImV4Y2x1\nZGVkIl0KClt3b3Jrc3BhY2UuZGVwZW5kZW5jaWVzXQptZW1iZXIgPSB7IHBh\ndGggPSAibWVtYmVyIiB9CmV4Y2x1ZGVkID0geyBwYXRoID0gImV4Y2x1ZGVk\nIiB9CmhleC1saXRlcmFsID0geyB2ZXJzaW9uID0gIjAuMy40IiB9\n",
"encoding": "base64",
"_links": {
"self": "https://api.github.com/repos/ggawryal/test-cargo-inherited-excluded-dependency/contents/Cargo.toml?ref=main",
"git": "https://api.github.com/repos/ggawryal/test-cargo-inherited-excluded-dependency/git/blobs/db652f42a677b4686ee668d1d2af9b4266daa15d",
"html": "https://github.com/ggawryal/test-cargo-inherited-excluded-dependency/blob/main/Cargo.toml"
}
}

0 comments on commit ef7e872

Please sign in to comment.