Skip to content

Commit b801f23

Browse files
gmazzoJamieMagee
authored andcommitted
Honoring configured networkTimeout when calling ./gradle wrapper
1 parent 1c3a7f8 commit b801f23

2 files changed

Lines changed: 40 additions & 13 deletions

File tree

gradle/lib/dependabot/gradle/file_updater/wrapper_updater.rb

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,24 @@ def update_files(build_file)
6464
cwd = File.join(temp_dir, base_path(build_file))
6565

6666
has_local_script = File.exist?(File.join(cwd, "./gradlew"))
67-
command_parts = %w(--no-daemon --stacktrace) + command_args(target_requirements)
68-
command = Shellwords.join([has_local_script ? "./gradlew" : "gradle"] + command_parts)
6967

7068
Dir.chdir(cwd) do
7169
FileUtils.chmod("+x", "./gradlew") if has_local_script
7270

7371
properties_file = File.join(cwd, "gradle/wrapper/gradle-wrapper.properties")
74-
validate_option = get_validate_distribution_url_option(properties_file)
72+
validate_distribution, network_timeout = read_wrapper_options(properties_file)
7573
env = { "JAVA_OPTS" => proxy_args.join(" ") } # set proxy for gradle execution
7674

75+
command_parts = %w(--no-daemon --stacktrace) + command_args(target_requirements, network_timeout)
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)
80+
7781
begin
78-
# first attempt: run the wrapper task via the local gradle wrapper (if present)
79-
# `gradle-wrapper.jar` might be too old to run on host's Java version
82+
# first attempt: run the wrapper task via the local Gradle wrapper (if present)
83+
# `gradle-wrapper.jar` might be too old to run on host's Java version or
84+
# the `gradlew` script may be corrupted, so we try and fall back to system Gradle before giving up
8085
SharedHelpers.run_shell_command(command, cwd: cwd, env: env)
8186
rescue SharedHelpers::HelperSubprocessFailed => e
8287
raise e unless has_local_script # already field with system one, there is no point to retry
@@ -90,7 +95,7 @@ def update_files(build_file)
9095
end
9196

9297
# Restore previous validateDistributionUrl option if it existed
93-
override_validate_distribution_url_option(properties_file, validate_option)
98+
override_validate_distribution_url_option(properties_file, validate_distribution)
9499

95100
update_files_content(temp_dir, local_files, updated_files)
96101
rescue SharedHelpers::HelperSubprocessFailed => e
@@ -111,8 +116,9 @@ def target_file?(file)
111116
@target_files.any? { |r| "/#{file.name}".end_with?(r) }
112117
end
113118

114-
sig { params(requirements: T::Array[T::Hash[Symbol, T.untyped]]).returns(T::Array[String]) }
115-
def command_args(requirements)
119+
# rubocop:disable Metrics/PerceivedComplexity
120+
sig { params(requirements: T::Array[T::Hash[Symbol, T.untyped]], network_timeout: T.nilable(String)).returns(T::Array[String]) }
121+
def command_args(requirements, network_timeout)
116122
version = T.let(requirements[0]&.[](:requirement), String)
117123
checksum = T.let(requirements[1]&.[](:requirement), String) if dependency.requirements.size > 1
118124
distribution_url = T.let(requirements[0]&.[](:source), T::Hash[Symbol, String])[:url]
@@ -133,6 +139,24 @@ def command_args(requirements)
133139
# See https://github.com/dependabot/dependabot-core/issues/14036
134140
args += %w(--no-validate-url)
135141

142+
# Gradle builds can be very complex, and our current Gradle parsing is limited.
143+
# To keep `./gradlew wrapper` running reliably, we generate a minimal build that omits the
144+
# project’s build scripts and customizations. As a result, any `tasks.wrapper {}` DSL configuration
145+
# defined in the original project is not applied.
146+
#
147+
# This approach, combined with https://github.com/gradle/gradle/issues/36172 where the wrapper task
148+
# relies on hardcoded defaults instead of reading from `gradle-wrapper.properties`, causes
149+
# `networkTimeout` customizations to be reset to the default value on every Dependabot pull request.
150+
#
151+
# This change mitigates the issue by reading the existing value and passing it explicitly to the
152+
# `wrapper` command, ensuring any custom `networkTimeout` setting is preserved.
153+
#
154+
# In future iterations, we may consider parsing the full Gradle build and extracting only the
155+
# wrapper-related customizations so the project-specific `tasks.wrapper {}` behavior is retained.
156+
# Alternatively, if Gradle addresses the upstream issue, we can revert to using the default minimal
157+
# build without needing explicit configuration.
158+
args += %W(--network-timeout #{network_timeout}) if network_timeout
159+
136160
args += %W(--distribution-type #{distribution_type}) if distribution_type
137161
args += %W(--gradle-distribution-sha256-sum #{checksum}) if checksum
138162
args
@@ -183,12 +207,15 @@ def populate_temp_directory(temp_dir)
183207
end
184208
end
185209

186-
sig { params(properties_file: T.any(Pathname, String)).returns(T.nilable(String)) }
187-
def get_validate_distribution_url_option(properties_file)
188-
return nil unless File.exist?(properties_file)
210+
sig { params(properties_file: T.any(Pathname, String)).returns(T::Array[T.nilable(String)]) }
211+
def read_wrapper_options(properties_file)
212+
return [nil, nil] unless File.exist?(properties_file)
189213

190214
properties_content = File.read(properties_file)
191-
properties_content.match(/^validateDistributionUrl=(.*)$/)&.captures&.first
215+
validate_distribution = properties_content.match(/^validateDistributionUrl=(.*)$/)&.captures&.first
216+
network_timeout = properties_content.match(/^networkTimeout=(.*)$/)&.captures&.first
217+
218+
[validate_distribution, network_timeout]
192219
end
193220

194221
sig { params(properties_file: T.any(Pathname, String), value: T.nilable(String)).void }
@@ -203,7 +230,6 @@ def override_validate_distribution_url_option(properties_file, value)
203230
File.write(properties_file, updated_content)
204231
end
205232

206-
# rubocop:disable Metrics/PerceivedComplexity
207233
sig { returns(T::Array[String]) }
208234
def proxy_args
209235
http_proxy = ENV.fetch("HTTP_PROXY", nil)

gradle/spec/dependabot/gradle/file_updater_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,7 @@
724724
its(:content) do
725725
expected_command = %W(
726726
./gradlew --no-daemon --stacktrace wrapper --gradle-version 9.0.0 --no-validate-url
727+
--network-timeout 10000
727728
--distribution-type #{type}
728729
).join(" ")
729730
expected_env = { "JAVA_OPTS" => %w(

0 commit comments

Comments
 (0)