dependabot-vcpkg 0.330.0 → 0.331.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: 7713306fbe4ea0b15cfa64dd7fc1e907e4752f7b1bec45aacf4225c19aef3aff
4
- data.tar.gz: aaa38b5fd4b6f611f39e712b9e85d57b52f7ee0874af2ba643b68223f42a0bd6
3
+ metadata.gz: de783ea876a57b2c06a733fcfc7a7d77d40620d31e716228011c6c8b2de31198
4
+ data.tar.gz: e0d94dec9bc66e517553e733a3d1217c1f36e2ab28060a9988cfdf4ad30ea21a
5
5
  SHA512:
6
- metadata.gz: 5a4fd0d7a1c07f2500a00a6bb0835620e65848150616730f4614964a3788d9d31c8cc8b623c7a604040309f6f4653b025dbb2b8f9ecb665ac5e3248a8ec2ae4b
7
- data.tar.gz: 4d7fbde51aa2ee19e1df4cac2219419112105bb1c065994a445137c3203a3e812118163843b1b55a3dcb5383ef6611cbe7df4a9bc95d25565b288dbe4cf4d952
6
+ metadata.gz: 07746f666b174819f3282ff4c37d8bc2ee8314979a2a04928324cac306668aeb4e16596b7f0bac79772bdad2d073becc589074f5121835ae1dfdb658256cde94
7
+ data.tar.gz: 9295a5ae0296def79c693358ab21adad0986b214be5ec530b00caa567199aa0711447966c732188ace6394de030f234d69c3187e96c32351cd90e06d9103e3bb
@@ -6,6 +6,7 @@ require "sorbet-runtime"
6
6
  require "dependabot/dependency"
7
7
  require "dependabot/file_parsers"
8
8
  require "dependabot/file_parsers/base"
9
+ require "dependabot/logger"
9
10
 
10
11
  require "dependabot/vcpkg"
11
12
  require "dependabot/vcpkg/language"
@@ -20,12 +21,7 @@ module Dependabot
20
21
 
21
22
  sig { override.returns(T::Array[Dependabot::Dependency]) }
22
23
  def parse
23
- dependency_set = DependencySet.new
24
-
25
- dependency_files.filter_map { |file| parse_dependency_file(file) }
26
- .each { |dependency| dependency_set << dependency }
27
-
28
- dependency_set.dependencies
24
+ dependency_files.flat_map { |file| parse_dependency_file(file) }.compact
29
25
  end
30
26
 
31
27
  sig { override.returns(Ecosystem) }
@@ -49,31 +45,41 @@ module Dependabot
49
45
  raise Dependabot::DependencyFileNotFound, VCPKG_JSON_FILENAME
50
46
  end
51
47
 
52
- sig { params(dependency_file: Dependabot::DependencyFile).returns(T.nilable(Dependabot::Dependency)) }
48
+ sig { params(dependency_file: Dependabot::DependencyFile).returns(T::Array[Dependabot::Dependency]) }
53
49
  def parse_dependency_file(dependency_file)
54
- return unless dependency_file.content
50
+ return [] unless dependency_file.content
55
51
 
56
52
  case dependency_file.name
57
- when VCPKG_JSON_FILENAME then parse_vcpkg_json(dependency_file)
58
- when VCPKG_CONFIGURATION_JSON_FILENAME then nil # TODO
53
+ in VCPKG_JSON_FILENAME then parse_vcpkg_json(dependency_file)
54
+ in VCPKG_CONFIGURATION_JSON_FILENAME then [] # TODO
55
+ else []
59
56
  end
60
57
  end
61
58
 
62
- sig { params(dependency_file: Dependabot::DependencyFile).returns(T.nilable(Dependabot::Dependency)) }
59
+ sig { params(dependency_file: Dependabot::DependencyFile).returns(T::Array[Dependabot::Dependency]) }
63
60
  def parse_vcpkg_json(dependency_file)
64
61
  contents = T.must(dependency_file.content)
65
-
66
62
  parsed_json = JSON.parse(contents)
67
- baseline = parsed_json["builtin-baseline"]
68
- return unless baseline
69
63
 
70
- build_baseline_dependency(baseline: baseline, file: dependency_file)
64
+ dependencies = []
65
+
66
+ parsed_json["builtin-baseline"]&.then do |baseline|
67
+ dependencies << parse_baseline_dependency(baseline:, dependency_file:)
68
+ end
69
+
70
+ parsed_json["dependencies"]&.each do |dep|
71
+ dependency = parse_port_dependency(dep:, dependency_file:)
72
+ dependencies << dependency if dependency
73
+ end
74
+
75
+ dependencies.compact
71
76
  rescue JSON::ParserError
