dependabot-common 0.238.0 → 0.240.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,13 @@
1
- # typed: true
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "sorbet-runtime"
4
5
  require "dependabot/metadata_finders"
5
6
 
6
7
  module Dependabot
7
8
  class PullRequestCreator
9
+ extend T::Sig
10
+
8
11
  require "dependabot/pull_request_creator/azure"
9
12
  require "dependabot/pull_request_creator/bitbucket"
10
13
  require "dependabot/pull_request_creator/codecommit"
@@ -42,7 +45,18 @@ module Dependabot
42
45
 
43
46
  # AnnotationError is raised if a PR was created, but failed annotation
44
47
  class AnnotationError < StandardError
45
- attr_reader :cause, :pull_request
48
+ extend T::Sig
49
+
50
+ sig { returns(StandardError) }
51
+ attr_reader :cause
52
+
53
+ # TODO: Currently, this error is only used by the GitHub PR creator.
54
+ # An Octokit update will likely give this a proper type,
55
+ # but we should consider a `Dependabot::PullRequest` type.
56
+ sig { returns(Sawyer::Resource) }
57
+ attr_reader :pull_request
58
+
59
+ sig { params(cause: StandardError, pull_request: Sawyer::Resource).void }
46
60
  def initialize(cause, pull_request)
47
61
  super(cause.message)
48
62
  @cause = cause
@@ -50,15 +64,113 @@ module Dependabot
50
64
  end
51
65
  end
52
66
 
