Class: Dependabot::Uv::UpdateChecker::PipCompileVersionResolver

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

Overview

This class does version resolution for pip-compile. Its approach is:

  • Unlock the dependency we’re checking in the requirements.in file

  • Run ‘pip-compile` and see what the result is

rubocop:disable Metrics/ClassLength

Constant Summary collapse

GIT_DEPENDENCY_UNREACHABLE_REGEX =
T.let(/git clone --filter=blob:none --quiet (?<url>[^\s]+).* /, Regexp)
GIT_REFERENCE_NOT_FOUND_REGEX =
T.let(/Did not find branch or tag '(?<tag>[^\n"]+)'/m, Regexp)
GIT_CREDENTIALS_ERROR_REGEX =
T.let(
  /could not read Username for '(?<url>[^']+)'/,
  Regexp
)
GIT_DEPENDENCY_URL_FROM_UV_REGEX =
T.let(
  %r{git\+(?<url>https?://[^\s@#]+)},
  Regexp
)
NATIVE_COMPILATION_ERROR =
T.let(
  "pip._internal.exceptions.InstallationSubprocessError: Getting requirements to build wheel exited with 1",
  String
)
PYTHON_PACKAGE_NAME_REGEX =
T.let(/[A-Za-z0-9_\-]+/, Regexp)
RESOLUTION_IMPOSSIBLE_ERROR =
T.let("ResolutionImpossible", String)
ERROR_REGEX =
T.let(/(?<=ERROR\:\W).*$/, Regexp)
UV_UNRESOLVABLE_REGEX =
T.let(/ × No solution found when resolving dependencies:[\s\S]*$/, Regexp)
PYTHON_VERSION_REGEX =
T.let(/--python-version[=\s]+(?<version>\d+\.\d+(?:\.\d+)?)/, Regexp)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dependency:, dependency_files:, credentials:, repo_contents_path:) ⇒ PipCompileVersionResolver

Returns a new instance of PipCompileVersionResolver.



75
76
77
78
79
80
81
82
# File 'lib/dependabot/uv/update_checker/pip_compile_version_resolver.rb', line 75

def initialize(dependency:, dependency_files:, credentials:, repo_contents_path:)
  @dependency               = T.let(dependency, Dependabot::Dependency)
  @dependency_files         = T.let(dependency_files, T::Array[Dependabot::DependencyFile])
  @credentials              = T.let(credentials, T::Array[Dependabot::Credential])
  @repo_contents_path       = T.let(repo_contents_path, T.nilable(String))
  @build_isolation = T.let(true, T::Boolean)
  @error_handler = T.let(PipCompileErrorHandler.new, PipCompileErrorHandler)
end

Instance Attribute Details

#credentialsObject (readonly)

Returns the value of attribute credentials.



59
60
61
# File 'lib/dependabot/uv/update_checker/pip_compile_version_resolver.rb', line 59

def credentials
  @credentials
end

#dependencyObject (readonly)

Returns the value of attribute dependency.



53
54
55
# File 'lib/dependabot/uv/update_checker/pip_compile_version_resolver.rb', line 53

def dependency
  @dependency
end

#dependency_filesObject (readonly)

Returns the value of attribute dependency_files.



56
57
58
# File 'lib/dependabot/uv/update_checker/pip_compile_version_resolver.rb', line 56

def dependency_files
  @dependency_files
end

#error_handlerObject (readonly)

Returns the value of attribute error_handler.



65
66
67
# File 'lib/dependabot/uv/update_checker/pip_compile_version_resolver.rb', line 65

def error_handler
  @error_handler
end

#repo_contents_pathObject (readonly)

Returns the value of attribute repo_contents_path.



62
63
64
# File 'lib/dependabot/uv/update_checker/pip_compile_version_resolver.rb', line 62

def repo_contents_path
  @repo_contents_path
end

Instance Method Details

#latest_resolvable_version(requirement: nil) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/dependabot/uv/update_checker/pip_compile_version_resolver.rb', line 85

def latest_resolvable_version(requirement: nil)
  @latest_resolvable_version_string ||= T.let(
    {},
    T.nilable(T::Hash[T.nilable(String), T.nilable(Dependabot::Uv::Version)])
  )
  return @latest_resolvable_version_string[requirement] if @latest_resolvable_version_string.key?(requirement)

  version_string =
    fetch_latest_resolvable_version_string(requirement: requirement)

  @latest_resolvable_version_string[requirement] ||=
    version_string.nil? ? nil : Uv::Version.new(version_string)
end

#resolvable?(version:) ⇒ Boolean

Returns:

  • (Boolean)


100
101
102
103
104
105
106
107
108
109
# File 'lib/dependabot/uv/update_checker/pip_compile_version_resolver.rb', line 100

def resolvable?(version:)
  @resolvable ||= T.let({}, T.nilable(T::Hash[Gem::Version, T::Boolean]))
  return T.must(@resolvable[version]) if @resolvable.key?(version)

  @resolvable[version] = if latest_resolvable_version(requirement: "==#{version}")
                           true
                         else
                           false
                         end
end