Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added sorbettype check as strict #11379

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 40 additions & 19 deletions python/lib/dependabot/python/file_parser/pipfile_files_parser.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# typed: true
# typed: strict
# frozen_string_literal: true

require "toml-rb"
Expand All @@ -13,7 +13,8 @@ module Dependabot
module Python
class FileParser
class PipfileFilesParser
DEPENDENCY_GROUP_KEYS = [
extend T::Sig
DEPENDENCY_GROUP_KEYS = T.let([
{
pipfile: "packages",
lockfile: "default"
Expand All @@ -22,12 +23,14 @@ class PipfileFilesParser
pipfile: "dev-packages",
lockfile: "develop"
}
].freeze
].freeze, T::Array[T::Hash[Symbol, String]])

sig { params(dependency_files: T::Array[Dependabot::DependencyFile]).void }
def initialize(dependency_files:)
@dependency_files = dependency_files
end

sig { returns(Dependabot::FileParsers::Base::DependencySet) }
def dependency_set
dependency_set = Dependabot::FileParsers::Base::DependencySet.new

Expand All @@ -39,19 +42,21 @@ def dependency_set

private

sig { returns(T::Array[Dependabot::DependencyFile]) }
attr_reader :dependency_files

sig { returns(Dependabot::FileParsers::Base::DependencySet) }
def pipfile_dependencies
dependencies = Dependabot::FileParsers::Base::DependencySet.new

DEPENDENCY_GROUP_KEYS.each do |keys|
next unless parsed_pipfile[keys[:pipfile]]
next unless parsed_pipfile[T.must(keys[:pipfile])]

parsed_pipfile[keys[:pipfile]].map do |dep_name, req|
parsed_pipfile[T.must(keys[:pipfile])].map do |dep_name, req|
group = keys[:lockfile]
next unless specifies_version?(req)
next if git_or_path_requirement?(req)
next if pipfile_lock && !dependency_version(dep_name, req, group)
next if pipfile_lock && !dependency_version(dep_name, req, T.must(group))

# Empty requirements are not allowed in Dependabot::Dependency and
# equivalent to "*" (latest available version)
Expand All @@ -60,10 +65,10 @@ def pipfile_dependencies
dependencies <<
Dependency.new(
name: normalised_name(dep_name),
version: dependency_version(dep_name, req, group),
version: dependency_version(dep_name, req, T.must(group)),
requirements: [{
requirement: req.is_a?(String) ? req : req["version"],
file: pipfile.name,
file: T.must(pipfile).name,
source: nil,
groups: [group]
}],
Expand All @@ -79,6 +84,7 @@ def pipfile_dependencies
# Create a DependencySet where each element has no requirement. Any
# requirements will be added when combining the DependencySet with
# other DependencySets.
sig { returns(Dependabot::FileParsers::Base::DependencySet) }
def pipfile_lock_dependencies
dependencies = Dependabot::FileParsers::Base::DependencySet.new
return dependencies unless pipfile_lock
Expand Down Expand Up @@ -108,6 +114,10 @@ def pipfile_lock_dependencies
dependencies
end

sig do
params(dep_name: String, requirement: T.any(String, T::Hash[String, T.untyped]),
group: String).returns(T.nilable(String))
end
def dependency_version(dep_name, requirement, group)
req = version_from_hash_or_string(requirement)

Expand All @@ -117,53 +127,64 @@ def dependency_version(dep_name, requirement, group)

version = version_from_hash_or_string(details)
version&.gsub(/^===?/, "")
elsif req.start_with?("==") && !req.include?("*")
req.strip.gsub(/^===?/, "")
elsif T.must(req).start_with?("==") && !T.must(req).include?("*")
T.must(req).strip.gsub(/^===?/, "")
end
end

sig do
params(obj: T.any(String, NilClass, T::Array[String], T::Hash[String, T.untyped])).returns(T.nilable(String))
end
def version_from_hash_or_string(obj)
case obj
when String then obj.strip
when Hash then obj["version"]
end
end

sig { params(req: T.any(String, T::Hash[String, T.untyped])).returns(T.any(T::Boolean, NilClass, String)) }
def specifies_version?(req)
return true if req.is_a?(String)

req["version"]
end

sig { params(req: T.any(String, T::Hash[String, T.untyped])).returns(T::Boolean) }
def git_or_path_requirement?(req)
return false unless req.is_a?(Hash)

%w(git path).any? { |k| req.key?(k) }
end

def normalised_name(name)
NameNormaliser.normalise(name)
sig { params(name: String, extras: T::Array[String]).returns(String) }
def normalised_name(name, extras = [])
NameNormaliser.normalise_including_extras(name, extras)
end

sig { returns(T::Hash[String, T.untyped]) }
def parsed_pipfile
@parsed_pipfile ||= TomlRB.parse(pipfile.content)
@parsed_pipfile ||= T.let(TomlRB.parse(T.must(pipfile).content), T.nilable(T::Hash[String, T.untyped]))
rescue TomlRB::ParseError, TomlRB::ValueOverwriteError
raise Dependabot::DependencyFileNotParseable, pipfile.path
raise Dependabot::DependencyFileNotParseable, T.must(pipfile).path
end

sig { returns(T::Hash[String, T.untyped]) }
def parsed_pipfile_lock
@parsed_pipfile_lock ||= JSON.parse(pipfile_lock.content)
@parsed_pipfile_lock ||= T.let(JSON.parse(T.must(T.must(pipfile_lock).content)),
T.nilable(T::Hash[String, T.untyped]))
rescue JSON::ParserError
raise Dependabot::DependencyFileNotParseable, pipfile_lock.path
raise Dependabot::DependencyFileNotParseable, T.must(pipfile_lock).path
end

sig { returns(T.nilable(Dependabot::DependencyFile)) }
def pipfile
@pipfile ||= dependency_files.find { |f| f.name == "Pipfile" }
@pipfile ||= T.let(dependency_files.find { |f| f.name == "Pipfile" }, T.nilable(Dependabot::DependencyFile))
end

sig { returns(T.nilable(Dependabot::DependencyFile)) }
def pipfile_lock
@pipfile_lock ||=
dependency_files.find { |f| f.name == "Pipfile.lock" }
@pipfile_lock ||= T.let(dependency_files.find { |f| f.name == "Pipfile.lock" },
T.nilable(Dependabot::DependencyFile))
end
end
end
Expand Down
Loading