53
- attr_reader :source, :dependencies, :files, :base_commit,
54
- :credentials, :pr_message_header, :pr_message_footer,
55
- :custom_labels, :author_details, :signature_key,
56
- :commit_message_options, :vulnerabilities_fixed,
57
- :reviewers, :assignees, :milestone, :branch_name_separator,
58
- :branch_name_prefix, :branch_name_max_length, :github_redirection_service,
59
- :custom_headers, :provider_metadata, :dependency_group, :pr_message_max_length,
60
- :pr_message_encoding
61
-
67
+ sig { returns(Dependabot::Source) }
68
+ attr_reader :source
69
+
70
+ sig { returns(T::Array[Dependabot::Dependency]) }
71
+ attr_reader :dependencies
72
+
73
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
74
+ attr_reader :files
75
+
76
+ sig { returns(String) }
77
+ attr_reader :base_commit
78
+
79
+ sig { returns(T::Array[T::Hash[String, String]]) }
80
+ attr_reader :credentials
81
+
82
+ sig { returns(T.nilable(String)) }
83
+ attr_reader :pr_message_header
84
+
85
+ sig { returns(T.nilable(String)) }
86
+ attr_reader :pr_message_footer
87
+
88
+ sig { returns(T.nilable(T::Array[String])) }
89
+ attr_reader :custom_labels
90
+
91
+ sig { returns(T.nilable(T::Hash[Symbol, String])) }
92
+ attr_reader :author_details
93
+
94
+ sig { returns(T.nilable(String)) }
95
+ attr_reader :signature_key
96
+
97
+ sig { returns(T::Hash[Symbol, T.untyped]) }
98
+ attr_reader :commit_message_options
99
+
100
+ sig { returns(T::Hash[String, String]) }
101
+ attr_reader :vulnerabilities_fixed
102
+
103
+ sig { returns(T.nilable(T::Array[String])) }
104
+ attr_reader :reviewers
105
+
106
+ sig { returns(T.nilable(T::Array[String])) }
107
+ attr_reader :assignees
108
+
109
+ sig { returns(T.nilable(String)) }
110
+ attr_reader :milestone
111
+
112
+ sig { returns(String) }
113
+ attr_reader :branch_name_separator
114
+
115
+ sig { returns(String) }
116
+ attr_reader :branch_name_prefix
117
+
118
+ sig { returns(T.nilable(Integer)) }
119
+ attr_reader :branch_name_max_length
120
+
121
+ sig { returns(String) }
122
+ attr_reader :github_redirection_service
123
+
124
+ sig { returns(T.nilable(T::Hash[String, String])) }
125
+ attr_reader :custom_headers
126
+
127
+ sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
128
+ attr_reader :provider_metadata
129
+
130
+ sig { returns(T.nilable(Dependabot::DependencyGroup)) }
131
+ attr_reader :dependency_group
132
+
133
+ sig { returns(T.nilable(Integer)) }
134
+ attr_reader :pr_message_max_length
135
+
136
+ sig { returns(T.nilable(Encoding)) }
137
+ attr_reader :pr_message_encoding
138
+
139
+ sig do
140
+ params(
141
+ source: Dependabot::Source,
142
+ base_commit: String,
143
+ dependencies: T::Array[Dependabot::Dependency],
144
+ files: T::Array[Dependabot::DependencyFile],
145
+ credentials: T::Array[T::Hash[String, String]],
146
+ pr_message_header: T.nilable(String),
147
+ pr_message_footer: T.nilable(String),
148
+ custom_labels: T.nilable(T::Array[String]),
149
+ author_details: T.nilable(T::Hash[Symbol, String]),
150
+ signature_key: T.nilable(String),
151
+ commit_message_options: T::Hash[Symbol, T.untyped],
152
+ vulnerabilities_fixed: T::Hash[String, String],
153
+ reviewers: T.nilable(T::Array[String]),
154
+ assignees: T.nilable(T::Array[String]),
155
+ milestone: T.nilable(String),
156
+ branch_name_separator: String,
157
+ branch_name_prefix: String,
158
+ branch_name_max_length: T.nilable(Integer),
159
+ label_language: T::Boolean,
160
+ automerge_candidate: T::Boolean,
161
+ github_redirection_service: String,
162
+ custom_headers: T.nilable(T::Hash[String, String]),
163
+ require_up_to_date_base: T::Boolean,
164
+ provider_metadata: T.nilable(T::Hash[Symbol, T.untyped]),
165
+ message: T.nilable(
166
+ T.any(Dependabot::PullRequestCreator::Message, Dependabot::PullRequestCreator::MessageBuilder)
167
+ ),
168
+ dependency_group: T.nilable(Dependabot::DependencyGroup),
169
+ pr_message_max_length: T.nilable(Integer),
170
+ pr_message_encoding: T.nilable(Encoding)
171
+ )
172
+ .void
173
+ end
62
174
  def initialize(source:, base_commit:, dependencies:, files:, credentials:,
63
175
  pr_message_header: nil, pr_message_footer: nil,
64
176
  custom_labels: nil, author_details: nil, signature_key: nil,
@@ -103,6 +215,7 @@ module Dependabot
103
215
  check_dependencies_have_previous_version
104
216
  end
105
217
 
218
+ sig { void }
106
219
  def check_dependencies_have_previous_version
107
220
  return if dependencies.all? { |d| requirements_changed?(d) }
108
221
  return if dependencies.all?(&:previous_version)
@@ -111,6 +224,10 @@ module Dependabot
111
224
  "requirement to have a pull request created for them!"
112
225
  end
113
226
 
227
+ # TODO: This returns client-specific objects.
228
+ # We should create a standard interface (`Dependabot::PullRequest`) and
229
+ # then convert to that
230
+ sig { returns(T.untyped) }
114
231
  def create
115
232
  case source.provider
116
233
  when "github" then github_creator.create
@@ -124,18 +241,22 @@ module Dependabot
124
241
 
125
242
  private
126
243
 
244
+ sig { returns(T::Boolean) }
127
245
  def label_language?
128
246
  @label_language
129
247
  end
130
248
 
249
+ sig { returns(T::Boolean) }
131
250
  def automerge_candidate?
132
251
  @automerge_candidate
133
252
  end
134
253
 
254
+ sig { returns(T::Boolean) }
135
255
  def require_up_to_date_base?
136
256
  @require_up_to_date_base
137
257
  end
138
258
 
259
+ sig { returns(Dependabot::PullRequestCreator::Github) }
139
260
  def github_creator
140
261
  Github.new(
141
262
  source: source,
@@ -157,6 +278,7 @@ module Dependabot
157
278
  )
158
279
  end
159
280
 
281
+ sig { returns(Dependabot::PullRequestCreator::Gitlab) }
160
282
  def gitlab_creator
161
283
  Gitlab.new(
162
284
  source: source,
@@ -172,10 +294,11 @@ module Dependabot
172
294
  approvers: reviewers,
173
295
  assignees: assignees,
174
296
  milestone: milestone,
175
- target_project_id: provider_metadata[:target_project_id]
297
+ target_project_id: provider_metadata&.fetch(:target_project_id)
176
298
  )
177
299
  end
178
300
 
301
+ sig { returns(Dependabot::PullRequestCreator::Azure) }
179
302
  def azure_creator
180
303
  Azure.new(
181
304
  source: source,
@@ -194,6 +317,7 @@ module Dependabot
194
317
  )
195
318
  end
196
319
 
320
+ sig { returns(Dependabot::PullRequestCreator::Bitbucket) }
197
321
  def bitbucket_creator
198
322
  Bitbucket.new(
199
323
  source: source,
@@ -210,6 +334,7 @@ module Dependabot
210
334
  )
211
335
  end
212
336
 
337
+ sig { returns(Dependabot::PullRequestCreator::Codecommit) }
213
338
  def codecommit_creator
214
339
  Codecommit.new(
215
340
  source: source,
@@ -226,6 +351,7 @@ module Dependabot
226
351
  )
227
352
  end
228
353
 
354
+ sig { returns(T.any(Dependabot::PullRequestCreator::Message, Dependabot::PullRequestCreator::MessageBuilder)) }
229
355
  def message
230
356
  return @message unless @message.nil?
231
357
 
@@ -257,8 +383,9 @@ module Dependabot
257
383
  )
