dependabot-common 0.381.0 → 0.382.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: d1bc1965fa1a1b0995cf9a71e47f098f471c2727513d3a69d7c8cf35b82a3cc3
4
- data.tar.gz: 4273d18c7f649c135c28db5f864d82dc120f56a683a2b5fd823a09a486fc530b
3
+ metadata.gz: 6b53185ee3c744622d14656ac582aaa779b5b9f3394497824d49561fe78fe2d8
4
+ data.tar.gz: cd5ce58e980459603217ea2693475a224691f67149215d1fb5031472bc065507
5
5
  SHA512:
6
- metadata.gz: 72acbd4917a61c50117d9014f26ac4cae89567215682764b01506c1a36f4eb80df3245f4ca4cad9ad7ab0f5d834e9e4540a67a6ea0dab5441d2d9c0a62f6acff
7
- data.tar.gz: d2acef41e94afb6b5d0d171139e615adbbcc491e89a35ec78d7852b2d745e301ea3f9ec212b035452f7898cdfd791c8e2ff25decf021e5bc2fbda58011879688
6
+ metadata.gz: 1216f4ef150d1c76b7180f780b1d67831359c9f327bf1a00cf885d3f9b3313ce354a694803de8ec91c1eebc138e922d65cde4f4e5ede88f6da7ceb23c6306026
7
+ data.tar.gz: 1377f5537d8d8e637945e35d59ba58dde50ec048f29abf6e9d50c4239ce2a7ca292aa379cfd7c28af7c9efe12723bdf71d55a007ad7e4839a177472f57f7a256
@@ -52,7 +52,7 @@ module Dependabot
52
52
  update_types.map(&:downcase).filter_map(&:strip)
53
53
  end
54
54
 
55
- sig { params(dependency: Dependency).returns(T::Array[T.untyped]) }
55
+ sig { params(dependency: Dependency).returns(T::Array[String]) }
56
56
  def versions_by_type(dependency)
57
57
  version = correct_version_for(dependency)
58
58
  return [] unless version
@@ -11,10 +11,20 @@ module Dependabot
11
11
 
12
12
  def_delegators :@credential, :fetch, :keys, :[]=, :delete, :slice, :values, :entries
13
13
 
14
- sig { params(credential: T::Hash[String, T.any(T::Boolean, String)]).void }
14
+ sig { params(credential: T::Hash[String, T.any(T::Boolean, String, T::Array[String])]).void }
15
15
  def initialize(credential)
16
16
  @replaces_base = T.let(credential["replaces-base"] == true, T::Boolean)
17
17
  credential.delete("replaces-base")
18
+
19
+ raw_scope = credential.delete("scope")
20
+ @scope = T.let(
21
+ case raw_scope
22
+ when String then [raw_scope]
23
+ when Array then raw_scope
24
+ end,
25
+ T.nilable(T::Array[String])
26
+ )
27
+
18
28
  @credential = T.let(T.unsafe(credential), T::Hash[String, String])
19
29
  end
20
30
 
@@ -23,6 +33,9 @@ module Dependabot
23
33
  @replaces_base
24
34
  end
25
35
 
36
+ sig { returns(T.nilable(T::Array[String])) }
37
+ attr_reader :scope
38
+
26
39
  sig { params(key: String).returns(T.nilable(String)) }
27
40
  def [](key)
28
41
  @credential[key]
@@ -2,6 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "sorbet-runtime"
5
+ require "dependabot/dependency_requirement"
5
6
  require "dependabot/version"
6
7
 
7
8
  module Dependabot
@@ -90,7 +91,7 @@ module Dependabot
90
91
  sig { returns(T.nilable(String)) }
91
92
  attr_reader :version
92
93
 
93
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
94
+ sig { returns(T::Array[Dependabot::DependencyRequirement]) }
94
95
  attr_reader :requirements
95
96
 
96
97
  sig { returns(String) }
