dependabot-gradle 0.381.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_parser/distributions_finder.rb +25 -21
- 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 +140 -79
- 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 +1 -1
- 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
|
|
@@ -26,30 +26,34 @@ module Dependabot
|
|
|
26
26
|
version = match.fetch("version")
|
|
27
27
|
|
|
28
28
|
requirements = T.let(
|
|
29
|
-
[
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
[DependencyRequirement.create(
|
|
30
|
+
{
|
|
31
|
+
requirement: version,
|
|
32
|
+
file: properties_file.name,
|
|
33
|
+
source: {
|
|
34
|
+
type: Distributions::DISTRIBUTION_DEPENDENCY_TYPE,
|
|
35
|
+
url: distribution_url,
|
|
36
|
+
property: "distributionUrl"
|
|
37
|
+
},
|
|
38
|
+
groups: []
|
|
39
|
+
}
|
|
40
|
+
)],
|
|
41
|
+
T::Array[Dependabot::DependencyRequirement]
|
|
40
42
|
)
|
|
41
43
|
|
|
42
44
|
if checksum
|
|
43
|
-
requirements <<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
requirements << DependencyRequirement.create(
|
|
46
|
+
{
|
|
47
|
+
requirement: checksum,
|
|
48
|
+
file: properties_file.name,
|
|
49
|
+
source: {
|
|
50
|
+
type: Distributions::DISTRIBUTION_DEPENDENCY_TYPE,
|
|
51
|
+
url: "#{distribution_url}.sha256",
|
|
52
|
+
property: "distributionSha256Sum"
|
|
53
|
+
},
|
|
54
|
+
groups: []
|
|
55
|
+
}
|
|
56
|
+
)
|
|
53
57
|
end
|
|
54
58
|
|
|
55
59
|
Dependency.new(
|
|
@@ -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
|
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "sorbet-runtime"
|
|
5
|
+
require "base64"
|
|
5
6
|
require "shellwords"
|
|
7
|
+
require "pathname"
|
|
6
8
|
|
|
7
9
|
require "dependabot/gradle/distributions"
|
|
10
|
+
require "dependabot/gradle/version"
|
|
8
11
|
|
|
9
12
|
module Dependabot
|
|
10
13
|
module Gradle
|
|
@@ -13,6 +16,11 @@ module Dependabot
|
|
|
13
16
|
extend T::Sig
|
|
14
17
|
include Dependabot::Gradle::Distributions
|
|
15
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
|
+
|
|
16
24
|
sig { params(dependency_files: T::Array[Dependabot::DependencyFile], dependency: Dependabot::Dependency).void }
|
|
17
25
|
def initialize(dependency_files:, dependency:)
|
|
18
26
|
@dependency_files = dependency_files
|
|
@@ -39,15 +47,12 @@ module Dependabot
|
|
|
39
47
|
|
|
40
48
|
# rubocop:disable Metrics/AbcSize
|
|
41
49
|
# rubocop:disable Metrics/MethodLength
|
|
42
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
43
50
|
sig { params(build_file: Dependabot::DependencyFile).returns(T::Array[Dependabot::DependencyFile]) }
|
|
44
51
|
def update_files(build_file)
|
|
45
52
|
# We only run this updater if it's a distribution dependency
|
|
46
53
|
return [] unless Distributions.distribution_requirements?(dependency.requirements)
|
|
47
54
|
|
|
48
|
-
local_files =
|
|
49
|
-
file.directory == build_file.directory && target_file?(file)
|
|
50
|
-
end
|
|
55
|
+
local_files = local_wrapper_files(build_file)
|
|
51
56
|
|
|
52
57
|
# If we don't have any files in the build files don't generate one
|
|
53
58
|
return [] unless local_files.any?
|
|
@@ -69,14 +74,11 @@ module Dependabot
|
|
|
69
74
|
FileUtils.chmod("+x", "./gradlew") if has_local_script
|
|
70
75
|
|
|
71
76
|
properties_file = File.join(cwd, "gradle/wrapper/gradle-wrapper.properties")
|
|
72
|
-
|
|
77
|
+
original_properties_content = read_file(properties_file)
|
|
78
|
+
original_document = original_properties_content && Wrapper::PropertiesDocument.parse(original_properties_content)
|
|
73
79
|
env = { "JAVA_OPTS" => proxy_args.join(" ") } # set proxy for gradle execution
|
|
74
80
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
# There is no guarantee that the `gradlew` script is present on the project,
|
|
78
|
-
# if it's not, we fall back to system Gradle
|
|
79
|
-
command = Shellwords.join([has_local_script ? "./gradlew" : "gradle"] + command_parts)
|
|
81
|
+
command = local_wrapper_command(has_local_script, target_requirements, original_document, cwd, env)
|
|
80
82
|
|
|
81
83
|
begin
|
|
82
84
|
# first attempt: run the wrapper task via the local Gradle wrapper (if present)
|
|
@@ -84,18 +86,23 @@ module Dependabot
|
|
|
84
86
|
# the `gradlew` script may be corrupted, so we try and fall back to system Gradle before giving up
|
|
85
87
|
SharedHelpers.run_shell_command(command, cwd: cwd, env: env)
|
|
86
88
|
rescue SharedHelpers::HelperSubprocessFailed => e
|
|
87
|
-
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
|
|
88
90
|
|
|
89
91
|
Dependabot.logger.warn("Running #{command} failed, retrying first with system Gradle: #{e.message}")
|
|
90
92
|
|
|
91
|
-
# second attempt: run the wrapper task via system gradle and then retry via local wrapper
|
|
92
|
-
|
|
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)
|
|
93
97
|
SharedHelpers.run_shell_command(system_command, cwd: cwd, env: env) # run via system gradle
|
|
94
98
|
SharedHelpers.run_shell_command(command, cwd: cwd, env: env) # retry via local wrapper
|
|
95
99
|
end
|
|
96
100
|
|
|
97
|
-
#
|
|
98
|
-
|
|
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)
|
|
99
106
|
|
|
100
107
|
update_files_content(temp_dir, local_files, updated_files)
|
|
101
108
|
rescue SharedHelpers::HelperSubprocessFailed => e
|
|
@@ -107,7 +114,6 @@ module Dependabot
|
|
|
107
114
|
end
|
|
108
115
|
# rubocop:enable Metrics/AbcSize
|
|
109
116
|
# rubocop:enable Metrics/MethodLength
|
|
110
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
111
117
|
|
|
112
118
|
private
|
|
113
119
|
|
|
@@ -116,50 +122,103 @@ module Dependabot
|
|
|
116
122
|
@target_files.any? { |r| "/#{file.name}".end_with?(r) }
|
|
117
123
|
end
|
|
118
124
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
125
|
+
sig { params(build_file: Dependabot::DependencyFile).returns(T::Array[Dependabot::DependencyFile]) }
|
|
126
|
+
def local_wrapper_files(build_file)
|
|
127
|
+
wrapper_root = wrapper_root_for(build_file)
|
|
128
|
+
|
|
129
|
+
dependency_files.select do |file|
|
|
130
|
+
file.directory == build_file.directory && target_file_for_wrapper_root?(file, wrapper_root)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
sig { params(file: Dependabot::DependencyFile, wrapper_root: String).returns(T::Boolean) }
|
|
135
|
+
def target_file_for_wrapper_root?(file, wrapper_root)
|
|
136
|
+
@target_files.any? do |target_file|
|
|
137
|
+
target_path = target_file.delete_prefix("/")
|
|
138
|
+
expected_path = wrapper_root.empty? ? target_path : File.join(wrapper_root, target_path)
|
|
139
|
+
file_path(file) == Pathname.new(expected_path).cleanpath.to_path
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
sig { params(build_file: Dependabot::DependencyFile).returns(String) }
|
|
144
|
+
def wrapper_root_for(build_file)
|
|
145
|
+
path = file_path(build_file)
|
|
146
|
+
root = if target_file?(build_file)
|
|
147
|
+
File.dirname(path, 3)
|
|
148
|
+
else
|
|
149
|
+
File.dirname(path)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
root == "." ? "" : root
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
sig { params(file: Dependabot::DependencyFile).returns(String) }
|
|
156
|
+
def file_path(file)
|
|
157
|
+
Pathname.new(file.name).cleanpath.to_path
|
|
158
|
+
end
|
|
159
|
+
|
|
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
|
+
|
|
199
|
+
sig do
|
|
200
|
+
params(
|
|
201
|
+
requirements: T::Array[Dependabot::DependencyRequirement],
|
|
202
|
+
original_document: T.nilable(Wrapper::PropertiesDocument),
|
|
203
|
+
gradle_version: T.nilable(Dependabot::Gradle::Version)
|
|
204
|
+
).returns(T::Array[String])
|
|
205
|
+
end
|
|
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
|
|
163
222
|
end
|
|
164
223
|
|
|
165
224
|
# Gradle builds can be complex, to maximize the chances of a successful we just keep related wrapper files
|
|
@@ -191,7 +250,11 @@ module Dependabot
|
|
|
191
250
|
end
|
|
192
251
|
def update_files_content(temp_dir, local_files, updated_files)
|
|
193
252
|
local_files.each do |file|
|
|
194
|
-
f_content =
|
|
253
|
+
f_content = if file.binary?
|
|
254
|
+
File.binread(File.join(temp_dir, file.directory, file.name))
|
|
255
|
+
else
|
|
256
|
+
File.read(File.join(temp_dir, file.directory, file.name))
|
|
257
|
+
end
|
|
195
258
|
tmp_file = file.dup
|
|
196
259
|
tmp_file.content = tmp_file.binary? ? Base64.encode64(f_content) : f_content
|
|
197
260
|
updated_files[T.must(updated_files.index(file))] = tmp_file
|
|
@@ -203,33 +266,31 @@ module Dependabot
|
|
|
203
266
|
files_to_populate.each do |file|
|
|
204
267
|
in_path_name = File.join(temp_dir, file.directory, file.name)
|
|
205
268
|
FileUtils.mkdir_p(File.dirname(in_path_name))
|
|
206
|
-
File.
|
|
269
|
+
File.binwrite(in_path_name, file.decoded_content)
|
|
207
270
|
end
|
|
208
271
|
end
|
|
209
272
|
|
|
210
|
-
sig { params(
|
|
211
|
-
def
|
|
212
|
-
return
|
|
213
|
-
|
|
214
|
-
properties_content = File.read(properties_file)
|
|
215
|
-
validate_distribution = properties_content.match(/^validateDistributionUrl=(.*)$/)&.captures&.first
|
|
216
|
-
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)
|
|
217
276
|
|
|
218
|
-
|
|
277
|
+
File.read(path)
|
|
219
278
|
end
|
|
220
279
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
|
229
289
|
)
|
|
230
|
-
File.write(properties_file,
|
|
290
|
+
File.write(properties_file, reconciled) if reconciled && reconciled != regenerated_content
|
|
231
291
|
end
|
|
232
292
|
|
|
293
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
233
294
|
sig { returns(T::Array[String]) }
|
|
234
295
|
def proxy_args
|
|
235
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
|
)
|
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
|