dependabot-common 0.313.0 → 0.315.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: a7a5bf7bdeabf2957b9ecbe1efa5f27f9552b31db52d76970484c665e249e756
4
- data.tar.gz: 32722bfd412044839d449b19b77469a3c4253802b63adc5c35aef80a9eb9b00e
3
+ metadata.gz: 68238b0440934d660fcb680bd94b21397bf3396c0e4467fbd88fd21a23453a6f
4
+ data.tar.gz: d263bcc8392bbad1168f031af2bdbf243190ab91ab1f019a7206c1af76f95652
5
5
  SHA512:
6
- metadata.gz: 1752b119bf852196e0b870ec8d6a30473c898e0002c5467108e99447fdf88374dbeef037da2fa839fd685f9efa3bc229c7f4732b32cfd18fcdd151899c273066
7
- data.tar.gz: 3e2da158a84b3717ba3f05c6e3cd673e26941889fc8716920bc877cc09db8d68454a02a915d10821229e44c82c545ed9fbf4d7e1550763d428d8f4468bbec95a
6
+ metadata.gz: 3165f873c2ff8492dc8f7ee6cfe0a136d664cf35653f9856ebc80f6c5c0fce35e287950be698263f62152affc82859d8808edb0bd2355d12f481193e9c463cb2
7
+ data.tar.gz: 5692d5ad262572fc9cc91095010ed4b2381335d98d1064ee078c845cb9b17a060be52dd48d0ff72dc82526fd9bd1ed8c5dcd1551822be4c1e5c7f763df46c69e
@@ -297,7 +297,7 @@ module Dependabot
297
297
  sig { params(url: String).returns(Excon::Response) }
298
298
  def get(url)
