豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit f3bd8ca

Browse files
add support for extarcting version from comment
1 parent 5d96f6a commit f3bd8ca

File tree

5 files changed

+355
-18
lines changed

5 files changed

+355
-18
lines changed

.rubocop_todo.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ Metrics/AbcSize:
155155
# Offense count: 354/350
156156
Metrics/ClassLength:
157157
Exclude:
158+
- 'common/lib/dependabot/dependency.rb'
158159
- 'opentofu/lib/dependabot/opentofu/file_parser.rb'
159160

160161
# Offense count: 8

common/lib/dependabot/dependency.rb

Lines changed: 60 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ class Dependency
1414
)
1515
@display_name_builders = T.let({}, T::Hash[String, T.proc.params(arg0: String).returns(String)])
1616
@name_normalisers = T.let({}, T::Hash[String, T.proc.params(arg0: String).returns(String)])
17+
@humanized_previous_version_builders = T.let(
18+
{},
19+
T::Hash[String, T.proc.params(arg0: Dependency).returns(T.nilable(String))]
20+
)
1721

1822
sig do
1923
params(package_manager: String).returns(T.proc.params(arg0: T::Array[T.untyped]).returns(T::Boolean))
@@ -61,6 +65,25 @@ def self.register_name_normaliser(package_manager, name_builder)
6165
@name_normalisers[package_manager] = name_builder
6266
end
6367

68+
sig do
69+
params(
70+
package_manager: String
71+
).returns(T.nilable(T.proc.params(arg0: Dependency).returns(T.nilable(String))))
72+
end
73+
def self.humanized_previous_version_builder_for_package_manager(package_manager)
74+
@humanized_previous_version_builders[package_manager]
75+
end
76+
77+
sig do
78+
params(
79+
package_manager: String,
80+
builder: T.proc.params(arg0: Dependency).returns(T.nilable(String))
81+
).void
82+
end
83+
def self.register_humanized_previous_version_builder(package_manager, builder)
84+
@humanized_previous_version_builders[package_manager] = builder
85+
end
86+
6487
sig { returns(String) }
6588
attr_reader :name
6689

@@ -225,24 +248,10 @@ def display_name
225248

226249
sig { returns(T.nilable(String)) }
227250
def humanized_previous_version
228-
# If we don't have a previous version, we *may* still be able to figure
229-
# one out if a ref was provided and has been changed (in which case the
230-
# previous ref was essentially the version).
231-
if previous_version.nil?
232-
return ref_changed? ? previous_ref : nil
233-
end
234-
235-
if T.must(previous_version).match?(/^[0-9a-f]{40}/)
236-
return previous_ref if ref_changed? && previous_ref
251+
custom_version = custom_humanized_previous_version
252+
return custom_version if custom_version
237253

238-
"`#{T.must(previous_version)[0..6]}`"
239-
elsif version == previous_version &&
240-
package_manager == "docker"
241-
digest = docker_digest_from_reqs(T.must(previous_requirements))
242-
"`#{T.must(T.must(digest).split(':').last)[0..6]}`"
243-
else
244-
previous_version
245-
end
254+
default_humanized_previous_version
246255
end
247256

248257
sig { returns(T.nilable(String)) }
@@ -391,6 +400,40 @@ def requirements_changed?
391400

392401
private
393402

403+
sig { returns(T.nilable(String)) }
404+
def custom_humanized_previous_version
405+
builder = self.class.humanized_previous_version_builder_for_package_manager(package_manager)
406+
return nil unless builder
407+
408+
builder.call(self)
409+
end
410+
411+
sig { returns(T.nilable(String)) }
412+
def default_humanized_previous_version
413+
# If we don't have a previous version, we *may* still be able to figure
414+
# one out if a ref was provided and has been changed (in which case the
415+
# previous ref was essentially the version).
416+
return (ref_changed? ? previous_ref : nil) if previous_version.nil?
417+
418+
return humanized_sha_previous_version if T.must(previous_version).match?(/^[0-9a-f]{40}/)
419+
return humanized_docker_previous_version if version == previous_version && package_manager == "docker"
420+
421+
previous_version
422+
end
423+
424+
sig { returns(T.nilable(String)) }
425+
def humanized_sha_previous_version
426+
return previous_ref if ref_changed? && previous_ref
427+
428+
"`#{T.must(previous_version)[0..6]}`"
429+
end
430+
431+
sig { returns(String) }
432+
def humanized_docker_previous_version
433+
digest = docker_digest_from_reqs(T.must(previous_requirements))
434+
"`#{T.must(T.must(digest).split(':').last)[0..6]}`"
435+
end
436+
394437
sig { void }
395438
def check_values
396439
check_requirement_fields

