Skip to content

Commit

Permalink
Strict type Dependabot::Bundler::PathGemSpecFinder.
Browse files Browse the repository at this point in the history
  • Loading branch information
raj-meka committed Jun 18, 2024
1 parent 663bc8e commit 8dee25b
Showing 1 changed file with 21 additions and 9 deletions.
30 changes: 21 additions & 9 deletions bundler/lib/dependabot/bundler/file_fetcher/path_gemspec_finder.rb
Original file line number Diff line number Diff line change
@@ -1,47 +1,54 @@
# typed: true
# typed: strict
# frozen_string_literal: true

require "pathname"
require "parser/current"
require "dependabot/bundler/file_fetcher"
require "dependabot/errors"
require "sorbet-runtime"

module Dependabot
module Bundler
class FileFetcher
# Finds the paths of any gemspecs declared using `path: ` in the
# passed Gemfile.
class PathGemspecFinder
extend T::Sig

sig { params(gemfile: Dependabot::DependencyFile).void }
def initialize(gemfile:)
@gemfile = gemfile
end

sig { returns(T::Array[String]) }
def path_gemspec_paths
ast = Parser::CurrentRuby.parse(gemfile.content)
ast = Parser::CurrentRuby.parse(gemfile&.content)
find_path_gemspec_paths(ast)
rescue Parser::SyntaxError
raise Dependabot::DependencyFileNotParseable, gemfile.path
raise Dependabot::DependencyFileNotParseable, T.must(gemfile&.path)
end

private

sig { returns(T.nilable(Dependabot::DependencyFile)) }
attr_reader :gemfile

sig { params(node: T.untyped).returns(T::Array[T.untyped]) }
def find_path_gemspec_paths(node)
return [] unless node.is_a?(Parser::AST::Node)

if declares_path_dependency?(node)
path_node = path_node_for_gem_declaration(node)

unless path_node.type == :str
path = gemfile.path
unless path_node&.type == :str
path = gemfile&.path
msg = "Dependabot only supports uninterpolated string arguments " \
"for path dependencies. Got " \
"`#{path_node.loc.expression.source}`"
raise Dependabot::DependencyFileNotParseable.new(path, msg)
"`#{path_node&.loc&.expression&.source}`"
raise Dependabot::DependencyFileNotParseable.new(T.must(path), msg)
end

path = path_node.loc.expression.source.gsub(/['"]/, "")
path = T.must(path_node).loc.expression.source.gsub(/['"]/, "")
return [clean_path(path)]
end

Expand All @@ -50,19 +57,22 @@ def find_path_gemspec_paths(node)
end
end

sig { returns(T.nilable(String)) }
def current_dir
@current_dir ||= gemfile.name.rpartition("/").first
@current_dir ||= T.let(gemfile&.name&.rpartition("/")&.first, T.nilable(String))
@current_dir = nil if @current_dir == ""
@current_dir
end

sig { params(node: Parser::AST::Node).returns(T::Boolean) }
def declares_path_dependency?(node)
return false unless node.is_a?(Parser::AST::Node)
return false unless node.children[1] == :gem

!path_node_for_gem_declaration(node).nil?
end

sig { params(path: String).returns(Pathname) }
def clean_path(path)
if Pathname.new(path).absolute?
base_path = Pathname.new(File.expand_path(Dir.pwd))
Expand All @@ -72,6 +82,7 @@ def clean_path(path)
Pathname.new(path).cleanpath
end

sig { params(node: Parser::AST::Node).returns(T.nilable(Parser::AST::Node)) }
def path_node_for_gem_declaration(node)
return unless node.children.last.type == :hash

Expand All @@ -86,6 +97,7 @@ def path_node_for_gem_declaration(node)
path_hash_pair.children.last
end

sig { params(node: Parser::AST::Node).returns(Symbol) }
def key_from_hash_pair(node)
node.children.first.children.first.to_sym
end
Expand Down

0 comments on commit 8dee25b

Please sign in to comment.