Class: Dependabot::NpmAndYarn::UpdateChecker::VersionResolver

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb

Constant Summary collapse

TIGHTLY_COUPLED_MONOREPOS =
T.let(
  {
    "vue" => %w(vue vue-template-compiler)
  }.freeze,
  T::Hash[String, T::Array[String]]
)
YARN_PEER_DEP_ERROR_REGEX =

Error message returned by ‘yarn add` (for Yarn classic): “ > @reach/[email protected]” has incorrect peer dependency “[email protected] || 16.x || 16.4.0-alpha.0911da3” “workspace-aggregator-<random-string> > test > [email protected]” has incorrect peer dependency “react@^15.6.2” “ > [email protected]” has unmet peer dependency “react@>=0.14.0 <16.0.0”

/
  \s>\s(?<requiring_dep>[^>"]+)"\s
  has\s(incorrect|unmet)\speer\sdependency\s
  "(?<required_dep>[^"]+)"
/x
YARN_BERRY_PEER_DEP_ERROR_REGEX =

Error message returned by ‘yarn add` (for Yarn berry): YN0060: │ eve-roster@workspace:. provides jest (p8d618) \ with version 29.3.0, which doesn’t satisfy \ what ts-jest requestsn

/
  YN0060:.+\sprovides\s(?<required_dep>.+?)\s\((?<info_hash>\w+)\).+what\s(?<requiring_dep>.+?)\srequests
/x
YARN_BERRY_V4_PEER_DEP_ERROR_REGEX =

Error message returned by ‘yarn add` (for Yarn berry v4): YN0060: │ react is listed by your project with version 15.2.0, \ which doesn’t satisfy what react-dom (p89012) requests (^16.0.0).

/
  YN0060:.+\s(?<required_dep>.+?)\sis\s.+what\s(?<requiring_dep>.+?)\s\((?<info_hash>\w+)\)\srequests
/x
PNPM_PEER_DEP_ERROR_REGEX =

Error message returned by ‘pnpm update`: └─┬ react-dom 15.7.0

/
  ┬\s(?<requiring_dep>[^\n]+)\n
  [^\n]*✕\sunmet\speer\s(?<required_dep>[^:]+):
/mx
NPM6_PEER_DEP_ERROR_REGEX =

Error message returned by ‘npm install` (for NPM 6): [email protected] requires a peer of react@^15.2.0 \ but none is installed. You must install peer dependencies yourself.

/
  (?<requiring_dep>[^\s]+)\s
  requires\sa\speer\sof\s
  (?<required_dep>.+?)\sbut\snone\sis\sinstalled.
/x
NPM8_PEER_DEP_ERROR_REGEX =

Error message returned by ‘npm install` (for NPM 8): npm ERR! Could not resolve dependency: npm ERR! peer react@“^16.14.0” from [email protected]

or with two semver constraints: npm ERR! Could not resolve dependency: npm ERR! peer @opentelemetry/api@“>=1.0.0 <1.1.0” from @opentelemetry/[email protected]

/
  npm\s(?:WARN|ERR!)\sCould\snot\sresolve\sdependency:\n
  npm\s(?:WARN|ERR!)\speer\s(?<required_dep>\S+@\S+(\s\S+)?)\sfrom\s(?<requiring_dep>\S+@\S+)
/x

Instance Method Summary collapse

Constructor Details

#initialize(dependency:, dependency_files:, credentials:, latest_allowable_version:, latest_version_finder:, repo_contents_path:, dependency_group: nil, raise_on_ignored: false, update_cooldown: nil) ⇒ VersionResolver

rubocop:disable Metrics/AbcSize



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb', line 110

def initialize( # rubocop:disable Metrics/AbcSize
  dependency:,
  dependency_files:,
  credentials:,
  latest_allowable_version:,
  latest_version_finder:,
  repo_contents_path:,
  dependency_group: nil,
  raise_on_ignored: false,
  update_cooldown: nil
)
  @dependency               = dependency
  @dependency_files         = dependency_files
  @credentials              = credentials
  @latest_allowable_version = latest_allowable_version
  @dependency_group = dependency_group

  @latest_version_finder = T.let({}, T::Hash[Dependabot::Dependency, PackageLatestVersionFinder])
  @latest_version_finder[dependency] = latest_version_finder
  @repo_contents_path = repo_contents_path
  @raise_on_ignored = raise_on_ignored
  @update_cooldown = update_cooldown

  @types_package = T.let(nil, T.nilable(Dependabot::Dependency))
  @original_package = T.let(nil, T.nilable(Dependabot::Dependency))
  @latest_types_package_version = T.let(nil, T.nilable(Dependabot::Version))
  @dependency_files_builder = T.let(nil, T.nilable(DependencyFilesBuilder))
  # @latest_resolvable_version = T.let(nil, T.nilable(T.any(String, Gem::Version)))
  @resolve_latest_previous_version = T.let({}, T::Hash[Dependabot::Dependency, T.nilable(String)])
  @paths_requiring_update_check = T.let(nil, T.nilable(T::Array[String]))
  @top_level_dependencies = T.let(nil, T.nilable(T::Array[Dependabot::Dependency]))
  # @peer_dependency_errors_checked = T.let(false, T::Boolean)
  @old_peer_dependency_errors = T.let(
    nil, T.nilable(T::Array[T.any(T::Hash[String, T.nilable(String)], String)])
  )
  @peer_dependency_errors = T.let(nil, T.nilable(T::Array[T.any(T::Hash[String, T.nilable(String)], String)]))
end

Instance Method Details

#dependency_updates_from_full_unlockObject



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb', line 178

def dependency_updates_from_full_unlock
  return if git_dependency?(dependency)
  return updated_monorepo_dependencies if part_of_tightly_locked_monorepo?
  return if newly_broken_peer_reqs_from_dep.any?
  return if original_package_update_available?

  updates = [{
    dependency: dependency,
    version: latest_allowable_version,
    previous_version: latest_resolvable_previous_version(
      latest_allowable_version
    )
  }]
  newly_broken_peer_reqs_on_dep.each do |peer_req|
    dep_name = peer_req.fetch(:requiring_dep_name)
    dep = top_level_dependencies.find { |d| d.name == dep_name }

    # Can't handle reqs from sub-deps or git source deps (yet)
    return nil if dep.nil?
    return nil if git_dependency?(dep)

    updated_version =
      latest_version_of_dep_with_satisfied_peer_reqs(dep)
    return nil unless updated_version

    updates << {
      dependency: dep,
      version: updated_version,
      previous_version: resolve_latest_previous_version(
        dep, updated_version
      )
    }
  end
  updates += updated_types_dependencies if types_update_available?
  updates.uniq
end

#latest_resolvable_previous_version(updated_version) ⇒ Object



172
173
174
# File 'lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb', line 172

def latest_resolvable_previous_version(updated_version)
  resolve_latest_previous_version(dependency, updated_version)
end

#latest_resolvable_versionObject



149
150
151
152
153
154
155
156
157
158
# File 'lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb', line 149

def latest_resolvable_version
  return latest_allowable_version if git_dependency?(dependency)
  return if part_of_tightly_locked_monorepo?
  return if types_update_available?
  return if original_package_update_available?

  return latest_allowable_version unless relevant_unmet_peer_dependencies.any?

  satisfying_versions.first
end

#latest_version_resolvable_with_full_unlock?Boolean

Returns:

  • (Boolean)


161
162
163
164
165
# File 'lib/dependabot/npm_and_yarn/update_checker/version_resolver.rb', line 161

def latest_version_resolvable_with_full_unlock?
  return false if dependency_updates_from_full_unlock.nil?

  true
end