@@ -99,7 +100,7 @@ module Dependabot
99
100
  sig { returns(T.nilable(String)) }
100
101
  attr_reader :previous_version
101
102
 
102
- sig { returns(T.nilable(T::Array[T::Hash[Symbol, T.untyped]])) }
103
+ sig { returns(T.nilable(T::Array[Dependabot::DependencyRequirement])) }
103
104
  attr_reader :previous_requirements
104
105
 
105
106
  sig { returns(T.nilable(String)) }
@@ -124,7 +125,6 @@ module Dependabot
124
125
  sig { returns(T.nilable(Time)) }
125
126
  attr_accessor :attribution_timestamp
126
127
 
127
- # rubocop:disable Metrics/AbcSize
128
128
  # rubocop:disable Metrics/PerceivedComplexity
129
129
  sig do
130
130
  params(
@@ -162,12 +162,15 @@ module Dependabot
162
162
  T.nilable(String)
163
163
  )
164
164
  @version = nil if @version == ""
165
- @requirements = T.let(requirements.map { |req| symbolize_keys(req) }, T::Array[T::Hash[Symbol, T.untyped]])
165
+ @requirements = T.let(
166
+ requirements.map { |req| DependencyRequirement.create(req) },
167
+ T::Array[Dependabot::DependencyRequirement]
168
+ )
166
169
  @previous_version = previous_version
167
170
  @previous_version = nil if @previous_version == ""
168
171
  @previous_requirements = T.let(
169
- previous_requirements&.map { |req| symbolize_keys(req) },
170
- T.nilable(T::Array[T::Hash[Symbol, T.untyped]])
172
+ previous_requirements&.map { |req| DependencyRequirement.create(req) },
173
+ T.nilable(T::Array[Dependabot::DependencyRequirement])
171
174
  )
172
175
  @package_manager = package_manager
173
176
  @directory = directory
@@ -181,7 +184,6 @@ module Dependabot
181
184
  @metadata = T.let(symbolize_keys(metadata || {}), T::Hash[Symbol, T.untyped])
182
185
  check_values
183
186
  end
184
- # rubocop:enable Metrics/AbcSize
185
187
  # rubocop:enable Metrics/PerceivedComplexity
186
188
 
187
189
  sig { returns(T::Boolean) }
@@ -272,7 +274,7 @@ module Dependabot
272
274
  end
273
275
  end
274
276
 
275
- sig { params(requirements: T::Array[T::Hash[Symbol, T.untyped]]).returns(T.nilable(String)) }
277
+ sig { params(requirements: T::Array[Dependabot::DependencyRequirement]).returns(T.nilable(String)) }
276
278
  def docker_digest_from_reqs(requirements)
277
279
  requirements
278
280
  .filter_map { |r| r.dig(:source, "digest") || r.dig(:source, :digest) }
@@ -340,9 +342,9 @@ module Dependabot
340
342
  self == other
341
343
  end
342
344
 
343
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
345
+ sig { returns(T::Array[Dependabot::DependencyRequirement]) }
344
346
  def specific_requirements
345
- requirements.select { |r| requirement_class.new(r[:requirement]).specific? }
347
+ requirements.select { |r| requirement_class.new(r.requirement).specific? }
346
348
  end
347
349
 
348
350
  sig { returns(T.class_of(Dependabot::Requirement)) }
@@ -123,7 +123,7 @@ module Dependabot
123
123
  raise "Only symlinked files must specify a target!" if symlink_target
124
124
  end
125
125
 
126
- sig { returns(T::Hash[String, T.untyped]) }
126
+ sig { returns(T::Hash[String, T.nilable(T.any(String, T::Boolean))]) }
127
127
  def to_h
