Class: Dependabot::Julia::FileUpdater
- Inherits:
-
FileUpdaters::Base
- Object
- FileUpdaters::Base
- Dependabot::Julia::FileUpdater
- Extended by:
- T::Sig
- Defined in:
- lib/dependabot/julia/file_updater.rb
Instance Attribute Summary collapse
-
#notices ⇒ Object
readonly
Returns the value of attribute notices.
Class Method Summary collapse
Instance Method Summary collapse
- #add_manifest_update_notice(manifest_path, error_message) ⇒ Object
- #all_project_files ⇒ Object
- #all_projects_only_update(updated_project_files) ⇒ Object
- #build_updated_files_multi(updated_files, updated_project_files, actual_manifest, result) ⇒ Object
- #call_julia_helper ⇒ Object
- #handle_julia_helper_error_multi(result, actual_manifest, updated_project_files) ⇒ Object
-
#initialize(dependencies:, dependency_files:, credentials:, repo_contents_path: nil, options: {}) ⇒ FileUpdater
constructor
A new instance of FileUpdater.
- #resolver_error?(error_message) ⇒ Boolean
- #update_all_project_files ⇒ Object
- #updated_dependency_files ⇒ Object
- #updated_files_with_julia_helper ⇒ Object
- #updated_project_content_for_file(proj_file) ⇒ Object
- #write_all_temporary_files(updated_project_files, actual_manifest) ⇒ Object
Constructor Details
#initialize(dependencies:, dependency_files:, credentials:, repo_contents_path: nil, options: {}) ⇒ FileUpdater
Returns a new instance of FileUpdater.
35 36 37 38 |
# File 'lib/dependabot/julia/file_updater.rb', line 35 def initialize(dependencies:, dependency_files:, credentials:, repo_contents_path: nil, options: {}) super @notices = T.let([], T::Array[Dependabot::Notice]) end |
Instance Attribute Details
#notices ⇒ Object (readonly)
Returns the value of attribute notices.
24 25 26 |
# File 'lib/dependabot/julia/file_updater.rb', line 24 def notices @notices end |
Class Method Details
.updated_files_regex ⇒ Object
19 20 21 |
# File 'lib/dependabot/julia/file_updater.rb', line 19 def self.updated_files_regex [/(?:Julia)?Project\.toml$/i, /(?:Julia)?Manifest(?:-v[\d.]+)?\.toml$/i] end |
Instance Method Details
#add_manifest_update_notice(manifest_path, error_message) ⇒ Object
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/dependabot/julia/file_updater.rb', line 178 def add_manifest_update_notice(manifest_path, ) # Resolve relative paths to absolute paths for clarity in user-facing notices # Use Pathname.cleanpath to handle any depth of relative paths (e.g., ../../Manifest.toml) project_dir = T.must(project_file).directory absolute_manifest_path = if manifest_path.start_with?("../", "./") # For workspace packages, compute the absolute path Pathname.new(File.join(project_dir, manifest_path)).cleanpath.to_s else # For regular packages, use the manifest path as-is File.join(project_dir, manifest_path) end @notices << Dependabot::Notice.new( mode: Dependabot::Notice::NoticeMode::WARN, type: "julia_manifest_not_updated", package_manager_name: "Pkg", title: "Could not update manifest #{absolute_manifest_path}", description: "The Julia package manager failed to update the new dependency versions " \ "in `#{absolute_manifest_path}`:\n\n```\n#{}\n```", show_in_pr: true, show_alert: true ) end |
#all_project_files ⇒ Object
104 105 106 |
# File 'lib/dependabot/julia/file_updater.rb', line 104 def all_project_files dependency_files.select { |f| f.name.match?(/Project\.toml$/i) } end |
#all_projects_only_update(updated_project_files) ⇒ Object
109 110 111 112 113 114 115 116 117 |
# File 'lib/dependabot/julia/file_updater.rb', line 109 def all_projects_only_update(updated_project_files) updated_project_files.filter_map do |update_info| file = T.cast(update_info[:file], Dependabot::DependencyFile) content = T.cast(update_info[:content], String) next if content == file.content updated_file(file: file, content: content) end end |
#build_updated_files_multi(updated_files, updated_project_files, actual_manifest, result) ⇒ Object
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/dependabot/julia/file_updater.rb', line 210 def build_updated_files_multi(updated_files, updated_project_files, actual_manifest, result) # Add all updated project files updated_project_files.each do |update_info| file = T.cast(update_info[:file], Dependabot::DependencyFile) content = T.cast(update_info[:content], String) next if content == file.content updated_files << updated_file(file: file, content: content) end return unless result["manifest_content"] updated_manifest_content = result["manifest_content"] return unless updated_manifest_content != actual_manifest.content manifest_for_update = if result["manifest_path"] manifest_file_for_path(result["manifest_path"]) else actual_manifest end updated_files << updated_file(file: manifest_for_update, content: updated_manifest_content) end |
#call_julia_helper ⇒ Object
143 144 145 146 147 148 |
# File 'lib/dependabot/julia/file_updater.rb', line 143 def call_julia_helper registry_client.update_manifest( project_path: Dir.pwd, updates: build_updates_hash ) end |
#handle_julia_helper_error_multi(result, actual_manifest, updated_project_files) ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/dependabot/julia/file_updater.rb', line 157 def handle_julia_helper_error_multi(result, actual_manifest, updated_project_files) = result["error"] manifest_path = actual_manifest.name is_resolver_error = resolver_error?() raise unless is_resolver_error add_manifest_update_notice(manifest_path, ) # Return all updated Project.toml files all_projects_only_update(updated_project_files) end |
#resolver_error?(error_message) ⇒ Boolean
171 172 173 174 175 |
# File 'lib/dependabot/julia/file_updater.rb', line 171 def resolver_error?() .start_with?("Pkg resolver error:") || .include?("Unsatisfiable requirements") || .include?("ResolverError") end |
#update_all_project_files ⇒ Object
76 77 78 79 80 81 82 83 |
# File 'lib/dependabot/julia/file_updater.rb', line 76 def update_all_project_files all_project_files.map do |proj_file| { file: proj_file, content: updated_project_content_for_file(proj_file) } end end |
#updated_dependency_files ⇒ Object
41 42 43 44 45 46 47 48 |
# File 'lib/dependabot/julia/file_updater.rb', line 41 def updated_dependency_files # If no project file, cannot proceed raise "No Project.toml file found" unless project_file # Use DependabotHelper.jl for manifest updating # This works for both standard packages and workspace packages updated_files_with_julia_helper end |
#updated_files_with_julia_helper ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/dependabot/julia/file_updater.rb', line 51 def updated_files_with_julia_helper updated_files = [] SharedHelpers.in_a_temporary_repo_directory(T.must(dependency_files.first).directory, repo_contents_path) do # Update all project files (main + workspace members) updated_project_files = update_all_project_files actual_manifest = find_manifest_file return all_projects_only_update(updated_project_files) if actual_manifest.nil? # Write all updated project files to disk for Julia's Pkg write_all_temporary_files(updated_project_files, actual_manifest) result = call_julia_helper return handle_julia_helper_error_multi(result, actual_manifest, updated_project_files) if result["error"] build_updated_files_multi(updated_files, updated_project_files, actual_manifest, result) end raise "No files changed!" if updated_files.empty? updated_files end |
#updated_project_content_for_file(proj_file) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/dependabot/julia/file_updater.rb', line 86 def updated_project_content_for_file(proj_file) content = T.must(proj_file.content) dependencies.each do |dependency| # Find the new requirement for this dependency in this file new_requirement = dependency.requirements .find { |req| T.cast(req[:file], String) == proj_file.name } &.fetch(:requirement) next unless new_requirement content = update_dependency_requirement_in_content(content, dependency.name, new_requirement) end content end |
#write_all_temporary_files(updated_project_files, actual_manifest) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/dependabot/julia/file_updater.rb', line 125 def write_all_temporary_files(updated_project_files, actual_manifest) # Write all updated project files updated_project_files.each do |update_info| file = T.cast(update_info[:file], Dependabot::DependencyFile) content = T.cast(update_info[:content], String) file_path = file.name FileUtils.mkdir_p(File.dirname(file_path)) if file_path.include?("/") File.write(file_path, content) end # Write manifest file manifest_path = actual_manifest.name FileUtils.mkdir_p(File.dirname(manifest_path)) if manifest_path.include?("/") File.write(manifest_path, actual_manifest.content) end |