dependabot-bundler 0.318.0 → 0.319.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2893c2182ca7aad9c1ab46333536daf31a7253a08c01b3a84f422622118aeebd
4
- data.tar.gz: ddffd70d6df0a1f77370bc93fe36bb92604f44353b8ed1ddcc317aabc5986de0
3
+ metadata.gz: c84a4ce3cf3c25f4653b83ec740ff4eab8e340e6f581b54927b3b538a555fbba
4
+ data.tar.gz: da79266f90324197c44ca612b834a8ff45cefdfba9c706e53634e343f09f1c07
5
5
  SHA512:
6
- metadata.gz: 97aa8b394311211a8ce25b920e8c230d8f4b75489f1f3ee90180796a9ccf6ab2b146d501bebeb44194f83737b0af620647ab52e789ea84f0ba4509667ce5aac0
7
- data.tar.gz: 54a4b721000eba54bee7d8608d0269858f1477ab67f4b8f560c96c37c6e1f1f884995c0705531e44d48051fe534518f31d5d675c105fb3c0cb73c58f3a779e65
6
+ metadata.gz: 1db9886067f3b48773a6f9e64def493290e161643cf4641c4e5b6b63287925494b360ee3f84e3052c05b699ed2b8f8a8f8f52cd42518b696621560376ab13a1d
7
+ data.tar.gz: 422cde4c40c7a03197589c5ad06afcd51816023c6afc31bd5727bb38974b834e943b108e30702b832bfd579d999d77c939fc885320c5449343e0d58fdbade790
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "pathname"
5
- require "parser/current"
5
+ require "prism"
6
6
  require "dependabot/bundler/file_fetcher"
7
7
  require "dependabot/errors"
8
8
  require "sorbet-runtime"
@@ -22,10 +22,10 @@ module Dependabot
22
22
 
23
23
  sig { returns(T::Array[String]) }
24
24
  def child_gemfile_paths
25
- ast = Parser::CurrentRuby.parse(gemfile&.content)
26
- find_child_gemfile_paths(ast)
27
- rescue Parser::SyntaxError
28
- raise Dependabot::DependencyFileNotParseable, T.must(gemfile&.path)
25
+ result = Prism.parse(gemfile&.content)
26
+ raise Dependabot::DependencyFileNotParseable, T.must(gemfile&.path) if result.failure?
27
+
28
+ find_child_gemfile_paths(result.value)
29
29
  end
30
30
 
31
31
  private
@@ -35,24 +35,24 @@ module Dependabot
35
35
 
36
36
  sig { params(node: T.untyped).returns(T::Array[String]) }
37
37
  def find_child_gemfile_paths(node)
38
- return [] unless node.is_a?(Parser::AST::Node)
38
+ return [] if node.nil?
39
39
 
40
40
  if declares_eval_gemfile?(node)
41
- path_node = node.children[2]
42
- unless path_node.type == :str
41
+ path_node = node.arguments&.arguments&.first
42
+ unless path_node.is_a?(Prism::StringNode)
43
43
  path = gemfile&.path
44
44
  msg = "Dependabot only supports uninterpolated string arguments " \
45
45
  "to eval_gemfile. Got " \
46
- "`#{path_node.loc.expression.source}`"
46
+ "`#{path_node.slice}`"
47
47
  raise Dependabot::DependencyFileNotParseable.new(T.must(path), msg)
48
48
  end
49
49
 
