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

Support Gradle files with no top level build.gradle file #4256

Merged
merged 2 commits into from
Oct 7, 2021
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions gradle/lib/dependabot/gradle/file_fetcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def self.required_files_message

def fetch_files
fetched_files = []
fetched_files << buildfile
fetched_files << buildfile if buildfile
fetched_files += subproject_buildfiles
fetched_files += dependency_script_plugins
check_required_files_present
Expand All @@ -46,17 +46,23 @@ def buildfile
def subproject_buildfiles
return [] unless settings_file

subproject_paths =
SettingsFileParser.
new(settings_file: settings_file).
subproject_paths

subproject_paths.map do |path|
fetch_file_from_host(File.join(path, @buildfile_name))
rescue Dependabot::DependencyFileNotFound
# Gradle itself doesn't worry about missing subprojects, so we don't
nil
end.compact
@subproject_buildfiles ||= begin
subproject_paths =
SettingsFileParser.
new(settings_file: settings_file).
subproject_paths

subproject_paths.map do |path|
if @buildfile_name
fetch_file_from_host(File.join(path, @buildfile_name))
else
supported_file(SUPPORTED_BUILD_FILE_NAMES.map { |f| File.join(path, f) })
end
rescue Dependabot::DependencyFileNotFound
# Gradle itself doesn't worry about missing subprojects, so we don't
nil
end.compact
end
end

# rubocop:disable Metrics/PerceivedComplexity
Expand All @@ -83,7 +89,7 @@ def dependency_script_plugins
# rubocop:enable Metrics/PerceivedComplexity

def check_required_files_present
return if buildfile
return if buildfile || (subproject_buildfiles && !subproject_buildfiles.empty?)

path = Pathname.new(File.join(directory, "build.gradle")).cleanpath.to_path
path += "(.kts)?"
Expand Down
2 changes: 1 addition & 1 deletion gradle/lib/dependabot/gradle/file_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ def script_plugin_files
end

def check_required_files
raise "No build.gradle or build.gradle.kts!" unless original_file
raise "No build.gradle or build.gradle.kts!" if dependency_files.empty?
end

def original_file
Expand Down
2 changes: 1 addition & 1 deletion gradle/lib/dependabot/gradle/file_updater.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def updated_dependency_files
private

def check_required_files
raise "No build.gradle or build.gradle.kts!" unless original_file
raise "No build.gradle or build.gradle.kts!" if dependency_files.empty?
end

def original_file
Expand Down
147 changes: 39 additions & 108 deletions gradle/spec/dependabot/gradle/file_fetcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@
let(:file_fetcher_instance) do
described_class.new(source: source, credentials: credentials)
end
def stub_content_request(path, fixture)
stub_request(:get, File.join(url, path)).
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", fixture),
headers: { "content-type" => "application/json" }
)
end
let(:directory) { "/" }
let(:github_url) { "https://api.github.com/" }
let(:url) { github_url + "repos/gocardless/bump/contents/" }
Expand All @@ -33,20 +42,8 @@

context "with a basic buildfile" do
before do
stub_request(:get, url + "?ref=sha").
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_java.json"),
headers: { "content-type" => "application/json" }
)
stub_request(:get, File.join(url, "build.gradle?ref=sha")).
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_java_basic_buildfile.json"),
headers: { "content-type" => "application/json" }
)
stub_content_request("?ref=sha", "contents_java.json")
stub_content_request("build.gradle?ref=sha", "contents_java_basic_buildfile.json")
end

it "fetches the buildfile" do
Expand All @@ -57,27 +54,9 @@

context "with a settings.gradle" do
before do
stub_request(:get, url + "?ref=sha").
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_java_with_settings.json"),
headers: { "content-type" => "application/json" }
)
stub_request(:get, File.join(url, "settings.gradle?ref=sha")).
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_java_simple_settings.json"),
headers: { "content-type" => "application/json" }
)
stub_request(:get, File.join(url, "app/build.gradle?ref=sha")).
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_java_basic_buildfile.json"),
headers: { "content-type" => "application/json" }
)
stub_content_request("?ref=sha", "contents_java_with_settings.json")
stub_content_request("settings.gradle?ref=sha", "contents_java_simple_settings.json")
stub_content_request("app/build.gradle?ref=sha", "contents_java_basic_buildfile.json")
end