common/spec/dependabot/dependency_spec.rb

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,4 +392,112 @@
392392
expect(dependency.all_versions).to eq(["1.0.0", "2.0.0"])
393393
end
394394
end
395+
396+
describe "#humanized_previous_version" do
397+
context "with a registered humanized_previous_version_builder" do
398+
before do
399+
described_class.register_humanized_previous_version_builder(
400+
"test_pm",
401+
->(dep) { dep.previous_requirements&.dig(0, :metadata, :comment_version) }
402+
)
403+
end
404+
405+
it "uses the registered builder when it returns a value" do
406+
dependency = described_class.new(
407+
name: "dep",
408+
version: "abc123def456789012345678901234567890abcd",
409+
previous_version: "6f6a02c2c85a1b45e39c1aa5e6cc40f7a3d6df5e",
410+
requirements: [{
411+
file: "config.yaml",
412+
requirement: nil,
413+
groups: [],
414+
source: { type: "git", ref: "abc123def456789012345678901234567890abcd" }
415+
}],
416+
previous_requirements: [{
417+
file: "config.yaml",
418+
requirement: nil,
419+
groups: [],
420+
source: { type: "git", ref: "6f6a02c2c85a1b45e39c1aa5e6cc40f7a3d6df5e" },
421+
metadata: { comment_version: "v2.2.1" }
422+
}],
423+
package_manager: "test_pm"
424+
)
425+
426+
expect(dependency.humanized_previous_version).to eq("v2.2.1")
427+
end
428+
429+
it "falls back to default behavior when builder returns nil" do
430+
dependency = described_class.new(
431+
name: "dep",
432+
version: "abc123def456789012345678901234567890abcd",
433+
previous_version: "6f6a02c2c85a1b45e39c1aa5e6cc40f7a3d6df5e",
434+
requirements: [{
435+
file: "config.yaml",
436+
requirement: nil,
437+
groups: [],
438+
source: { type: "git", ref: "abc123def456789012345678901234567890abcd" }
439+
}],
440+
previous_requirements: [{
441+
file: "config.yaml",
442+
requirement: nil,
443+
groups: [],
444+
source: { type: "git", ref: "6f6a02c2c85a1b45e39c1aa5e6cc40f7a3d6df5e" }
445+
}],
446+
package_manager: "test_pm"
447+
)
448+
449+
# Falls back to previous_ref when ref changed and previous_ref exists
450+
expect(dependency.humanized_previous_version).to eq("6f6a02c2c85a1b45e39c1aa5e6cc40f7a3d6df5e")
451+
end
452+
end
453+
454+
context "without a registered builder" do
455+
it "returns the previous_version when it's not a SHA" do
456+
dependency = described_class.new(
457+
name: "dep",
458+
version: "v2.0.0",
459+
previous_version: "v1.0.0",
460+
requirements: [{
461+
file: "config.yaml",
462+
requirement: nil,
463+
groups: [],
464+
source: nil
465+
}],
466+
previous_requirements: [{
467+
file: "config.yaml",
468+
requirement: nil,
469+
groups: [],
470+
source: nil
471+
}],
472+
package_manager: "no_builder_pm"
473+
)
474+
475+
expect(dependency.humanized_previous_version).to eq("v1.0.0")
476+
end
477+
478+
it "returns previous_ref when previous_version is a SHA and ref changed" do
479+
dependency = described_class.new(
480+
name: "dep",
481+
version: "abc123def456789012345678901234567890abcd",
482+
previous_version: "6f6a02c2c85a1b45e39c1aa5e6cc40f7a3d6df5e",
483+
requirements: [{
484+
file: "config.yaml",
485+
requirement: nil,
486+
groups: [],
487+
source: { type: "git", ref: "abc123def456789012345678901234567890abcd" }
488+
}],
489+
previous_requirements: [{
490+
file: "config.yaml",
491+
requirement: nil,
492+
groups: [],
493+
source: { type: "git", ref: "6f6a02c2c85a1b45e39c1aa5e6cc40f7a3d6df5e" }
494+
}],
495+
package_manager: "no_builder_pm"
496+
)
497+
498+
# Returns previous_ref when ref changed and previous_ref exists
499+
expect(dependency.humanized_previous_version).to eq("6f6a02c2c85a1b45e39c1aa5e6cc40f7a3d6df5e")
500+
end
501+
end
502+
end
395503
end

pre_commit/lib/dependabot/pre_commit.rb

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# typed: strong
1+
# typed: strict
22
# frozen_string_literal: true
33

44
# These all need to be required so the various classes can be registered in a
@@ -11,10 +11,29 @@
1111
require "dependabot/pre_commit/version"
1212
require "dependabot/pre_commit/requirement"
1313
require "dependabot/pre_commit/helpers"
14+
require "dependabot/pre_commit/comment_version_helper"
1415

1516
require "dependabot/pull_request_creator/labeler"
1617
Dependabot::PullRequestCreator::Labeler
1718
.register_label_details("pre_commit", name: "pre_commit", colour: "000000")
1819

1920
require "dependabot/dependency"
2021
Dependabot::Dependency.register_production_check("pre_commit", ->(_) { true })
22+
23+
# Register a humanized previous version builder for pre_commit that extracts
24+
# the version from the comment when using frozen SHA format (e.g., rev: <sha> # v2.2.1)
25+
Dependabot::Dependency.register_humanized_previous_version_builder(
26+
"pre_commit",
27+
lambda { |dep|
28+
previous_reqs = dep.previous_requirements
29+
return nil unless previous_reqs
30+
31+
comment = previous_reqs
32+
.filter_map { |r| r.dig(:metadata, :comment) }
33+
.first
34+
return nil unless comment
35+
36+
match = comment.match(Dependabot::PreCommit::CommentVersionHelper::COMMENT_VERSION_PATTERN)
37+
match&.[](0)
38+
}
39+
)

0 commit comments

Comments
 (0)