77
+ Dependabot.logger.warn("Failed to parse #{dependency_file.name}: #{dependency_file.content}")
72
78
  raise Dependabot::DependencyFileNotParseable, T.must(dependency_files.first).path
73
79
  end
74
80
 
75
- sig { params(baseline: String, file: Dependabot::DependencyFile).returns(Dependabot::Dependency) }
76
- def build_baseline_dependency(baseline:, file:)
81
+ sig { params(baseline: String, dependency_file: Dependabot::DependencyFile).returns(Dependabot::Dependency) }
82
+ def parse_baseline_dependency(baseline:, dependency_file:)
77
83
  Dependabot::Dependency.new(
78
84
  name: VCPKG_DEFAULT_BASELINE_DEPENDENCY_NAME,
79
85
  version: baseline,
@@ -86,20 +92,69 @@ module Dependabot
86
92
  url: VCPKG_DEFAULT_BASELINE_URL,
87
93
  ref: VCPKG_DEFAULT_BASELINE_DEFAULT_BRANCH
88
94
  },
89
- file: file.name
95
+ file: dependency_file.name
90
96
  }]
91
97
  )
92
98
  end
93
99
 
94
- sig { returns(Ecosystem::VersionManager) }
95
- def package_manager
96
- @package_manager ||= T.let(PackageManager.new, T.nilable(Dependabot::Vcpkg::PackageManager))
100
+ sig do
101
+ params(
102
+ dep: T.untyped,
103
+ dependency_file: Dependabot::DependencyFile
104
+ )
105
+ .returns(T.nilable(Dependabot::Dependency))
106
+ end
107
+ def parse_port_dependency(dep:, dependency_file:)
108
+ case dep
109
+ when String
110
+ # Simple string dependency like "curl" - log and skip
111
+ Dependabot.logger.warn("Skipping vcpkg dependency '#{dep}' without version>= constraint")
112
+ nil
113
+ when Hash
114
+ name = dep["name"]
115
+ version_constraint = dep["version>="]
116
+
117
+ return nil unless name.is_a?(String)
118
+
119
+ unless version_constraint
120
+ Dependabot.logger.warn("Skipping vcpkg dependency '#{name}' without version>= constraint")
121
+ return nil
122
+ end
123
+
124
+ # Parse version and optional port-version
125
+ version, _port_version = parse_version_with_port(version_constraint)
126
+
127
+ Dependabot::Dependency.new(
128
+ name:,
129
+ version:,
130
+ package_manager: "vcpkg",
131
+ requirements: [{
132
+ requirement: ">=#{version_constraint}",
133
+ groups: [],
134
+ source: nil,
135
+ file: dependency_file.name
136
+ }]
137
+ )
138
+ else
139
+ Dependabot.logger.warn("Skipping unknown vcpkg dependency format: #{dep.inspect}")
140
+ nil
141
+ end
97
142
  end
98
143
 
99
- sig { returns(Ecosystem::VersionManager) }
100
- def language
101
- @language ||= T.let(Language.new, T.nilable(Dependabot::Vcpkg::Language))
144
+ sig { params(version_string: String).returns([String, T.nilable(String)]) }
145
+ def parse_version_with_port(version_string)
146
+ if version_string.include?("#")
147
+ version_string.split("#", 2).then { |parts| [parts[0] || "", parts[1]] }
148
+ else
149
+ [version_string, nil]
150
+ end
102
151
  end
152
+
153
+ sig { returns(Ecosystem::VersionManager) }
154
+ def package_manager = @package_manager ||= T.let(PackageManager.new, T.nilable(Dependabot::Vcpkg::PackageManager))
155
+
156
+ sig { returns(Ecosystem::VersionManager) }
157
+ def language = @language ||= T.let(Language.new, T.nilable(Dependabot::Vcpkg::Language))
103
158
  end
104
159
  end
105
160
  end
@@ -23,9 +23,7 @@ module Dependabot
23
23
  sig { override.returns(T::Array[Dependabot::DependencyFile]) }
24
24
  def updated_dependency_files
25
25
  vcpkg_json_file = get_original_file(VCPKG_JSON_FILENAME)
26
- return [] unless vcpkg_json_file
27
-
28
- return [] unless file_changed?(vcpkg_json_file)
26
+ return [] unless vcpkg_json_file&.then { |file| file_changed?(file) }
29
27
 