it "fetches the main buildfile and subproject buildfile" do
Expand All @@ -101,22 +80,25 @@
end
end

context "only a settings.gradle" do
before do
stub_content_request("?ref=sha", "contents_java_only_settings.json")
stub_content_request("app?ref=sha", "contents_java_subproject.json")
stub_content_request("settings.gradle?ref=sha", "contents_java_simple_settings.json")
stub_content_request("app/build.gradle?ref=sha", "contents_java_basic_buildfile.json")
end

it "fetches the main buildfile and subproject buildfile" do
expect(file_fetcher_instance.files.count).to eq(1)
expect(file_fetcher_instance.files.map(&:name)).
to match_array(%w(app/build.gradle))
end
end

context "with kotlin" do
before do
stub_request(:get, url + "?ref=sha").
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_kotlin.json"),
headers: { "content-type" => "application/json" }
)
stub_request(:get, File.join(url, "build.gradle.kts?ref=sha")).
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_kotlin_basic_buildfile.json"),
headers: { "content-type" => "application/json" }
)
stub_content_request("?ref=sha", "contents_kotlin.json")
stub_content_request("build.gradle.kts?ref=sha", "contents_kotlin_basic_buildfile.json")
stub_request(:get, File.join(url, "settings.gradle.kts?ref=sha")).
with(headers: { "Authorization" => "token token" }).
to_return(status: 404)
Expand All @@ -130,27 +112,9 @@

context "with a settings.gradle.kts" do
before do
stub_request(:get, url + "?ref=sha").
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_kotlin_with_settings.json"),
headers: { "content-type" => "application/json" }
)
stub_request(:get, File.join(url, "settings.gradle.kts?ref=sha")).
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_kotlin_simple_settings.json"),
headers: { "content-type" => "application/json" }
)
stub_request(:get, File.join(url, "app/build.gradle.kts?ref=sha")).
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_kotlin_basic_buildfile.json"),
headers: { "content-type" => "application/json" }
)
stub_content_request("?ref=sha", "contents_kotlin_with_settings.json")
stub_content_request("settings.gradle.kts?ref=sha", "contents_kotlin_simple_settings.json")
stub_content_request("app/build.gradle.kts?ref=sha", "contents_kotlin_basic_buildfile.json")
end

it "fetches the main buildfile and subproject buildfile" do
Expand All @@ -164,30 +128,9 @@

context "with a script plugin" do
before do
stub_request(:get, url + "?ref=sha").
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_java.json"),
headers: { "content-type" => "application/json" }
)
stub_request(:get, File.join(url, "build.gradle?ref=sha")).
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture(
"github",
"contents_java_buildfile_with_script_plugins.json"
),
headers: { "content-type" => "application/json" }
)
stub_request(:get, File.join(url, "gradle/dependencies.gradle?ref=sha")).
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_java_simple_settings.json"),
headers: { "content-type" => "application/json" }
)
stub_content_request("?ref=sha", "contents_java.json")
stub_content_request("build.gradle?ref=sha", "contents_java_buildfile_with_script_plugins.json")
stub_content_request("gradle/dependencies.gradle?ref=sha", "contents_java_simple_settings.json")
end

it "fetches the buildfile and the dependencies script" do
Expand All @@ -198,26 +141,14 @@

context "that can't be found" do
before do
stub_request(:get, url + "?ref=sha").
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_java.json"),
headers: { "content-type" => "application/json" }
)
stub_content_request("?ref=sha", "contents_java.json")
stub_request(
:get,
File.join(url, "gradle/dependencies.gradle?ref=sha")
).with(headers: { "Authorization" => "token token" }).
to_return(status: 404)

stub_request(:get, File.join(url, "gradle?ref=sha")).
with(headers: { "Authorization" => "token token" }).
to_return(
status: 200,
body: fixture("github", "contents_with_settings.json"),
headers: { "content-type" => "application/json" }
)
stub_content_request("gradle?ref=sha", "contents_with_settings.json")
end

