dependabot-composer 0.308.0 → 0.309.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: e8cf83dff0ec628783dcf7ec7c9213b172c4b73b95f29f22c74360766e06fedb
4
- data.tar.gz: a5a7275d8226e18617c650554e1f3260ff6c5d311de4de575725471a1e85fa5e
3
+ metadata.gz: 5b48559b241f9da95640467394b1126858e5eabfbfe6f14d409e2ce774dd7afc
4
+ data.tar.gz: 3a0e66c465ea0793a19353c01a631e8f77e0ff46ecb9418a27690b544e32a214
5
5
  SHA512:
6
- metadata.gz: 82504108facc90a27aa88fc5274634b75095c9ad21f2aaae9996ad166c0021d64df43bffa8468eba5a8d6f96dd5bab7ecf5e26086edc660d6c4e8cc6dfd5bbe0
7
- data.tar.gz: 791e9ef944a5c1352246ae1663309cda79d62cd04a7da42f39601a092abaf91ee4c635c64b14dcb429655f104d97d11400ec150a50da1117989648fc2cdd295c
6
+ metadata.gz: 4074f195864b3aec259bf220a25901c7532dd994c3c950a3d3eeaa985492e9dac9c2904b0210a87050aab8f75f3e14a2eb7476c6e019a133655e700c121889c3
7
+ data.tar.gz: c7744f1a7bf86c76acedeb4b5e6552cc1a63d6723d32034d0195261756e4a8c243bbd08ccbd289fa0851516e6fe9c7335a73a7c44bb79f5d62173fa328d67526
@@ -1,7 +1,9 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "json"
5
+ require "sorbet-runtime"
6
+
5
7
  require "dependabot/dependency_file"
6
8
  require "dependabot/composer/file_fetcher"
7
9
  require "dependabot/composer/file_parser"
@@ -10,12 +12,17 @@ module Dependabot
10
12
  module Composer
11
13
  class FileFetcher
12
14
  class PathDependencyBuilder
15
+ extend T::Sig
16
+
17
+ sig { params(path: String, directory: String, lockfile: T.untyped).void }
13
18
  def initialize(path:, directory:, lockfile:)
14
- @path = path
15
- @directory = directory
16
- @lockfile = lockfile
19
+ @path = T.let(path, String)
20
+ @directory = T.let(directory, String)
21
+ @lockfile = T.let(lockfile, T.untyped)
22
+ @parsed_lockfile = T.let(nil, T.nilable(T::Hash[String, T.untyped]))
17
23
  end
18
24
 
25
+ sig { returns(T.nilable(DependencyFile)) }
19
26
  def dependency_file
20
27
  filename = File.join(path, PackageManager::MANIFEST_FILENAME)
21
28
 
@@ -35,10 +42,16 @@ module Dependabot
35
42
 
36
43
  private
37
44
 
45
+ sig { returns(String) }
38
46
  attr_reader :path
47
+
48
+ sig { returns(T.untyped) }
39
49
  attr_reader :lockfile
50
+
51
+ sig { returns(String) }
40
52
  attr_reader :directory
41
53
 
54
+ sig { returns(T.nilable(T::Hash[String, T.untyped])) }
42
55
  def details_from_lockfile
43
56
  keys = FileParser::DEPENDENCY_GROUP_KEYS
44
57
  .map { |h| h.fetch(:lockfile) }
@@ -54,16 +67,18 @@ module Dependabot
54
67
  nil
55
68
  end
56
69
 
70
+ sig { returns(T.nilable(String)) }
57
71
  def build_path_dep_content
58
72
  return unless details_from_lockfile
59
73
 
60
74
  details_from_lockfile.to_json
61
75
  end
62
76
 
77
+ sig { returns(T::Hash[String, T.untyped]) }
63
78
  def parsed_lockfile
64
79
  return {} unless lockfile
65
80
 
66
- @parsed_lockfile ||= JSON.parse(lockfile.content)
81
+ @parsed_lockfile ||= T.let(JSON.parse(lockfile.content), T.nilable(T::Hash[String, T.untyped]))
67
82
  rescue JSON::ParserError
68
83
  {}
69
84
  end
@@ -12,10 +12,12 @@ module Dependabot
12
12
  class MetadataFinder < Dependabot::MetadataFinders::Base