258
384
  end
259
385
 
386
+ sig { returns(Dependabot::PullRequestCreator::BranchNamer) }
260
387
  def branch_namer
261
- @branch_namer ||=
388
+ @branch_namer ||= T.let(
262
389
  BranchNamer.new(
263
390
  dependencies: dependencies,
264
391
  files: files,
@@ -266,12 +393,16 @@ module Dependabot
266
393
  dependency_group: dependency_group,
267
394
  separator: branch_name_separator,
268
395
  prefix: branch_name_prefix,
269
- max_length: branch_name_max_length
270
- )
396
+ max_length: branch_name_max_length,
397
+ includes_security_fixes: includes_security_fixes?
398
+ ),
399
+ T.nilable(Dependabot::PullRequestCreator::BranchNamer)
400
+ )
271
401
  end
272
402
 
403
+ sig { returns(Dependabot::PullRequestCreator::Labeler) }
273
404
  def labeler
274
- @labeler ||=
405
+ @labeler ||= T.let(
275
406
  Labeler.new(
276
407
  source: source,
277
408
  custom_labels: custom_labels,
@@ -280,15 +411,19 @@ module Dependabot
280
411
  dependencies: dependencies,
281
412
  label_language: label_language?,
282
413
  automerge_candidate: automerge_candidate?
283
- )
414
+ ),
415
+ T.nilable(Dependabot::PullRequestCreator::Labeler)
416
+ )
284
417
  end
285
418
 
419
+ sig { returns(T::Boolean) }
286
420
  def includes_security_fixes?
287
421
  vulnerabilities_fixed.values.flatten.any?
288
422
  end
289
423
 
424
+ sig { params(dependency: Dependabot::Dependency).returns(T::Boolean) }
290
425
  def requirements_changed?(dependency)
291
- (dependency.requirements - dependency.previous_requirements).any?
426
+ (dependency.requirements - T.must(dependency.previous_requirements)).any?
292
427
  end
293
428
  end
294
429
  end
@@ -1,17 +1,58 @@
1
- # typed: true
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "sorbet-runtime"
4
5
  require "dependabot/pull_request_updater/github"
5
6
  require "dependabot/pull_request_updater/gitlab"
6
7
  require "dependabot/pull_request_updater/azure"
7
8
 
8
9
  module Dependabot
9
10
  class PullRequestUpdater
11
+ extend T::Sig
12
+
10
13
  class BranchProtected < StandardError; end
11
14
 
12
- attr_reader :source, :files, :base_commit, :old_commit, :credentials,
13
- :pull_request_number, :author_details, :signature_key, :provider_metadata
15
+ sig { returns(Dependabot::Source) }
16
+ attr_reader :source
17
+
18
+ sig { returns(T::Array[Dependabot::DependencyFile]) }
19
+ attr_reader :files
20
+
21
+ sig { returns(String) }
22
+ attr_reader :base_commit
23
+
24
+ sig { returns(String) }
25
+ attr_reader :old_commit
26
+
27
+ sig { returns(T::Array[T::Hash[String, String]]) }
28
+ attr_reader :credentials
29
+
30
+ sig { returns(Integer) }
31
+ attr_reader :pull_request_number
14
32
 