it "raises a DependencyFileNotFound error" do
Expand Down
66 changes: 66 additions & 0 deletions gradle/spec/fixtures/github/contents_java_only_settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
[
{
"name": ".gitignore",
"path": ".gitignore",
"sha": "a1fc39c070f4f8ba52f278c15cd4d2121d07c8a8",
"size": 308,
"url": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/contents/.gitignore?ref=main",
"html_url": "https://github.com/dependabot-fixtures/gradle-with-settings/blob/main/.gitignore",
"git_url": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/git/blobs/a1fc39c070f4f8ba52f278c15cd4d2121d07c8a8",
"download_url": "https://raw.githubusercontent.com/dependabot-fixtures/gradle-with-settings/main/.gitignore",
"type": "file",
"_links": {
"self": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/contents/.gitignore?ref=main",
"git": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/git/blobs/a1fc39c070f4f8ba52f278c15cd4d2121d07c8a8",
"html": "https://github.com/dependabot-fixtures/gradle-with-settings/blob/main/.gitignore"
}
},
{
"name": "dependencies",
"path": "dependencies",
"sha": "5df7f650b80fef281199e7d1c6bf53c6a5280802",
"size": 0,
"url": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/contents/dependencies?ref=main",
"html_url": "https://github.com/dependabot-fixtures/gradle-with-settings/tree/main/dependencies",
"git_url": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/git/trees/5df7f650b80fef281199e7d1c6bf53c6a5280802",
"download_url": null,
"type": "dir",
"_links": {
"self": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/contents/dependencies?ref=main",
"git": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/git/trees/5df7f650b80fef281199e7d1c6bf53c6a5280802",
"html": "https://github.com/dependabot-fixtures/gradle-with-settings/tree/main/dependencies"
}
},
{
"name": "pom.xml",
"path": "pom.xml",
"sha": "9a0a1f4bb5db4083b7f4ba9d8fee33675de8dc62",
"size": 15579,
"url": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/contents/pom.xml?ref=main",
"html_url": "https://github.com/dependabot-fixtures/gradle-with-settings/blob/main/pom.xml",
"git_url": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/git/blobs/9a0a1f4bb5db4083b7f4ba9d8fee33675de8dc62",
"download_url": "https://raw.githubusercontent.com/dependabot-fixtures/gradle-with-settings/main/pom.xml",
"type": "file",
"_links": {
"self": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/contents/pom.xml?ref=main",
"git": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/git/blobs/9a0a1f4bb5db4083b7f4ba9d8fee33675de8dc62",
"html": "https://github.com/dependabot-fixtures/gradle-with-settings/blob/main/pom.xml"
}
},
{
"name": "settings.gradle",
"path": "settings.gradle",
"sha": "a9fc565d30dbca65176e111b6d9a24351e146b4c",
"size": 38,
"url": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/contents/settings.gradle?ref=main",
"html_url": "https://github.com/dependabot-fixtures/gradle-with-settings/blob/main/settings.gradle",
"git_url": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/git/blobs/a9fc565d30dbca65176e111b6d9a24351e146b4c",
"download_url": "https://raw.githubusercontent.com/dependabot-fixtures/gradle-with-settings/main/settings.gradle",
"type": "file",
"_links": {
"self": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/contents/settings.gradle?ref=main",
"git": "https://api.github.com/repos/dependabot-fixtures/gradle-with-settings/git/blobs/a9fc565d30dbca65176e111b6d9a24351e146b4c",
"html": "https://github.com/dependabot-fixtures/gradle-with-settings/blob/main/settings.gradle"
}
}
]
18 changes: 18 additions & 0 deletions gradle/spec/fixtures/github/contents_java_subproject.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[
{
"name": "build.gradle",
"path": "app/build.gradle",
"sha": "f036f9f0357a50b02a422923f0bb0c3719eaf8ae",
"size": 2355,
"url": "https://api.github.com/repos/dependabot-fixtures/gradle/contents/build.gradle?ref=main",
"html_url": "https://github.com/dependabot-fixtures/gradle/blob/main/build.gradle",
"git_url": "https://api.github.com/repos/dependabot-fixtures/gradle/git/blobs/f036f9f0357a50b02a422923f0bb0c3719eaf8ae",
"download_url": "https://raw.githubusercontent.com/dependabot-fixtures/gradle/main/build.gradle",
"type": "file",
"_links": {
"self": "https://api.github.com/repos/dependabot-fixtures/gradle/contents/build.gradle?ref=main",
"git": "https://api.github.com/repos/dependabot-fixtures/gradle/git/blobs/f036f9f0357a50b02a422923f0bb0c3719eaf8ae",
"html": "https://github.com/dependabot-fixtures/gradle/blob/main/build.gradle"
}
}
]