30
28
  [updated_file(
31
29
  file: vcpkg_json_file,
@@ -45,19 +43,28 @@ module Dependabot
45
43
  sig { params(file: Dependabot::DependencyFile).returns(String) }
46
44
  def updated_vcpkg_json_content(file)
47
45
  content = T.must(file.content)
48
-
49
46
  parsed_content = JSON.parse(content)
50
47
 
51
- # Find the baseline dependency and update it
52
48
  dependencies
53
- .find { |dep| dep.name == VCPKG_DEFAULT_BASELINE_DEPENDENCY_NAME }
54
- &.then { |dep| update_baseline_in_content(parsed_content, dep, file.name) }
49
+ .filter_map { |dep| [dep, dep.requirements.find { |r| r[:file] == file.name }] }
50
+ .select { |_, requirement| requirement }
51
+ .each { |dependency, _| update_dependency_in_content(parsed_content, dependency, file.name) }
55
52
 
56
53
  JSON.pretty_generate(parsed_content)
57
54
  rescue JSON::ParserError
58
55
  raise Dependabot::DependencyFileNotParseable, file.path
59
56
  end
60
57
 
58
+ sig { params(content: T::Hash[String, T.untyped], dependency: Dependabot::Dependency, filename: String).void }
59
+ def update_dependency_in_content(content, dependency, filename)
60
+ case dependency.name
61
+ when VCPKG_DEFAULT_BASELINE_DEPENDENCY_NAME
62
+ update_baseline_in_content(content, dependency, filename)
63
+ else
64
+ update_port_dependency_in_content(content, dependency)
65
+ end
66
+ end
67
+
61
68
  sig { params(content: T::Hash[String, T.untyped], dependency: Dependabot::Dependency, filename: String).void }
62
69
  def update_baseline_in_content(content, dependency, filename)
63
70
  # Find the requirement for this specific file
@@ -72,6 +79,17 @@ module Dependabot
72
79
  # Skip if source doesn't have the expected structure
73
80
  end
74
81
  end
82
+
83
+ sig { params(content: T::Hash[String, T.untyped], dependency: Dependabot::Dependency).void }
84
+ def update_port_dependency_in_content(content, dependency)
85
+ # Update the dependencies array
86
+ dependencies_array = content["dependencies"]
87
+ return unless dependencies_array.is_a?(Array)
88
+
89
+ # Find and update the specific dependency using more functional approach
90
+ target_dep = dependencies_array.find { _1.is_a?(Hash) && _1["name"] == dependency.name }
91
+ target_dep&.[]=("version>=", dependency.version)
92
+ end
75
93
  end
76
94
  end
77
95
  end
@@ -5,10 +5,13 @@ require "sorbet-runtime"
5
5
  require "uri"
6
6
 
7
7
  require "dependabot/git_commit_checker"
8
+ require "dependabot/logger"
8
9
  require "dependabot/package/package_details"
9
10
  require "dependabot/registry_client"
11
+ require "dependabot/shared_helpers"
10
12
  require "dependabot/update_checkers/base"
11
13
 
14
+ require "dependabot/vcpkg"
12
15
  require "dependabot/vcpkg/version"
13
16
 
14
17
  module Dependabot
@@ -31,20 +34,10 @@ module Dependabot
31
34
 
32
35
  sig { returns(T.nilable(Dependabot::Package::PackageDetails)) }
33
36
  def fetch
34
- return unless git_dependency?
35
-
36
- Dependabot::GitCommitChecker.new(
37
- dependency: dependency,
38
- credentials: []
39
- ).local_tags_for_allowed_versions
40
- .map { |tag_info| create_package_release(tag_info) }
41
- .reverse
42
- .uniq(&:version)
43
- .then do |releases|
44
- Dependabot::Package::PackageDetails.new(
45
- dependency: dependency,
46
- releases: releases
47
- )
37
+ if registry_dependency?
38
+ fetch_registry_releases
39
+ else
40
+ fetch_port_releases
48
41
  end
49
42
  rescue Dependabot::GitDependenciesNotReachable
50
43
  # Fallback to empty releases if git repo is not reachable
@@ -57,17 +50,122 @@ module Dependabot
57
50
  private
58
51
 
59
52
  sig { returns(T::Boolean) }
60
- def git_dependency?
53
+ def registry_dependency?
61
54
  dependency.source_details(allowed_types: ["git"]) in { type: "git" }
62
55
  end
63
56
 
57
+ sig { returns(T.nilable(Dependabot::Package::PackageDetails)) }
58
+ def fetch_registry_releases
59
+ Dependabot::GitCommitChecker
60
+ .new(
61
+ dependency: dependency,
62
+ credentials: []
63
+ )
64
+ .local_tags_for_allowed_versions
65
+ .map { |tag_info| create_registry_package_release(tag_info) }
66
+ .reverse
67
+ .uniq(&:version)
68
+ .then do |releases|
69
+ Dependabot::Package::PackageDetails.new(
70
+ dependency: dependency,
71
+ releases: releases
72
+ )
73
+ end
74
+ end
75
+
76
+ sig { returns(T.nilable(Dependabot::Package::PackageDetails)) }
77
+ def fetch_port_releases
78
+ fetch_port_versions_from_git
79
+ .filter_map { |version_info| create_port_package_release(version_info) }
80
+ .reverse
81
+ .uniq(&:version)
82
+ .then do |releases|
83
+ Dependabot::Package::PackageDetails.new(
84
+ dependency: dependency,
85
+ releases: releases
86
+ )
87
+ end
88
+ end
89
+
90
+ sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
91
+ def fetch_port_versions_from_git
92
+ port_path = "ports/#{dependency.name}/vcpkg.json"
93
+ vcpkg_repo_path = "/opt/vcpkg"
94
+
95
+ # Get each commit that modified the port's vcpkg.json
96
+ git_log_cmd = [
97
+ "git", "log", "--format=%H", "--follow", "--", port_path
98
+ ]
99
+
100
+ Dir.chdir(vcpkg_repo_path) do
101
+ log_output = Dependabot::SharedHelpers.run_shell_command(git_log_cmd.join(" "))
102
+
103
+ log_output.lines.map(&:strip).filter_map do |line|
104
+ next if line.empty?
105
+
106
+ commit_sha = line.strip
107
+ next unless commit_sha.match?(/\A[0-9a-f]{40}\z/) # Validate SHA format
108
+
109
+ # Get the vcpkg.json content for this commit
110
+ version_info = extract_version_from_commit(commit_sha, port_path)
111
+ version_info[:commit_sha] = commit_sha if version_info
112
+ version_info
113
+ end
114
+ end
115
+ rescue Dependabot::SharedHelpers::HelperSubprocessFailed => e
116
+ Dependabot.logger.warn("Failed to fetch port versions for #{dependency.name}: #{e.message}")
117
+ []
118
+ end
119
+
120
+ sig { params(commit_sha: String, file_path: String).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
121
+ def extract_version_from_commit(commit_sha, file_path)
122
+ show_cmd = ["git", "show", "#{commit_sha}:#{file_path}"]
123
+
124
+ file_content = Dependabot::SharedHelpers.run_shell_command(show_cmd.join(" "))
125
+ parsed_json = JSON.parse(file_content)
126
+
127
+ version = parsed_json["version"]
128
+ port_version = parsed_json["port-version"] || 0
129
+
130
+ return nil unless version
131
+
132
+ # Combine version and port-version
133
+ full_version = port_version.zero? ? version : "#{version}##{port_version}"
134
+
135
+ {
136
+ version: version,
137
+ port_version: port_version,
138
+ full_version: full_version,
139
+ commit_date: get_commit_date(commit_sha)
140
+ }
141
+ rescue JSON::ParserError => e
142
+ Dependabot.logger.warn("Failed to parse vcpkg.json for commit #{commit_sha}: #{e.message}")
143
+ nil
144
+ rescue Dependabot::SharedHelpers::HelperSubprocessFailed => e
145
+ Dependabot.logger.warn("Failed to show file #{file_path} for commit #{commit_sha}: #{e.message}")
146
+ nil
147
+ end
148
+
149
+ sig { params(commit_sha: String).returns(T.nilable(Time)) }
150
+ def get_commit_date(commit_sha)
151
+ date_cmd = ["git", "show", "--no-patch", "--format=%ci", commit_sha]
152
+ date_output = Dependabot::SharedHelpers.run_shell_command(date_cmd.join(" "))
153
+ Time.parse(date_output.strip)
154
+ rescue Dependabot::SharedHelpers::HelperSubprocessFailed => e
155
+ Dependabot.logger.warn("Failed to get commit date for #{commit_sha}: #{e.message}")
156
+ nil
157
+ rescue ArgumentError => e
158
+ Dependabot.logger.warn("Invalid date format for commit #{commit_sha}: #{e.message}")
159
+ nil
160
+ end
161
+
64
162
  sig { params(tag_info: T::Hash[Symbol, T.untyped]).returns(Dependabot::Package::PackageRelease) }
65
- def create_package_release(tag_info)
163
+ def create_registry_package_release(tag_info)
66
164
  Dependabot::Package::PackageRelease.new(
67
- version: Version.new(tag_info.fetch(:tag)),
165
+ version: Dependabot::Vcpkg::Version.new(tag_info.fetch(:tag)),
68
166
  tag: tag_info.fetch(:tag),
69
167
  url: dependency.source_details&.dig(:url),
70
- released_at: extract_release_date(tag_info.fetch(:tag)),
168
+ released_at: extract_release_date_from_tag(tag_info.fetch(:tag)),
71
169
  details: {
72
170
  "commit_sha" => tag_info.fetch(:commit_sha),
73
171
  "tag_sha" => tag_info.fetch(:tag_sha)
@@ -75,8 +173,23 @@ module Dependabot
75
173
  )
76
174
  end
77
175
 
176
+ sig { params(version_info: T::Hash[Symbol, T.untyped]).returns(Dependabot::Package::PackageRelease) }
177
+ def create_port_package_release(version_info)
178
+ Dependabot::Package::PackageRelease.new(
179
+ version: Dependabot::Vcpkg::Version.new(version_info.fetch(:full_version)),
180
+ tag: version_info.fetch(:full_version),
181
+ url: "#{Vcpkg::VCPKG_DEFAULT_BASELINE_URL}/tree/#{version_info[:commit_sha]}/ports/#{dependency.name}",
182
+ released_at: version_info[:commit_date],
183
+ details: {
184
+ "commit_sha" => version_info[:commit_sha],
185
+ "base_version" => version_info[:version],
186
+ "port_version" => version_info[:port_version]
187
+ }
188
+ )
189
+ end
190
+
78
191
  sig { params(tag_name: String).returns(T.nilable(Time)) }
79
- def extract_release_date(tag_name)
192
+ def extract_release_date_from_tag(tag_name)
80
193
  # Extract date from vcpkg tag format like "2025.06.13"
81
194
  # Use pattern matching for cleaner validation and extraction
82
195
  case tag_name.gsub(/^v?/, "")
@@ -24,17 +24,39 @@ module Dependabot
24
24
  )
25
25
  end
26
26
 
27
- sig { returns(T.nilable(String)) }
28
- def latest_tag
29
- available_versions
30
- &.then { |releases| filter_by_cooldown(releases) }
31
- &.max_by(&:version)
32
- &.details
33
- &.[]("tag_sha")
27
+ sig do
28
+ override
29
+ .params(language_version: T.nilable(T.any(String, Dependabot::Version)))
30
+ .returns(T.nilable(Dependabot::Version))
31
+ end
32
+ def fetch_latest_version(language_version: nil) # rubocop:disable Lint/UnusedMethodArgument
33
+ latest_release_info&.version
34
+ end
35
+
36
+ sig { returns(T.nilable(Dependabot::Package::PackageRelease)) }
37
+ def latest_release_info
38
+ @latest_release_info ||= T.let(
39
+ begin
40
+ releases = available_versions
41
+ return unless releases
42
+
43
+ releases = filter_yanked_versions(releases)
44
+ releases = filter_by_cooldown(releases)
45
+ releases = filter_ignored_versions(releases)
46
+
47
+ releases.max_by(&:version)
48
+ end,
49
+ T.nilable(Dependabot::Package::PackageRelease)
50
+ )
34
51
  end
35
52
 
36
53
  private
37
54
 
55
+ sig { returns(T::Boolean) }
56
+ def registry_dependency?
57
+ dependency.source_details(allowed_types: ["git"]) in { type: "git" }
58
+ end
59
+
38
60
  sig { override.returns(T::Boolean) }
39
61
  def cooldown_enabled? = true
40
62
  end
@@ -1,4 +1,4 @@
1
- # typed: strong
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "sorbet-runtime"
@@ -17,7 +17,7 @@ module Dependabot
17
17
  sig { override.returns(T.nilable(T.any(String, Dependabot::Version))) }
18
18
  def latest_version
19
19
  @latest_version ||= T.let(
20
- latest_version_finder.latest_tag,
20
+ latest_version_finder.latest_version,
21
21
  T.nilable(T.any(String, Dependabot::Version))
22
22
  )
23
23
  end
@@ -36,10 +36,17 @@ module Dependabot
36
36
 
37
37
  dependency.requirements.filter_map do |requirement|
38
38
  source = T.cast(requirement[:source], T.nilable(T::Hash[Symbol, T.untyped]))
39
+ requirement_constraint = requirement[:requirement]
39
40
 
40
- if source
41
- requirement.merge(source: source.merge(ref: latest_version.to_s))
41
+ if source && registry_dependency?
42
+ # For git dependencies (baselines), update the git ref with the commit SHA
43
+ latest_commit_sha = latest_version_finder.latest_release_info&.details&.dig("commit_sha")
44
+ requirement.merge(source: source.merge(ref: latest_commit_sha))
45
+ elsif source.nil? && requirement_constraint
46
+ # For port dependencies (no source but has requirement), update the version constraint
47
+ requirement.merge(requirement: ">=#{latest_version}")
42
48
  else
49
+ # Keep the original requirement unchanged for other cases
43
50
  requirement
44
51
  end
45
52
  end
@@ -47,6 +54,17 @@ module Dependabot
47
54
 
48
55
  private
49
56
 
57
+ sig { returns(T::Boolean) }
58
+ def registry_dependency?
59
+ dependency.source_details(allowed_types: ["git"]) in { type: "git" }
60
+ end
61
+
62
+ sig { returns(T::Boolean) }
63
+ def port_dependency?
64
+ # A port dependency has no git source but has a requirement constraint
65
+ !registry_dependency? && dependency.requirements.any? { |req| req[:requirement] }
66
+ end
67
+
50
68
  # Vcpkg doesn't support full unlocking since dependencies are tracked via baselines
51
69
  sig { override.returns(T::Boolean) }
52
70
  def latest_version_resolvable_with_full_unlock? = false
@@ -9,6 +9,62 @@ require "dependabot/version"
9
9
  module Dependabot
10
10
  module Vcpkg
11
11
  class Version < Dependabot::Version
12
+ extend T::Sig
13
+
14
+ VERSION_PATTERN = /\A([0-9]+(?:\.[0-9]+)*(?:-[0-9A-Za-z\-\.]+)?(?:\+[0-9A-Za-z\-\.]+)?)(?:\#([0-9]+))?\z/
15
+
16
+ sig { override.params(version: VersionParameter).void }
17
+ def initialize(version)
18
+ @version_string = T.let(version.to_s, String)
19
+ parsed_version = parse_version(@version_string)
20
+ super(T.cast(parsed_version[:base_version], String))
21
+ @port_version = T.let(parsed_version[:port_version], T.nilable(Integer))
22
+ end
23
+
24
+ sig { returns(T.nilable(Integer)) }
25
+ attr_reader :port_version
26
+
27
+ sig { override.returns(String) }
28
+ def to_s
29
+ port_version ? "#{super}##{port_version}" : super
30
+ end
31
+
32
+ sig { params(other: Object).returns(T.nilable(Integer)) }
33
+ def <=>(other)
34
+ case other
35
+ when Version
36
+ # Compare with another vcpkg version
37
+ base_comparison = super
38
+ return base_comparison if base_comparison.nil? || !base_comparison.zero?
39
+
40
+ # If base versions are equal, compare port versions
41
+ (port_version || 0) <=> (other.port_version || 0)
42
+ when String
43
+ # Compare with a string by creating a version object from it
44
+ begin
45
+ self <=> self.class.new(other)
46
+ rescue ArgumentError
47
+ # If the string isn't a valid version, try comparing as base version only
48
+ super(Gem::Version.new(other))
49
+ end
50
+ when Gem::Version, Dependabot::Version
51
+ # Compare with a regular Gem::Version by comparing just the base version
52
+ super
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ sig { params(version_string: String).returns(T::Hash[Symbol, T.untyped]) }
59
+ def parse_version(version_string)
60
+ match = version_string.match(VERSION_PATTERN)
61
+ raise ArgumentError, "Malformed version number string #{version_string}" unless match
62
+
63
+ {
64
+ base_version: match[1],
65
+ port_version: match[2]&.to_i
66
+ }
67
+ end
12
68
  end
13
69
  end
14
70
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-vcpkg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.330.0
4
+ version: 0.331.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.330.0
18
+ version: 0.331.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.330.0
25
+ version: 0.331.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: debug
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -256,7 +256,7 @@ licenses:
256
256
  - MIT
257
257
  metadata:
258
258
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
259
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.330.0
259
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.331.0
260
260
  rdoc_options: []
261
261
  require_paths:
262
262
  - lib