Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cd: correctly find workspace.dependencies-declared dependencies and their Cargo.toml #7649

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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"
}
}