From d8840c00ab2e184c891ca146d5ff4fda59505501 Mon Sep 17 00:00:00 2001 From: Alfredo Cerezo Date: Tue, 29 Nov 2022 12:00:01 +0100 Subject: [PATCH 1/7] Add version catalog library support --- gradle/lib/dependabot/gradle/file_fetcher.rb | 19 ++- gradle/lib/dependabot/gradle/file_parser.rb | 36 +++++ .../dependabot/gradle/file_fetcher_spec.rb | 71 +++++++++ .../dependabot/gradle/file_parser_spec.rb | 140 ++++++++++++++++++ .../fixtures/github/content_gradle_toml.json | 18 +++ .../fixtures/github/libs_versions_toml.json | 18 +++ .../libs.versions.overlapping.toml | 31 ++++ .../version_catalog_file/libs.versions.toml | 29 ++++ 8 files changed, 361 insertions(+), 1 deletion(-) create mode 100644 gradle/spec/fixtures/github/content_gradle_toml.json create mode 100644 gradle/spec/fixtures/github/libs_versions_toml.json create mode 100644 gradle/spec/fixtures/version_catalog_file/libs.versions.overlapping.toml create mode 100644 gradle/spec/fixtures/version_catalog_file/libs.versions.toml diff --git a/gradle/lib/dependabot/gradle/file_fetcher.rb b/gradle/lib/dependabot/gradle/file_fetcher.rb index 62afbf98196..d05dd4b76d7 100644 --- a/gradle/lib/dependabot/gradle/file_fetcher.rb +++ b/gradle/lib/dependabot/gradle/file_fetcher.rb @@ -14,6 +14,10 @@ class FileFetcher < Dependabot::FileFetchers::Base SUPPORTED_SETTINGS_FILE_NAMES = %w(settings.gradle settings.gradle.kts).freeze + # For now Gradle only supports libray .toml files in the main gradle folder + SUPPORTED_VERSION_CATALOG_FILE_PATH = + %w(/gradle/libs.versions.toml).freeze + def self.required_files_in?(filenames) filenames.any? do |filename| SUPPORTED_BUILD_FILE_NAMES.include?(filename) @@ -33,7 +37,7 @@ def fetch_files end def all_buildfiles_in_build(root_dir) - files = [buildfile(root_dir), settings_file(root_dir)].compact + files = [buildfile(root_dir), settings_file(root_dir), version_catalog_file(root_dir)].compact files += subproject_buildfiles(root_dir) files += dependency_script_plugins(root_dir) files + included_builds(root_dir). @@ -82,6 +86,15 @@ def subproject_buildfiles(root_dir) end end + def version_catalog_file(root_dir) + return nil unless root_dir == "." + + gradle_toml_file(root_dir) + rescue Dependabot::DependencyFileNotFound + # Catalog file is optional for Gradle + nil + end + # rubocop:disable Metrics/PerceivedComplexity def dependency_script_plugins(root_dir) return [] unless buildfile(root_dir) @@ -127,6 +140,10 @@ def buildfile(dir) file end + def gradle_toml_file(dir) + find_first(dir, SUPPORTED_VERSION_CATALOG_FILE_PATH) + end + def settings_file(dir) find_first(dir, SUPPORTED_SETTINGS_FILE_NAMES) end diff --git a/gradle/lib/dependabot/gradle/file_parser.rb b/gradle/lib/dependabot/gradle/file_parser.rb index ac21996109c..e47a368790b 100644 --- a/gradle/lib/dependabot/gradle/file_parser.rb +++ b/gradle/lib/dependabot/gradle/file_parser.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "toml-rb" + require "dependabot/dependency" require "dependabot/file_parsers" require "dependabot/file_parsers/base" @@ -44,6 +46,9 @@ def parse script_plugin_files.each do |plugin_file| dependency_set += buildfile_dependencies(plugin_file) end + version_catalog_file.each do |toml_file| + dependency_set += version_catalog_dependencies(toml_file) + end dependency_set.dependencies end @@ -62,6 +67,31 @@ def self.find_includes(buildfile, dependency_files) private + def version_catalog_dependencies(toml_file) + dependency_set = DependencySet.new + libraries = parsed_toml_file(toml_file)["libraries"] + libraries.each do |_mod, declaration| + version = declaration["version"] + next if version.nil? + + # Only support basic version and reference formats for now, + # refrain from updating anything else as it's likely to be a very deliberate choice. + next unless Gradle::Version.correct?(version) || (version.is_a?(Hash) && version.key?("ref")) + + version_details = version["ref"].nil? ? version : "$" + version["ref"] + group, name = declaration["module"].split(":") + details = { group: group, name: name, version: version_details } + dependency_set << dependency_from(details_hash: details, buildfile: toml_file) + end + dependency_set + end + + def parsed_toml_file(file) + TomlRB.parse(file.content) + rescue TomlRB::ParseError, TomlRB::ValueOverwriteError + raise Dependabot::DependencyFileNotParseable, file.path + end + def map_value_regex(key) /(?:^|\s|,|\()#{Regexp.quote(key)}(\s*=|:)\s*['"](?[^'"]+)['"]/ end @@ -314,6 +344,12 @@ def buildfiles end end + def version_catalog_file + @version_catalog_file ||= dependency_files.select do |f| + f.name.end_with?("libs.versions.toml") + end + end + def script_plugin_files @script_plugin_files ||= buildfiles.flat_map do |buildfile| diff --git a/gradle/spec/dependabot/gradle/file_fetcher_spec.rb b/gradle/spec/dependabot/gradle/file_fetcher_spec.rb index 82df84a7a51..15ed2d43e99 100644 --- a/gradle/spec/dependabot/gradle/file_fetcher_spec.rb +++ b/gradle/spec/dependabot/gradle/file_fetcher_spec.rb @@ -38,10 +38,17 @@ def stub_content_request(path, fixture) }] end + def stub_no_content_request(path) + stub_request(:get, File.join(url, path)). + with(headers: { "Authorization" => "token token" }). + to_return(status: 404) + end + before { allow(file_fetcher_instance).to receive(:commit).and_return("sha") } context "with a basic buildfile" do before do + stub_no_content_request("gradle?ref=sha") stub_content_request("?ref=sha", "contents_java.json") stub_content_request("build.gradle?ref=sha", "contents_java_basic_buildfile.json") end @@ -52,6 +59,19 @@ def stub_content_request(path, fixture) to match_array(%w(build.gradle)) end + context "with version catalog" do + before do + stub_content_request("gradle?ref=sha", "content_gradle_toml.json") + stub_content_request("gradle/libs.versions.toml?ref=sha", "libs_versions_toml.json") + end + + it "fetches the toml file" do + expect(file_fetcher_instance.files.count).to eq(2) + expect(file_fetcher_instance.files.map(&:name)). + to match_array(%w(build.gradle gradle/libs.versions.toml)) + end + end + context "with a settings.gradle" do before do stub_content_request("?ref=sha", "contents_java_with_settings.json") @@ -78,6 +98,19 @@ def stub_content_request(path, fixture) to match_array(%w(build.gradle settings.gradle)) end end + + context "whith versions catalog" do + before do + stub_content_request("gradle?ref=sha", "content_gradle_toml.json") + stub_content_request("gradle/libs.versions.toml?ref=sha", "libs_versions_toml.json") + end + + it "fetches the main buildfile and subproject buildfile and version catalog" do + expect(file_fetcher_instance.files.count).to eq(4) + expect(file_fetcher_instance.files.map(&:name)). + to match_array(%w(build.gradle settings.gradle app/build.gradle gradle/libs.versions.toml)) + end + end end context "with included builds" do @@ -96,6 +129,18 @@ def stub_content_request(path, fixture) expect(file_fetcher_instance.files.map(&:name)). to match_array(%w(build.gradle buildSrc/build.gradle)) end + + context "with version catalog" do + before do + stub_content_request("gradle?ref=sha", "content_gradle_toml.json") + stub_content_request("gradle/libs.versions.toml?ref=sha", "libs_versions_toml.json") + end + + it "fetches all buildfiles and version catalog" do + expect(file_fetcher_instance.files.map(&:name)). + to match_array(%w(build.gradle buildSrc/build.gradle gradle/libs.versions.toml)) + end + end end context "explicitly included" do @@ -244,6 +289,18 @@ def stub_content_request(path, fixture) expect(file_fetcher_instance.files.map(&:name)). to match_array(%w(settings.gradle app/build.gradle)) end + + context "with version catalog" do + before do + stub_content_request("gradle?ref=sha", "content_gradle_toml.json") + stub_content_request("gradle/libs.versions.toml?ref=sha", "libs_versions_toml.json") + end + + it "fetches the main buildfile, subproject buildfile and version catalog" do + expect(file_fetcher_instance.files.map(&:name)). + to match_array(%w(settings.gradle app/build.gradle gradle/libs.versions.toml)) + end + end end context "with kotlin" do @@ -279,6 +336,7 @@ def stub_content_request(path, fixture) context "with a script plugin" do before do + stub_no_content_request("gradle?ref=sha") 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") @@ -290,6 +348,18 @@ def stub_content_request(path, fixture) to match_array(%w(build.gradle gradle/dependencies.gradle)) end + context "with version catalog" do + before do + stub_content_request("gradle?ref=sha", "content_gradle_toml.json") + stub_content_request("gradle/libs.versions.toml?ref=sha", "libs_versions_toml.json") + end + + it "fetches the main buildfile, subproject buildfile and version catalog" do + expect(file_fetcher_instance.files.map(&:name)). + to match_array(%w(build.gradle gradle/dependencies.gradle gradle/libs.versions.toml)) + end + end + context "that can't be found" do before do stub_content_request("?ref=sha", "contents_java.json") @@ -311,6 +381,7 @@ def stub_content_request(path, fixture) context "with no required manifest files" do before do + stub_no_content_request("gradle?ref=sha") stub_request(:get, url + "?ref=sha"). with(headers: { "Authorization" => "token token" }). to_return( diff --git a/gradle/spec/dependabot/gradle/file_parser_spec.rb b/gradle/spec/dependabot/gradle/file_parser_spec.rb index 5b9d8ca504f..973d78f1d03 100644 --- a/gradle/spec/dependabot/gradle/file_parser_spec.rb +++ b/gradle/spec/dependabot/gradle/file_parser_spec.rb @@ -803,5 +803,145 @@ its(:length) { is_expected.to eq(20) } end end + + describe "with a version catalog file" do + let(:files) { [buildfile, version_catalog] } + let(:version_catalog) do + Dependabot::DependencyFile.new( + name: "gradle/libs.versions.toml", + content: fixture("version_catalog_file", "libs.versions.toml") + ) + end + + its(:length) { is_expected.to eq(30) } + + describe "the first dependency" do + subject(:dependency) { dependencies.first } + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.name).to eq("co.aikar:acf-paper") + expect(dependency.version).to eq("0.5.0-SNAPSHOT") + expect(dependency.requirements).to eq( + [{ + requirement: "0.5.0-SNAPSHOT", + file: "build.gradle", + groups: [], + source: nil, + metadata: nil + }] + ) + end + end + + describe "dependency with explicit module and referenced version" do + let(:dependency) do + dependencies.find { |dep| dep.name == "androidx.test.espresso:espresso-core" } + end + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.version).to eq("3.5.0") + expect(dependency.requirements).to eq( + [{ + requirement: "3.5.0", + file: "gradle/libs.versions.toml", + groups: [], + source: nil, + metadata: { property_name: "espresso" } + }] + ) + end + end + + describe "non-referenced version dependency" do + subject(:dependency) do + dependencies.find { |d| d.name == "androidx.activity:activity-compose" } + end + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.name).to eq("androidx.activity:activity-compose") + expect(dependency.version).to eq("1.3.1") + expect(dependency.requirements).to eq( + [{ + requirement: "1.3.1", + file: "gradle/libs.versions.toml", + groups: [], + source: nil, + metadata: nil + }] + ) + end + end + + describe "rich version dependency is ignored" do + subject(:dependency) do + dependencies.find { |d| d.name == "androidx.compose.material:material" } + end + it "has the right details" do + expect(dependency).to be(nil) + end + end + + context "with version catalog file containing dependency overlap with build file" do + let(:files) { [buildfile, version_catalog_overlap] } + + let(:version_catalog_overlap) do + Dependabot::DependencyFile.new( + name: "gradle/libs.versions.toml", + content: fixture("version_catalog_file", "libs.versions.overlapping.toml") + ) + end + + its(:length) { is_expected.to eq(30) } + + describe "the first dependency" do + subject(:dependency) { dependencies.first } + + # This test is wrong, req should also contain changes in the version catalog file + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.name).to eq("co.aikar:acf-paper") + expect(dependency.version).to eq("0.5.0-SNAPSHOT") + expect(dependency.requirements).to eq( + [{ + requirement: "0.5.0-SNAPSHOT", + file: "build.gradle", + groups: [], + source: nil, + metadata: nil + }, + { + requirement: "0.5.0-SNAPSHOT", + file: "gradle/libs.versions.toml", + groups: [], + source: nil, + metadata: { property_name: "coAikar" } + }] + ) + end + end + + describe "the last dependency" do + subject(:dependency) { dependencies.last } + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.name).to eq("androidx.test.espresso:espresso-core") + expect(dependency.version).to eq("3.5.0") + expect(dependency.requirements).to eq( + [{ + requirement: "3.5.0", + file: "gradle/libs.versions.toml", + groups: [], + source: nil, + metadata: { property_name: "espresso" } + }] + ) + end + end + end + end end end diff --git a/gradle/spec/fixtures/github/content_gradle_toml.json b/gradle/spec/fixtures/github/content_gradle_toml.json new file mode 100644 index 00000000000..1d692e7a85a --- /dev/null +++ b/gradle/spec/fixtures/github/content_gradle_toml.json @@ -0,0 +1,18 @@ +[ + { + "name": "libs.versions.toml", + "path": "gradle/libs.versions.toml", + "sha": "61e2017c7cfb111d2c1ada6dc9508711ae02b5c1", + "size": 1470, + "url": "https://api.github.com/repos/bigandroidenergies/version_catalog/contents/gradle/libs.versions.toml?ref=main", + "html_url": "https://github.com/bigandroidenergies/version_catalog/blob/main/gradle/libs.versions.toml", + "git_url": "https://api.github.com/repos/bigandroidenergies/version_catalog/git/blobs/61e2017c7cfb111d2c1ada6dc9508711ae02b5c1", + "download_url": "https://raw.githubusercontent.com/bigandroidenergies/version_catalog/main/gradle/libs.versions.toml", + "type": "file", + "_links": { + "self": "https://api.github.com/repos/bigandroidenergies/version_catalog/contents/gradle/libs.versions.toml?ref=main", + "git": "https://api.github.com/repos/bigandroidenergies/version_catalog/git/blobs/61e2017c7cfb111d2c1ada6dc9508711ae02b5c1", + "html": "https://github.com/bigandroidenergies/version_catalog/blob/main/gradle/libs.versions.toml" + } + } + ] diff --git a/gradle/spec/fixtures/github/libs_versions_toml.json b/gradle/spec/fixtures/github/libs_versions_toml.json new file mode 100644 index 00000000000..1b1fa5502e6 --- /dev/null +++ b/gradle/spec/fixtures/github/libs_versions_toml.json @@ -0,0 +1,18 @@ +{ + "name": "libs.versions.toml", + "path": "gradle/libs.versions.toml", + "sha": "be86def0733c2cd34f58fb5bf4f051b989408f71", + "size": 1510, + "url": "https://api.github.com/repos/bigandroidenergies/version_catalog/contents/gradle/libs.versions.toml?ref=main", + "html_url": "https://github.com/bigandroidenergies/version_catalog/blob/main/gradle/libs.versions.toml", + "git_url": "https://api.github.com/repos/bigandroidenergies/version_catalog/git/blobs/be86def0733c2cd34f58fb5bf4f051b989408f71", + "download_url": "https://raw.githubusercontent.com/bigandroidenergies/version_catalog/main/gradle/libs.versions.toml", + "type": "file", + "content": "W3ZlcnNpb25zXQpjb3Jla3R4ID0gIjEuNy4wIgpsaWZlY3ljbGVSdW50aW1l\nID0gIjIuMy4xIgphY3Rpdml0eUNvbXBvc2UgPSAiMS4zLjEiCmNvbXBvc2VV\naSA9ICIxLjIuMCIKY29tcG9zZU1hdGVyaWFsID0gIjEuMi4wIgpqVW5pdFZl\ncnNpb24gPSAiNC4xMy4yIgphbmRyb2lkeEp1bml0ID0gIjEuMS4zIgplc3By\nZXNzbyA9ICIzLjUuMCIKCltsaWJyYXJpZXNdCmNvcmVrdHggPSB7IG1vZHVs\nZSA9ICJhbmRyb2lkeC5jb3JlOmNvcmUta3R4IiwgdmVyc2lvbi5yZWYgPSAi\nY29yZWt0eCIgfQpsaWZlY3ljbGVSdW50aW1lS3R4ID0geyBtb2R1bGUgPSAi\nYW5kcm9pZHgubGlmZWN5Y2xlOmxpZmVjeWNsZS1ydW50aW1lLWt0eCIsIHZl\ncnNpb24ucmVmID0gImxpZmVjeWNsZVJ1bnRpbWUiIH0KCmNvbXBvc2UtYWN0\naXZpdHkgPSB7IG1vZHVsZSA9ICJhbmRyb2lkeC5hY3Rpdml0eTphY3Rpdml0\neS1jb21wb3NlIiwgdmVyc2lvbi5yZWYgPSAiYWN0aXZpdHlDb21wb3NlIiB9\nCmNvbXBvc2UtdWkgPSB7IG1vZHVsZSA9ICJhbmRyb2lkeC5jb21wb3NlLnVp\nOnVpIiwgdmVyc2lvbi5yZWYgPSAiY29tcG9zZVVpIiB9CmNvbXBvc2UtdWkt\ndG9vbGluZyA9IHsgbW9kdWxlID0gImFuZHJvaWR4LmNvbXBvc2UudWk6dWkt\ndG9vbGluZy1wcmV2aWV3IiwgdmVyc2lvbi5yZWYgPSAiY29tcG9zZVVpIiB9\nCmNvbXBvc2UtbWF0ZXJpYWwgPSB7IG1vZHVsZSA9ICJhbmRyb2lkeC5jb21w\nb3NlLm1hdGVyaWFsOm1hdGVyaWFsIiwgdmVyc2lvbi5yZWYgPSAiY29tcG9z\nZU1hdGVyaWFsIiB9Cgp0ZXN0LWp1bml0ID0geyBtb2R1bGUgPSAianVuaXQ6\nanVuaXQiLCB2ZXJzaW9uLnJlZiA9ICJqVW5pdFZlcnNpb24iIH0KdGVzdC1h\nbmRvcmlkeC1qdW5pdCA9IHsgbW9kdWxlID0gImFuZHJvaWR4LnRlc3QuZXh0\nOmp1bml0IiwgdmVyc2lvbi5yZWYgPSAiYW5kcm9pZHhKdW5pdCIgfQp0ZXN0\nLWNvbXBvc2UtdWkgPSB7IG1vZHVsZSA9ICJhbmRyb2lkeC5jb21wb3NlLnVp\nOnVpLXRlc3QtanVuaXQ0IiwgdmVyc2lvbi5yZWYgPSAiY29tcG9zZVVpIiB9\nCnRlc3QtY29tcG9zZS11aS10b29saW5nID0geyBtb2R1bGUgPSAiYW5kcm9p\nZHguY29tcG9zZS51aTp1aS10b29saW5nIiwgdmVyc2lvbi5yZWYgPSAiY29t\ncG9zZVVpIiB9CnRlc3QtY29tcG9zZS1tYW5pZmVzdCA9IHsgbW9kdWxlID0g\nImFuZHJvaWR4LmNvbXBvc2UudWk6dWktdGVzdC1tYW5pZmVzdCIsIHZlcnNp\nb24ucmVmID0gImNvbXBvc2VVaSIgfQp0ZXN0LWVzcHJlc3NvLUNvcmUgPSB7\nIG1vZHVsZSA9ICJhbmRyb2lkeC50ZXN0LmVzcHJlc3NvOmVzcHJlc3NvLWNv\ncmUiLCB2ZXJzaW9uLnJlZiA9ICJlc3ByZXNzbyIgfQoKW2J1bmRsZXNdCmNv\nbXBvc2UgPSBbImNvbXBvc2UtYWN0aXZpdHkiLCAiY29tcG9zZS11aSIsICJj\nb21wb3NlLXVpLXRvb2xpbmciLCAiY29tcG9zZS1tYXRlcmlhbCJdCgpbcGx1\nZ2luc10Ka290bGludGVyID0geyBpZCA9ICJvcmcuam1haWxlbi5rb3RsaW50\nZXIiLCB2ZXJzaW9uID0gIjMuMTEuMCIgfQ==\n", + "encoding": "base64", + "_links": { + "self": "https://api.github.com/repos/bigandroidenergies/version_catalog/contents/gradle/libs.versions.toml?ref=main", + "git": "https://api.github.com/repos/bigandroidenergies/version_catalog/git/blobs/be86def0733c2cd34f58fb5bf4f051b989408f71", + "html": "https://github.com/bigandroidenergies/version_catalog/blob/main/gradle/libs.versions.toml" + } +} diff --git a/gradle/spec/fixtures/version_catalog_file/libs.versions.overlapping.toml b/gradle/spec/fixtures/version_catalog_file/libs.versions.overlapping.toml new file mode 100644 index 00000000000..1989ee8e2d0 --- /dev/null +++ b/gradle/spec/fixtures/version_catalog_file/libs.versions.overlapping.toml @@ -0,0 +1,31 @@ +[versions] +corektx = "1.7.0" +lifecycleRuntime = "2.3.1" +composeUi = "1.2.0" +jUnitVersion = "4.13.2" +androidxJunit = "1.1.3" +espresso = "3.5.0" +coAikar = "0.5.0-SNAPSHOT" + +[libraries] +coakir = { module = "co.aikar:acf-paper", version.ref = "coAikar" } +corektx = { module = "androidx.core:core-ktx", version.ref = "corektx" } +lifecycleRuntimeKtx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycleRuntime" } + +compose-activity = { module = "androidx.activity:activity-compose", version = "1.3.1" } +compose-ui = { module = "androidx.compose.ui:ui", version.ref = "composeUi" } +compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "composeUi" } +compose-material = { module = "androidx.compose.material:material", version = { strictly = "[1.2.0, 1.3.1[", prefer="1.3.0" } } + +test-junit = { module = "junit:junit", version.ref = "jUnitVersion" } +test-andoridx-junit = { module = "androidx.test.ext:junit", version.ref = "androidxJunit" } +test-compose-ui = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "composeUi" } +test-compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "composeUi" } +test-compose-manifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "composeUi" } +test-espresso-Core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" } + +[bundles] +compose = ["compose-activity", "compose-ui", "compose-ui-tooling", "compose-material"] + +[plugins] +kotlinter = { id = "org.jmailen.kotlinter", version = "3.11.0" } diff --git a/gradle/spec/fixtures/version_catalog_file/libs.versions.toml b/gradle/spec/fixtures/version_catalog_file/libs.versions.toml new file mode 100644 index 00000000000..a3701ffa507 --- /dev/null +++ b/gradle/spec/fixtures/version_catalog_file/libs.versions.toml @@ -0,0 +1,29 @@ +[versions] +corektx = "1.7.0" +lifecycleRuntime = "2.3.1" +composeUi = "1.2.0" +jUnitVersion = "4.13.2" +androidxJunit = "1.1.3" +espresso = "3.5.0" + +[libraries] +corektx = { module = "androidx.core:core-ktx", version.ref = "corektx" } +lifecycleRuntimeKtx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycleRuntime" } + +compose-activity = { module = "androidx.activity:activity-compose", version = "1.3.1" } +compose-ui = { module = "androidx.compose.ui:ui", version.ref = "composeUi" } +compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "composeUi" } +compose-material = { module = "androidx.compose.material:material", version = { strictly = "[1.2.0, 1.3.1[", prefer="1.3.0" } } + +test-junit = { module = "junit:junit", version.ref = "jUnitVersion" } +test-andoridx-junit = { module = "androidx.test.ext:junit", version.ref = "androidxJunit" } +test-compose-ui = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "composeUi" } +test-compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "composeUi" } +test-compose-manifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "composeUi" } +test-espresso-Core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" } + +[bundles] +compose = ["compose-activity", "compose-ui", "compose-ui-tooling", "compose-material"] + +[plugins] +kotlinter = { id = "org.jmailen.kotlinter", version = "3.11.0" } From 684b7fd925c71aa57cbf589982aab33fa15994b2 Mon Sep 17 00:00:00 2001 From: Alfredo Cerezo Date: Fri, 16 Dec 2022 15:46:29 +0100 Subject: [PATCH 2/7] Fix parsing when dependency defined by group + name --- gradle/lib/dependabot/gradle/file_parser.rb | 7 +++++- .../dependabot/gradle/file_parser_spec.rb | 22 ++++++++++++++++++- .../version_catalog_file/libs.versions.toml | 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/gradle/lib/dependabot/gradle/file_parser.rb b/gradle/lib/dependabot/gradle/file_parser.rb index e47a368790b..3a179bb9e1c 100644 --- a/gradle/lib/dependabot/gradle/file_parser.rb +++ b/gradle/lib/dependabot/gradle/file_parser.rb @@ -79,7 +79,12 @@ def version_catalog_dependencies(toml_file) next unless Gradle::Version.correct?(version) || (version.is_a?(Hash) && version.key?("ref")) version_details = version["ref"].nil? ? version : "$" + version["ref"] - group, name = declaration["module"].split(":") + group, name = if declaration["module"] + declaration["module"].split(":") + else + [declaration["group"], declaration["name"]] + end + details = { group: group, name: name, version: version_details } dependency_set << dependency_from(details_hash: details, buildfile: toml_file) end diff --git a/gradle/spec/dependabot/gradle/file_parser_spec.rb b/gradle/spec/dependabot/gradle/file_parser_spec.rb index 973d78f1d03..fe6175e0839 100644 --- a/gradle/spec/dependabot/gradle/file_parser_spec.rb +++ b/gradle/spec/dependabot/gradle/file_parser_spec.rb @@ -813,7 +813,7 @@ ) end - its(:length) { is_expected.to eq(30) } + its(:length) { is_expected.to eq(31) } describe "the first dependency" do subject(:dependency) { dependencies.first } @@ -854,6 +854,26 @@ end end + describe "dependency with group + name and referenced version" do + let(:dependency) do + dependencies.find { |dep| dep.name == "org.jetbrains.kotlin:kotlin-gradle-plugin" } + end + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.version).to eq("1.7.20") + expect(dependency.requirements).to eq( + [{ + requirement: "1.7.20", + file: "gradle/libs.versions.toml", + groups: [], + source: nil, + metadata: { property_name: "kotlin" } + }] + ) + end + end + describe "non-referenced version dependency" do subject(:dependency) do dependencies.find { |d| d.name == "androidx.activity:activity-compose" } diff --git a/gradle/spec/fixtures/version_catalog_file/libs.versions.toml b/gradle/spec/fixtures/version_catalog_file/libs.versions.toml index a3701ffa507..d8cf4881f95 100644 --- a/gradle/spec/fixtures/version_catalog_file/libs.versions.toml +++ b/gradle/spec/fixtures/version_catalog_file/libs.versions.toml @@ -1,4 +1,5 @@ [versions] +kotlin = "1.7.20" corektx = "1.7.0" lifecycleRuntime = "2.3.1" composeUi = "1.2.0" @@ -10,6 +11,8 @@ espresso = "3.5.0" corektx = { module = "androidx.core:core-ktx", version.ref = "corektx" } lifecycleRuntimeKtx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycleRuntime" } +kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" } + compose-activity = { module = "androidx.activity:activity-compose", version = "1.3.1" } compose-ui = { module = "androidx.compose.ui:ui", version.ref = "composeUi" } compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "composeUi" } From ad253849f027e6ca6165f7d3c2e8d455eb2a5fd9 Mon Sep 17 00:00:00 2001 From: Aydin Emre Iskender Date: Fri, 2 Dec 2022 10:08:37 +0100 Subject: [PATCH 3/7] Add version catalog plugin support --- gradle/lib/dependabot/gradle/file_parser.rb | 39 +++-- gradle/lib/dependabot/gradle/file_updater.rb | 2 + .../dependabot/gradle/file_parser_spec.rb | 53 ++++++- .../dependabot/gradle/file_updater_spec.rb | 134 ++++++++++++++++++ .../version_catalog_file/libs.versions.toml | 5 +- 5 files changed, 220 insertions(+), 13 deletions(-) diff --git a/gradle/lib/dependabot/gradle/file_parser.rb b/gradle/lib/dependabot/gradle/file_parser.rb index 3a179bb9e1c..fa402cef016 100644 --- a/gradle/lib/dependabot/gradle/file_parser.rb +++ b/gradle/lib/dependabot/gradle/file_parser.rb @@ -69,8 +69,23 @@ def self.find_includes(buildfile, dependency_files) def version_catalog_dependencies(toml_file) dependency_set = DependencySet.new - libraries = parsed_toml_file(toml_file)["libraries"] - libraries.each do |_mod, declaration| + parsed_toml_file = parsed_toml_file(toml_file) + dependency_set += version_catalog_library_dependencies(parsed_toml_file, toml_file) + dependency_set += version_catalog_plugin_dependencies(parsed_toml_file, toml_file) + dependency_set + end + + def version_catalog_library_dependencies(parsed_toml_file, toml_file) + dependencies_for_declarations(parsed_toml_file["libraries"], toml_file, :details_for_library_dependency) + end + + def version_catalog_plugin_dependencies(parsed_toml_file, toml_file) + dependencies_for_declarations(parsed_toml_file["plugins"], toml_file, :details_for_plugin_dependency) + end + + def dependencies_for_declarations(declarations, toml_file, details_getter) + dependency_set = DependencySet.new + declarations.each do |_mod, declaration| version = declaration["version"] next if version.nil? @@ -79,18 +94,26 @@ def version_catalog_dependencies(toml_file) next unless Gradle::Version.correct?(version) || (version.is_a?(Hash) && version.key?("ref")) version_details = version["ref"].nil? ? version : "$" + version["ref"] - group, name = if declaration["module"] - declaration["module"].split(":") - else - [declaration["group"], declaration["name"]] - end - + group, name = send(details_getter, declaration) details = { group: group, name: name, version: version_details } + dependency_set << dependency_from(details_hash: details, buildfile: toml_file) end dependency_set end + def details_for_library_dependency(declaration) + if declaration["module"] + declaration["module"].split(":") + else + [declaration["group"], declaration["name"]] + end + end + + def details_for_plugin_dependency(declaration) + ["plugins", declaration["id"]] + end + def parsed_toml_file(file) TomlRB.parse(file.content) rescue TomlRB::ParseError, TomlRB::ValueOverwriteError diff --git a/gradle/lib/dependabot/gradle/file_updater.rb b/gradle/lib/dependabot/gradle/file_updater.rb index 347da1488da..73d9967dfbe 100644 --- a/gradle/lib/dependabot/gradle/file_updater.rb +++ b/gradle/lib/dependabot/gradle/file_updater.rb @@ -142,6 +142,8 @@ def original_buildfile_declarations(dependency, requirement) if dependency.name.include?(":") next false unless line.include?(dependency.name.split(":").first) next false unless line.include?(dependency.name.split(":").last) + elsif requirement.fetch(:file).end_with?(".toml") + next false unless line.include?(dependency.name) else name_regex_value = /['"]#{Regexp.quote(dependency.name)}['"]/ name_regex = /(id|kotlin)(\s+#{name_regex_value}|\(#{name_regex_value}\))/ diff --git a/gradle/spec/dependabot/gradle/file_parser_spec.rb b/gradle/spec/dependabot/gradle/file_parser_spec.rb index fe6175e0839..46c23e943fb 100644 --- a/gradle/spec/dependabot/gradle/file_parser_spec.rb +++ b/gradle/spec/dependabot/gradle/file_parser_spec.rb @@ -813,7 +813,7 @@ ) end - its(:length) { is_expected.to eq(31) } + its(:length) { is_expected.to eq(33) } describe "the first dependency" do subject(:dependency) { dependencies.first } @@ -874,6 +874,32 @@ end end + describe "plugin with explicit module and referenced version" do + let(:dependency) do + dependencies.find { |dep| dep.name == "org.jlleitschuh.gradle.ktlint" } + end + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.version).to eq("9.0.0") + expect(dependency.requirements).to eq( + [{ + requirement: "10.0.0", + file: "gradle/libs.versions.toml", + groups: ["plugins"], + source: nil, + metadata: { property_name: "ktlint" } + }, { + requirement: "9.0.0", + file: "gradle/libs.versions.toml", + groups: ["plugins"], + source: nil, + metadata: nil + }] + ) + end + end + describe "non-referenced version dependency" do subject(:dependency) do dependencies.find { |d| d.name == "androidx.activity:activity-compose" } @@ -914,7 +940,7 @@ ) end - its(:length) { is_expected.to eq(30) } + its(:length) { is_expected.to eq(31) } describe "the first dependency" do subject(:dependency) { dependencies.first } @@ -943,8 +969,8 @@ end end - describe "the last dependency" do - subject(:dependency) { dependencies.last } + describe "the last library dependency" do + subject(:dependency) { dependencies[-2] } it "has the right details" do expect(dependency).to be_a(Dependabot::Dependency) @@ -961,6 +987,25 @@ ) end end + + describe "the version catalog plugin" do + subject(:dependency) { dependencies.last } + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.name).to eq("org.jmailen.kotlinter") + expect(dependency.version).to eq("3.11.0") + expect(dependency.requirements).to eq( + [{ + requirement: "3.11.0", + file: "gradle/libs.versions.toml", + groups: ["plugins"], + source: nil, + metadata: nil + }] + ) + end + end end end end diff --git a/gradle/spec/dependabot/gradle/file_updater_spec.rb b/gradle/spec/dependabot/gradle/file_updater_spec.rb index 4b0bd34bffb..17f85e83b1e 100644 --- a/gradle/spec/dependabot/gradle/file_updater_spec.rb +++ b/gradle/spec/dependabot/gradle/file_updater_spec.rb @@ -568,6 +568,140 @@ to include("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1") end end + + context "with a version catalog" do + let(:buildfile) do + Dependabot::DependencyFile.new( + name: "gradle/libs.versions.toml", + content: fixture("version_catalog_file", "libs.versions.toml") + ) + end + let(:dependency) do + Dependabot::Dependency.new( + name: "org.jmailen.kotlinter", + version: "3.12.0", + previous_version: "3.10.0", + requirements: [{ + file: "gradle/libs.versions.toml", + requirement: "3.12.0", + groups: ["plugins"], + source: { type: "maven_repo", url: "https://plugins.gradle.org/m2" }, + metadata: nil + }], + previous_requirements: [{ + file: "gradle/libs.versions.toml", + requirement: "3.10.0", + groups: ["plugins"], + source: { type: "maven_repo", url: "https://plugins.gradle.org/m2" }, + metadata: nil + }], + package_manager: "gradle" + ) + end + + subject(:updated_buildfile) do + updated_files.find { |f| f.name == "gradle/libs.versions.toml" } + end + its(:content) do + is_expected.to include( + 'kotlinter = { id = "org.jmailen.kotlinter", version = "3.12.0" }' + ) + end + end + context "with a version catalog with ref" do + let(:buildfile) do + Dependabot::DependencyFile.new( + name: "gradle/libs.versions.toml", + content: fixture("version_catalog_file", "libs.versions.toml") + ) + end + let(:dependency) do + Dependabot::Dependency.new( + name: "org.jlleitschuh.gradle.ktlint", + version: "11.0.0", + previous_version: "10.0.0", + requirements: [{ + file: "gradle/libs.versions.toml", + requirement: "11.0.0", + groups: ["plugins"], + source: { type: "maven_repo", url: "https://plugins.gradle.org/m2" }, + metadata: { property_name: "ktlint" } + }], + previous_requirements: [{ + file: "gradle/libs.versions.toml", + requirement: "10.0.0", + groups: ["plugins"], + source: { type: "maven_repo", url: "https://plugins.gradle.org/m2" }, + metadata: { property_name: "ktlint" } + }], + package_manager: "gradle" + ) + end + + subject(:updated_buildfile) do + updated_files.find { |f| f.name == "gradle/libs.versions.toml" } + end + its(:content) do + is_expected.to include( + 'ktlint = "11.0.0"' + ) + end + end + + context "with a version catalog with ref and non-ref mixed" do + let(:buildfile) do + Dependabot::DependencyFile.new( + name: "gradle/libs.versions.toml", + content: fixture("version_catalog_file", "libs.versions.toml") + ) + end + let(:dependency) do + Dependabot::Dependency.new( + name: "org.jlleitschuh.gradle.ktlint", + version: "11.0.0", + previous_version: "9.0.0", + requirements: [{ + file: "gradle/libs.versions.toml", + requirement: "11.0.0", + groups: ["plugins"], + source: { type: "maven_repo", url: "https://plugins.gradle.org/m2" }, + metadata: { property_name: "ktlint" } + }, { + file: "gradle/libs.versions.toml", + requirement: "11.0.0", + groups: ["plugins"], + source: { type: "maven_repo", url: "https://plugins.gradle.org/m2" }, + metadata: nil + }], + previous_requirements: [{ + file: "gradle/libs.versions.toml", + requirement: "10.0.0", + groups: ["plugins"], + source: { type: "maven_repo", url: "https://plugins.gradle.org/m2" }, + metadata: { property_name: "ktlint" } + }, { + file: "gradle/libs.versions.toml", + requirement: "9.0.0", + groups: ["plugins"], + source: { type: "maven_repo", url: "https://plugins.gradle.org/m2" }, + metadata: nil + }], + package_manager: "gradle" + ) + end + + subject(:updated_buildfile) do + updated_files.find { |f| f.name == "gradle/libs.versions.toml" } + end + its(:content) do + is_expected.to include( + 'ktlint = "11.0.0"' + ) + is_expected.to include( + 'ktlintUpdated = { id = "org.jlleitschuh.gradle.ktlint", version = "11.0.0" }' + ) + end + end end end end diff --git a/gradle/spec/fixtures/version_catalog_file/libs.versions.toml b/gradle/spec/fixtures/version_catalog_file/libs.versions.toml index d8cf4881f95..92d8d41c558 100644 --- a/gradle/spec/fixtures/version_catalog_file/libs.versions.toml +++ b/gradle/spec/fixtures/version_catalog_file/libs.versions.toml @@ -6,6 +6,7 @@ composeUi = "1.2.0" jUnitVersion = "4.13.2" androidxJunit = "1.1.3" espresso = "3.5.0" +ktlint = "10.0.0" [libraries] corektx = { module = "androidx.core:core-ktx", version.ref = "corektx" } @@ -29,4 +30,6 @@ test-espresso-Core = { module = "androidx.test.espresso:espresso-core", version. compose = ["compose-activity", "compose-ui", "compose-ui-tooling", "compose-material"] [plugins] -kotlinter = { id = "org.jmailen.kotlinter", version = "3.11.0" } +kotlinter = { id = "org.jmailen.kotlinter", version = "3.10.0" } +ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" } +ktlintUpdated = { id = "org.jlleitschuh.gradle.ktlint", version = "9.0.0" } From ea828719426df698eef85b90c586427160a05ee3 Mon Sep 17 00:00:00 2001 From: Alfredo Cerezo Date: Fri, 16 Dec 2022 15:11:22 +0100 Subject: [PATCH 4/7] Support version catalog with only plugins or libraries --- gradle/lib/dependabot/gradle/file_parser.rb | 2 ++ .../dependabot/gradle/file_parser_spec.rb | 24 +++++++++++++++++++ .../libs.versions.only.libraries.toml | 22 +++++++++++++++++ .../libs.versions.only.plugins.toml | 7 ++++++ 4 files changed, 55 insertions(+) create mode 100644 gradle/spec/fixtures/version_catalog_file/libs.versions.only.libraries.toml create mode 100644 gradle/spec/fixtures/version_catalog_file/libs.versions.only.plugins.toml diff --git a/gradle/lib/dependabot/gradle/file_parser.rb b/gradle/lib/dependabot/gradle/file_parser.rb index fa402cef016..d19421264ec 100644 --- a/gradle/lib/dependabot/gradle/file_parser.rb +++ b/gradle/lib/dependabot/gradle/file_parser.rb @@ -85,6 +85,8 @@ def version_catalog_plugin_dependencies(parsed_toml_file, toml_file) def dependencies_for_declarations(declarations, toml_file, details_getter) dependency_set = DependencySet.new + return dependency_set unless declarations + declarations.each do |_mod, declaration| version = declaration["version"] next if version.nil? diff --git a/gradle/spec/dependabot/gradle/file_parser_spec.rb b/gradle/spec/dependabot/gradle/file_parser_spec.rb index 46c23e943fb..a3816e88ef0 100644 --- a/gradle/spec/dependabot/gradle/file_parser_spec.rb +++ b/gradle/spec/dependabot/gradle/file_parser_spec.rb @@ -1008,5 +1008,29 @@ end end end + + describe "parse only version catalog file that contains only libraries" do + let(:files) { [version_catalog] } + let(:version_catalog) do + Dependabot::DependencyFile.new( + name: "gradle/libs.versions.toml", + content: fixture("version_catalog_file", "libs.versions.only.libraries.toml") + ) + end + + its(:length) { is_expected.to eq(11) } + end + + describe "parse only version catalog file that contains only plugins" do + let(:files) { [version_catalog] } + let(:version_catalog) do + Dependabot::DependencyFile.new( + name: "gradle/libs.versions.toml", + content: fixture("version_catalog_file", "libs.versions.only.plugins.toml") + ) + end + + its(:length) { is_expected.to eq(2) } + end end end diff --git a/gradle/spec/fixtures/version_catalog_file/libs.versions.only.libraries.toml b/gradle/spec/fixtures/version_catalog_file/libs.versions.only.libraries.toml new file mode 100644 index 00000000000..1f3050164b5 --- /dev/null +++ b/gradle/spec/fixtures/version_catalog_file/libs.versions.only.libraries.toml @@ -0,0 +1,22 @@ +[versions] +corektx = "1.7.0" +lifecycleRuntime = "2.3.1" +composeUi = "1.2.0" +jUnitVersion = "4.13.2" +androidxJunit = "1.1.3" +espresso = "3.5.0" + +[libraries] +corektx = { module = "androidx.core:core-ktx", version.ref = "corektx" } +lifecycleRuntimeKtx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycleRuntime" } + +compose-activity = { module = "androidx.activity:activity-compose", version = "1.3.1" } +compose-ui = { module = "androidx.compose.ui:ui", version.ref = "composeUi" } +compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "composeUi" } + +test-junit = { module = "junit:junit", version.ref = "jUnitVersion" } +test-andoridx-junit = { module = "androidx.test.ext:junit", version.ref = "androidxJunit" } +test-compose-ui = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "composeUi" } +test-compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "composeUi" } +test-compose-manifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "composeUi" } +test-espresso-Core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" } diff --git a/gradle/spec/fixtures/version_catalog_file/libs.versions.only.plugins.toml b/gradle/spec/fixtures/version_catalog_file/libs.versions.only.plugins.toml new file mode 100644 index 00000000000..4d7a089361d --- /dev/null +++ b/gradle/spec/fixtures/version_catalog_file/libs.versions.only.plugins.toml @@ -0,0 +1,7 @@ +[versions] +ktlint = "10.0.0" + +[plugins] +kotlinter = { id = "org.jmailen.kotlinter", version = "3.10.0" } +ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" } +ktlintUpdated = { id = "org.jlleitschuh.gradle.ktlint", version = "9.0.0" } From d88a61c46bfed5edf734e933bf74cf1f245ff27c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 21 Feb 2023 18:02:00 +0100 Subject: [PATCH 5/7] Support short notation for libraries and plugins --- gradle/lib/dependabot/gradle/file_parser.rb | 28 +++++++++++++------ .../dependabot/gradle/file_parser_spec.rb | 2 +- .../version_catalog_file/libs.versions.toml | 4 +++ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/gradle/lib/dependabot/gradle/file_parser.rb b/gradle/lib/dependabot/gradle/file_parser.rb index d19421264ec..172097c0e92 100644 --- a/gradle/lib/dependabot/gradle/file_parser.rb +++ b/gradle/lib/dependabot/gradle/file_parser.rb @@ -88,15 +88,13 @@ def dependencies_for_declarations(declarations, toml_file, details_getter) return dependency_set unless declarations declarations.each do |_mod, declaration| - version = declaration["version"] - next if version.nil? + group, name, version = send(details_getter, declaration) # Only support basic version and reference formats for now, # refrain from updating anything else as it's likely to be a very deliberate choice. next unless Gradle::Version.correct?(version) || (version.is_a?(Hash) && version.key?("ref")) version_details = version["ref"].nil? ? version : "$" + version["ref"] - group, name = send(details_getter, declaration) details = { group: group, name: name, version: version_details } dependency_set << dependency_from(details_hash: details, buildfile: toml_file) @@ -105,15 +103,27 @@ def dependencies_for_declarations(declarations, toml_file, details_getter) end def details_for_library_dependency(declaration) - if declaration["module"] - declaration["module"].split(":") - else - [declaration["group"], declaration["name"]] - end + version = declaration["version"] + return declaration.split(":") if version.nil? + + group, name = if declaration["module"] + declaration["module"].split(":") + else + [declaration["group"], declaration["name"]] + end + + [group, name, version] end def details_for_plugin_dependency(declaration) - ["plugins", declaration["id"]] + version = declaration["version"] + if version.nil? + name, version = declaration.split(":") + else + name = declaration["id"] + end + + ["plugins", name, version] end def parsed_toml_file(file) diff --git a/gradle/spec/dependabot/gradle/file_parser_spec.rb b/gradle/spec/dependabot/gradle/file_parser_spec.rb index a3816e88ef0..067004941e8 100644 --- a/gradle/spec/dependabot/gradle/file_parser_spec.rb +++ b/gradle/spec/dependabot/gradle/file_parser_spec.rb @@ -813,7 +813,7 @@ ) end - its(:length) { is_expected.to eq(33) } + its(:length) { is_expected.to eq(35) } describe "the first dependency" do subject(:dependency) { dependencies.first } diff --git a/gradle/spec/fixtures/version_catalog_file/libs.versions.toml b/gradle/spec/fixtures/version_catalog_file/libs.versions.toml index 92d8d41c558..d91dfe67ea9 100644 --- a/gradle/spec/fixtures/version_catalog_file/libs.versions.toml +++ b/gradle/spec/fixtures/version_catalog_file/libs.versions.toml @@ -26,6 +26,8 @@ test-compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.r test-compose-manifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "composeUi" } test-espresso-Core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" } +my-lib = "com.mycompany:mylib:1.4" + [bundles] compose = ["compose-activity", "compose-ui", "compose-ui-tooling", "compose-material"] @@ -33,3 +35,5 @@ compose = ["compose-activity", "compose-ui", "compose-ui-tooling", "compose-mate kotlinter = { id = "org.jmailen.kotlinter", version = "3.10.0" } ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" } ktlintUpdated = { id = "org.jlleitschuh.gradle.ktlint", version = "9.0.0" } + +short-notation = "some.plugin.id:1.4" From d52d157b0dfc8d3ef16ba76aec95604fb30d25eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Tue, 21 Feb 2023 18:43:43 +0100 Subject: [PATCH 6/7] Fix parsing dependencies including "ref" in their version --- gradle/lib/dependabot/gradle/file_parser.rb | 26 +++++++------------ .../dependabot/gradle/file_parser_spec.rb | 13 +++++++++- .../version_catalog_file/libs.versions.toml | 1 + 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/gradle/lib/dependabot/gradle/file_parser.rb b/gradle/lib/dependabot/gradle/file_parser.rb index 172097c0e92..4699c601470 100644 --- a/gradle/lib/dependabot/gradle/file_parser.rb +++ b/gradle/lib/dependabot/gradle/file_parser.rb @@ -94,7 +94,7 @@ def dependencies_for_declarations(declarations, toml_file, details_getter) # refrain from updating anything else as it's likely to be a very deliberate choice. next unless Gradle::Version.correct?(version) || (version.is_a?(Hash) && version.key?("ref")) - version_details = version["ref"].nil? ? version : "$" + version["ref"] + version_details = Gradle::Version.correct?(version) ? version : "$" + version["ref"] details = { group: group, name: name, version: version_details } dependency_set << dependency_from(details_hash: details, buildfile: toml_file) @@ -103,27 +103,19 @@ def dependencies_for_declarations(declarations, toml_file, details_getter) end def details_for_library_dependency(declaration) - version = declaration["version"] - return declaration.split(":") if version.nil? + return declaration.split(":") if declaration.is_a?(String) - group, name = if declaration["module"] - declaration["module"].split(":") - else - [declaration["group"], declaration["name"]] - end - - [group, name, version] + if declaration["module"] + [*declaration["module"].split(":"), declaration["version"]] + else + [declaration["group"], declaration["name"], declaration["version"]] + end end def details_for_plugin_dependency(declaration) - version = declaration["version"] - if version.nil? - name, version = declaration.split(":") - else - name = declaration["id"] - end + return ["plugins", *declaration.split(":")] if declaration.is_a?(String) - ["plugins", name, version] + ["plugins", declaration["id"], declaration["version"]] end def parsed_toml_file(file) diff --git a/gradle/spec/dependabot/gradle/file_parser_spec.rb b/gradle/spec/dependabot/gradle/file_parser_spec.rb index 067004941e8..c95a7991724 100644 --- a/gradle/spec/dependabot/gradle/file_parser_spec.rb +++ b/gradle/spec/dependabot/gradle/file_parser_spec.rb @@ -813,7 +813,7 @@ ) end - its(:length) { is_expected.to eq(35) } + its(:length) { is_expected.to eq(36) } describe "the first dependency" do subject(:dependency) { dependencies.first } @@ -900,6 +900,17 @@ end end + describe "dependency with short format and 'ref' in its version" do + let(:dependency) do + dependencies.find { |dep| dep.name == "com.mycompany:mylib-with-version-including-ref" } + end + + it "has the right details" do + expect(dependency).to be_a(Dependabot::Dependency) + expect(dependency.version).to eq("1.4-ref") + end + end + describe "non-referenced version dependency" do subject(:dependency) do dependencies.find { |d| d.name == "androidx.activity:activity-compose" } diff --git a/gradle/spec/fixtures/version_catalog_file/libs.versions.toml b/gradle/spec/fixtures/version_catalog_file/libs.versions.toml index d91dfe67ea9..e983b7406a2 100644 --- a/gradle/spec/fixtures/version_catalog_file/libs.versions.toml +++ b/gradle/spec/fixtures/version_catalog_file/libs.versions.toml @@ -27,6 +27,7 @@ test-compose-manifest = { module = "androidx.compose.ui:ui-test-manifest", versi test-espresso-Core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" } my-lib = "com.mycompany:mylib:1.4" +my-lib-with-version-including-ref = "com.mycompany:mylib-with-version-including-ref:1.4-ref" [bundles] compose = ["compose-activity", "compose-ui", "compose-ui-tooling", "compose-material"] From 37797fe2436ed55a61bd8d085ab4036be77d6944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rodr=C3=ADguez?= Date: Fri, 10 Mar 2023 14:17:14 +0100 Subject: [PATCH 7/7] Also ignore rich versions specified as properties --- gradle/lib/dependabot/gradle/file_parser.rb | 4 +++- gradle/spec/dependabot/gradle/file_parser_spec.rb | 9 +++++++++ .../fixtures/version_catalog_file/libs.versions.toml | 3 +++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gradle/lib/dependabot/gradle/file_parser.rb b/gradle/lib/dependabot/gradle/file_parser.rb index 4699c601470..097690c04dd 100644 --- a/gradle/lib/dependabot/gradle/file_parser.rb +++ b/gradle/lib/dependabot/gradle/file_parser.rb @@ -96,8 +96,10 @@ def dependencies_for_declarations(declarations, toml_file, details_getter) version_details = Gradle::Version.correct?(version) ? version : "$" + version["ref"] details = { group: group, name: name, version: version_details } + dependency = dependency_from(details_hash: details, buildfile: toml_file) + next unless dependency - dependency_set << dependency_from(details_hash: details, buildfile: toml_file) + dependency_set << dependency end dependency_set end diff --git a/gradle/spec/dependabot/gradle/file_parser_spec.rb b/gradle/spec/dependabot/gradle/file_parser_spec.rb index c95a7991724..7630fff9e99 100644 --- a/gradle/spec/dependabot/gradle/file_parser_spec.rb +++ b/gradle/spec/dependabot/gradle/file_parser_spec.rb @@ -941,6 +941,15 @@ end end + describe "rich version dependency specified as a property is ignored" do + subject(:dependency) do + dependencies.find { |d| d.name == "com.util.juice:juice" } + end + it "has the right details" do + expect(dependency).to be(nil) + end + end + context "with version catalog file containing dependency overlap with build file" do let(:files) { [buildfile, version_catalog_overlap] } diff --git a/gradle/spec/fixtures/version_catalog_file/libs.versions.toml b/gradle/spec/fixtures/version_catalog_file/libs.versions.toml index e983b7406a2..3bf79b2943a 100644 --- a/gradle/spec/fixtures/version_catalog_file/libs.versions.toml +++ b/gradle/spec/fixtures/version_catalog_file/libs.versions.toml @@ -7,6 +7,7 @@ jUnitVersion = "4.13.2" androidxJunit = "1.1.3" espresso = "3.5.0" ktlint = "10.0.0" +juice = { strictly = "3.0" } [libraries] corektx = { module = "androidx.core:core-ktx", version.ref = "corektx" } @@ -29,6 +30,8 @@ test-espresso-Core = { module = "androidx.test.espresso:espresso-core", version. my-lib = "com.mycompany:mylib:1.4" my-lib-with-version-including-ref = "com.mycompany:mylib-with-version-including-ref:1.4-ref" +juice = { module = "com.util.juice:juice", version.ref="juice" } + [bundles] compose = ["compose-activity", "compose-ui", "compose-ui-tooling", "compose-material"]