50
- path = path_node.loc.expression.source.gsub(/['"]/, "")
50
+ path = path_node.unescaped
51
51
  path = File.join(current_dir, path) unless current_dir.nil?
52
52
  return [Pathname.new(path).cleanpath.to_path]
53
53
  end
54
54
 
55
- node.children.flat_map do |child_node|
55
+ node.child_nodes.flat_map do |child_node|
56
56
  find_child_gemfile_paths(child_node)
57
57
  end
58
58
  end
@@ -64,11 +64,11 @@ module Dependabot
64
64
  @current_dir
65
65
  end
66
66
 
67
- sig { params(node: Parser::AST::Node).returns(T::Boolean) }
67
+ sig { params(node: Prism::Node).returns(T::Boolean) }
68
68
  def declares_eval_gemfile?(node)
69
- return false unless node.is_a?(Parser::AST::Node)
69
+ return false unless node.is_a?(Prism::CallNode)
70
70
 
71
- node.children[1] == :eval_gemfile
71
+ node.name == :eval_gemfile
72
72
  end
73
73
  end
74
74
  end
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "pathname"
5
- require "parser/current"
5
+ require "prism"
6
6
  require "dependabot/bundler/file_fetcher"
7
7
  require "dependabot/errors"
8
8
  require "sorbet-runtime"
@@ -22,10 +22,10 @@ module Dependabot
22
22
 
23
23
  sig { returns(T::Array[String]) }
24
24
  def gemspec_directories
25
- ast = Parser::CurrentRuby.parse(T.must(gemfile).content)
26
- find_gemspec_paths(ast)
27
- rescue Parser::SyntaxError
28
- raise Dependabot::DependencyFileNotParseable, T.must(gemfile).path
25
+ result = Prism.parse(T.must(gemfile).content)
26
+ raise Dependabot::DependencyFileNotParseable, T.must(gemfile).path if result.failure?
27
+
28
+ find_gemspec_paths(result.value)
29
29
  end
30
30
 
31
31
  private
@@ -33,27 +33,27 @@ module Dependabot
33
33
  sig { returns(T.nilable(Dependabot::DependencyFile)) }
34
34
  attr_reader :gemfile
35
35
 
36
- sig { params(node: T.untyped).returns(T::Array[T.untyped]) }
36
+ sig { params(node: T.nilable(Prism::Node)).returns(T::Array[T.untyped]) }
37
37
  def find_gemspec_paths(node)
38
- return [] unless node.is_a?(Parser::AST::Node)
38
+ return [] if node.nil?
39
39
 
40
40
  if declares_gemspec_dependency?(node)
41
41
  path_node = path_node_for_gem_declaration(node)
42
42
  return [clean_path(".")] unless path_node
43
43
 
44
- unless path_node.type == :str
44
+ unless path_node.is_a?(Prism::StringNode)
45
45
  path = T.must(gemfile).path
46
46
  msg = "Dependabot only supports uninterpolated string arguments " \
47
47
  "to gemspec. Got " \
48
- "`#{path_node.loc.expression.source}`"
48
+ "`#{path_node.slice}`"
49
49
  raise Dependabot::DependencyFileNotParseable.new(path, msg)
50
50
  end
51
51
 
52
- path = path_node.loc.expression.source.gsub(/['"]/, "")
52
+ path = path_node.unescaped
53
53
  return [clean_path(path)]
54
54
  end
55
55
 
56
- node.children.flat_map do |child_node|
56
+ node.child_nodes.flat_map do |child_node|
57
57
  find_gemspec_paths(child_node)
58
58
  end
59
59
  end
@@ -65,11 +65,11 @@ module Dependabot
65
65
  @current_dir
66
66
  end
67
67
 
68
- sig { params(node: Parser::AST::Node).returns(T::Boolean) }
68
+ sig { params(node: Prism::Node).returns(T::Boolean) }
69
69
  def declares_gemspec_dependency?(node)
70
- return false unless node.is_a?(Parser::AST::Node)
70
+ return false unless node.is_a?(Prism::CallNode)
71
71
 
72
- node.children[1] == :gemspec
72
+ node.name == :gemspec
73
73
  end
74
74
 
75
75
  sig { params(path: String).returns(Pathname) }
@@ -82,25 +82,31 @@ module Dependabot
82
82
  Pathname.new(path).cleanpath
83
83
  end
84
84
 
85
- sig { params(node: Parser::AST::Node).returns(T.nilable(Parser::AST::Node)) }
85
+ sig { params(node: Prism::Node).returns(T.nilable(Prism::Node)) }
86
86
  def path_node_for_gem_declaration(node)
87
- return unless node.children.last.is_a?(Parser::AST::Node)
88
- return unless node.children.last.type == :hash
87
+ return unless node.is_a?(Prism::CallNode)
88
+
89
+ kwargs_node = node.arguments&.arguments&.last
89
90
 
90
- kwargs_node = node.children.last
91
+ return unless kwargs_node.is_a?(Prism::Node)
91
92
 
92
93
  path_hash_pair =
93
- kwargs_node.children
94
+ kwargs_node.child_nodes
94
95
  .find { |hash_pair| key_from_hash_pair(hash_pair) == :path }
95
96
 
96
97
  return unless path_hash_pair
97
98
 
98
- path_hash_pair.children.last
99
+ T.cast(path_hash_pair, Prism::AssocNode).value
99
100
  end
100
101
 
101
- sig { params(node: Parser::AST::Node).returns(Symbol) }
102
+ sig { params(node: T.nilable(Prism::Node)).returns(T.nilable(Symbol)) }
102
103
  def key_from_hash_pair(node)
103
- node.children.first.children.first.to_sym
104
+ return unless node.is_a?(Prism::AssocNode)
105
+
106
+ key_node = node.key
107
+ return unless key_node.is_a?(Prism::StringNode) || key_node.is_a?(Prism::SymbolNode)
108
+
109
+ key_node.unescaped.to_sym
104
110
  end
105
111
  end
106
112
  end
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "pathname"
5
- require "parser/current"
5
+ require "prism"
6
6
  require "dependabot/bundler/file_fetcher"
7
7
  require "dependabot/errors"
8
8
  require "sorbet-runtime"
@@ -22,10 +22,10 @@ module Dependabot
22
22
 
23
23
  sig { returns(T::Array[String]) }
24
24
  def find_included_paths
25
- ast = Parser::CurrentRuby.parse(file.content)
26
- find_require_relative_paths(ast) + find_eval_paths(ast)
27
- rescue Parser::SyntaxError
28
- raise Dependabot::DependencyFileNotParseable, file.path
25
+ result = Prism.parse(file.content)
26
+ raise Dependabot::DependencyFileNotParseable, file.path if result.failure?
27
+
28
+ find_require_relative_paths(result.value) + find_eval_paths(result.value)
29
29
  end
30
30
 
31
31
  private
@@ -35,59 +35,50 @@ module Dependabot
35
35
 
36
36
  sig { params(node: T.untyped).returns(T::Array[String]) }
37
37
  def find_require_relative_paths(node)
38
- return [] unless node.is_a?(Parser::AST::Node)
38
+ return [] if node.nil?
39
39
 
40
40
  if declares_require_relative?(node)
41
- return [] unless node.children[2].type == :str
41
+ relative_arg = node.arguments&.arguments&.first
42
+ return [] unless relative_arg.is_a?(Prism::StringNode)
42
43
 
43
- path = node.children[2].loc.expression.source.gsub(/['"]/, "")
44
+ path = relative_arg.unescaped
44
45
  path = File.join(current_dir, path) unless current_dir.nil?
45
46
  path += ".rb" unless path.end_with?(".rb")
46
47
  return [Pathname.new(path).cleanpath.to_path]
47
48
  end
48
49
 
49
- node.children.flat_map do |child_node|
50
+ node.child_nodes.flat_map do |child_node|
50
51
  find_require_relative_paths(child_node)
51
52
  end
52
53
  end
53
54
 
54
55
  sig { params(node: T.untyped).returns(T::Array[String]) }
55
56
  def find_eval_paths(node)
56
- return [] unless node.is_a?(Parser::AST::Node)
57
+ return [] if node.nil?
57
58
 
58
59
  if declares_eval?(node)
59
- eval_arg = node.children[2]
60
- if eval_arg.is_a?(Parser::AST::Node)
60
+ eval_arg = node.arguments&.arguments&.first
61
+
62
+ if eval_arg.is_a?(Prism::Node)
61
63
  file_read_node = find_file_read_node(eval_arg)
62
64
  path = extract_path_from_file_read(file_read_node) if file_read_node
63
65
  return [path] if path
64
66
  end
65
67
  end
66
68
 
67
- node.children.flat_map do |child_node|
69
+ node.child_nodes.flat_map do |child_node|
68
70
  find_eval_paths(child_node)
69
71
  end
70
72
  end
71
73
 
72
- sig { params(node: Parser::AST::Node).returns(T.nilable(Parser::AST::Node)) }
74
+ sig { params(node: T.nilable(Prism::Node)).returns(T.nilable(Prism::Node)) }
73
75
  def find_file_read_node(node)
74
- return nil unless node.is_a?(Parser::AST::Node)
75
-
76
- # Check if the node represents a method call (:send)
77
- # and if the method name is :read
78
- method_name = node.children[1]
79
- receiver_node = node.children[0]
76
+ return nil unless node.is_a?(Prism::Node)
80
77
 
81
- if node.type == :send && method_name == :read && receiver_node.is_a?(Parser::AST::Node)
82
- # Check if the receiver of the :read method call is :File
83
- receiver_const = receiver_node.children[1]
84
- return node if receiver_const == :File
85
- end
78
+ return node if contains_receiver_node?(node)
86
79
 
87
80
  # Recursively search for a file read node in the children
88
- node.children.each do |child|
89
- next unless child.is_a?(Parser::AST::Node)
90
-
81
+ node.child_nodes.each do |child|
91
82
  result = find_file_read_node(child)
92
83
  return result if result
93
84
  end
@@ -95,14 +86,29 @@ module Dependabot
95
86
  nil
96
87
  end
97
88
 
98
- sig { params(node: Parser::AST::Node).returns(T.nilable(String)) }
89
+ sig { params(node: Prism::Node).returns(T::Boolean) }
90
+ def contains_receiver_node?(node)
91
+ return false unless node.is_a?(Prism::CallNode) && node.name == :read
92
+
93
+ # Check if the node represents a method call (CallNode))
94
+ # and if the method name is :read
95
+ receiver_node = node.arguments&.arguments&.first
96
+
97
+ # Check if the receiver of the :read method call is :File
98
+ return false unless receiver_node.is_a?(Prism::CallNode)
99
+
100
+ constant_node = T.cast(receiver_node.receiver, T.nilable(Prism::ConstantReadNode))
101
+ constant_node&.name == :File
102
+ end
103
+
104
+ sig { params(node: Prism::Node).returns(T.nilable(String)) }
99
105
  def extract_path_from_file_read(node)
100
- return nil unless node.is_a?(Parser::AST::Node)
106
+ return nil unless node.is_a?(Prism::CallNode)
101
107
 
102
- expand_path_node = node.children[2]
103
- if expand_path_node.type == :send && expand_path_node.children[1] == :expand_path
104
- path_node = expand_path_node.children[2]
105
- return path_node.loc.expression.source.gsub(/['"]/, "") if path_node.type == :str
108
+ expand_path_node = node.arguments&.arguments&.first
109
+ if expand_path_node.is_a?(Prism::CallNode) && expand_path_node.name == :expand_path
110
+ path_node = expand_path_node.arguments&.arguments&.first
111
+ return path_node.unescaped if path_node.is_a?(Prism::StringNode)
106
112
  end
107
113
  nil
108
114
  end
@@ -114,18 +120,18 @@ module Dependabot
114
120
  @current_dir
115
121
  end
116
122
 
117
- sig { params(node: Parser::AST::Node).returns(T::Boolean) }
123
+ sig { params(node: Prism::Node).returns(T::Boolean) }
118
124
  def declares_require_relative?(node)
119
- return false unless node.is_a?(Parser::AST::Node)
125
+ return false unless node.is_a?(Prism::CallNode)
120
126
 
121
- node.children[1] == :require_relative
127
+ node.name == :require_relative
122
128
  end
123
129
 
124
- sig { params(node: Parser::AST::Node).returns(T::Boolean) }
130
+ sig { params(node: Prism::Node).returns(T::Boolean) }
125
131
  def declares_eval?(node)
126
- return false unless node.is_a?(Parser::AST::Node)
132
+ return false unless node.is_a?(Prism::CallNode)
127
133
 
128
- node.children[1] == :eval
134
+ node.name == :eval
129
135
  end
130
136
  end
131
137
  end
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "pathname"
5
- require "parser/current"
5
+ require "prism"
6
6
  require "dependabot/bundler/file_fetcher"
7
7
  require "dependabot/errors"
8
8
  require "sorbet-runtime"
@@ -22,10 +22,10 @@ module Dependabot
22
22
 
23
23
  sig { returns(T::Array[String]) }
24
24
  def path_gemspec_paths
25
- ast = Parser::CurrentRuby.parse(gemfile&.content)
26
- find_path_gemspec_paths(ast)
27
- rescue Parser::SyntaxError
28
- raise Dependabot::DependencyFileNotParseable, T.must(gemfile).path
25
+ result = Prism.parse(gemfile&.content)
26
+ raise Dependabot::DependencyFileNotParseable, T.must(gemfile).path if result.failure?
27
+
28
+ find_path_gemspec_paths(result.value)
29
29
  end
30
30
 
31
31
  private
@@ -35,24 +35,24 @@ module Dependabot
35
35
 
36
36
  sig { params(node: T.untyped).returns(T::Array[T.untyped]) }
37
37
  def find_path_gemspec_paths(node)
38
- return [] unless node.is_a?(Parser::AST::Node)
38
+ return [] unless node.is_a?(Prism::Node)
39
39
 
40
40
  if declares_path_dependency?(node)
41
41
  path_node = path_node_for_gem_declaration(node)
42
42
 
43
- unless path_node&.type == :str
43
+ unless path_node.is_a?(Prism::StringNode)
44
44
  path = gemfile&.path
45
45
  msg = "Dependabot only supports uninterpolated string arguments " \
46
46
  "for path dependencies. Got " \
47
- "`#{path_node&.loc&.expression&.source}`"
47
+ "`#{path_node&.slice}`"
48
48
  raise Dependabot::DependencyFileNotParseable.new(T.must(path), msg)
49
49
  end
50
50
 
51
- path = T.must(path_node).loc.expression.source.gsub(/['"]/, "")
51
+ path = path_node.unescaped
52
52
  return [clean_path(path)]
53
53
  end
54
54
 
55
- node.children.flat_map do |child_node|
55
+ node.child_nodes.flat_map do |child_node|
56
56
  find_path_gemspec_paths(child_node)
57
57
  end
58
58
  end
@@ -64,10 +64,10 @@ module Dependabot
64
64
  @current_dir
65
65
  end
66
66
 
67
- sig { params(node: Parser::AST::Node).returns(T::Boolean) }
67
+ sig { params(node: Prism::Node).returns(T::Boolean) }
68
68
  def declares_path_dependency?(node)
69
- return false unless node.is_a?(Parser::AST::Node)
70
- return false unless node.children[1] == :gem
69
+ return false unless node.is_a?(Prism::CallNode)
70
+ return false unless node.name == :gem
71
71
 
72
72
  !path_node_for_gem_declaration(node).nil?
73
73
  end
@@ -82,24 +82,31 @@ module Dependabot
82
82
  Pathname.new(path).cleanpath
83
83
  end
84
84
 
85
- sig { params(node: Parser::AST::Node).returns(T.nilable(Parser::AST::Node)) }
85
+ sig { params(node: Prism::Node).returns(T.nilable(Prism::Node)) }
86
86
  def path_node_for_gem_declaration(node)
87
- return unless node.children.last.type == :hash
87
+ return unless node.is_a?(Prism::CallNode)
88
+
89
+ kwargs_node = node.arguments&.arguments&.last
88
90
 
89
- kwargs_node = node.children.last
91
+ return unless kwargs_node.is_a?(Prism::Node)
90
92
 
91
93
  path_hash_pair =
92
- kwargs_node.children
94
+ kwargs_node.child_nodes
93
95
  .find { |hash_pair| key_from_hash_pair(hash_pair) == :path }
94
96
 
95
97
  return unless path_hash_pair
96
98
 
97
- path_hash_pair.children.last
99
+ T.cast(path_hash_pair, Prism::AssocNode).value
98
100
  end
99
101
 
100
- sig { params(node: Parser::AST::Node).returns(Symbol) }
102
+ sig { params(node: T.nilable(Prism::Node)).returns(T.nilable(Symbol)) }
101
103
  def key_from_hash_pair(node)
102
- node.children.first.children.first.to_sym
104
+ return unless node.is_a?(Prism::AssocNode)
105
+
106
+ key_node = node.key
107
+ return unless key_node.is_a?(Prism::StringNode) || key_node.is_a?(Prism::SymbolNode)
108
+
109
+ key_node.unescaped.to_sym
103
110
  end
104
111
  end
105
112
  end
@@ -1,7 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "parser/current"
4
+ require "prism"
5
5
  require "sorbet-runtime"
6
6
 
7
7
  require "dependabot/file_parsers/base"
@@ -16,7 +16,7 @@ module Dependabot
16
16
  sig { params(gemfile: Dependabot::DependencyFile).void }
17
17
  def initialize(gemfile:)
18
18
  @gemfile = gemfile
19
- @declaration_nodes = T.let({}, T::Hash[T::Hash[String, String], T.nilable(Parser::AST::Node)])
19
+ @declaration_nodes = T.let({}, T::Hash[T::Hash[String, String], T.nilable(Prism::Node)])
20
20
  end
21
21
 
22
22
  sig { params(dependency: T::Hash[String, String]).returns(T::Boolean) }
@@ -30,13 +30,16 @@ module Dependabot
30
30
  return unless gemfile_includes_dependency?(dependency)
31
31
 
32
32
  fallback_string = dependency.fetch("requirement")
33
- req_nodes = declaration_node(dependency)&.children&.[](3..-1)
34
- req_nodes = req_nodes.reject { |child| child.type == :hash }
33
+ call_node = declaration_node(dependency)
34
+ return fallback_string unless call_node.is_a?(Prism::CallNode)
35
+
36
+ req_nodes = call_node.arguments&.arguments&.[](1..-1) || []
37
+ req_nodes = req_nodes.reject { |child| child.is_a?(Prism::HashNode) || child.is_a?(Prism::KeywordHashNode) }
35
38
 
36
39
  return fallback_string if req_nodes.none?
37
- return fallback_string unless req_nodes.all? { |n| n.type == :str }
40
+ return fallback_string unless req_nodes.all?(Prism::StringNode)
38
41
 
39
- original_req_string = req_nodes.map { |n| n.children.last }
42
+ original_req_string = T.cast(req_nodes, T::Array[Prism::StringNode]).map(&:unescaped)
40
43
  fallback_requirement =
41
44
  Gem::Requirement.new(fallback_string.split(", "))
42
45
  if fallback_requirement == Gem::Requirement.new(original_req_string)
@@ -52,21 +55,21 @@ module Dependabot
52
55
  sig { returns(Dependabot::DependencyFile) }
53
56
  attr_reader :gemfile
54
57
 
55
- sig { returns(T.nilable(Parser::AST::Node)) }
58
+ sig { returns(T.nilable(Prism::Node)) }
56
59
  def parsed_gemfile
57
60
  @parsed_gemfile ||= T.let(
58
- Parser::CurrentRuby.parse(gemfile.content),
59
- T.nilable(Parser::AST::Node)
61
+ Prism.parse(gemfile.content).value,
62
+ T.nilable(Prism::Node)
60
63
  )
61
64
  end
62
65
 
63
- sig { params(dependency: T::Hash[String, String]).returns(T.nilable(Parser::AST::Node)) }
66
+ sig { params(dependency: T::Hash[String, String]).returns(T.nilable(Prism::Node)) }
64
67
  def declaration_node(dependency)
65
68
  return @declaration_nodes[dependency] if @declaration_nodes.key?(dependency)
66
69
  return unless parsed_gemfile
67
70
 
68
71
  @declaration_nodes[dependency] = nil
69
- T.must(parsed_gemfile).children.any? do |node|
72
+ T.must(parsed_gemfile).child_nodes.any? do |node|
70
73
  @declaration_nodes[dependency] = deep_search_for_gem(node, dependency)
71
74
  end
72
75
  @declaration_nodes[dependency]
@@ -77,14 +80,14 @@ module Dependabot
77
80
  node: T.untyped,
78
81
  dependency: T::Hash[String, String]
79
82
  )
80
- .returns(T.nilable(Parser::AST::Node))
83
+ .returns(T.nilable(Prism::Node))
81
84
  end
82
85
  def deep_search_for_gem(node, dependency)
83
- return T.cast(node, Parser::AST::Node) if declares_targeted_gem?(node, dependency)
84
- return unless node.is_a?(Parser::AST::Node)
86
+ return unless node.is_a?(Prism::Node)
87
+ return node if declares_targeted_gem?(node, dependency)
85
88
 
86
- declaration_node = T.let(nil, T.nilable(Parser::AST::Node))
87
- node.children.find do |child_node|
89
+ declaration_node = T.let(nil, T.nilable(Prism::Node))
90
+ node.child_nodes.find do |child_node|
88
91
  declaration_node = deep_search_for_gem(child_node, dependency)
89
92
  end
90
93
  declaration_node
@@ -98,10 +101,13 @@ module Dependabot
98
101
  .returns(T::Boolean)
99
102
  end
100
103
  def declares_targeted_gem?(node, dependency)
101
- return false unless node.is_a?(Parser::AST::Node)
102
- return false unless node.children[1] == :gem
104
+ return false unless node.is_a?(Prism::CallNode)
105
+ return false unless node.name == :gem
106
+
107
+ gem_name_node = node.arguments&.arguments&.first
108
+ return false unless gem_name_node.is_a?(Prism::StringNode)
103
109
 
104
- node.children[2].children.first == dependency.fetch("name")
110
+ gem_name_node.unescaped == dependency.fetch("name")
105
111
  end
106
112
  end
107
113
  end
@@ -1,7 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "parser/current"
4
+ require "prism"
5
5
  require "sorbet-runtime"
6
6
 
7
7
  require "dependabot/file_parsers/base"
@@ -16,7 +16,7 @@ module Dependabot
16
16
  sig { params(gemspec: Dependabot::DependencyFile).void }
17
17
  def initialize(gemspec:)
18
18
  @gemspec = gemspec
19
- @declaration_nodes = T.let({}, T::Hash[T::Hash[String, String], T.nilable(Parser::AST::Node)])
19
+ @declaration_nodes = T.let({}, T::Hash[T::Hash[String, String], T.nilable(Prism::Node)])
20
20
  end
21
21
 
22
22
  sig { params(dependency: T::Hash[String, String]).returns(T::Boolean) }
@@ -29,30 +29,30 @@ module Dependabot
29
29
  sig { returns(Dependabot::DependencyFile) }
30
30
  attr_reader :gemspec
31
31
 
32
- sig { returns(T.nilable(Parser::AST::Node)) }
32
+ sig { returns(T.nilable(Prism::Node)) }
33
33
  def parsed_gemspec
34
- @parsed_gemspec ||= T.let(Parser::CurrentRuby.parse(gemspec.content), T.nilable(Parser::AST::Node))
34
+ @parsed_gemspec ||= T.let(Prism.parse(gemspec.content).value, T.nilable(Prism::Node))
35
35
  end
36
36
 
37
- sig { params(dependency: T::Hash[String, String]).returns(T.nilable(Parser::AST::Node)) }
37
+ sig { params(dependency: T::Hash[String, String]).returns(T.nilable(Prism::Node)) }
38
38
  def declaration_node(dependency)
39
39
  return @declaration_nodes[dependency] if @declaration_nodes.key?(dependency)
40
40
  return unless parsed_gemspec
41
41
 
42
42
  @declaration_nodes[dependency] = nil
43
- T.must(parsed_gemspec).children.any? do |node|
43
+ T.must(parsed_gemspec).child_nodes.any? do |node|
44
44
  @declaration_nodes[dependency] = deep_search_for_gem(node, dependency)
45
45
  end
46
46
  @declaration_nodes[dependency]
47
47
  end
48
48
 
49
- sig { params(node: T.untyped, dependency: T::Hash[String, String]).returns(T.nilable(Parser::AST::Node)) }
49
+ sig { params(node: T.untyped, dependency: T::Hash[String, String]).returns(T.nilable(Prism::Node)) }
50
50
  def deep_search_for_gem(node, dependency)
51
- return T.cast(node, Parser::AST::Node) if declares_targeted_gem?(node, dependency)
52
- return unless node.is_a?(Parser::AST::Node)
51
+ return unless node.is_a?(Prism::Node)
52
+ return T.cast(node, Prism::CallNode) if declares_targeted_gem?(node, dependency)
53
53
 
54
- declaration_node = T.let(nil, T.nilable(Parser::AST::Node))
55
- node.children.find do |child_node|
54
+ declaration_node = T.let(nil, T.nilable(Prism::Node))
55
+ node.child_nodes.find do |child_node|
56
56
  declaration_node = deep_search_for_gem(child_node, dependency)
57
57
  end
58
58
  declaration_node
@@ -60,13 +60,16 @@ module Dependabot
60
60
 
61
61
  sig { params(node: T.untyped, dependency: T::Hash[String, String]).returns(T::Boolean) }
62
62
  def declares_targeted_gem?(node, dependency)
63
- return false unless node.is_a?(Parser::AST::Node)
63
+ return false unless node.is_a?(Prism::CallNode)
64
64
 
65
- second_child = node.children[1]
65
+ second_child = node.name
66
66
  allowed_declarations = %i(add_dependency add_runtime_dependency add_development_dependency)
67
67
  return false unless allowed_declarations.include?(second_child)
68
68
 
69
- node.children[2].children.first == dependency.fetch("name")
69
+ gem_name_node = node.arguments&.child_nodes&.first
70
+ return false unless gem_name_node.is_a?(Prism::StringNode)
71
+
72
+ gem_name_node.unescaped == dependency.fetch("name")
70
73
  end
71
74
  end
72
75
  end
@@ -1,7 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "parser/current"
4
+ require "prism"
5
5
  require "dependabot/bundler/file_updater"
6
6
 
7
7
  module Dependabot
@@ -10,8 +10,6 @@ module Dependabot
10
10
  class GemspecDependencyNameFinder
11
11
  extend T::Sig
12
12
 
13
- ChildNode = T.type_alias { T.nilable(T.any(Parser::AST::Node, Symbol, String, Integer, Float)) }
14
-
15
13
  sig { returns(String) }
16
14
  attr_reader :gemspec_content
17
15
 
@@ -23,12 +21,15 @@ module Dependabot
23
21
  # rubocop:disable Security/Eval
24
22
  sig { returns(T.nilable(String)) }
25
23
  def dependency_name
26
- ast = Parser::CurrentRuby.parse(gemspec_content)
27
- dependency_name_node = find_dependency_name_node(ast)
28
- return unless dependency_name_node
24
+ result = Prism.parse(gemspec_content)
25
+ dependency_name_node = find_dependency_name_node(result.value)
26
+ return unless dependency_name_node.is_a?(Prism::CallNode)
27
+
28
+ arg_node = dependency_name_node.arguments&.arguments&.first
29
+ return if arg_node.nil?
29
30
 
30
31
  begin
31
- eval(dependency_name_node.children[2].loc.expression.source)
32
+ eval(arg_node.slice)
32
33
  rescue StandardError
33
34
  nil # If we can't evaluate the expression just return nil
34
35
  end
@@ -37,22 +38,22 @@ module Dependabot
37
38
 
38
39
  private
39
40
 
40
- sig { params(node: ChildNode).returns(T.nilable(Parser::AST::Node)) }
41
+ sig { params(node: T.nilable(Prism::Node)).returns(T.nilable(Prism::Node)) }
41
42
  def find_dependency_name_node(node)
42
- return unless node.is_a?(Parser::AST::Node)
43
+ return unless node.is_a?(Prism::Node)
43
44
  return node if declares_dependency_name?(node)
44
45
 
45
- node.children.find do |cn|
46
+ node.child_nodes.find do |cn|
46
47
  dependency_name_node = find_dependency_name_node(cn)
47
48
  break dependency_name_node if dependency_name_node
48
49
  end
49
50
  end
50
51
 
51
- sig { params(node: ChildNode).returns(T::Boolean) }
52
+ sig { params(node: Prism::Node).returns(T::Boolean) }
52
53
  def declares_dependency_name?(node)
53
- return false unless node.is_a?(Parser::AST::Node)
54
+ return false unless node.is_a?(Prism::CallNode)
54
55
 
55
- node.children[1] == :name=
56
+ node.name == :name=
56
57
  end
57
58
  end
58
59
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-bundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.318.0
4
+ version: 0.319.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.318.0
18
+ version: 0.319.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.318.0
25
+ version: 0.319.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: parallel
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -322,7 +322,7 @@ licenses:
322
322
  - MIT
323
323
  metadata:
324
324
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
325
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.318.0
325
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.319.0
326
326
  rdoc_options: []
327
327
  require_paths:
328
328
  - lib