13
13
  private
14
14
 
15
+ sig { override.returns(T.nilable(Source)) }
15
16
  def look_up_source
16
17
  source_from_dependency || look_up_source_from_packagist
17
18
  end
18
19
 
20
+ sig { returns(T.nilable(Source)) }
19
21
  def source_from_dependency
20
22
  source_url =
21
23
  dependency.requirements
@@ -25,18 +27,21 @@ module Dependabot
25
27
  Source.from_url(source_url)
26
28
  end
27
29
 
30
+ sig { returns(T.nilable(Source)) }
28
31
  def look_up_source_from_packagist
29
- return nil if packagist_listing&.fetch("packages", nil) == []
30
- return nil unless packagist_listing&.dig("packages", dependency.name.downcase)
32
+ listing = packagist_listing
33
+ return nil if listing&.fetch("packages", nil) == []
34
+
35
+ packages = listing&.dig("packages", dependency.name.downcase)
36
+ return nil unless packages
31
37
 
32
- version_listings = packagist_listing["packages"][dependency.name.downcase]
33
38
  # Packagist returns an array of version listings sorted newest to oldest.
34
39
  # So iterate until we find the first URL that appears to be a source URL.
35
40
  #
36
41
  # NOTE: Each listing may not have all fields because they are minified to remove duplicate elements:
37
42
  # * https://github.com/composer/composer/blob/main/UPGRADE-2.0.md#for-composer-repository-implementors
38
43
  # * https://github.com/composer/metadata-minifier
39
- version_listings.each do |i|
44
+ packages.each do |i|
40
45
  [i["homepage"], i.dig("source", "url")].each do |url|
41
46
  source_url = Source.from_url(url)
42
47
  return source_url unless source_url.nil?
@@ -45,6 +50,7 @@ module Dependabot
45
50
  nil
46
51
  end
47
52
 
53
+ sig { returns(T.nilable(T::Hash[String, T.untyped])) }
48
54
  def packagist_listing
49
55
  return @packagist_listing unless @packagist_listing.nil?
50
56
 
@@ -1,17 +1,24 @@
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
  module Composer
6
8
  module NativeHelpers
9
+ extend T::Sig
10
+
11
+ sig { params(composer_version: String).returns(String) }
7
12
  def self.composer_helper_path(composer_version: "2")
8
13
  File.join(composer_helpers_dir, "v#{composer_version}", "bin/run")
9
14
  end
10
15
 
16
+ sig { returns(String) }
11
17
  def self.composer_helpers_dir
12
18
  File.join(native_helpers_root, "composer")
13
19
  end
14
20
 
21
+ sig { returns(String) }
15
22
  def self.native_helpers_root
16
23
  default_path = File.join(__dir__, "../../../..")
17
24
  ENV.fetch("DEPENDABOT_NATIVE_HELPERS_PATH", default_path)
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "sorbet-runtime"
@@ -14,6 +14,7 @@ module Dependabot
14
14
  AND_SEPARATOR = /(?<=[a-zA-Z0-9*])(?<!\sas)[\s,]+(?![\s,]*[|-]|as)/
15
15
  OR_SEPARATOR = /(?<=[a-zA-Z0-9*])[\s,]*\|\|?\s*/
16
16
 
17
+ sig { params(obj: String).returns(T::Array[T.any(String, Version)]) }
17
18
  def self.parse(obj)
18
19
  new_obj = obj.gsub(/@\w+/, "").gsub(/[a-z0-9\-_\.]*\sas\s+/i, "")
19
20
  return DefaultRequirement if new_obj == ""
@@ -30,6 +31,7 @@ module Dependabot
30
31
  end
31
32
  end
32
33
 
34
+ sig { params(requirements: T.untyped).void }
33
35
  def initialize(*requirements)
34
36
  requirements =
35
37
  requirements.flatten
@@ -41,6 +43,7 @@ module Dependabot
41
43
 
42
44
  private
43
45
 
46
+ sig { params(req_string: String).returns(T.any(String, T::Array[String])) }
44
47
  def convert_php_constraint_to_ruby_constraint(req_string)
45
48
  req_string = req_string.strip.gsub(/v(?=\d)/, "").gsub(/\.$/, "")
46
49
 
@@ -59,6 +62,7 @@ module Dependabot
59
62
  end