299
299
  response = Excon.get(
300
- URI::DEFAULT_PARSER.escape(url),
300
+ URI::RFC2396_PARSER.escape(url),
301
301
  user: credentials&.fetch("username", nil),
302
302
  password: credentials&.fetch("password", nil),
303
303
  # Setting to false to prevent Excon retries, use BitbucketWithRetries for retries.
@@ -1,8 +1,10 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "stringio"
4
+ require "ostruct"
5
5
  require "sorbet-runtime"
6
+ require "stringio"
7
+
6
8
  require "dependabot/config"
7
9
  require "dependabot/dependency_file"
8
10
  require "dependabot/source"
@@ -2,8 +2,8 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "excon"
5
- require "gitlab"
6
5
  require "sorbet-runtime"
6
+ require "gitlab"
7
7
  require "dependabot/clients/github_with_retries"
8
8
  require "dependabot/clients/gitlab_with_retries"
9
9
  require "dependabot/clients/bitbucket_with_retries"
@@ -220,6 +220,11 @@ module Dependabot
220
220
  @dependency_source_details || dependency.source_details(allowed_types: ["git"])
221
221
  end
222
222
 
223
+ sig { returns(T::Array[Dependabot::GitTagWithDetail]) }
224
+ def refs_for_tag_with_detail
225
+ local_repo_git_metadata_fetcher.refs_for_tag_with_detail
226
+ end
227
+
223
228
  sig { params(commit_sha: T.nilable(String)).returns(T.nilable(String)) }
224
229
  def most_specific_version_tag_for_sha(commit_sha)
225
230
  tags = local_tags.select { |t| t.commit_sha == commit_sha && version_class.correct?(t.name) }
@@ -229,6 +234,13 @@ module Dependabot
229
234
  tags[-1]&.name
230
235
  end
231
236
 
237
+ sig { params(tags: T::Array[Dependabot::GitRef]).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
238
+ def max_local_tag(tags)
239
+ max_version_tag = tags.max_by { |t| version_from_tag(t) }
240
+
241
+ to_local_tag(max_version_tag)
242
+ end
243
+
232
244
  private
233
245
 
234
246
  sig { returns(Dependabot::Dependency) }
@@ -250,13 +262,6 @@ module Dependabot
250
262
  max_local_tag(select_lower_precision(tags))
251
263
  end
252
264
 
253
- sig { params(tags: T::Array[Dependabot::GitRef]).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
254
- def max_local_tag(tags)
255
- max_version_tag = tags.max_by { |t| version_from_tag(t) }
256
-
257
- to_local_tag(max_version_tag)
258
- end
259
-
260
265
  # Find the latest version with the same precision as the pinned version.
261
266
  sig { params(tags: T::Array[Dependabot::GitRef]).returns(T::Array[Dependabot::GitRef]) }
262
267
  def select_matching_existing_precision(tags)
@@ -3,10 +3,12 @@
3
3
 
4
4
  require "excon"
5
5
  require "open3"
6
+ require "ostruct"
6
7
  require "sorbet-runtime"
7
8
 
8
9
  require "dependabot/errors"
9
10
  require "dependabot/git_ref"
11
+ require "dependabot/git_tag_with_detail"
10
12
  require "dependabot/credential"
11
13
 
12
14
  module Dependabot
@@ -93,6 +95,29 @@ module Dependabot
93
95
  &.commit_sha
94
96
  end
95
97
 
98
+ sig { returns(T::Array[GitTagWithDetail]) }
99
+ def refs_for_tag_with_detail
100
+ @refs_for_tag_with_detail ||= T.let(parse_refs_for_tag_with_detail,
101
+ T.nilable(T::Array[GitTagWithDetail]))
102
+ end
103
+
104
+ sig { returns(T::Array[GitTagWithDetail]) }
105
+ def parse_refs_for_tag_with_detail
106
+ result_lines = []
107
+ return result_lines if upload_tag_with_detail.nil?
108
+
109
+ T.must(upload_tag_with_detail).lines.each do |line|
110
+ tag, detail = line.split(/\s+/, 2)
111
+ next unless tag && detail
112
+
113
+ result_lines << GitTagWithDetail.new(
114
+ tag: tag.strip,
115
+ release_date: detail.strip
116
+ )
117
+ end
118
+ result_lines
119
+ end
120
+
96
121
  private
97
122
 
98
123
  sig { returns(String) }
@@ -260,5 +285,62 @@ module Dependabot
260
285
  # Some git hosts are slow when returning a large number of tags
261
286
  SharedHelpers.excon_defaults(read_timeout: 20)
262
287
  end
288
+
289
+ sig { returns(T.nilable(String)) }
290
+ def upload_tag_with_detail
291
+ @upload_tag_detail ||= T.let(fetch_tags_with_detail(url), T.nilable(String))
292
+ rescue Octokit::ClientError
293
+ raise Dependabot::GitDependenciesNotReachable, [url]
294
+ end
295
+
296
+ sig { params(uri: String).returns(String) }
297
+ def fetch_tags_with_detail(uri)
298
+ response = fetch_raw_upload_pack_for(uri)
299
+ return response.body if response.status == 200
300
+
301
+ response_with_git = fetch_tags_with_detail_from_git_for(uri)
302
+ return response_with_git.body if response_with_git.status == 200
303
+
304
+ raise Dependabot::GitDependenciesNotReachable, [uri] unless uri.match?(KNOWN_HOSTS)
305
+
306
+ raise "Unexpected response: #{response.status} - #{response.body}" if response.status < 400
307
+
308
+ if uri.match?(/github\.com/i)
309
+ response = response.data
310
+ response[:response_headers] = response[:headers]
311
+ raise Octokit::Error.from_response(response)
312
+ end
313
+
314
+ raise "Server error at #{uri}: #{response.body}" if response.status >= 500
315
+
316
+ raise Dependabot::GitDependenciesNotReachable, [uri]
317
+ rescue Excon::Error::Socket, Excon::Error::Timeout
318
+ raise if uri.match?(KNOWN_HOSTS)
319
+
320
+ raise Dependabot::GitDependenciesNotReachable, [uri]
321
+ end
322
+
323
+ sig { params(uri: String).returns(T.untyped) }
324
+ def fetch_tags_with_detail_from_git_for(uri)
325
+ complete_uri = uri
326
+ complete_uri += ".git" unless complete_uri.end_with?(".git") || skip_git_suffix(uri)
327
+
328
+ env = { "PATH" => ENV.fetch("PATH", nil), "GIT_TERMINAL_PROMPT" => "0" }
329
+ command = "git for-each-ref --format=\"%(refname:short) %(creatordate:short)\" refs/tags #{complete_uri}"
330
+ command = SharedHelpers.escape_command(command)
331
+
332
+ begin
333
+ stdout, stderr, process = Open3.capture3(env, command)
334
+ # package the command response like a HTTP response so error handling remains unchanged
335
+ rescue Errno::ENOENT => e # thrown when `git` isn't installed...
336
+ OpenStruct.new(body: e.message, status: 500)
337
+ else
338
+ if process.success?
339
+ OpenStruct.new(body: stdout, status: 200)
340
+ else
341
+ OpenStruct.new(body: stderr, status: 500)
342
+ end
343
+ end
344
+ end
263
345
  end
264
346
  end
@@ -0,0 +1,45 @@
1
+ # typed: strong
2
+ # frozen_string_literal: true
3
+
4
+ require "sorbet-runtime"
5
+
6
+ module Dependabot
7
+ class GitTagWithDetail
8
+ extend T::Sig
9
+
10
+ sig { returns(String) }
11
+ attr_accessor :tag
12
+
13
+ sig { returns(String) }
14
+ attr_accessor :release_date
15
+
16
+ sig do
17
+ params(
18
+ tag: String,
19
+ release_date: String
20
+ ).void
21
+ end
22
+ def initialize(tag:, release_date:)
23
+ @tag = tag
24
+ @release_date = release_date
25
+ end
26
+
27
+ sig { params(other: BasicObject).returns(T::Boolean) }
28
+ def ==(other)
29
+ case other
30
+ when GitTagWithDetail
31
+ to_h == other.to_h
32
+ else
33
+ false
34
+ end
35
+ end
36
+
37
+ sig { returns(T::Hash[Symbol, T.nilable(String)]) }
38
+ def to_h
39
+ {
40
+ tag: tag,
41
+ release_date: release_date
42
+ }.compact
43
+ end
44
+ end
45
+ end
@@ -2,6 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "excon"
5
+ require "ostruct"
5
6
  require "sorbet-runtime"
6
7
 
7
8
  require "dependabot/clients/github_with_retries"
@@ -1,6 +1,7 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "ostruct"
4
5
  require "sorbet-runtime"
5
6
 
6
7
  require "dependabot/credential"
@@ -0,0 +1,80 @@
1
+ # typed: strong
2
+ # frozen_string_literal: true
3
+
4
+ require "sorbet-runtime"
5
+ require "dependabot/pull_request_creator/branch_namer/base"
6
+
7
+ module Dependabot
8
+ class PullRequestCreator
9
+ class BranchNamer
10
+ class MultiEcosystemStrategy < Base
11
+ extend T::Sig
12
+
13
+ sig do
14
+ params(
15
+ dependencies: T::Array[Dependabot::Dependency],
16
+ files: T::Array[Dependabot::DependencyFile],
17
+ target_branch: T.nilable(String),
18
+ includes_security_fixes: T::Boolean,
19
+ multi_ecosystem_name: String,
20
+ separator: String,
21
+ prefix: String,
22
+ max_length: T.nilable(Integer)
23
+ )
24
+ .void
25
+ end
26
+ def initialize(dependencies:, files:, target_branch:, includes_security_fixes:, multi_ecosystem_name:,
27
+ separator: "/", prefix: "dependabot", max_length: nil)
28
+ super(
29
+ dependencies: dependencies,
30
+ files: files,
31
+ target_branch: target_branch,
32
+ separator: separator,
33
+ prefix: prefix,
34
+ max_length: max_length,
35
+ )
36
+
37
+ @multi_ecosystem_name = multi_ecosystem_name
38
+ @includes_security_fixes = includes_security_fixes
39
+ end
40
+
41
+ sig { override.returns(String) }
42
+ def new_branch_name
43
+ sanitize_branch_name(File.join(prefixes, group_name_with_dependency_digest))
44
+ end
45
+
46
+ private
47
+
48
+ sig { returns(String) }
49
+ attr_reader :multi_ecosystem_name
50
+
51
+ sig { returns(T::Array[String]) }
52
+ def prefixes
53
+ [
54
+ prefix,
55
+ target_branch
56
+ ].compact
57
+ end
58
+
59
+ sig { returns(String) }
60
+ def group_name_with_dependency_digest
61
+ if @includes_security_fixes
62
+ "group-security-#{multi_ecosystem_name}-#{dependency_digest}"
63
+ else
64
+ "#{multi_ecosystem_name}-#{dependency_digest}"
65
+ end
66
+ end
67
+
68
+ sig { returns(T.nilable(String)) }
69
+ def dependency_digest
70
+ @dependency_digest ||= T.let(
71
+ Digest::MD5.hexdigest(dependencies.map do |dependency|
72
+ "#{dependency.name}-#{dependency.removed? ? 'removed' : dependency.version}"
73
+ end.sort.join(",")).slice(0, 10),
74
+ T.nilable(String)
75
+ )
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -8,6 +8,7 @@ require "dependabot/metadata_finders"
8
8
  require "dependabot/pull_request_creator"
9
9
  require "dependabot/pull_request_creator/branch_namer/solo_strategy"
10
10
  require "dependabot/pull_request_creator/branch_namer/dependency_group_strategy"
11
+ require "dependabot/pull_request_creator/branch_namer/multi_ecosystem_strategy"
11
12
 
12
13
  module Dependabot
13
14
  class PullRequestCreator
@@ -38,6 +39,9 @@ module Dependabot
38
39
  sig { returns(T::Boolean) }
39
40
  attr_reader :includes_security_fixes
40
41
 
42
+ sig { returns(T.nilable(String)) }
43
+ attr_reader :multi_ecosystem_name
44
+
41
45
  sig do
42
46
  params(
43
47
  dependencies: T::Array[Dependabot::Dependency],
@@ -47,12 +51,13 @@ module Dependabot
47
51
  separator: String,
48
52
  prefix: String,
49
53
  max_length: T.nilable(Integer),
50
- includes_security_fixes: T::Boolean
54
+ includes_security_fixes: T::Boolean,
55
+ multi_ecosystem_name: T.nilable(String)
51
56
  )
52
57
  .void
53
58
  end
54
59
  def initialize(dependencies:, files:, target_branch:, dependency_group: nil, separator: "/",
55
- prefix: "dependabot", max_length: nil, includes_security_fixes: false)
60
+ prefix: "dependabot", max_length: nil, includes_security_fixes: false, multi_ecosystem_name: nil)
56
61
  @dependencies = dependencies
57
62
  @files = files
58
63
  @target_branch = target_branch
@@ -61,6 +66,7 @@ module Dependabot
61
66
  @prefix = prefix
62
67
  @max_length = max_length
63
68
  @includes_security_fixes = includes_security_fixes
69
+ @multi_ecosystem_name = multi_ecosystem_name
64
70
  end
65
71
 
66
72
  sig { returns(String) }
@@ -73,30 +79,56 @@ module Dependabot
73
79
  sig { returns(Dependabot::PullRequestCreator::BranchNamer::Base) }
74
80
  def strategy
75
81
  @strategy ||= T.let(
76
- if dependency_group.nil?
77
- SoloStrategy.new(
78
- dependencies: dependencies,
79
- files: files,
80
- target_branch: target_branch,
81
- separator: separator,
82
- prefix: prefix,
83
- max_length: max_length
84
- )
82
+ if multi_ecosystem_name
83
+ build_multi_ecosystem_strategy
84
+ elsif dependency_group.nil?
85
+ build_solo_strategy
85
86
  else
86
- DependencyGroupStrategy.new(
87
- dependencies: dependencies,
88
- files: files,
89
- target_branch: target_branch,
90
- dependency_group: T.must(dependency_group),
91
- includes_security_fixes: includes_security_fixes,
92
- separator: separator,
93
- prefix: prefix,
94
- max_length: max_length
95
- )
87
+ build_dependency_group_strategy
96
88
  end,
97
89
  T.nilable(Dependabot::PullRequestCreator::BranchNamer::Base)
98
90
  )
99
91
  end
92
+
93
+ sig { returns(Dependabot::PullRequestCreator::BranchNamer::MultiEcosystemStrategy) }
94
+ def build_multi_ecosystem_strategy
95
+ MultiEcosystemStrategy.new(
96
+ dependencies: dependencies,
97
+ files: files,
98
+ target_branch: target_branch,
99
+ includes_security_fixes: includes_security_fixes,
100
+ separator: separator,
101
+ prefix: prefix,
102
+ max_length: max_length,
103
+ multi_ecosystem_name: T.must(multi_ecosystem_name)
104
+ )
105
+ end
106
+
107
+ sig { returns(Dependabot::PullRequestCreator::BranchNamer::SoloStrategy) }
108
+ def build_solo_strategy
109
+ SoloStrategy.new(
110
+ dependencies: dependencies,
111
+ files: files,
112
+ target_branch: target_branch,
113
+ separator: separator,
114
+ prefix: prefix,
115
+ max_length: max_length
116
+ )
117
+ end
118
+
119
+ sig { returns(Dependabot::PullRequestCreator::BranchNamer::DependencyGroupStrategy) }
120
+ def build_dependency_group_strategy
121
+ DependencyGroupStrategy.new(
122
+ dependencies: dependencies,
123
+ files: files,
124
+ target_branch: target_branch,
125
+ dependency_group: T.must(dependency_group),
126
+ includes_security_fixes: includes_security_fixes,
127
+ separator: separator,
128
+ prefix: prefix,
129
+ max_length: max_length
130
+ )
131
+ end
100
132
  end
101
133
  end
102
134
  end
@@ -2,7 +2,6 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "tmpdir"
5
- require "set"
6
5
  require "sorbet-runtime"
7
6
 
8
7
  require "dependabot/requirement"
data/lib/dependabot.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Dependabot
5
- VERSION = "0.313.0"
5
+ VERSION = "0.315.0"
6
6
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-common
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.313.0
4
+ version: 0.315.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-05-15 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: aws-sdk-codecommit
@@ -91,14 +91,14 @@ dependencies:
91
91
  requirements:
92
92
  - - "~>"
93
93
  - !ruby/object:Gem::Version
94
- version: '0.109'
94
+ version: '1.2'
95
95
  type: :runtime
96
96
  prerelease: false
97
97
  version_requirements: !ruby/object:Gem::Requirement
98
98
  requirements:
99
99
  - - "~>"
100
100
  - !ruby/object:Gem::Version
101
- version: '0.109'
101
+ version: '1.2'
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: faraday
104
104
  requirement: !ruby/object:Gem::Requirement
@@ -225,6 +225,20 @@ dependencies:
225
225
  - - "~>"
226
226
  - !ruby/object:Gem::Version
227
227
  version: '0.3'
228
+ - !ruby/object:Gem::Dependency
229
+ name: ostruct
230
+ requirement: !ruby/object:Gem::Requirement
231
+ requirements:
232
+ - - "~>"
233
+ - !ruby/object:Gem::Version
234
+ version: '0.6'
235
+ type: :runtime
236
+ prerelease: false
237
+ version_requirements: !ruby/object:Gem::Requirement
238
+ requirements:
239
+ - - "~>"
240
+ - !ruby/object:Gem::Version
241
+ version: '0.6'
228
242
  - !ruby/object:Gem::Dependency
229
243
  name: parser
230
244
  requirement: !ruby/object:Gem::Requirement
@@ -548,6 +562,7 @@ files:
548
562
  - lib/dependabot/git_commit_checker.rb
549
563
  - lib/dependabot/git_metadata_fetcher.rb
550
564
  - lib/dependabot/git_ref.rb
565
+ - lib/dependabot/git_tag_with_detail.rb
551
566
  - lib/dependabot/logger.rb
552
567
  - lib/dependabot/metadata_finders.rb
553
568
  - lib/dependabot/metadata_finders/README.md
@@ -568,6 +583,7 @@ files:
568
583
  - lib/dependabot/pull_request_creator/branch_namer.rb
569
584
  - lib/dependabot/pull_request_creator/branch_namer/base.rb
570
585
  - lib/dependabot/pull_request_creator/branch_namer/dependency_group_strategy.rb
586
+ - lib/dependabot/pull_request_creator/branch_namer/multi_ecosystem_strategy.rb
571
587
  - lib/dependabot/pull_request_creator/branch_namer/solo_strategy.rb
572
588
  - lib/dependabot/pull_request_creator/codecommit.rb
573
589
  - lib/dependabot/pull_request_creator/commit_signer.rb
@@ -609,7 +625,7 @@ licenses:
609
625
  - MIT
610
626
  metadata:
611
627
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
612
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.313.0
628
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.315.0
613
629
  rdoc_options: []
614
630
  require_paths:
615
631
  - lib
@@ -617,14 +633,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
617
633
  requirements:
618
634
  - - ">="
619
635
  - !ruby/object:Gem::Version
620
- version: 3.1.0
636
+ version: 3.3.0
621
637
  required_rubygems_version: !ruby/object:Gem::Requirement
622
638
  requirements:
623
639
  - - ">="
624
640
  - !ruby/object:Gem::Version
625
641
  version: 3.3.7
626
642
  requirements: []
627
- rubygems_version: 3.6.3
643
+ rubygems_version: 3.6.9
628
644
  specification_version: 4
629
645
  summary: Shared code used across Dependabot Core
630
646
  test_files: []