128
128
  details = {
129
129
  "name" => name,
@@ -0,0 +1,94 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "sorbet-runtime"
5
+
6
+ module Dependabot
7
+ # A single requirement entry within Dependency#requirements, e.g.:
8
+ #
9
+ # {
10
+ # requirement: ">= 1.0, < 2.0",
11
+ # file: "Gemfile",
12
+ # groups: [:default],
13
+ # source: { type: "rubygems", url: "https://rubygems.org" },
14
+ # metadata: { property_name: "rails.version" } # optional
15
+ # }
16
+ #
17
+ # Subclasses Hash so it is a drop-in replacement at call sites (and in
18
+ # type annotations) that treat requirement entries as
19
+ # T::Hash[Symbol, T.untyped], while exposing typed readers for the
20
+ # well-known keys. New code should prefer the typed readers; hash-style
21
+ # access remains supported while call sites are migrated gradually.
22
+ #
23
+ # Wire compatibility: instances serialise to JSON exactly like the plain
24
+ # hash they were created from, and compare equal (==/eql?/#hash) to plain
25
+ # hashes with the same content, so existing comparisons, Array/Set
26
+ # operations, and API payloads are unaffected.
27
+ #
28
+ # Note on Hash methods: in Ruby 3+, #merge, #dup and #compact preserve
29
+ # this class, while #select, #reject, #except, #transform_values and
30
+ # #to_h return plain Hash instances. Dependency#initialize re-wraps
31
+ # whatever it is given, so both styles remain safe.
32
+ class DependencyRequirement < Hash
33
+ extend T::Sig
34
+ extend T::Generic
35
+
36
+ # The values of a requirement entry are heterogeneous and
37
+ # ecosystem-specific, so this bridge class is necessarily untyped at
38
+ # the Hash level; the typed readers below are the migration path.
39
+ # rubocop:disable Sorbet/ForbidTUntyped
40
+ K = type_member { { fixed: Symbol } }
41
+ V = type_member { { fixed: T.untyped } }
42
+ Elem = type_member { { fixed: [Symbol, T.untyped] } }
43
+
44
+ # Builds a DependencyRequirement from a requirement hash, symbolising
45
+ # top-level keys. Accepts both plain hashes and existing
46
+ # DependencyRequirement instances and always returns a new instance.
47
+ sig { params(hash: T::Hash[T.any(Symbol, String), T.untyped]).returns(DependencyRequirement) }
48
+ def self.create(hash)
49
+ requirement = new
50
+ requirement.replace(hash.keys.to_h { |k| [k.to_sym, hash[k]] })
51
+ requirement
52
+ end
53
+
54
+ # The version constraint string, e.g. ">= 1.0, < 2.0". Nil when the
55
+ # dependency is pinned by a lockfile rather than a manifest constraint.
56
+ sig { returns(T.nilable(String)) }
57
+ def requirement
58
+ self[:requirement]
59
+ end
60
+
61
+ # The manifest file this requirement was declared in, e.g. "Gemfile".
62
+ sig { returns(T.nilable(String)) }
63
+ def file
64
+ self[:file]
65
+ end
66
+
67
+ # The dependency groups this requirement belongs to, e.g. ["dev"] or
68
+ # [:default]. Element types vary by ecosystem (strings or symbols).
69
+ # Nilable because some requirement entries are constructed with
70
+ # groups: nil, and the reader must reflect that to stay a drop-in for
71
+ # the underlying hash access under sorbet-runtime.
72
+ sig { returns(T.nilable(T::Array[T.untyped])) }
73
+ def groups
74
+ self[:groups]
75
+ end
76
+
77
+ # The source details for the dependency, e.g.
78
+ # { type: "git", url: "https://github.com/..." }. Keys may be symbols
79
+ # or strings depending on whether the requirement was built by a file
80
+ # parser or deserialised from a job definition.
81
+ sig { returns(T.nilable(T::Hash[T.any(Symbol, String), T.untyped])) }
82
+ def source
83
+ self[:source]
84
+ end
85
+
86
+ # Optional ecosystem-specific metadata about the requirement, e.g.
87
+ # { property_name: "rails.version" }.
88
+ sig { returns(T.nilable(T::Hash[T.any(Symbol, String), T.untyped])) }
89
+ def metadata
90
+ self[:metadata]
91
+ end
92
+ # rubocop:enable Sorbet/ForbidTUntyped
93
+ end
94
+ end
@@ -33,7 +33,7 @@ module Dependabot
33
33
  @dependencies.values.filter_map(&:combined)
34
34
  end
35
35
 
36
- sig { params(dep: Dependabot::Dependency).returns(T.untyped) }
36
+ sig { params(dep: Dependabot::Dependency).returns(T.self_type) }
37
37
  def <<(dep)
38
38
  T.must(@dependencies[key_for_dependency(dep)]) << dep
39
39
  self
@@ -28,6 +28,11 @@ module Dependabot
28
28
  sig { returns(T::Hash[Symbol, T.untyped]) }
29
29
  attr_reader :options
30
30
 
31
+ sig { returns(T::Boolean) }
32
+ def reject_external_code?
33
+ @reject_external_code
34
+ end
35
+
31
36
  sig do
32
37
  params(
33
38
  dependency_files: T::Array[Dependabot::DependencyFile],
@@ -1,4 +1,4 @@
1
- # typed: strict
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "sorbet-runtime"
@@ -120,25 +120,46 @@ module Dependabot
120
120
 
121
121
  sig do
122
122
  overridable
123
- .params(parameters: T::Hash[Symbol, T.untyped])
123
+ .params(
124
+ name: String,
125
+ content: T.nilable(String),
126
+ directory: String,
127
+ type: String,
128
+ support_file: T::Boolean,
129
+ vendored_file: T::Boolean,
130
+ symlink_target: T.nilable(String),
131
+ content_encoding: String,
132
+ deleted: T::Boolean,
133
+ operation: String,
134
+ mode: T.nilable(String)
135
+ )
124
136
  .returns(Dependabot::DependencyFile)
125
137
  end
126
- def create_dependency_file(parameters)
138
+ def create_dependency_file(
139
+ name:,
140
+ content: nil,
141
+ directory: "/",
142
+ type: "file",
143
+ support_file: false,
144
+ vendored_file: false,
145
+ symlink_target: nil,
146
+ content_encoding: Dependabot::DependencyFile::ContentEncoding::UTF_8,
147
+ deleted: false,
148
+ operation: Dependabot::DependencyFile::Operation::UPDATE,
149
+ mode: nil
150
+ )
127
151
  Dependabot::DependencyFile.new(
128
- name: parameters.fetch(:name),
129
- content: parameters[:content],
130
- directory: parameters.fetch(:directory, "/"),
131
- type: parameters.fetch(:type, "file"),
132
- support_file: parameters.fetch(:support_file, false),
133
- vendored_file: parameters.fetch(:vendored_file, false),
134
- symlink_target: parameters[:symlink_target],
135
- content_encoding: parameters.fetch(
136
- :content_encoding,
137
- Dependabot::DependencyFile::ContentEncoding::UTF_8
138
- ),
139
- deleted: parameters.fetch(:deleted, false),
140
- operation: parameters.fetch(:operation, Dependabot::DependencyFile::Operation::UPDATE),
141
- mode: parameters[:mode]
152
+ name: name,
153
+ content: content,
154
+ directory: directory,
155
+ type: type,
156
+ support_file: support_file,
157
+ vendored_file: vendored_file,
158
+ symlink_target: symlink_target,
159
+ content_encoding: content_encoding,
160
+ deleted: deleted,
161
+ operation: operation,
162
+ mode: mode
142
163
  )
143
164
  end
144
165
  end
@@ -31,27 +31,51 @@ module Dependabot
31
31
 
32
32
  private
33
33
 
34
+ # VendorUpdater always flags files as vendored, so it accepts but ignores
35
+ # the vendored_file argument. The parameter must stay to keep the override
36
+ # signature compatible with ArtifactUpdater#create_dependency_file.
34
37
  sig do
35
38
  override
36
- .params(parameters: T::Hash[Symbol, T.untyped])
39
+ .params(
40
+ name: String,
41
+ content: T.nilable(String),
42
+ directory: String,
43
+ type: String,
44
+ support_file: T::Boolean,
45
+ vendored_file: T::Boolean,
46
+ symlink_target: T.nilable(String),
47
+ content_encoding: String,
48
+ deleted: T::Boolean,
49
+ operation: String,
50
+ mode: T.nilable(String)
51
+ )
37
52
  .returns(Dependabot::DependencyFile)
38
53
  end
39
- def create_dependency_file(parameters)
40
- Dependabot::DependencyFile.new(
41
- name: parameters.fetch(:name),
42
- content: parameters[:content],
43
- directory: parameters.fetch(:directory, "/"),
44
- type: parameters.fetch(:type, "file"),
45
- support_file: parameters.fetch(:support_file, false),
54
+ def create_dependency_file(
55
+ name:,
56
+ content: nil,
57
+ directory: "/",
58
+ type: "file",
59
+ support_file: false,
60
+ vendored_file: false, # rubocop:disable Lint/UnusedMethodArgument
61
+ symlink_target: nil,
62
+ content_encoding: Dependabot::DependencyFile::ContentEncoding::UTF_8,
63
+ deleted: false,
64
+ operation: Dependabot::DependencyFile::Operation::UPDATE,
65
+ mode: nil
66
+ )
67
+ super(
68
+ name: name,
69
+ content: content,
70
+ directory: directory,
71
+ type: type,
72
+ support_file: support_file,
46
73
  vendored_file: true,
47
- symlink_target: parameters[:symlink_target],
48
- content_encoding: parameters.fetch(
49
- :content_encoding,
50
- Dependabot::DependencyFile::ContentEncoding::UTF_8
51
- ),
52
- deleted: parameters.fetch(:deleted, false),
53
- operation: parameters.fetch(:operation, Dependabot::DependencyFile::Operation::UPDATE),
54
- mode: parameters[:mode]
74
+ symlink_target: symlink_target,
75
+ content_encoding: content_encoding,
76
+ deleted: deleted,
77
+ operation: operation,
78
+ mode: mode
55
79
  )
56
80
  end
57
81
  end
@@ -14,6 +14,7 @@ require "dependabot/source"
14
14
  require "dependabot/dependency"
15
15
  require "dependabot/credential"
16
16
  require "dependabot/git_metadata_fetcher"
17
+ require "dependabot/git_tag_details"
17
18
  module Dependabot
18
19
  # rubocop:disable Metrics/ClassLength
19
20
  class GitCommitChecker
@@ -159,31 +160,31 @@ module Dependabot
159
160
  local_repo_git_metadata_fetcher.head_commit_for_ref(name)
160
161
  end
161
162
 
162
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
163
+ sig { returns(T.nilable(Dependabot::GitTagDetails)) }
163
164
  def local_ref_for_latest_version_matching_existing_precision
164
165
  allowed_refs = local_tag_for_pinned_sha ? allowed_version_tags : allowed_version_refs
165
166
 
166
167
  max_local_tag_for_current_precision(allowed_refs)
167
168
  end
168
169
 
169
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
170
+ sig { returns(T.nilable(Dependabot::GitTagDetails)) }
170
171
  def local_ref_for_latest_version_lower_precision
171
172
  allowed_refs = local_tag_for_pinned_sha ? allowed_version_tags : allowed_version_refs
172
173
 
173
174
  max_local_tag_for_lower_precision(allowed_refs)
174
175
  end
175
176
 
176
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
177
+ sig { returns(T.nilable(Dependabot::GitTagDetails)) }
177
178
  def local_tag_for_latest_version
178
179
  max_local_tag(allowed_version_tags)
179
180
  end
180
181
 
181
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
182
+ sig { returns(T::Array[Dependabot::GitTagDetails]) }
182
183
  def local_tags_for_allowed_versions_matching_existing_precision
183
184
  select_matching_existing_precision(allowed_version_tags).filter_map { |t| to_local_tag(t) }
184
185
  end
185
186
 
186
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
187
+ sig { returns(T::Array[Dependabot::GitTagDetails]) }
187
188
  def local_tags_for_allowed_versions
188
189
  allowed_version_tags.filter_map { |t| to_local_tag(t) }
189
190
  end
@@ -272,7 +273,7 @@ module Dependabot
272
273
  local_tags_matching_sha(commit_sha).map(&:name)
273
274
  end
274
275
 
275
- sig { params(tags: T::Array[Dependabot::GitRef]).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
276
+ sig { params(tags: T::Array[Dependabot::GitRef]).returns(T.nilable(Dependabot::GitTagDetails)) }
276
277
  def max_local_tag(tags)
277
278
  max_version_tag = tags.max_by { |t| version_from_tag(t) }
278
279
 
@@ -295,12 +296,12 @@ module Dependabot
295
296
  sig { returns(T::Array[String]) }
296
297
  attr_reader :ignored_versions
297
298
 
298
- sig { params(tags: T::Array[Dependabot::GitRef]).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
299
+ sig { params(tags: T::Array[Dependabot::GitRef]).returns(T.nilable(Dependabot::GitTagDetails)) }
299
300
  def max_local_tag_for_current_precision(tags)
300
301
  max_local_tag(select_matching_existing_precision(tags))
301
302
  end
302
303
 
303
- sig { params(tags: T::Array[Dependabot::GitRef]).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
304
+ sig { params(tags: T::Array[Dependabot::GitRef]).returns(T.nilable(Dependabot::GitTagDetails)) }
304
305
  def max_local_tag_for_lower_precision(tags)
305
306
  max_local_tag(select_lower_precision(tags))
306
307
  end
@@ -553,17 +554,17 @@ module Dependabot
553
554
  prefix.length > 1 ? prefix.gsub(/v$/i, "") : prefix.gsub(/^v$/i, "")
554
555
  end
555
556
 
556
- sig { params(tag: T.nilable(Dependabot::GitRef)).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
557
+ sig { params(tag: T.nilable(Dependabot::GitRef)).returns(T.nilable(Dependabot::GitTagDetails)) }
557
558
  def to_local_tag(tag)
558
559
  return unless tag
559
560
 
560
561
  version = version_from_tag(tag)
561
- {
562
+ GitTagDetails.new(
562
563
  tag: tag.name,
563
564
  version: version,
564
565
  commit_sha: tag.commit_sha,
565
566
  tag_sha: tag.ref_sha
566
- }
567
+ )
567
568
  end
568
569
 
569
570
  sig { returns(T.nilable(String)) }
@@ -0,0 +1,78 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "sorbet-runtime"
5
+
6
+ module Dependabot
7
+ # A git tag (or ref) resolved to a version, as produced by GitCommitChecker's
8
+ # local_tag_for_* / local_ref_for_* methods, e.g.:
9
+ #
10
+ # {
11
+ # tag: "v1.2.0",
12
+ # version: Dependabot::Version.new("1.2.0"),
13
+ # commit_sha: "a1b2c3...",
14
+ # tag_sha: "d4e5f6..." # nil for lightweight tags
15
+ # }
16
+ #
17
+ # Distinct from Dependabot::GitTagWithDetail, which carries a tag name and
18
+ # release date for cooldown handling.
19
+ #
20
+ # Subclasses Hash so it is a drop-in replacement at the many call sites that
21
+ # read entries with [:key] / fetch and treat them as
22
+ # T::Hash[Symbol, T.untyped], while exposing typed readers for the well-known
23
+ # keys. Instances compare equal (Hash#==) to plain hashes with the same
24
+ # content, so existing comparisons and API payloads are unaffected.
25
+ class GitTagDetails < Hash
26
+ extend T::Sig
27
+ extend T::Generic
28
+
29
+ # The values are heterogeneous (strings and a version object), so this
30
+ # bridge class is necessarily untyped at the Hash level; the typed readers
31
+ # below are the migration path.
32
+ # rubocop:disable Sorbet/ForbidTUntyped
33
+ K = type_member { { fixed: Symbol } }
34
+ V = type_member { { fixed: T.untyped } }
35
+ Elem = type_member { { fixed: [Symbol, T.untyped] } }
36
+ # rubocop:enable Sorbet/ForbidTUntyped
37
+
38
+ sig do
39
+ params(
40
+ tag: String,
41
+ version: T.nilable(Gem::Version),
42
+ commit_sha: T.nilable(String),
43
+ tag_sha: T.nilable(String)
44
+ ).void
45
+ end
46
+ def initialize(tag:, version: nil, commit_sha: nil, tag_sha: nil)
47
+ super()
48
+ self[:tag] = tag
49
+ self[:version] = version
50
+ self[:commit_sha] = commit_sha
51
+ self[:tag_sha] = tag_sha
52
+ end
53
+
54
+ # The tag or ref name, e.g. "v1.2.0".
55
+ sig { returns(String) }
56
+ def tag
57
+ self[:tag]
58
+ end
59
+
60
+ # The version parsed from the tag name.
61
+ sig { returns(T.nilable(Gem::Version)) }
62
+ def version
63
+ self[:version]
64
+ end
65
+
66
+ # The SHA of the commit the tag points at.
67
+ sig { returns(T.nilable(String)) }
68
+ def commit_sha
69
+ self[:commit_sha]
70
+ end
71
+
72
+ # The SHA of the tag object itself (nil for lightweight tags).
73
+ sig { returns(T.nilable(String)) }
74
+ def tag_sha
75
+ self[:tag_sha]
76
+ end
77
+ end
78
+ end
@@ -145,7 +145,7 @@ module Dependabot
145
145
  end
146
146
 
147
147
  # TODO: Refactor me so that Composer doesn't need to be special cased
148
- sig { params(requirements: T.nilable(T::Array[T::Hash[Symbol, T.untyped]])).returns(T::Boolean) }
148
+ sig { params(requirements: T.nilable(T::Array[Dependabot::DependencyRequirement])).returns(T::Boolean) }
149
149
  def git_source?(requirements)
150
150
  # Special case Composer, which uses git as a source but handles tags
151
151
  # internally
@@ -59,7 +59,7 @@ module Dependabot
59
59
 
60
60
  # Converts the Notice object to a hash.
61
61
  # @return [Hash] The hash representation of the notice.
62
- sig { returns(T::Hash[Symbol, T.untyped]) }
62
+ sig { returns(T::Hash[Symbol, T.any(String, T::Boolean)]) }
63
63
  def to_hash
64
64
  {
65
65
  mode: @mode,
@@ -119,21 +119,21 @@ module Dependabot
119
119
 
120
120
  sig { params(dependency: Dependabot::Dependency).returns(String) }
121
121
  def sanitized_requirement(dependency)
122
- new_library_requirement(dependency)
123
- .delete(" ")
124
- .gsub("!=", "neq-")
125
- .gsub(">=", "gte-")
126
- .gsub("<=", "lte-")
127
- .gsub("~>", "tw-")
128
- .gsub("^", "tw-")
129
- .gsub("||", "or-")
130
- .gsub("~", "approx-")
131
- .gsub("~=", "tw-")
132
- .gsub(/==*/, "eq-")
133
- .gsub(">", "gt-")
134
- .gsub("<", "lt-")
135
- .gsub("*", "star")
136
- .gsub(",", "-and-")
122
+ T.must(new_library_requirement(dependency))
123
+ .delete(" ")
124
+ .gsub("!=", "neq-")
125
+ .gsub(">=", "gte-")
126
+ .gsub("<=", "lte-")
127
+ .gsub("~>", "tw-")
128
+ .gsub("^", "tw-")
129
+ .gsub("||", "or-")
130
+ .gsub("~", "approx-")
131
+ .gsub("~=", "tw-")
132
+ .gsub(/==*/, "eq-")
133
+ .gsub(">", "gt-")
134
+ .gsub("<", "lt-")
135
+ .gsub("*", "star")
136
+ .gsub(",", "-and-")
137
137
  end
138
138
 
139
139
  sig { params(dependency: Dependabot::Dependency).returns(T.nilable(String)) }
@@ -176,7 +176,7 @@ module Dependabot
176
176
  previous_ref(dependency) != new_ref(dependency)
177
177
  end
178
178
 
179
- sig { params(dependency: Dependabot::Dependency).returns(T.untyped) }
179
+ sig { params(dependency: Dependabot::Dependency).returns(T.nilable(String)) }
180
180
  def new_library_requirement(dependency)
181
181
  updated_reqs =
182
182
  dependency.requirements - T.must(dependency.previous_requirements)
@@ -182,7 +182,7 @@ module Dependabot
182
182
  dependency.version
183
183
  end
184
184
 
185
- sig { overridable.returns(T::Array[T::Hash[Symbol, T.untyped]]) }
185
+ sig { overridable.returns(T::Array[Dependabot::DependencyRequirement]) }
186
186
  def updated_requirements
187
187
  raise NotImplementedError
188
188
  end
@@ -226,6 +226,20 @@ module Dependabot
226
226
 
227
227
  private
228
228
 
229
+ # Wraps an array of raw requirement hashes (e.g. the output of an
230
+ # ecosystem RequirementsUpdater) into typed DependencyRequirement
231
+ # objects, so updated_requirements overrides can satisfy the typed
232
+ # return contract. Entries that are already DependencyRequirement
233
+ # instances are returned as-is; plain hashes are wrapped. Re-wrapping
234
+ # would produce a value-equal copy, so skipping it avoids needless
235
+ # allocations.
236
+ sig { params(requirements: T::Array[T::Hash[Symbol, T.untyped]]).returns(T::Array[Dependabot::DependencyRequirement]) }
237
+ def wrap_requirements(requirements)
238
+ requirements.map do |requirement|
239
+ requirement.is_a?(Dependabot::DependencyRequirement) ? requirement : Dependabot::DependencyRequirement.create(requirement)
240
+ end
241
+ end
242
+
229
243
  sig { returns(T::Array[Dependabot::SecurityAdvisory]) }
230
244
  def active_advisories
231
245
  security_advisories.select { |a| a.vulnerable?(T.must(current_version)) }
data/lib/dependabot.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Dependabot
5
- VERSION = "0.381.0"
5
+ VERSION = "0.382.0"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-common
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.381.0
4
+ version: 0.382.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -534,6 +534,7 @@ files:
534
534
  - lib/dependabot/dependency_graphers/base.rb
535
535
  - lib/dependabot/dependency_graphers/generic.rb
536
536
  - lib/dependabot/dependency_group.rb
537
+ - lib/dependabot/dependency_requirement.rb
537
538
  - lib/dependabot/ecosystem.rb
538
539
  - lib/dependabot/errors.rb
539
540
  - lib/dependabot/experiments.rb
@@ -553,6 +554,7 @@ files:
553
554
  - lib/dependabot/git_commit_checker.rb
554
555
  - lib/dependabot/git_metadata_fetcher.rb
555
556
  - lib/dependabot/git_ref.rb
557
+ - lib/dependabot/git_tag_details.rb
556
558
  - lib/dependabot/git_tag_with_detail.rb
557
559
  - lib/dependabot/logger.rb
558
560
  - lib/dependabot/metadata_finders.rb
@@ -617,7 +619,7 @@ licenses:
617
619
  - MIT
618
620
  metadata:
619
621
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
620
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.381.0
622
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.382.0
621
623
  rdoc_options: []
622
624
  require_paths:
623
625
  - lib