class Dependabot::NpmAndYarn::UpdateChecker::SubdependencyVersionResolver
Attributes
Public Class Methods
# File lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb, line 21 def initialize(dependency:, credentials:, dependency_files:, ignored_versions:, latest_allowable_version:) @dependency = dependency @credentials = credentials @dependency_files = dependency_files @ignored_versions = ignored_versions @latest_allowable_version = latest_allowable_version end
Public Instance Methods
# File lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb, line 30 def latest_resolvable_version raise "Not a subdependency!" if dependency.requirements.any? return if bundled_dependency? SharedHelpers.in_a_temporary_directory do dependency_files_builder.write_temporary_dependency_files updated_lockfiles = filtered_lockfiles.map do |lockfile| updated_content = update_subdependency_in_lockfile(lockfile) updated_lockfile = lockfile.dup updated_lockfile.content = updated_content updated_lockfile end version_from_updated_lockfiles(updated_lockfiles) end rescue SharedHelpers::HelperSubprocessFailed # TODO: Move error handling logic from the FileUpdater to this class # Return nil (no update possible) if an unknown error occurred nil end
Private Instance Methods
TODO: We should try and fix this by updating the parent that's not bundled. For this case: `chokidar > fsevents > node-pre-gyp > tar` we would need to update `fsevents`
We shouldn't update bundled sub-dependencies as they have been bundled into the release at an exact version by a parent using `bundledDependencies`.
For example, fsevents < 2 bundles node-pre-gyp meaning all it's sub-dependencies get bundled into the release tarball at publish time so you always get the same sub-dependency versions if you re-install a specific version of fsevents.
Updating the sub-dependency by deleting the entry works but it gets removed from the bundled set of dependencies and moved top level resulting in a bunch of package duplication which is pretty confusing.
# File lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb, line 173 def bundled_dependency? dependency.subdependency_metadata&. any? { |h| h.fetch(:npm_bundled, false) } || false end
# File lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb, line 148 def dependency_files_builder @dependency_files_builder ||= DependencyFilesBuilder.new( dependency: dependency, dependency_files: dependency_files, credentials: credentials ) end
# File lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb, line 140 def filtered_lockfiles @filtered_lockfiles ||= SubDependencyFilesFilterer.new( dependency_files: dependency_files, updated_dependencies: [updated_dependency] ).files_requiring_update end
# File lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb, line 112 def run_npm_updater(path, lockfile_name, lockfile_content) SharedHelpers.with_git_configured(credentials: credentials) do Dir.chdir(path) do npm_version = Dependabot::NpmAndYarn::Helpers.npm_version(lockfile_content) SharedHelpers.run_helper_subprocess( command: NativeHelpers.helper_path, function: "#{npm_version}:updateSubdependency", args: [Dir.pwd, lockfile_name, [dependency.to_h]] ) end end end
# File lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb, line 88 def run_yarn_updater(path, lockfile_name) SharedHelpers.with_git_configured(credentials: credentials) do Dir.chdir(path) do SharedHelpers.run_helper_subprocess( command: NativeHelpers.helper_path, function: "yarn:updateSubdependency", args: [Dir.pwd, lockfile_name] ) end end rescue SharedHelpers::HelperSubprocessFailed => e unfindable_str = "find package \"#{dependency.name}" raise unless e.message.include?("The registry may be down") || e.message.include?("ETIMEDOUT") || e.message.include?("ENOBUFS") || e.message.include?(unfindable_str) retry_count ||= 0 retry_count += 1 raise if retry_count > 2 sleep(rand(3.0..10.0)) && retry end
# File lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb, line 58 def update_subdependency_in_lockfile(lockfile) lockfile_name = Pathname.new(lockfile.name).basename.to_s path = Pathname.new(lockfile.name).dirname.to_s updated_files = if lockfile.name.end_with?("yarn.lock") run_yarn_updater(path, lockfile_name) else run_npm_updater(path, lockfile_name, lockfile.content) end updated_files.fetch(lockfile_name) end
# File lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb, line 130 def updated_dependency Dependabot::Dependency.new( name: dependency.name, version: latest_allowable_version, previous_version: dependency.version, requirements: [], package_manager: dependency.package_manager ) end
# File lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb, line 126 def version_class NpmAndYarn::Version end
# File lib/dependabot/npm_and_yarn/update_checker/subdependency_version_resolver.rb, line 71 def version_from_updated_lockfiles(updated_lockfiles) updated_files = dependency_files - dependency_files_builder.yarn_locks - dependency_files_builder.package_locks - dependency_files_builder.shrinkwraps + updated_lockfiles updated_version = NpmAndYarn::FileParser.new( dependency_files: updated_files, source: nil, credentials: credentials ).parse.find { |d| d.name == dependency.name }&.version return unless updated_version version_class.new(updated_version) end