dependabot-gradle 0.382.0 → 0.383.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/dependabot/gradle/distributions.rb +3 -1
- data/lib/dependabot/gradle/file_updater/wrapper/command_builder.rb +103 -0
- data/lib/dependabot/gradle/file_updater/wrapper/executing_version_detector.rb +60 -0
- data/lib/dependabot/gradle/file_updater/wrapper/gradle_version_capabilities.rb +59 -0
- data/lib/dependabot/gradle/file_updater/wrapper/properties_document.rb +96 -0
- data/lib/dependabot/gradle/file_updater/wrapper/properties_reconciler.rb +71 -0
- data/lib/dependabot/gradle/file_updater/wrapper_updater.rb +91 -72
- data/lib/dependabot/gradle/package/package_details_fetcher.rb +6 -3
- data/lib/dependabot/gradle/update_checker/requirements_updater.rb +16 -11
- data/lib/dependabot/gradle/update_checker/version_finder.rb +4 -2
- data/lib/dependabot/gradle/update_checker.rb +6 -8
- metadata +11 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d3cb4e728e6f95cd0ba68227af68fd31b0e30ff55a7c28090bfd7f9bc0a357bd
|
|
4
|
+
data.tar.gz: 268f0b46c9fce142acc4f4b615803481e6e9a72844aafcaee0b18becccd471ef
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 935e89f7162570265dc615315f89267fa5aee57d231e5ad7f561d4f08e7759310b3deff9c2e9170c8286d5e57384574c990bfc6be3101835e5ab72d5cf5b1a63
|
|
7
|
+
data.tar.gz: 06c419e20a01912105e76ec70577a27ab9fc091b37493b7d2481ae7e3383fc1d971004b6561b573f45db9bb0d54cfaafa35588e38b5e1aafd8f5c50cbc31f563
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# typed: strict
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
+
require "dependabot/dependency_requirement"
|
|
5
|
+
|
|
4
6
|
module Dependabot
|
|
5
7
|
module Gradle
|
|
6
8
|
module Distributions
|
|
@@ -9,7 +11,7 @@ module Dependabot
|
|
|
9
11
|
DISTRIBUTION_REPOSITORY_URL = "https://services.gradle.org"
|
|
10
12
|
DISTRIBUTION_DEPENDENCY_TYPE = "gradle-distribution"
|
|
11
13
|
|
|
12
|
-
sig { params(requirements: T::Array[
|
|
14
|
+
sig { params(requirements: T::Array[Dependabot::DependencyRequirement]).returns(T::Boolean) }
|
|
13
15
|
def self.distribution_requirements?(requirements)
|
|
14
16
|
requirements.any? do |req|
|
|
15
17
|
req.dig(:source, :type) == DISTRIBUTION_DEPENDENCY_TYPE
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
|
|
6
|
+
require "dependabot/gradle/file_updater"
|
|
7
|
+
require "dependabot/gradle/file_updater/wrapper/gradle_version_capabilities"
|
|
8
|
+
require "dependabot/gradle/file_updater/wrapper/properties_document"
|
|
9
|
+
|
|
10
|
+
module Dependabot
|
|
11
|
+
module Gradle
|
|
12
|
+
class FileUpdater
|
|
13
|
+
module Wrapper
|
|
14
|
+
# Builds the argument list for Gradle's `wrapper` task.
|
|
15
|
+
#
|
|
16
|
+
# The output file is reconciled afterwards (see PropertiesReconciler), so these arguments do
|
|
17
|
+
# not need to fully reproduce the user's file. We still forward the user's gated, run-relevant
|
|
18
|
+
# settings (networkTimeout/retries/retryBackOffMs) when the *executing* Gradle version supports
|
|
19
|
+
# them, both to honor the user's configuration during the run and to align with the wrapper
|
|
20
|
+
# task's intended usage. Options unsupported by the executing version are omitted so the run
|
|
21
|
+
# never aborts on an unknown flag.
|
|
22
|
+
class CommandBuilder
|
|
23
|
+
extend T::Sig
|
|
24
|
+
|
|
25
|
+
# Maps an existing properties key to its wrapper CLI option and the capability key used to
|
|
26
|
+
# decide whether the executing Gradle version understands the flag.
|
|
27
|
+
STEERED_OPTIONS = T.let(
|
|
28
|
+
[
|
|
29
|
+
["networkTimeout", "--network-timeout", GradleVersionCapabilities::NETWORK_TIMEOUT],
|
|
30
|
+
["retries", "--retries", GradleVersionCapabilities::RETRIES],
|
|
31
|
+
["retryBackOffMs", "--retry-back-off-ms", GradleVersionCapabilities::RETRY_BACK_OFF_MS]
|
|
32
|
+
].freeze,
|
|
33
|
+
T::Array[[String, String, String]]
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
sig do
|
|
37
|
+
params(
|
|
38
|
+
requirements: T::Array[Dependabot::DependencyRequirement],
|
|
39
|
+
original_properties: T.nilable(PropertiesDocument),
|
|
40
|
+
gradle_version: T.nilable(Dependabot::Gradle::Version)
|
|
41
|
+
).void
|
|
42
|
+
end
|
|
43
|
+
def initialize(requirements:, original_properties:, gradle_version:)
|
|
44
|
+
@requirements = requirements
|
|
45
|
+
@original_properties = original_properties
|
|
46
|
+
@gradle_version = gradle_version
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
sig { returns(T::Array[String]) }
|
|
50
|
+
def build
|
|
51
|
+
args = %W(wrapper --gradle-version #{version})
|
|
52
|
+
|
|
53
|
+
# Dependabot's proxy cannot satisfy the HEAD request Gradle issues to validate the
|
|
54
|
+
# distribution URL, so we always skip validation. The user's original
|
|
55
|
+
# `validateDistributionUrl` value is preserved by reconciliation.
|
|
56
|
+
args += %w(--no-validate-url)
|
|
57
|
+
|
|
58
|
+
args += steered_args
|
|
59
|
+
args += %W(--distribution-type #{distribution_type}) if distribution_type
|
|
60
|
+
args += %W(--gradle-distribution-sha256-sum #{checksum}) if checksum
|
|
61
|
+
args
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
sig { returns(T::Array[String]) }
|
|
67
|
+
def steered_args
|
|
68
|
+
properties = @original_properties
|
|
69
|
+
return [] if properties.nil?
|
|
70
|
+
|
|
71
|
+
STEERED_OPTIONS.flat_map do |property_key, flag, capability|
|
|
72
|
+
value = properties.value_for(property_key)
|
|
73
|
+
next [] if value.nil? || value.strip.empty?
|
|
74
|
+
next [] unless GradleVersionCapabilities.supports?(capability, @gradle_version)
|
|
75
|
+
|
|
76
|
+
[flag, value]
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
sig { returns(String) }
|
|
81
|
+
def version
|
|
82
|
+
T.let(T.must(@requirements[0])[:requirement], String)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
sig { returns(T.nilable(String)) }
|
|
86
|
+
def checksum
|
|
87
|
+
return nil unless @requirements.size > 1
|
|
88
|
+
|
|
89
|
+
T.let(T.must(@requirements[1])[:requirement], String)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
sig { returns(T.nilable(String)) }
|
|
93
|
+
def distribution_type
|
|
94
|
+
url = T.let(T.must(@requirements[0])[:source], T::Hash[Symbol, String])[:url]
|
|
95
|
+
# Anchor to the `-bin.zip` / `-all.zip` filename suffix so a path segment such as a
|
|
96
|
+
# mirror host (e.g. https://binaries.example.com/...) can't false-match `bin`/`all`.
|
|
97
|
+
url&.match(/-(bin|all)\.zip/)&.captures&.first
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
|
|
6
|
+
require "dependabot/gradle/file_updater"
|
|
7
|
+
require "dependabot/gradle/version"
|
|
8
|
+
|
|
9
|
+
module Dependabot
|
|
10
|
+
module Gradle
|
|
11
|
+
class FileUpdater
|
|
12
|
+
module Wrapper
|
|
13
|
+
# Detects the Gradle version that will actually *execute* the wrapper task.
|
|
14
|
+
#
|
|
15
|
+
# The wrapper task runs under whatever Gradle the project currently resolves to (the OLD
|
|
16
|
+
# distribution), not the target version. Knowing that version lets CommandBuilder decide
|
|
17
|
+
# which version-gated CLI flags are safe to pass.
|
|
18
|
+
module ExecutingVersionDetector
|
|
19
|
+
extend T::Sig
|
|
20
|
+
|
|
21
|
+
# Matches the version embedded in a Gradle distribution URL, e.g.
|
|
22
|
+
# https://services.gradle.org/distributions/gradle-9.5.0-bin.zip
|
|
23
|
+
# Anchored to the `gradle-<version>-(bin|all).zip` filename so host/port numbers in custom
|
|
24
|
+
# mirror URLs are never mistaken for the version. The captured token is validated with
|
|
25
|
+
# Version.correct? so non-version matches (and RC/milestone names) are handled safely.
|
|
26
|
+
DISTRIBUTION_URL_VERSION_REGEX = T.let(
|
|
27
|
+
/gradle-(?<version>.+?)-(?:bin|all)\.zip/,
|
|
28
|
+
Regexp
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Matches the version printed by `gradle --version`, e.g. "Gradle 9.2.1".
|
|
32
|
+
GRADLE_VERSION_OUTPUT_REGEX = T.let(/^Gradle\s+(?<version>\d+(?:\.\d+){1,2}(?:-[\w.]+)?)/, Regexp)
|
|
33
|
+
|
|
34
|
+
sig { params(distribution_url: T.nilable(String)).returns(T.nilable(Dependabot::Gradle::Version)) }
|
|
35
|
+
def self.from_distribution_url(distribution_url)
|
|
36
|
+
return nil if distribution_url.nil?
|
|
37
|
+
|
|
38
|
+
captured = distribution_url.match(DISTRIBUTION_URL_VERSION_REGEX)&.named_captures&.fetch("version", nil)
|
|
39
|
+
build_version(captured)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
sig { params(output: T.nilable(String)).returns(T.nilable(Dependabot::Gradle::Version)) }
|
|
43
|
+
def self.from_version_output(output)
|
|
44
|
+
return nil if output.nil?
|
|
45
|
+
|
|
46
|
+
captured = output.match(GRADLE_VERSION_OUTPUT_REGEX)&.named_captures&.fetch("version", nil)
|
|
47
|
+
build_version(captured)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
sig { params(captured: T.nilable(String)).returns(T.nilable(Dependabot::Gradle::Version)) }
|
|
51
|
+
def self.build_version(captured)
|
|
52
|
+
return nil if captured.nil? || !Dependabot::Gradle::Version.correct?(captured)
|
|
53
|
+
|
|
54
|
+
T.cast(Dependabot::Gradle::Version.new(captured), Dependabot::Gradle::Version)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
|
|
6
|
+
require "dependabot/gradle/file_updater"
|
|
7
|
+
require "dependabot/gradle/version"
|
|
8
|
+
|
|
9
|
+
module Dependabot
|
|
10
|
+
module Gradle
|
|
11
|
+
class FileUpdater
|
|
12
|
+
module Wrapper
|
|
13
|
+
# Declarative table of `wrapper` task command-line options and the minimum Gradle
|
|
14
|
+
# version that supports each one. The wrapper task is executed by the Gradle version
|
|
15
|
+
# currently resolved by the project (not the target version), so passing an option
|
|
16
|
+
# that the executing Gradle does not understand would abort the run. We use this table
|
|
17
|
+
# to only emit options that are safe for the executing version.
|
|
18
|
+
#
|
|
19
|
+
# Sources (gradle/gradle `Wrapper.java`):
|
|
20
|
+
# --network-timeout @since 7.6
|
|
21
|
+
# --validate-url @since 8.2 (incubating)
|
|
22
|
+
# --retries @since 9.5.0 (incubating)
|
|
23
|
+
# --retry-back-off-ms @since 9.5.0 (incubating)
|
|
24
|
+
module GradleVersionCapabilities
|
|
25
|
+
extend T::Sig
|
|
26
|
+
|
|
27
|
+
NETWORK_TIMEOUT = "network-timeout"
|
|
28
|
+
VALIDATE_URL = "validate-url"
|
|
29
|
+
RETRIES = "retries"
|
|
30
|
+
RETRY_BACK_OFF_MS = "retry-back-off-ms"
|
|
31
|
+
|
|
32
|
+
MINIMUM_VERSIONS = T.let(
|
|
33
|
+
{
|
|
34
|
+
NETWORK_TIMEOUT => "7.6",
|
|
35
|
+
VALIDATE_URL => "8.2",
|
|
36
|
+
RETRIES => "9.5.0",
|
|
37
|
+
RETRY_BACK_OFF_MS => "9.5.0"
|
|
38
|
+
}.freeze,
|
|
39
|
+
T::Hash[String, String]
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Returns true when the given (executing) Gradle version is known to support the option.
|
|
43
|
+
# When the version is unknown (nil) we conservatively refuse options that are gated behind
|
|
44
|
+
# a minimum version, so we never pass a flag that could abort the wrapper run. Reconciliation
|
|
45
|
+
# of the properties file guarantees the user's value is preserved regardless.
|
|
46
|
+
sig { params(option: String, gradle_version: T.nilable(Dependabot::Gradle::Version)).returns(T::Boolean) }
|
|
47
|
+
def self.supports?(option, gradle_version)
|
|
48
|
+
minimum = MINIMUM_VERSIONS[option]
|
|
49
|
+
return true if minimum.nil? # ungated option
|
|
50
|
+
|
|
51
|
+
return false if gradle_version.nil?
|
|
52
|
+
|
|
53
|
+
gradle_version >= Dependabot::Gradle::Version.new(minimum)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
|
|
6
|
+
require "dependabot/gradle/file_updater"
|
|
7
|
+
|
|
8
|
+
module Dependabot
|
|
9
|
+
module Gradle
|
|
10
|
+
class FileUpdater
|
|
11
|
+
module Wrapper
|
|
12
|
+
# An order-preserving model of a `gradle-wrapper.properties` file.
|
|
13
|
+
#
|
|
14
|
+
# Java's `Properties.store` (used by Gradle's wrapper task) discards comments, blank
|
|
15
|
+
# lines, custom keys and the original key ordering. To preserve everything the user
|
|
16
|
+
# configured, we parse the original file into this document, mutate only the keys we
|
|
17
|
+
# intend to change, and render it back verbatim.
|
|
18
|
+
class PropertiesDocument
|
|
19
|
+
extend T::Sig
|
|
20
|
+
|
|
21
|
+
# A single physical line: either a raw line (comment/blank/unparsed) or a property.
|
|
22
|
+
class Line < T::Struct
|
|
23
|
+
prop :raw, String
|
|
24
|
+
prop :indent, String, default: ""
|
|
25
|
+
prop :key, T.nilable(String)
|
|
26
|
+
prop :separator, T.nilable(String)
|
|
27
|
+
prop :value, T.nilable(String)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Properties files use `=`, `:` or whitespace as the key/value separator. Gradle always
|
|
31
|
+
# writes `=`, but we parse all three so user-authored files are handled faithfully.
|
|
32
|
+
KEY_VALUE_REGEX = T.let(/\A(\s*)([^\s:=]+)(\s*[:=]\s*|\s+)(.*)\z/, Regexp)
|
|
33
|
+
COMMENT_REGEX = T.let(/\A\s*[#!]/, Regexp)
|
|
34
|
+
|
|
35
|
+
sig { params(content: String).returns(PropertiesDocument) }
|
|
36
|
+
def self.parse(content)
|
|
37
|
+
lines = content.split("\n", -1).map { |line| parse_line(line) }
|
|
38
|
+
new(lines)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
sig { params(line: String).returns(Line) }
|
|
42
|
+
def self.parse_line(line)
|
|
43
|
+
return Line.new(raw: line) if line.strip.empty? || line.match?(COMMENT_REGEX)
|
|
44
|
+
|
|
45
|
+
match = line.match(KEY_VALUE_REGEX)
|
|
46
|
+
return Line.new(raw: line) unless match
|
|
47
|
+
|
|
48
|
+
Line.new(
|
|
49
|
+
raw: line,
|
|
50
|
+
indent: match[1] || "",
|
|
51
|
+
key: match[2],
|
|
52
|
+
separator: match[3],
|
|
53
|
+
value: match[4]
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
sig { params(lines: T::Array[Line]).void }
|
|
58
|
+
def initialize(lines)
|
|
59
|
+
@lines = lines
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
sig { params(key: String).returns(T::Boolean) }
|
|
63
|
+
def key?(key)
|
|
64
|
+
@lines.any? { |line| line.key == key }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
sig { params(key: String).returns(T.nilable(String)) }
|
|
68
|
+
def value_for(key)
|
|
69
|
+
@lines.find { |line| line.key == key }&.value
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Sets `key` to `value`, preserving the line's original position, indentation and separator
|
|
73
|
+
# when the key already exists, otherwise appending a new `key=value` line at the end.
|
|
74
|
+
sig { params(key: String, value: String).void }
|
|
75
|
+
def upsert(key, value)
|
|
76
|
+
existing = @lines.find { |line| line.key == key }
|
|
77
|
+
if existing
|
|
78
|
+
separator = existing.separator || "="
|
|
79
|
+
existing.value = value
|
|
80
|
+
existing.separator = separator
|
|
81
|
+
existing.raw = "#{existing.indent}#{key}#{separator}#{value}"
|
|
82
|
+
return
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
@lines << Line.new(raw: "#{key}=#{value}", key: key, separator: "=", value: value)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
sig { returns(String) }
|
|
89
|
+
def to_s
|
|
90
|
+
@lines.map(&:raw).join("\n")
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
|
|
6
|
+
require "dependabot/gradle/file_updater"
|
|
7
|
+
require "dependabot/gradle/file_updater/wrapper/properties_document"
|
|
8
|
+
|
|
9
|
+
module Dependabot
|
|
10
|
+
module Gradle
|
|
11
|
+
class FileUpdater
|
|
12
|
+
module Wrapper
|
|
13
|
+
# Reconciles the `gradle-wrapper.properties` file after Gradle's wrapper task has
|
|
14
|
+
# regenerated it from hardcoded defaults (see https://github.com/gradle/gradle/issues/36172).
|
|
15
|
+
#
|
|
16
|
+
# The reconciliation policy is deliberately conservative: the user's original file is the
|
|
17
|
+
# source of truth for everything (comments, ordering, custom keys, networkTimeout, retries,
|
|
18
|
+
# retryBackOffMs, validateDistributionUrl, distributionBase/Path, store paths, ...). Only the
|
|
19
|
+
# keys that legitimately change for a version bump are taken from the regenerated file.
|
|
20
|
+
class PropertiesReconciler
|
|
21
|
+
extend T::Sig
|
|
22
|
+
|
|
23
|
+
# Keys whose value is owned by the update itself and therefore taken from the regenerated
|
|
24
|
+
# file. Everything not listed here is preserved verbatim from the user's original file.
|
|
25
|
+
MANAGED_KEYS = T.let(
|
|
26
|
+
%w(distributionUrl distributionSha256Sum).freeze,
|
|
27
|
+
T::Array[String]
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Reconciles the regenerated wrapper properties back onto the user's original file.
|
|
31
|
+
#
|
|
32
|
+
# When the original file is missing there is nothing to preserve, so nil is returned and the
|
|
33
|
+
# caller keeps the regenerated file as-is. When only the regenerated file is missing (e.g. the
|
|
34
|
+
# wrapper task did not produce one) the original content is returned unchanged.
|
|
35
|
+
sig do
|
|
36
|
+
params(original_content: T.nilable(String), regenerated_content: T.nilable(String))
|
|
37
|
+
.returns(T.nilable(String))
|
|
38
|
+
end
|
|
39
|
+
def self.reconcile(original_content:, regenerated_content:)
|
|
40
|
+
new(original_content: original_content, regenerated_content: regenerated_content).reconcile
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
sig { params(original_content: T.nilable(String), regenerated_content: T.nilable(String)).void }
|
|
44
|
+
def initialize(original_content:, regenerated_content:)
|
|
45
|
+
@original_content = original_content
|
|
46
|
+
@regenerated_content = regenerated_content
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
sig { returns(T.nilable(String)) }
|
|
50
|
+
def reconcile
|
|
51
|
+
original_content = @original_content
|
|
52
|
+
regenerated_content = @regenerated_content
|
|
53
|
+
return original_content if original_content.nil? || regenerated_content.nil?
|
|
54
|
+
|
|
55
|
+
document = PropertiesDocument.parse(original_content)
|
|
56
|
+
regenerated = PropertiesDocument.parse(regenerated_content)
|
|
57
|
+
|
|
58
|
+
MANAGED_KEYS.each do |key|
|
|
59
|
+
new_value = regenerated.value_for(key)
|
|
60
|
+
next if new_value.nil?
|
|
61
|
+
|
|
62
|
+
document.upsert(key, new_value)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
document.to_s
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -7,6 +7,7 @@ require "shellwords"
|
|
|
7
7
|
require "pathname"
|
|
8
8
|
|
|
9
9
|
require "dependabot/gradle/distributions"
|
|
10
|
+
require "dependabot/gradle/version"
|
|
10
11
|
|
|
11
12
|
module Dependabot
|
|
12
13
|
module Gradle
|
|
@@ -15,6 +16,11 @@ module Dependabot
|
|
|
15
16
|
extend T::Sig
|
|
16
17
|
include Dependabot::Gradle::Distributions
|
|
17
18
|
|
|
19
|
+
require_relative "wrapper/command_builder"
|
|
20
|
+
require_relative "wrapper/executing_version_detector"
|
|
21
|
+
require_relative "wrapper/properties_document"
|
|
22
|
+
require_relative "wrapper/properties_reconciler"
|
|
23
|
+
|
|
18
24
|
sig { params(dependency_files: T::Array[Dependabot::DependencyFile], dependency: Dependabot::Dependency).void }
|
|
19
25
|
def initialize(dependency_files:, dependency:)
|
|
20
26
|
@dependency_files = dependency_files
|
|
@@ -68,14 +74,11 @@ module Dependabot
|
|
|
68
74
|
FileUtils.chmod("+x", "./gradlew") if has_local_script
|
|
69
75
|
|
|
70
76
|
properties_file = File.join(cwd, "gradle/wrapper/gradle-wrapper.properties")
|
|
71
|
-
|
|
77
|
+
original_properties_content = read_file(properties_file)
|
|
78
|
+
original_document = original_properties_content && Wrapper::PropertiesDocument.parse(original_properties_content)
|
|
72
79
|
env = { "JAVA_OPTS" => proxy_args.join(" ") } # set proxy for gradle execution
|
|
73
80
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
# There is no guarantee that the `gradlew` script is present on the project,
|
|
77
|
-
# if it's not, we fall back to system Gradle
|
|
78
|
-
command = Shellwords.join([has_local_script ? "./gradlew" : "gradle"] + command_parts)
|
|
81
|
+
command = local_wrapper_command(has_local_script, target_requirements, original_document, cwd, env)
|
|
79
82
|
|
|
80
83
|
begin
|
|
81
84
|
# first attempt: run the wrapper task via the local Gradle wrapper (if present)
|
|
@@ -83,18 +86,23 @@ module Dependabot
|
|
|
83
86
|
# the `gradlew` script may be corrupted, so we try and fall back to system Gradle before giving up
|
|
84
87
|
SharedHelpers.run_shell_command(command, cwd: cwd, env: env)
|
|
85
88
|
rescue SharedHelpers::HelperSubprocessFailed => e
|
|
86
|
-
raise e unless has_local_script # already
|
|
89
|
+
raise e unless has_local_script # already failed with system one, there is no point to retry
|
|
87
90
|
|
|
88
91
|
Dependabot.logger.warn("Running #{command} failed, retrying first with system Gradle: #{e.message}")
|
|
89
92
|
|
|
90
|
-
# second attempt: run the wrapper task via system gradle and then retry via local wrapper
|
|
91
|
-
|
|
93
|
+
# second attempt: run the wrapper task via system gradle and then retry via local wrapper.
|
|
94
|
+
# The system Gradle may be a different (often older) version than the wrapper, so we rebuild
|
|
95
|
+
# the command against its detected version to avoid passing unsupported, version-gated flags.
|
|
96
|
+
system_command = system_wrapper_command(target_requirements, original_document, cwd, env)
|
|
92
97
|
SharedHelpers.run_shell_command(system_command, cwd: cwd, env: env) # run via system gradle
|
|
93
98
|
SharedHelpers.run_shell_command(command, cwd: cwd, env: env) # retry via local wrapper
|
|
94
99
|
end
|
|
95
100
|
|
|
96
|
-
#
|
|
97
|
-
|
|
101
|
+
# Gradle's wrapper task regenerates gradle-wrapper.properties from hardcoded defaults
|
|
102
|
+
# (https://github.com/gradle/gradle/issues/36172), discarding comments, ordering, custom
|
|
103
|
+
# keys and user-customized values. Reconcile the regenerated file back onto the user's
|
|
104
|
+
# original so only the version-bump keys change.
|
|
105
|
+
reconcile_properties(properties_file, original_properties_content)
|
|
98
106
|
|
|
99
107
|
update_files_content(temp_dir, local_files, updated_files)
|
|
100
108
|
rescue SharedHelpers::HelperSubprocessFailed => e
|
|
@@ -149,55 +157,68 @@ module Dependabot
|
|
|
149
157
|
Pathname.new(file.name).cleanpath.to_path
|
|
150
158
|
end
|
|
151
159
|
|
|
152
|
-
#
|
|
160
|
+
# Builds the command for the first wrapper attempt.
|
|
161
|
+
#
|
|
162
|
+
# When the project ships a `gradlew` script we run it: it downloads and executes the Gradle
|
|
163
|
+
# version pinned in the current gradle-wrapper.properties, so wrapper flags are gated on that
|
|
164
|
+
# distributionUrl version. When `gradlew` is missing we instead invoke system Gradle directly,
|
|
165
|
+
# so flags must be gated on the system Gradle's detected version (not the wrapper's) to avoid
|
|
166
|
+
# forwarding options that an older system Gradle does not understand and aborting the run.
|
|
167
|
+
sig do
|
|
168
|
+
params(
|
|
169
|
+
has_local_script: T::Boolean,
|
|
170
|
+
requirements: T::Array[Dependabot::DependencyRequirement],
|
|
171
|
+
original_document: T.nilable(Wrapper::PropertiesDocument),
|
|
172
|
+
cwd: String,
|
|
173
|
+
env: T::Hash[String, String]
|
|
174
|
+
).returns(String)
|
|
175
|
+
end
|
|
176
|
+
def local_wrapper_command(has_local_script, requirements, original_document, cwd, env)
|
|
177
|
+
return system_wrapper_command(requirements, original_document, cwd, env) unless has_local_script
|
|
178
|
+
|
|
179
|
+
distribution_url = original_document&.value_for("distributionUrl")
|
|
180
|
+
gradle_version = Wrapper::ExecutingVersionDetector.from_distribution_url(distribution_url)
|
|
181
|
+
Shellwords.join(["./gradlew"] + build_command_parts(requirements, original_document, gradle_version))
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Builds the system-Gradle fallback command, gating wrapper flags on the system Gradle's own
|
|
185
|
+
# version (which may differ from the project's wrapper version).
|
|
186
|
+
sig do
|
|
187
|
+
params(
|
|
188
|
+
requirements: T::Array[Dependabot::DependencyRequirement],
|
|
189
|
+
original_document: T.nilable(Wrapper::PropertiesDocument),
|
|
190
|
+
cwd: String,
|
|
191
|
+
env: T::Hash[String, String]
|
|
192
|
+
).returns(String)
|
|
193
|
+
end
|
|
194
|
+
def system_wrapper_command(requirements, original_document, cwd, env)
|
|
195
|
+
gradle_version = detect_system_gradle_version(cwd, env)
|
|
196
|
+
Shellwords.join(["gradle"] + build_command_parts(requirements, original_document, gradle_version))
|
|
197
|
+
end
|
|
198
|
+
|
|
153
199
|
sig do
|
|
154
200
|
params(
|
|
155
201
|
requirements: T::Array[Dependabot::DependencyRequirement],
|
|
156
|
-
|
|
202
|
+
original_document: T.nilable(Wrapper::PropertiesDocument),
|
|
203
|
+
gradle_version: T.nilable(Dependabot::Gradle::Version)
|
|
157
204
|
).returns(T::Array[String])
|
|
158
205
|
end
|
|
159
|
-
def
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
# persist the change in the properties file, which is not the behavior we want for users.
|
|
176
|
-
# TODO: Investigate and fix the root cause of the proxy issue and remove this workaround
|
|
177
|
-
# See https://github.com/dependabot/dependabot-core/issues/14036
|
|
178
|
-
args += %w(--no-validate-url)
|
|
179
|
-
|
|
180
|
-
# Gradle builds can be very complex, and our current Gradle parsing is limited.
|
|
181
|
-
# To keep `./gradlew wrapper` running reliably, we generate a minimal build that omits the
|
|
182
|
-
# project’s build scripts and customizations. As a result, any `tasks.wrapper {}` DSL configuration
|
|
183
|
-
# defined in the original project is not applied.
|
|
184
|
-
#
|
|
185
|
-
# This approach, combined with https://github.com/gradle/gradle/issues/36172 where the wrapper task
|
|
186
|
-
# relies on hardcoded defaults instead of reading from `gradle-wrapper.properties`, causes
|
|
187
|
-
# `networkTimeout` customizations to be reset to the default value on every Dependabot pull request.
|
|
188
|
-
#
|
|
189
|
-
# This change mitigates the issue by reading the existing value and passing it explicitly to the
|
|
190
|
-
# `wrapper` command, ensuring any custom `networkTimeout` setting is preserved.
|
|
191
|
-
#
|
|
192
|
-
# In future iterations, we may consider parsing the full Gradle build and extracting only the
|
|
193
|
-
# wrapper-related customizations so the project-specific `tasks.wrapper {}` behavior is retained.
|
|
194
|
-
# Alternatively, if Gradle addresses the upstream issue, we can revert to using the default minimal
|
|
195
|
-
# build without needing explicit configuration.
|
|
196
|
-
args += %W(--network-timeout #{network_timeout}) if network_timeout
|
|
197
|
-
|
|
198
|
-
args += %W(--distribution-type #{distribution_type}) if distribution_type
|
|
199
|
-
args += %W(--gradle-distribution-sha256-sum #{checksum}) if checksum
|
|
200
|
-
args
|
|
206
|
+
def build_command_parts(requirements, original_document, gradle_version)
|
|
207
|
+
wrapper_args = Wrapper::CommandBuilder.new(
|
|
208
|
+
requirements: requirements,
|
|
209
|
+
original_properties: original_document,
|
|
210
|
+
gradle_version: gradle_version
|
|
211
|
+
).build
|
|
212
|
+
%w(--no-daemon --stacktrace) + wrapper_args
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
sig { params(cwd: String, env: T::Hash[String, String]).returns(T.nilable(Dependabot::Gradle::Version)) }
|
|
216
|
+
def detect_system_gradle_version(cwd, env)
|
|
217
|
+
output = SharedHelpers.run_shell_command("gradle --version", cwd: cwd, env: env)
|
|
218
|
+
Wrapper::ExecutingVersionDetector.from_version_output(output)
|
|
219
|
+
rescue SharedHelpers::HelperSubprocessFailed => e
|
|
220
|
+
Dependabot.logger.warn("Unable to detect system Gradle version: #{e.message}")
|
|
221
|
+
nil
|
|
201
222
|
end
|
|
202
223
|
|
|
203
224
|
# Gradle builds can be complex, to maximize the chances of a successful we just keep related wrapper files
|
|
@@ -249,29 +270,27 @@ module Dependabot
|
|
|
249
270
|
end
|
|
250
271
|
end
|
|
251
272
|
|
|
252
|
-
sig { params(
|
|
253
|
-
def
|
|
254
|
-
return
|
|
255
|
-
|
|
256
|
-
properties_content = File.read(properties_file)
|
|
257
|
-
validate_distribution = properties_content.match(/^validateDistributionUrl=(.*)$/)&.captures&.first
|
|
258
|
-
network_timeout = properties_content.match(/^networkTimeout=(.*)$/)&.captures&.first
|
|
273
|
+
sig { params(path: T.any(Pathname, String)).returns(T.nilable(String)) }
|
|
274
|
+
def read_file(path)
|
|
275
|
+
return nil unless File.exist?(path)
|
|
259
276
|
|
|
260
|
-
|
|
277
|
+
File.read(path)
|
|
261
278
|
end
|
|
262
279
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
280
|
+
# Reconciles the wrapper-regenerated properties file back onto the user's original content,
|
|
281
|
+
# overwriting only the keys that legitimately change for a version bump. Preserves comments,
|
|
282
|
+
# ordering, custom keys and all other user-customized values.
|
|
283
|
+
sig { params(properties_file: T.any(Pathname, String), original_content: T.nilable(String)).void }
|
|
284
|
+
def reconcile_properties(properties_file, original_content)
|
|
285
|
+
regenerated_content = read_file(properties_file)
|
|
286
|
+
reconciled = Wrapper::PropertiesReconciler.reconcile(
|
|
287
|
+
original_content: original_content,
|
|
288
|
+
regenerated_content: regenerated_content
|
|
271
289
|
)
|
|
272
|
-
File.write(properties_file,
|
|
290
|
+
File.write(properties_file, reconciled) if reconciled && reconciled != regenerated_content
|
|
273
291
|
end
|
|
274
292
|
|
|
293
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
275
294
|
sig { returns(T::Array[String]) }
|
|
276
295
|
def proxy_args
|
|
277
296
|
http_proxy = ENV.fetch("HTTP_PROXY", nil)
|
|
@@ -15,6 +15,7 @@ require "dependabot/logger"
|
|
|
15
15
|
require "dependabot/gradle/metadata_finder"
|
|
16
16
|
require "dependabot/gradle/package/release_date_extractor"
|
|
17
17
|
require "dependabot/gradle/package/version_release_date_fallback_fetcher"
|
|
18
|
+
require "dependabot/package/release_cooldown_options"
|
|
18
19
|
|
|
19
20
|
module Dependabot
|
|
20
21
|
module Gradle
|
|
@@ -55,14 +56,16 @@ module Dependabot
|
|
|
55
56
|
dependency: Dependabot::Dependency,
|
|
56
57
|
dependency_files: T::Array[Dependabot::DependencyFile],
|
|
57
58
|
credentials: T::Array[Dependabot::Credential],
|
|
58
|
-
forbidden_urls: T.nilable(T::Array[String])
|
|
59
|
+
forbidden_urls: T.nilable(T::Array[String]),
|
|
60
|
+
cooldown_options: T.nilable(Dependabot::Package::ReleaseCooldownOptions)
|
|
59
61
|
).void
|
|
60
62
|
end
|
|
61
|
-
def initialize(dependency:, dependency_files:, credentials:, forbidden_urls:)
|
|
63
|
+
def initialize(dependency:, dependency_files:, credentials:, forbidden_urls:, cooldown_options: nil)
|
|
62
64
|
@dependency = dependency
|
|
63
65
|
@dependency_files = dependency_files
|
|
64
66
|
@credentials = credentials
|
|
65
67
|
@forbidden_urls = forbidden_urls
|
|
68
|
+
@cooldown_options = T.let(cooldown_options, T.nilable(Dependabot::Package::ReleaseCooldownOptions))
|
|
66
69
|
@repositories = T.let(nil, T.nilable(T::Array[T::Hash[String, T.untyped]]))
|
|
67
70
|
@google_version_details = T.let(nil, T.nilable(T::Array[T::Hash[String, T.untyped]]))
|
|
68
71
|
@dependency_repository_details = T.let(nil, T.nilable(T::Array[T::Hash[String, T.untyped]]))
|
|
@@ -101,7 +104,7 @@ module Dependabot
|
|
|
101
104
|
end.flatten.compact
|
|
102
105
|
|
|
103
106
|
version_details = version_details.sort_by { |details| details.fetch(:version) }
|
|
104
|
-
release_date_info = release_details
|
|
107
|
+
release_date_info = @cooldown_options ? release_details : {}
|
|
105
108
|
version_details.each do |info|
|
|
106
109
|
package_releases << {
|
|
107
110
|
version: Gradle::Version.new(info[:version].to_s),
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
require "sorbet-runtime"
|
|
10
10
|
|
|
11
|
+
require "dependabot/dependency_requirement"
|
|
11
12
|
require "dependabot/requirements_updater/base"
|
|
12
13
|
require "dependabot/gradle/distributions"
|
|
13
14
|
require "dependabot/gradle/package/distributions_fetcher"
|
|
@@ -29,7 +30,7 @@ module Dependabot
|
|
|
29
30
|
|
|
30
31
|
sig do
|
|
31
32
|
params(
|
|
32
|
-
requirements: T::Array[
|
|
33
|
+
requirements: T::Array[Dependabot::DependencyRequirement],
|
|
33
34
|
latest_version: T.nilable(T.any(Version, String)),
|
|
34
35
|
source_url: T.nilable(String),
|
|
35
36
|
properties_to_update: T::Array[String]
|
|
@@ -51,7 +52,7 @@ module Dependabot
|
|
|
51
52
|
@is_distribution = T.let(Distributions.distribution_requirements?(requirements), T::Boolean)
|
|
52
53
|
end
|
|
53
54
|
|
|
54
|
-
sig { override.returns(T::Array[
|
|
55
|
+
sig { override.returns(T::Array[Dependabot::DependencyRequirement]) }
|
|
55
56
|
def updated_requirements
|
|
56
57
|
return requirements unless latest_version
|
|
57
58
|
return updated_distribution_requirements if @is_distribution
|
|
@@ -67,13 +68,13 @@ module Dependabot
|
|
|
67
68
|
next req if property_name && !properties_to_update.include?(property_name)
|
|
68
69
|
|
|
69
70
|
new_req = update_requirement(req[:requirement])
|
|
70
|
-
req.merge(requirement: new_req, source: updated_source)
|
|
71
|
+
Dependabot::DependencyRequirement.create(req.merge(requirement: new_req, source: updated_source))
|
|
71
72
|
end
|
|
72
73
|
end
|
|
73
74
|
|
|
74
75
|
private
|
|
75
76
|
|
|
76
|
-
sig { returns(T::Array[
|
|
77
|
+
sig { returns(T::Array[Dependabot::DependencyRequirement]) }
|
|
77
78
|
attr_reader :requirements
|
|
78
79
|
|
|
79
80
|
sig { returns(T.nilable(Version)) }
|
|
@@ -118,7 +119,7 @@ module Dependabot
|
|
|
118
119
|
end
|
|
119
120
|
end
|
|
120
121
|
|
|
121
|
-
sig { returns(T::Array[
|
|
122
|
+
sig { returns(T::Array[Dependabot::DependencyRequirement]) }
|
|
122
123
|
def updated_distribution_requirements
|
|
123
124
|
distribution_url = T.let(nil, T.nilable(String))
|
|
124
125
|
|
|
@@ -132,15 +133,19 @@ module Dependabot
|
|
|
132
133
|
version = update_exact_requirement(requirement)
|
|
133
134
|
distribution_url = source[:url].gsub(requirement, version)
|
|
134
135
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
Dependabot::DependencyRequirement.create(
|
|
137
|
+
req.merge(
|
|
138
|
+
requirement: version,
|
|
139
|
+
source: source.merge(url: distribution_url)
|
|
140
|
+
)
|
|
138
141
|
)
|
|
139
142
|
when "distributionSha256Sum"
|
|
140
143
|
checksum_url, checksum = Gradle::Package::DistributionsFetcher.resolve_checksum(T.must(distribution_url))
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
+
Dependabot::DependencyRequirement.create(
|
|
145
|
+
req.merge(
|
|
146
|
+
requirement: checksum,
|
|
147
|
+
source: source.merge(url: checksum_url)
|
|
148
|
+
)
|
|
144
149
|
)
|
|
145
150
|
else
|
|
146
151
|
next req
|
|
@@ -124,7 +124,8 @@ module Dependabot
|
|
|
124
124
|
dependency: dependency,
|
|
125
125
|
dependency_files: dependency_files,
|
|
126
126
|
credentials: credentials,
|
|
127
|
-
forbidden_urls: forbidden_urls
|
|
127
|
+
forbidden_urls: forbidden_urls,
|
|
128
|
+
cooldown_options: cooldown_options
|
|
128
129
|
).fetch_available_versions
|
|
129
130
|
end
|
|
130
131
|
|
|
@@ -169,7 +170,8 @@ module Dependabot
|
|
|
169
170
|
dependency: dependency,
|
|
170
171
|
dependency_files: dependency_files,
|
|
171
172
|
credentials: credentials,
|
|
172
|
-
forbidden_urls: []
|
|
173
|
+
forbidden_urls: [],
|
|
174
|
+
cooldown_options: cooldown_options
|
|
173
175
|
),
|
|
174
176
|
T.nilable(Dependabot::Gradle::Package::PackageDetailsFetcher)
|
|
175
177
|
)
|
|
@@ -68,14 +68,12 @@ module Dependabot
|
|
|
68
68
|
declarations_using_a_property
|
|
69
69
|
.map { |req| req.dig(:metadata, :property_name) }
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
).updated_requirements
|
|
78
|
-
)
|
|
71
|
+
RequirementsUpdater.new(
|
|
72
|
+
requirements: dependency.requirements,
|
|
73
|
+
latest_version: preferred_resolvable_version&.to_s,
|
|
74
|
+
source_url: preferred_version_details&.fetch(:source_url),
|
|
75
|
+
properties_to_update: property_names
|
|
76
|
+
).updated_requirements
|
|
79
77
|
end
|
|
80
78
|
|
|
81
79
|
sig { override.returns(T::Boolean) }
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dependabot-gradle
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.383.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dependabot
|
|
@@ -15,28 +15,28 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.
|
|
18
|
+
version: 0.383.0
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.
|
|
25
|
+
version: 0.383.0
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: dependabot-maven
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
30
|
- - '='
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 0.
|
|
32
|
+
version: 0.383.0
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - '='
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: 0.
|
|
39
|
+
version: 0.383.0
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: debug
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -267,6 +267,11 @@ files:
|
|
|
267
267
|
- lib/dependabot/gradle/file_updater/dependency_set_updater.rb
|
|
268
268
|
- lib/dependabot/gradle/file_updater/lockfile_updater.rb
|
|
269
269
|
- lib/dependabot/gradle/file_updater/property_value_updater.rb
|
|
270
|
+
- lib/dependabot/gradle/file_updater/wrapper/command_builder.rb
|
|
271
|
+
- lib/dependabot/gradle/file_updater/wrapper/executing_version_detector.rb
|
|
272
|
+
- lib/dependabot/gradle/file_updater/wrapper/gradle_version_capabilities.rb
|
|
273
|
+
- lib/dependabot/gradle/file_updater/wrapper/properties_document.rb
|
|
274
|
+
- lib/dependabot/gradle/file_updater/wrapper/properties_reconciler.rb
|
|
270
275
|
- lib/dependabot/gradle/file_updater/wrapper_updater.rb
|
|
271
276
|
- lib/dependabot/gradle/language.rb
|
|
272
277
|
- lib/dependabot/gradle/metadata_finder.rb
|
|
@@ -286,7 +291,7 @@ licenses:
|
|
|
286
291
|
- MIT
|
|
287
292
|
metadata:
|
|
288
293
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
|
289
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
|
294
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.383.0
|
|
290
295
|
rdoc_options: []
|
|
291
296
|
require_paths:
|
|
292
297
|
- lib
|