class Dependabot::Bundler::FileUpdater::LockfileUpdater
Constants
- GIT_DEPENDENCIES_SECTION
- GIT_DEPENDENCY_DETAILS
- LOCKFILE_ENDING
Attributes
credentials[R]
dependencies[R]
dependency_files[R]
options[R]
repo_contents_path[R]
Public Class Methods
new(dependencies:, dependency_files:, repo_contents_path: nil, credentials:, options:)
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 35 def initialize(dependencies:, dependency_files:, repo_contents_path: nil, credentials:, options:) @dependencies = dependencies @dependency_files = dependency_files @repo_contents_path = repo_contents_path @credentials = credentials @options = options end
Public Instance Methods
gemspec_sources()
click to toggle source
Can't be a constant because some of these don't exist in bundler 1.15, which Heroku uses, which causes an exception on boot.
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 28 def gemspec_sources [ ::Bundler::Source::Path, ::Bundler::Source::Gemspec ] end
updated_lockfile_content()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 44 def updated_lockfile_content @updated_lockfile_content ||= begin updated_content = build_updated_lockfile raise "Expected content to change!" if lockfile.content == updated_content updated_content end end
Private Instance Methods
build_updated_lockfile()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 60 def build_updated_lockfile base_dir = dependency_files.first.directory lockfile_body = SharedHelpers.in_a_temporary_repo_directory( base_dir, repo_contents_path ) do |tmp_dir| write_temporary_dependency_files NativeHelpers.run_bundler_subprocess( bundler_version: bundler_version, function: "update_lockfile", args: { gemfile_name: gemfile.name, lockfile_name: lockfile.name, dir: tmp_dir, credentials: credentials, dependencies: dependencies.map(&:to_h) } ) end post_process_lockfile(lockfile_body) rescue SharedHelpers::HelperSubprocessFailed => e raise unless ruby_lock_error?(e) @dont_lock_ruby_version = true retry end
bundler_version()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 300 def bundler_version @bundler_version ||= Helpers.bundler_version(lockfile) end
evaled_gemfiles()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 283 def evaled_gemfiles @evaled_gemfiles ||= dependency_files. reject { |f| f.name.end_with?(".gemspec") }. reject { |f| f.name.end_with?(".specification") }. reject { |f| f.name.end_with?(".lock") }. reject { |f| f.name.end_with?(".ruby-version") }. reject { |f| f.name == "Gemfile" }. reject { |f| f.name == "gems.rb" }. reject { |f| f.name == "gems.locked" }. reject(&:support_file?) end
gemfile()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 267 def gemfile @gemfile ||= dependency_files.find { |f| f.name == "Gemfile" } || dependency_files.find { |f| f.name == "gems.rb" } end
imported_ruby_files()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 154 def imported_ruby_files dependency_files. select { |f| f.name.end_with?(".rb") }. reject { |f| f.name == "gems.rb" } end
lockfile()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 272 def lockfile @lockfile ||= dependency_files.find { |f| f.name == "Gemfile.lock" } || dependency_files.find { |f| f.name == "gems.locked" } end
path_gemspecs()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 149 def path_gemspecs all = dependency_files.select { |f| f.name.end_with?(".gemspec") } all - top_level_gemspecs end
post_process_lockfile(lockfile_body)
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 170 def post_process_lockfile(lockfile_body) lockfile_body = reorder_git_dependencies(lockfile_body) replace_lockfile_ending(lockfile_body) end
prepared_gemfile_content(file)
click to toggle source
rubocop:enable Metrics/PerceivedComplexity
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 238 def prepared_gemfile_content(file) content = GemfileUpdater.new( dependencies: dependencies, gemfile: file ).updated_gemfile_content return content if @dont_lock_ruby_version top_level_gemspecs.each do |gs| content = RubyRequirementSetter.new(gemspec: gs).rewrite(content) end content end
reorder_git_dependencies(lockfile_body)
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 175 def reorder_git_dependencies(lockfile_body) new_section = lockfile_body.match(GIT_DEPENDENCIES_SECTION)&.to_s old_section = lockfile.content.match(GIT_DEPENDENCIES_SECTION)&.to_s return lockfile_body unless new_section && old_section new_deps = new_section.scan(GIT_DEPENDENCY_DETAILS) old_deps = old_section.scan(GIT_DEPENDENCY_DETAILS) return lockfile_body unless new_deps.count == old_deps.count reordered_new_section = new_deps.sort_by do |new_dep_details| remote = new_dep_details.match(/remote: (?<remote>.*\n)/)[:remote] i = old_deps.index { |details| details.include?(remote) } # If this dependency isn't in the old lockfile then we can't rely # on that (presumably outdated) lockfile to do reordering. # Instead, we just return the default-ordered content just # generated. return lockfile_body unless i i end.join lockfile_body.gsub(new_section, reordered_new_section) end
replace_lockfile_ending(lockfile_body)
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 202 def replace_lockfile_ending(lockfile_body) # Re-add the old `BUNDLED WITH` version (and remove the RUBY VERSION # if it wasn't previously present in the lockfile) lockfile_body.gsub( LOCKFILE_ENDING, lockfile.content.match(LOCKFILE_ENDING)&.[](:ending) || "\n" ) end
replacement_version_for_gemspec(gemspec_content)
click to toggle source
rubocop:disable Metrics/PerceivedComplexity
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 220 def replacement_version_for_gemspec(gemspec_content) return "0.0.1" unless lockfile gemspec_specs = ::Bundler::LockfileParser.new(sanitized_lockfile_body).specs. select { |s| gemspec_sources.include?(s.source.class) } gem_name = GemspecDependencyNameFinder.new(gemspec_content: gemspec_content). dependency_name return gemspec_specs.first&.version || "0.0.1" unless gem_name spec = gemspec_specs.find { |s| s.name == gem_name } spec&.version || gemspec_specs.first&.version || "0.0.1" end
ruby_lock_error?(error)
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 89 def ruby_lock_error?(error) return false unless error.error_class == "Bundler::VersionConflict" return false unless error.message.include?(" for gem \"ruby\0\"") return false if @dont_lock_ruby_version dependency_files.any? { |f| f.name.end_with?(".gemspec") } end
ruby_version_file()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 166 def ruby_version_file dependency_files.find { |f| f.name == ".ruby-version" } end
sanitized_gemspec_content(gemspec_content)
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 211 def sanitized_gemspec_content(gemspec_content) new_version = replacement_version_for_gemspec(gemspec_content) GemspecSanitizer. new(replacement_version: new_version). rewrite(gemspec_content) end
sanitized_lockfile_body()
click to toggle source
TODO: Stop sanitizing the lockfile once we have bundler 2 installed
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 279 def sanitized_lockfile_body lockfile.content.gsub(LOCKFILE_ENDING, "") end
specification_files()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 296 def specification_files dependency_files.select { |f| f.name.end_with?(".specification") } end
top_level_gemspecs()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 160 def top_level_gemspecs dependency_files. select { |file| file.name.end_with?(".gemspec") }. reject(&:support_file?) end
updated_gemfile_content(file)
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 253 def updated_gemfile_content(file) GemfileUpdater.new( dependencies: dependencies, gemfile: file ).updated_gemfile_content end
updated_gemspec_content(gemspec)
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 260 def updated_gemspec_content(gemspec) GemspecUpdater.new( dependencies: dependencies, gemspec: gemspec ).updated_gemspec_content end
write_imported_ruby_files()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 141 def write_imported_ruby_files imported_ruby_files.each do |file| path = file.name FileUtils.mkdir_p(Pathname.new(path).dirname) File.write(path, file.content) end end
write_path_gemspecs()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 127 def write_path_gemspecs path_gemspecs.each do |file| path = file.name FileUtils.mkdir_p(Pathname.new(path).dirname) File.write(path, sanitized_gemspec_content(file.content)) end specification_files.each do |file| path = file.name FileUtils.mkdir_p(Pathname.new(path).dirname) File.write(path, file.content) end end
write_ruby_version_file()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 119 def write_ruby_version_file return unless ruby_version_file path = ruby_version_file.name FileUtils.mkdir_p(Pathname.new(path).dirname) File.write(path, ruby_version_file.content) end
write_temporary_dependency_files()
click to toggle source
# File lib/dependabot/bundler/file_updater/lockfile_updater.rb, line 97 def write_temporary_dependency_files File.write(gemfile.name, prepared_gemfile_content(gemfile)) File.write(lockfile.name, sanitized_lockfile_body) top_level_gemspecs.each do |gemspec| path = gemspec.name FileUtils.mkdir_p(Pathname.new(path).dirname) updated_content = updated_gemspec_content(gemspec) File.write(path, sanitized_gemspec_content(updated_content)) end write_ruby_version_file write_path_gemspecs write_imported_ruby_files evaled_gemfiles.each do |file| path = file.name FileUtils.mkdir_p(Pathname.new(path).dirname) File.write(path, updated_gemfile_content(file)) end end