60
63
  end
61
64
 
65
+ sig { params(req_string: String).returns(String) }
62
66
  def convert_wildcard_req(req_string)
63
67
  if req_string.start_with?(">", "<")
64
68
  msg = "Illformed requirement [#{req_string.inspect}]"
@@ -69,17 +73,19 @@ module Dependabot
69
73
  "~> #{version}.0"
70
74
  end
71
75
 
76
+ sig { params(req_string: String).returns(String) }
72
77
  def convert_tilde_req(req_string)
73
78
  version = req_string.gsub(/^~/, "")
74
79
  "~> #{version}"
75
80
  end
76
81
 
82
+ sig { params(req_string: String).returns(T::Array[String]) }
77
83
  def convert_caret_req(req_string)
78
84
  version = req_string.gsub(/^\^/, "").gsub("x-dev", "0")
79
85
  parts = version.split(".")
80
86
  first_non_zero = parts.find { |d| d != "0" }
81
87
  first_non_zero_index =
82
- first_non_zero ? parts.index(first_non_zero) : parts.count - 1
88
+ first_non_zero ? T.must(parts.index(first_non_zero)) : parts.count - 1
83
89
  upper_bound = parts.map.with_index do |part, i|
84
90
  if i < first_non_zero_index then part
85
91
  elsif i == first_non_zero_index then (part.to_i + 1).to_s
@@ -91,8 +97,10 @@ module Dependabot
91
97
  [">= #{version}", "< #{upper_bound}"]
92
98
  end
93
99
 
100
+ sig { params(req_string: String).returns(T::Array[String]) }
94
101
  def convert_hyphen_req(req_string)
95
102
  lower_bound, upper_bound = req_string.split(/\s+-\s+/)
103
+ upper_bound = T.must(upper_bound)
96
104
  if upper_bound.split(".").count < 3
97
105
  upper_bound_parts = upper_bound.split(".")
98
106
  upper_bound_parts[-1] = (upper_bound_parts[-1].to_i + 1).to_s
@@ -260,23 +260,6 @@ module Dependabot
260
260
  raise PrivateSourceAuthenticationFailure, "nova.laravel.com"
261
261
  end
262
262
 
263
- # To handle the case where the PHP version (configured in composer.json) is not supported
264
- # league/csv 9.21.0 requires php ^8.1.2 -> your php version 8.1
265
- if error.message.include?("your php version")
266
- tool_name = "PHP"
267
- # Match for the detected PHP version
268
- detected_version_match =
269
- error.message.match(/your php version \((\d+\.\d+\.\d+)\)/) ||
270
- error.message.match(/your php version \((.*?)\s*;/)
271
- detected_version = detected_version_match ? detected_version_match[1] : nil
272
-
273
- # Match for the supported PHP versions
274
- supported_versions_match = error.message.match(/requires php\s(.*?)\s->/)
275
- supported_versions = supported_versions_match ? supported_versions_match[1] : nil
276
-
277
- raise ToolVersionNotSupported.new(tool_name, detected_version, supported_versions)
278
- end
279
-
280
263
  dependency_url = Helpers.dependency_url_from_git_clone_error(error.message)
281
264
  if dependency_url
282
265
  raise Dependabot::GitDependenciesNotReachable, dependency_url
@@ -1,7 +1,8 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "json"
5
+ require "sorbet-runtime"
5
6
 
6
7
  require "dependabot/errors"
7
8
  require "dependabot/requirements_update_strategy"
@@ -12,10 +13,13 @@ require "dependabot/update_checkers/base"
12
13
  module Dependabot
13
14
  module Composer
14
15
  class UpdateChecker < Dependabot::UpdateCheckers::Base
16
+ extend T::Sig
17
+
15
18
  require_relative "update_checker/requirements_updater"
16
19
  require_relative "update_checker/version_resolver"
17
20
  require_relative "update_checker/latest_version_finder"
18
21
 
22
+ sig { override.returns(T.nilable(T.any(String, Gem::Version))) }
19
23
  def latest_version
20
24
  return nil if path_dependency?
21
25
  return latest_version_for_git_dependency if git_dependency?
@@ -24,45 +28,54 @@ module Dependabot
24
28
  latest_version_from_registry || latest_resolvable_version
25
29
  end
26
30
 
31
+ sig { override.returns(T.nilable(Dependabot::Composer::Version)) }
27
32
  def latest_resolvable_version
28
33
  return nil if path_dependency? || git_dependency?
29
34
 
30
- @latest_resolvable_version ||=
35
+ @latest_resolvable_version ||= T.let(
31
36
  VersionResolver.new(
32
37
  credentials: credentials,
33
38
  dependency: dependency,
34
39
  dependency_files: dependency_files,
35
40
  latest_allowable_version: latest_version_from_registry,
36
41
  requirements_to_unlock: :own
37
- ).latest_resolvable_version
42
+ ).latest_resolvable_version,
43
+ T.nilable(Dependabot::Composer::Version)
44
+ )
38
45
  end