33
+ sig { returns(T.nilable(T::Hash[Symbol, String])) }
34
+ attr_reader :author_details
35
+
36
+ sig { returns(T.nilable(String)) }
37
+ attr_reader :signature_key
38
+
39
+ sig { returns(T::Hash[Symbol, T.untyped]) }
40
+ attr_reader :provider_metadata
41
+
42
+ sig do
43
+ params(
44
+ source: Dependabot::Source,
45
+ base_commit: String,
46
+ old_commit: String,
47
+ files: T::Array[Dependabot::DependencyFile],
48
+ credentials: T::Array[T::Hash[String, String]],
49
+ pull_request_number: Integer,
50
+ author_details: T.nilable(T::Hash[Symbol, String]),
51
+ signature_key: T.nilable(String),
52
+ provider_metadata: T::Hash[Symbol, T.untyped]
53
+ )
54
+ .void
55
+ end
15
56
  def initialize(source:, base_commit:, old_commit:, files:,
16
57
  credentials:, pull_request_number:,
17
58
  author_details: nil, signature_key: nil,
@@ -27,6 +68,9 @@ module Dependabot
27
68
  @provider_metadata = provider_metadata
28
69
  end
29
70
 
71
+ # TODO: Each implementation returns a client-specific type.
72
+ # We should standardise this to return a `Dependabot::Branch` type instead.
73
+ sig { returns(T.untyped) }
30
74
  def update
31
75
  case source.provider
32
76
  when "github" then github_updater.update
@@ -38,6 +82,7 @@ module Dependabot
38
82
 
39
83
  private
40
84
 
85
+ sig { returns(Dependabot::PullRequestUpdater::Github) }
41
86
  def github_updater
42
87
  Github.new(
43
88
  source: source,
@@ -51,6 +96,7 @@ module Dependabot
51
96
  )
52
97
  end
53
98
 
99
+ sig { returns(Dependabot::PullRequestUpdater::Gitlab) }
54
100
  def gitlab_updater
55
101
  Gitlab.new(
56
102
  source: source,
@@ -63,6 +109,7 @@ module Dependabot
63
109
  )
64
110
  end
65
111
 
112
+ sig { returns(Dependabot::PullRequestUpdater::Azure) }
66
113
  def azure_updater
67
114
  Azure.new(
68
115
  source: source,
@@ -1,6 +1,7 @@
1
- # typed: true
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "sorbet-runtime"
4
5
  require "dependabot/shared_helpers"
5
6
 
6
7
  # This class provides a thin wrapper around our normal usage of Excon as a simple HTTP client in order to
@@ -11,10 +12,20 @@ require "dependabot/shared_helpers"
11
12
  # read-timeouts as some jobs tend to be sensitive to exceeding our overall 45 minute timeout.
12
13
  module Dependabot
13
14
  class RegistryClient
14
- @cached_errors = {}
15
+ extend T::Sig
15
16
 
17
+ @cached_errors = T.let({}, T::Hash[T.nilable(String), Excon::Error::Timeout])
18
+
19
+ sig do
20
+ params(
21
+ url: String,
22
+ headers: T::Hash[Symbol, T.untyped],
23
+ options: T::Hash[Symbol, T.untyped]
24
+ )
25
+ .returns(Excon::Response)
26
+ end
16
27
  def self.get(url:, headers: {}, options: {})
17
- raise cached_error_for(url) if cached_error_for(url)
28
+ raise T.must(cached_error_for(url)) if cached_error_for(url)
18
29
 
19
30
  Excon.get(
20
31
  url,
@@ -26,8 +37,16 @@ module Dependabot
26
37
  raise e
27
38
  end
28
39
 
40
+ sig do
41
+ params(
42
+ url: String,
43
+ headers: T::Hash[Symbol, T.untyped],
44
+ options: T::Hash[Symbol, T.untyped]
45
+ )
46
+ .returns(Excon::Response)
47
+ end
29
48
  def self.head(url:, headers: {}, options: {})
30
- raise cached_error_for(url) if cached_error_for(url)
49
+ raise T.must(cached_error_for(url)) if cached_error_for(url)
31
50
 
32
51
  Excon.head(
33
52
  url,
@@ -39,15 +58,18 @@ module Dependabot
39
58
  raise e
40
59
  end
41
60
 
61
+ sig { void }
42
62
  def self.clear_cache!
43
63
  @cached_errors = {}
44
64
  end
45
65
 
66
+ sig { params(url: String, error: Excon::Error::Timeout).void }
46
67
  private_class_method def self.cache_error(url, error)
47
68
  host = URI(url).host
48
69
  @cached_errors[host] = error
49
70
  end
50
71
 
72
+ sig { params(url: String).returns(T.nilable(Excon::Error::Timeout)) }
51
73
  private_class_method def self.cached_error_for(url)
52
74
  host = URI(url).host
53
75
  @cached_errors.fetch(host, nil)
@@ -0,0 +1,20 @@
1
+ # typed: strong
2
+ # frozen_string_literal: true
3
+
4
+ require "sorbet-runtime"
5
+
6
+ module Dependabot
7
+ class Requirement < Gem::Requirement
8
+ extend T::Sig
9
+ extend T::Helpers
10
+
11
+ abstract!
12
+
13
+ sig do
14
+ abstract
15
+ .params(requirement_string: T.nilable(String))
16
+ .returns(T::Array[Requirement])
17
+ end
18
+ def self.requirements_array(requirement_string); end
19
+ end
20
+ end
@@ -4,6 +4,8 @@
4
4
  require "tmpdir"
5
5
  require "set"
6
6
  require "sorbet-runtime"
7
+
8
+ require "dependabot/requirement"
7
9
  require "dependabot/version"
8
10
  require "dependabot/config/file"
9
11
 
@@ -33,9 +35,9 @@ module Dependabot
33
35
  @version_classes[package_manager] = version_class
34
36
  end
35
37
 
36
- @requirement_classes = T.let({}, T::Hash[String, T.class_of(Gem::Requirement)])
38
+ @requirement_classes = T.let({}, T::Hash[String, T.class_of(Dependabot::Requirement)])
37
39
 
38
- sig { params(package_manager: String).returns(T.class_of(Gem::Requirement)) }
40
+ sig { params(package_manager: String).returns(T.class_of(Dependabot::Requirement)) }
39
41
  def self.requirement_class_for_package_manager(package_manager)
40
42
  requirement_class = @requirement_classes[package_manager]
41
43
  return requirement_class if requirement_class
@@ -43,7 +45,7 @@ module Dependabot
43
45
  raise "Unregistered package_manager #{package_manager}"
44
46
  end
45
47
 
46
- sig { params(package_manager: String, requirement_class: T.class_of(Gem::Requirement)).void }
48
+ sig { params(package_manager: String, requirement_class: T.class_of(Dependabot::Requirement)).void }
47
49
  def self.register_requirement_class(package_manager, requirement_class)
48
50
  validate_package_manager!(package_manager)
49
51
 
@@ -1,21 +1,75 @@
1
- # typed: true
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "sorbet-runtime"
5
+
4
6
  module Dependabot
5
7
  class Version < Gem::Version
8
+ extend T::Sig
9
+ extend T::Helpers
10
+
11
+ abstract!
12
+
13
+ sig do
14
+ override
15
+ .overridable
16
+ .params(
17
+ version: T.any(
18
+ String,
19
+ Integer,
20
+ Float,
21
+ Gem::Version,
22
+ NilClass
23
+ )
24
+ )
25
+ .void
26
+ end
6
27
  def initialize(version)
7
- @original_version = version
28
+ @original_version = T.let(version.to_s, String)
8
29
 
9
- super
30
+ T.unsafe(super(version))
31
+ end
32
+
33
+ sig do
34
+ override
35
+ .overridable
36
+ .params(
37
+ version: T.any(
38
+ String,
39
+ Integer,
40
+ Float,
41
+ Gem::Version,
42
+ NilClass
43
+ )
44
+ )
45
+ .returns(Dependabot::Version)
46
+ end
47
+ def self.new(version)
48
+ T.cast(super, Dependabot::Version)
10
49
  end
11
50
 
12
51
  # Opt-in to Rubygems 4 behavior
52
+ sig do
53
+ override
54
+ .overridable
55
+ .params(
56
+ version: T.any(
57
+ String,
58
+ Integer,
59
+ Float,
60
+ Gem::Version,
61
+ NilClass
62
+ )
63
+ )
64
+ .returns(T::Boolean)
65
+ end
13
66
  def self.correct?(version)
14
67
  return false if version.nil?
15
68
 
16
69
  version.to_s.match?(ANCHORED_VERSION_PATTERN)
17
70
  end
18
71
 
72
+ sig { overridable.returns(String) }
19
73
  def to_semver
20
74
  @original_version
21
75
  end
@@ -31,7 +31,10 @@ module Dependabot
31
31
 
32
32
  sig { override.returns(String) }
33
33
  def to_patch
34
- run_shell_command("git diff --patch #{@initial_head_sha}.. .")
34
+ run_shell_command(
35
+ "git diff --patch #{@initial_head_sha}.. .",
36
+ fingerprint: "git diff --path <initial_head_sha>.. ."
37
+ )
35
38
  end
36
39
 
37
40
  sig { override.returns(NilClass) }
@@ -103,17 +106,27 @@ module Dependabot
103
106
 
104
107
  sig { params(ignored_mode: String).returns(String) }
105
108
  def changed_files(ignored_mode: "traditional")
106
- run_shell_command("git status --untracked-files=all --ignored=#{ignored_mode} --short .").strip
109
+ run_shell_command(
110
+ "git status --untracked-files=all --ignored=#{ignored_mode} --short .",
111
+ fingerprint: "git status --untracked-files=all --ignored=<ignored_mode> --short ."
112
+ ).strip
107
113
  end
108
114
 
109
115
  sig { params(memo: T.nilable(String)).returns([String, String]) }
110
116
  def stash(memo = nil)
111
117
  msg = memo || "workspace change attempt"
112
118
  run_shell_command("git add --all --force .")
113
- run_shell_command(%(git stash push --all -m "#{msg}"), allow_unsafe_shell_command: true)
119
+ run_shell_command(
120
+ %(git stash push --all -m "#{msg}"),
121
+ fingerprint: "git stash push --all -m \"<msg>\"",
122
+ allow_unsafe_shell_command: true
123
+ )
114
124
 
115
125
  sha = last_stash_sha
116
- diff = run_shell_command("git stash show --patch #{sha}")
126
+ diff = run_shell_command(
127
+ "git stash show --patch #{sha}",
128
+ fingerprint: "git stash show --patch <sha>"
129
+ )
117
130
 
118
131
  [sha, diff]
119
132
  end
@@ -124,14 +137,21 @@ module Dependabot
124
137
  diff = run_shell_command("git diff --cached .")
125
138
 
126
139
  msg = memo || "workspace change"
127
- run_shell_command(%(git commit -m "#{msg}"), allow_unsafe_shell_command: true)
140
+ run_shell_command(
141
+ %(git commit -m "#{msg}"),
142
+ fingerprint: "git commit -m \"<msg>\"",
143
+ allow_unsafe_shell_command: true
144
+ )
128
145
 
129
146
  [head_sha, diff]
130
147
  end
131
148
 
132
149
  sig { params(sha: String).returns(String) }
133
150
  def reset(sha)
134
- run_shell_command("git reset --hard #{sha}")
151
+ run_shell_command(
152
+ "git reset --hard #{sha}",
153
+ fingerprint: "git reset --hard <sha>"
154
+ )
135
155
  end
136
156
 
137
157
  sig { override.returns(String) }
@@ -139,7 +159,7 @@ module Dependabot
139
159
  run_shell_command("git clean -fx .")
140
160
  end
141
161
 
142
- sig { params(args: String, kwargs: T::Boolean).returns(String) }
162
+ sig { params(args: String, kwargs: T.any(T::Boolean, String)).returns(String) }
143
163
  def run_shell_command(*args, **kwargs)
144
164
  Dir.chdir(path) { T.unsafe(SharedHelpers).run_shell_command(*args, **kwargs) }
145
165
  end
data/lib/dependabot.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Dependabot
5
- VERSION = "0.238.0"
5
+ VERSION = "0.240.0"
6
6
  end