Class: Dependabot::Python::LanguageVersionManager
- Inherits:
-
Object
- Object
- Dependabot::Python::LanguageVersionManager
- Extended by:
- T::Sig
- Defined in:
- lib/dependabot/python/language_version_manager.rb
Instance Method Summary collapse
-
#initialize(python_requirement_parser:) ⇒ LanguageVersionManager
constructor
A new instance of LanguageVersionManager.
- #install_required_python ⇒ Object
- #installed_version ⇒ Object
- #normalize_python_exact_version(requirement_string) ⇒ Object
- #python_major_minor ⇒ Object
- #python_requirement_string ⇒ Object
- #python_version ⇒ Object
- #python_version_from_supported_versions ⇒ Object
- #python_version_matching(requirements) ⇒ Object
- #python_version_matching_imputed_requirements ⇒ Object
- #user_specified_python_version ⇒ Object
Constructor Details
#initialize(python_requirement_parser:) ⇒ LanguageVersionManager
Returns a new instance of LanguageVersionManager.
14 15 16 |
# File 'lib/dependabot/python/language_version_manager.rb', line 14 def initialize(python_requirement_parser:) @python_requirement_parser = python_requirement_parser end |
Instance Method Details
#install_required_python ⇒ Object
19 20 21 22 23 24 25 26 |
# File 'lib/dependabot/python/language_version_manager.rb', line 19 def install_required_python # The leading space is important in the version check return if SharedHelpers.run_shell_command("pyenv versions").include?(" #{python_major_minor}.") SharedHelpers.run_shell_command( "tar -axf /usr/local/.pyenv/versions/#{python_version}.tar.zst -C /usr/local/.pyenv/versions" ) end |
#installed_version ⇒ Object
29 30 31 32 33 34 35 |
# File 'lib/dependabot/python/language_version_manager.rb', line 29 def installed_version # Use `pyenv exec` to query the active Python version output, _status = SharedHelpers.run_shell_command("pyenv exec python --version") version = output.strip.split.last # Extract the version number (e.g., "3.13.1") T.must(version) end |
#normalize_python_exact_version(requirement_string) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/dependabot/python/language_version_manager.rb', line 62 def normalize_python_exact_version(requirement_string) return requirement_string if requirement_string.nil? || requirement_string.strip.empty? requirement_string = requirement_string.strip # If the requirement already has a wildcard, return nil return nil if requirement_string == "*" # If the requirement is not an exact version such as not X.Y.Z, =X.Y.Z, ==X.Y.Z, ===X.Y.Z # then return the requirement as is return requirement_string unless requirement_string.match?(/^=?={0,2}\s*\d+\.\d+(\.\d+)?(-[a-z0-9.-]+)?$/i) parts = requirement_string.gsub(/^=+/, "").split(".") case parts.length when 1 # Only major version (X) ">= #{parts[0]}.0.0 < #{parts[0].to_i + 1}.0.0" # Ensure only major version range when 2 # Major.Minor (X.Y) ">= #{parts[0]}.#{parts[1]}.0 < #{parts[0].to_i}.#{parts[1].to_i + 1}.0" # Ensure only minor version range when 3 # Major.Minor.Patch (X.Y.Z) ">= #{parts[0]}.#{parts[1]}.0 < #{parts[0].to_i}.#{parts[1].to_i + 1}.0" # Convert to >= X.Y.0 else requirement_string end end |
#python_major_minor ⇒ Object
38 39 40 |
# File 'lib/dependabot/python/language_version_manager.rb', line 38 def python_major_minor @python_major_minor ||= T.let(T.must(Python::Version.new(python_version).segments[0..1]).join("."), T.untyped) end |
#python_requirement_string ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/dependabot/python/language_version_manager.rb', line 48 def python_requirement_string if user_specified_python_version if user_specified_python_version.start_with?(/\d/) parts = user_specified_python_version.split(".") parts.fill("*", (parts.length)..2).join(".") else user_specified_python_version end else python_version_matching_imputed_requirements || Language::PRE_INSTALLED_HIGHEST_VERSION.to_s end end |
#python_version ⇒ Object
43 44 45 |
# File 'lib/dependabot/python/language_version_manager.rb', line 43 def python_version @python_version ||= T.let(python_version_from_supported_versions, T.nilable(String)) end |
#python_version_from_supported_versions ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/dependabot/python/language_version_manager.rb', line 89 def python_version_from_supported_versions requirement_string = python_requirement_string # If the requirement string isn't already a range (eg ">3.10"), coerce it to "major.minor.*". # The patch version is ignored because a non-matching patch version is unlikely to affect resolution. requirement_string = requirement_string.gsub(/\.\d+$/, ".*") if /^\d/.match?(requirement_string) requirement_string = normalize_python_exact_version(requirement_string) if requirement_string.nil? || requirement_string.strip.empty? return Language::PRE_INSTALLED_HIGHEST_VERSION.to_s end # Try to match one of our pre-installed Python versions requirement = T.must(Python::Requirement.requirements_array(requirement_string).first) version = Language::PRE_INSTALLED_PYTHON_VERSIONS.find { |v| requirement.satisfied_by?(v) } return version.to_s if version # Otherwise we have to raise an error supported_versions = Language::SUPPORTED_VERSIONS.map { |v| "#{v}.*" }.join(", ") raise ToolVersionNotSupported.new("Python", python_requirement_string, supported_versions) end |
#python_version_matching(requirements) ⇒ Object
130 131 132 133 134 135 136 137 138 |
# File 'lib/dependabot/python/language_version_manager.rb', line 130 def python_version_matching(requirements) Language::PRE_INSTALLED_PYTHON_VERSIONS.find do |version| requirements.all? do |req| next req.any? { |r| r.satisfied_by?(version) } if req.is_a?(Array) req.satisfied_by?(version) end end.to_s end |
#python_version_matching_imputed_requirements ⇒ Object
119 120 121 122 123 124 125 126 127 |
# File 'lib/dependabot/python/language_version_manager.rb', line 119 def python_version_matching_imputed_requirements compiled_file_python_requirement_markers = @python_requirement_parser.imputed_requirements.map do |r| Dependabot::Python::Requirement.new(r) end return unless compiled_file_python_requirement_markers.any? python_version_matching(compiled_file_python_requirement_markers) end |
#user_specified_python_version ⇒ Object
114 115 116 |
# File 'lib/dependabot/python/language_version_manager.rb', line 114 def user_specified_python_version @python_requirement_parser.user_specified_requirements.first end |