39
46
 
47
+ sig { override.returns(T.nilable(Dependabot::Composer::Version)) }
40
48
  def lowest_security_fix_version
41
49
  latest_version_finder.lowest_security_fix_version
42
50
  end
43
51
 
52
+ sig { override.returns(T.nilable(Dependabot::Composer::Version)) }
44
53
  def lowest_resolvable_security_fix_version
45
54
  raise "Dependency not vulnerable!" unless vulnerable?
46
55
 
47
- return @lowest_resolvable_security_fix_version if defined?(@lowest_resolvable_security_fix_version)
48
-
49
- @lowest_resolvable_security_fix_version =
50
- fetch_lowest_resolvable_security_fix_version
56
+ @lowest_resolvable_security_fix_version ||= T.let(
57
+ fetch_lowest_resolvable_security_fix_version,
58
+ T.nilable(Dependabot::Composer::Version)
59
+ )
51
60
  end
52
61
 
62
+ sig { override.returns(T.nilable(Dependabot::Composer::Version)) }
53
63
  def latest_resolvable_version_with_no_unlock
54
64
  return nil if path_dependency? || git_dependency?
55
65
 
56
- @latest_resolvable_version_with_no_unlock ||=
66
+ @latest_resolvable_version_with_no_unlock ||= T.let(
57
67
  VersionResolver.new(
58
68
  credentials: credentials,
59
69
  dependency: dependency,
60
70
  dependency_files: dependency_files,
61
71
  latest_allowable_version: latest_version_from_registry,
62
72
  requirements_to_unlock: :none
63
- ).latest_resolvable_version
73
+ ).latest_resolvable_version,
74
+ T.nilable(Dependabot::Composer::Version)
75
+ )
64
76
  end
65
77
 
78
+ sig { override.returns(T::Array[T::Hash[Symbol, T.untyped]]) }
66
79
  def updated_requirements
67
80
  RequirementsUpdater.new(
68
81
  requirements: dependency.requirements,
@@ -71,10 +84,12 @@ module Dependabot
71
84
  ).updated_requirements
72
85
  end
73
86
 
87
+ sig { returns(T::Boolean) }
74
88
  def requirements_unlocked_or_can_be?
75
- !requirements_update_strategy.lockfile_only?
89
+ !requirements_update_strategy&.lockfile_only?
76
90
  end
77
91
 
92
+ sig { returns(T.nilable(Dependabot::RequirementsUpdateStrategy)) }
78
93
  def requirements_update_strategy
79
94
  # If passed in as an option (in the base class) honour that option
80
95
  return @requirements_update_strategy if @requirements_update_strategy
@@ -85,30 +100,38 @@ module Dependabot
85
100
 
86
101
  private
87
102
 
103
+ sig { override.returns(T::Boolean) }
88
104
  def latest_version_resolvable_with_full_unlock?
89
105
  # Full unlock checks aren't implemented for Composer (yet)
90
106
  false
91
107
  end
92
108
 
109
+ sig { override.returns(T::Array[Dependabot::Dependency]) }
93
110
  def updated_dependencies_after_full_unlock
94
111
  raise NotImplementedError
95
112
  end
96
113
 
114
+ sig { returns(T.nilable(Dependabot::Composer::Version)) }
97
115
  def latest_version_from_registry
98
116
  latest_version_finder.latest_version
99
117
  end
100
118
 
119
+ sig { returns(Dependabot::Composer::UpdateChecker::LatestVersionFinder) }
101
120
  def latest_version_finder
