@@ -42,39 +42,75 @@ def update_files(build_file)
4242 # We only run this updater if it's a distribution dependency
4343 return [ ] unless Distributions . distribution_requirements? ( dependency . requirements )
4444
45- local_files = dependency_files . select do |file |
46- file . directory == build_file . directory && target_file? ( file )
47- end
45+ # Find all wrapper files - they can span multiple directories
46+ local_files = dependency_files . select { |file | target_file? ( file ) }
4847
4948 # If we don't have any files in the build files don't generate one
50- return [ ] unless local_files . any?
49+ return dependency_files unless local_files . any?
5150
5251 updated_files = dependency_files . dup
5352 SharedHelpers . in_a_temporary_directory do |temp_dir |
5453 populate_temp_directory ( temp_dir )
55- cwd = File . join ( temp_dir , base_path ( build_file ) )
56-
57- # Create gradle.properties file with proxy settings
58- # Would prefer to use command line arguments, but they don't work.
59- properties_filename = File . join ( temp_dir , build_file . directory , "gradle.properties" )
60- write_properties_file ( properties_filename )
61-
62- command_parts = %w( gradle --no-daemon --stacktrace ) + command_args
63- command = Shellwords . join ( command_parts )
64-
65- Dir . chdir ( cwd ) do
66- SharedHelpers . run_shell_command ( command , cwd : cwd )
67- update_files_content ( temp_dir , local_files , updated_files )
68- rescue SharedHelpers ::HelperSubprocessFailed => e
69- puts "Failed to update files: #{ e . message } "
70- return updated_files
71- end
54+ update_wrapper_files ( build_file , temp_dir , local_files , updated_files )
7255 end
7356 updated_files
7457 end
7558
7659 private
7760
61+ sig do
62+ params (
63+ build_file : Dependabot ::DependencyFile ,
64+ temp_dir : T . any ( Pathname , String ) ,
65+ local_files : T ::Array [ Dependabot ::DependencyFile ] ,
66+ updated_files : T ::Array [ Dependabot ::DependencyFile ]
67+ ) . void
68+ end
69+ def update_wrapper_files ( build_file , temp_dir , local_files , updated_files )
70+ cwd = File . join ( temp_dir , base_path ( build_file ) )
71+
72+ # Create gradle.properties file with proxy settings
73+ properties_filename = File . join ( temp_dir , build_file . directory , "gradle.properties" )
74+ write_properties_file ( properties_filename )
75+
76+ Dir . chdir ( cwd ) do
77+ run_wrapper_tasks ( cwd )
78+ update_file_contents ( temp_dir , local_files , updated_files )
79+ rescue SharedHelpers ::HelperSubprocessFailed => e
80+ handle_wrapper_update_error ( e )
81+ end
82+ end
83+
84+ sig { params ( cwd : String ) . void }
85+ def run_wrapper_tasks ( cwd )
86+ gradlew_script = File . exist? ( "gradlew.bat" ) && !File . exist? ( "gradlew" ) ? "gradlew.bat" : "./gradlew"
87+
88+ # First run: Update wrapper with new version and download new distribution
89+ first_command = Shellwords . join ( [ gradlew_script , "--no-daemon" , "--stacktrace" ] + command_args )
90+ SharedHelpers . run_shell_command ( first_command , cwd : cwd )
91+
92+ # Second run: Regenerate wrapper binaries (gradlew, gradlew.bat, gradle-wrapper.jar)
93+ second_command = Shellwords . join ( [ gradlew_script , "--no-daemon" , "--stacktrace" , "wrapper" ] )
94+ SharedHelpers . run_shell_command ( second_command , cwd : cwd )
95+ end
96+
97+ sig do
98+ params (
99+ temp_dir : T . any ( Pathname , String ) ,
100+ local_files : T ::Array [ Dependabot ::DependencyFile ] ,
101+ updated_files : T ::Array [ Dependabot ::DependencyFile ]
102+ ) . void
103+ end
104+ def update_file_contents ( temp_dir , local_files , updated_files )
105+ local_files . each do |file |
106+ file_path = File . join ( temp_dir , file . directory , file . name )
107+ f_content = file . binary? ? File . binread ( file_path ) : File . read ( file_path )
108+ tmp_file = file . dup
109+ tmp_file . content = file . binary? ? Base64 . encode64 ( f_content ) : f_content
110+ updated_files [ T . must ( updated_files . index ( file ) ) ] = tmp_file
111+ end
112+ end
113+
78114 sig { params ( file : Dependabot ::DependencyFile ) . returns ( T ::Boolean ) }
79115 def target_file? ( file )
80116 @target_files . any? { |r | "/#{ file . name } " . end_with? ( r ) }
@@ -110,31 +146,32 @@ def base_path(build_file)
110146 File . dirname ( File . join ( build_file . directory , build_file . name ) ) . delete_suffix ( "/gradle/wrapper" )
111147 end
112148
113- sig do
114- params (
115- temp_dir : T . any ( Pathname , String ) ,
116- local_files : T ::Array [ Dependabot ::DependencyFile ] ,
117- updated_files : T ::Array [ Dependabot ::DependencyFile ]
118- ) . void
119- end
120- def update_files_content ( temp_dir , local_files , updated_files )
121- local_files . each do |file |
122- f_content = File . read ( File . join ( temp_dir , file . directory , file . name ) )
123- tmp_file = file . dup
124- tmp_file . content = tmp_file . binary? ? Base64 . encode64 ( f_content ) : f_content
125- updated_files [ T . must ( updated_files . index ( file ) ) ] = tmp_file
126- end
127- end
128-
129149 sig { params ( temp_dir : T . any ( Pathname , String ) ) . void }
130150 def populate_temp_directory ( temp_dir )
131151 files_to_populate . each do |file |
132152 in_path_name = File . join ( temp_dir , file . directory , file . name )
133153 FileUtils . mkdir_p ( File . dirname ( in_path_name ) )
134- File . write ( in_path_name , file . content )
154+
155+ # Write file content - binary files need special handling
156+ if file . binary?
157+ File . binwrite ( in_path_name , Base64 . decode64 ( T . must ( file . content ) ) )
158+ else
159+ File . write ( in_path_name , file . content )
160+ end
161+
162+ # Make gradlew scripts executable so they can be run
163+ FileUtils . chmod ( 0o755 , in_path_name ) if file . name . end_with? ( "gradlew" , "gradlew.bat" )
135164 end
136165 end
137166
167+ sig { params ( error : SharedHelpers ::HelperSubprocessFailed ) . returns ( T . noreturn ) }
168+ def handle_wrapper_update_error ( error )
169+ # Gradle wrapper update failures typically indicate build compatibility issues
170+ # with the new Gradle version. Raise as DependencyFileNotResolvable so the
171+ # service layer can handle appropriately.
172+ raise Dependabot ::DependencyFileNotResolvable , error . message
173+ end
174+
138175 sig { params ( file_name : String ) . void }
139176 def write_properties_file ( file_name ) # rubocop:disable Metrics/PerceivedComplexity
140177 http_proxy = ENV . fetch ( "HTTP_PROXY" , nil )
0 commit comments