102
- @latest_version_finder ||= LatestVersionFinder.new(
103
- dependency: dependency,
104
- dependency_files: dependency_files,
105
- credentials: credentials,
106
- ignored_versions: ignored_versions,
107
- raise_on_ignored: raise_on_ignored,
108
- security_advisories: security_advisories
121
+ @latest_version_finder ||= T.let(
122
+ LatestVersionFinder.new(
123
+ dependency: dependency,
124
+ dependency_files: dependency_files,
125
+ credentials: credentials,
126
+ ignored_versions: ignored_versions,
127
+ raise_on_ignored: raise_on_ignored,
128
+ security_advisories: security_advisories
129
+ ),
130
+ T.nilable(Dependabot::Composer::UpdateChecker::LatestVersionFinder)
109
131
  )
110
132
  end
111
133
 
134
+ sig { returns(T.nilable(Dependabot::Composer::Version)) }
112
135
  def fetch_lowest_resolvable_security_fix_version
113
136
  return nil if path_dependency? || git_dependency?
114
137
 
@@ -128,15 +151,18 @@ module Dependabot
128
151
  latest_resolvable_version
129
152
  end
130
153
 
154
+ sig { returns(T::Boolean) }
131
155
  def path_dependency?
132
156
  dependency.requirements.any? { |r| r.dig(:source, :type) == "path" }
133
157
  end
134
158
 
135
159
  # To be a true git dependency, it must have a branch.
160
+ sig { returns(T::Boolean) }
136
161
  def git_dependency?
137
162
  dependency.requirements.any? { |r| r.dig(:source, :branch) }
138
163
  end
139
164
 
165
+ sig { returns(Dependabot::DependencyFile) }
140
166
  def composer_file
141
167
  composer_file =
142
168
  dependency_files.find { |f| f.name == PackageManager::MANIFEST_FILENAME }
@@ -145,10 +171,12 @@ module Dependabot
145
171
  composer_file
146
172
  end
147
173
 
174
+ sig { returns(T::Boolean) }
148
175
  def library?
149
- JSON.parse(composer_file.content)["type"] == "library"
176
+ JSON.parse(T.must(composer_file.content))["type"] == "library"
150
177
  end
151
178
 
179
+ sig { returns(T.nilable(String)) }
152
180
  def latest_version_for_git_dependency
153
181
  # If the dependency isn't pinned then we just want to check that it
154
182
  # points to the latest commit on the relevant branch.
@@ -160,7 +188,7 @@ module Dependabot
160
188
  if git_commit_checker.pinned_ref_looks_like_version? &&
161
189
  git_commit_checker.local_tag_for_latest_version
162
190
  latest_tag = git_commit_checker.local_tag_for_latest_version
163
- return latest_tag.fetch(:commit_sha)
191
+ return latest_tag&.fetch(:commit_sha)
164
192
  end
165
193
 
166
194
  # If the dependency is pinned to a tag that doesn't look like a
@@ -168,12 +196,16 @@ module Dependabot
168
196
  dependency.version
169
197
  end
170
198
 
199
+ sig { returns(Dependabot::GitCommitChecker) }
171
200
  def git_commit_checker
172
- @git_commit_checker ||= Dependabot::GitCommitChecker.new(
173
- dependency: dependency,
174
- credentials: credentials,
175
- ignored_versions: ignored_versions,
176
- raise_on_ignored: raise_on_ignored
201
+ @git_commit_checker ||= T.let(
202
+ Dependabot::GitCommitChecker.new(
203
+ dependency: dependency,
204
+ credentials: credentials,
205
+ ignored_versions: ignored_versions,
206
+ raise_on_ignored: raise_on_ignored
207
+ ),
208
+ T.nilable(Dependabot::GitCommitChecker)
177
209
  )
178
210
  end
179
211
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-composer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.308.0
4
+ version: 0.309.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-12 00:00:00.000000000 Z
10
+ date: 2025-04-17 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: dependabot-common
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.308.0
18
+ version: 0.309.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.308.0
25
+ version: 0.309.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: debug
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -279,7 +279,7 @@ licenses:
279
279
  - MIT
280
280
  metadata:
281
281
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
282
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.308.0
282
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.309.0
283
283
  rdoc_options: []
284
284
  require_paths:
285
285
  - lib