dependabot-common 0.384.0 → 0.386.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 +4 -4
- data/lib/dependabot/command_helpers.rb +9 -9
- data/lib/dependabot/dependency_graphers/base.rb +103 -0
- data/lib/dependabot/errors.rb +5 -5
- data/lib/dependabot/experiments.rb +5 -5
- data/lib/dependabot/file_parsers/base.rb +2 -2
- data/lib/dependabot/file_updaters/base.rb +2 -2
- data/lib/dependabot/git_commit_checker.rb +163 -4
- data/lib/dependabot/package/package_latest_version_finder.rb +3 -3
- data/lib/dependabot/package/package_release.rb +3 -3
- data/lib/dependabot/pull_request_creator/branch_name_template.rb +138 -0
- data/lib/dependabot/pull_request_creator/branch_namer/base.rb +62 -2
- data/lib/dependabot/pull_request_creator/branch_namer/dependency_group_strategy.rb +37 -2
- data/lib/dependabot/pull_request_creator/branch_namer/multi_ecosystem_strategy.rb +32 -2
- data/lib/dependabot/pull_request_creator/branch_namer/solo_strategy.rb +42 -16
- data/lib/dependabot/pull_request_creator/branch_namer.rb +30 -2
- data/lib/dependabot/pull_request_creator/message_builder.rb +7 -7
- data/lib/dependabot/pull_request_creator.rb +29 -8
- data/lib/dependabot/registry_client.rb +4 -4
- data/lib/dependabot/simple_instrumentor.rb +4 -4
- data/lib/dependabot/source.rb +25 -5
- data/lib/dependabot/update_checkers/base.rb +4 -4
- data/lib/dependabot.rb +1 -1
- metadata +3 -2
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
|
|
6
|
+
require "dependabot/errors"
|
|
7
|
+
require "dependabot/pull_request_creator"
|
|
8
|
+
|
|
9
|
+
module Dependabot
|
|
10
|
+
class PullRequestCreator
|
|
11
|
+
class BranchNameTemplate
|
|
12
|
+
extend T::Sig
|
|
13
|
+
|
|
14
|
+
class Error < Dependabot::DependabotError; end
|
|
15
|
+
|
|
16
|
+
SOLO_PLACEHOLDERS = T.let(
|
|
17
|
+
%w(prefix package_manager directory target_branch dependency version name).freeze,
|
|
18
|
+
T::Array[String]
|
|
19
|
+
)
|
|
20
|
+
GROUP_PLACEHOLDERS = T.let(
|
|
21
|
+
%w(prefix package_manager directory target_branch group_name name).freeze,
|
|
22
|
+
T::Array[String]
|
|
23
|
+
)
|
|
24
|
+
MULTI_ECO_PLACEHOLDERS = T.let(
|
|
25
|
+
%w(prefix target_branch group_name name).freeze,
|
|
26
|
+
T::Array[String]
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# ---------------------------------------------------------------
|
|
30
|
+
# 1. validate_template(template, strategy:)
|
|
31
|
+
# Ensures every {token} is allowed for the given strategy,
|
|
32
|
+
# brackets are well-formed, and no forbidden placeholders used.
|
|
33
|
+
# ---------------------------------------------------------------
|
|
34
|
+
sig { params(template: String, strategy: Symbol).returns(T::Boolean) }
|
|
35
|
+
def self.validate_template(template, strategy:) # rubocop:disable Naming/PredicateMethod
|
|
36
|
+
raise Error, "Template must be a non-empty string." if template.empty?
|
|
37
|
+
|
|
38
|
+
allowed = allowed_placeholders(strategy)
|
|
39
|
+
messages = collect_template_errors(template, allowed, strategy)
|
|
40
|
+
|
|
41
|
+
raise Error, "#{messages.join("\n")}\nAllowed: #{allowed.map { |v| "{#{v}}" }.join(', ')}" if messages.any?
|
|
42
|
+
|
|
43
|
+
true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
sig { params(strategy: Symbol).returns(T::Array[String]) }
|
|
47
|
+
def self.allowed_placeholders(strategy)
|
|
48
|
+
case strategy
|
|
49
|
+
when :solo then SOLO_PLACEHOLDERS
|
|
50
|
+
when :group then GROUP_PLACEHOLDERS
|
|
51
|
+
when :multi_ecosystem then MULTI_ECO_PLACEHOLDERS
|
|
52
|
+
else
|
|
53
|
+
raise Error, "Unknown strategy: #{strategy}"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
sig { params(template: String, allowed: T::Array[String], strategy: Symbol).returns(T::Array[String]) }
|
|
58
|
+
def self.collect_template_errors(template, allowed, strategy)
|
|
59
|
+
used = template.scan(/\{(\w+)\}/).flatten
|
|
60
|
+
unknown = used.uniq.reject { |t| allowed.include?(t) }
|
|
61
|
+
unknown -= ["package_manager"] if strategy == :multi_ecosystem && used.include?("package_manager")
|
|
62
|
+
malformed = template.gsub(/\{\w+\}/, "").match?(/[{}]/)
|
|
63
|
+
|
|
64
|
+
messages = T.let([], T::Array[String])
|
|
65
|
+
messages << "Unknown placeholder(s): #{unknown.map { |v| "{#{v}}" }.join(', ')}" unless unknown.empty?
|
|
66
|
+
messages << "Malformed or unclosed braces detected." if malformed
|
|
67
|
+
|
|
68
|
+
if strategy == :multi_ecosystem && used.include?("package_manager")
|
|
69
|
+
messages << "{package_manager} is not available for multi-ecosystem groups (spans multiple ecosystems)."
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
messages
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# ---------------------------------------------------------------
|
|
76
|
+
# 2. validate_ref_name(name)
|
|
77
|
+
# Validates the final branch name against Git ref rules.
|
|
78
|
+
# ---------------------------------------------------------------
|
|
79
|
+
sig { params(name: String).returns(T::Boolean) }
|
|
80
|
+
def self.validate_ref_name(name) # rubocop:disable Naming/PredicateMethod
|
|
81
|
+
illegal = %r{
|
|
82
|
+
[\x00-\x1F\x7F\ ~^:?*\[\\] |
|
|
83
|
+
\.\. |
|
|
84
|
+
@\{ |
|
|
85
|
+
// |
|
|
86
|
+
/\. |
|
|
87
|
+
\A/ |
|
|
88
|
+
/\z |
|
|
89
|
+
\.lock\z |
|
|
90
|
+
\A- |
|
|
91
|
+
\.\z |
|
|
92
|
+
\A@\z
|
|
93
|
+
}x
|
|
94
|
+
|
|
95
|
+
raise Error, "Resolved branch name \"#{name}\" is not a valid Git ref." if name.match?(illegal)
|
|
96
|
+
|
|
97
|
+
true
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# ---------------------------------------------------------------
|
|
101
|
+
# 3. render(template, vars, strategy:, digest: nil)
|
|
102
|
+
# Full pipeline: validate template -> substitute -> append digest
|
|
103
|
+
# -> validate ref.
|
|
104
|
+
# ---------------------------------------------------------------
|
|
105
|
+
sig do
|
|
106
|
+
params(
|
|
107
|
+
template: String,
|
|
108
|
+
vars: T::Hash[String, String],
|
|
109
|
+
strategy: Symbol,
|
|
110
|
+
digest: T.nilable(String)
|
|
111
|
+
).returns(String)
|
|
112
|
+
end
|
|
113
|
+
def self.render(template, vars, strategy:, digest: nil)
|
|
114
|
+
validate_template(template, strategy: strategy)
|
|
115
|
+
|
|
116
|
+
# Substitute placeholders
|
|
117
|
+
name = template.gsub(/\{(\w+)\}/) do
|
|
118
|
+
key = T.must(Regexp.last_match(1))
|
|
119
|
+
raise Error, "Missing value for placeholder \"{#{key}}\"." unless vars.key?(key)
|
|
120
|
+
|
|
121
|
+
T.must(vars[key])
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Auto-append digest for Group/MultiEcosystem
|
|
125
|
+
name = "#{name}-#{digest}" if digest && strategy != :solo
|
|
126
|
+
|
|
127
|
+
# Collapse empty path segments (e.g. {target_branch} when nil) and strip edge slashes
|
|
128
|
+
name = name.squeeze("/").gsub(%r{\A/|/\z}, "")
|
|
129
|
+
raise Error, "Resolved branch name is empty." if name.empty?
|
|
130
|
+
|
|
131
|
+
# Validate git ref after all transformations
|
|
132
|
+
validate_ref_name(name)
|
|
133
|
+
|
|
134
|
+
name
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
require "digest"
|
|
5
5
|
require "sorbet-runtime"
|
|
6
6
|
|
|
7
|
+
require "dependabot/pull_request_creator/branch_name_template"
|
|
8
|
+
|
|
7
9
|
module Dependabot
|
|
8
10
|
class PullRequestCreator
|
|
9
11
|
class BranchNamer
|
|
@@ -28,6 +30,15 @@ module Dependabot
|
|
|
28
30
|
sig { returns(T.nilable(Integer)) }
|
|
29
31
|
attr_reader :max_length
|
|
30
32
|
|
|
33
|
+
sig { returns(T.nilable(String)) }
|
|
34
|
+
attr_reader :word_separator
|
|
35
|
+
|
|
36
|
+
sig { returns(T.nilable(String)) }
|
|
37
|
+
attr_reader :branch_name_case
|
|
38
|
+
|
|
39
|
+
sig { returns(T.nilable(String)) }
|
|
40
|
+
attr_reader :template
|
|
41
|
+
|
|
31
42
|
sig do
|
|
32
43
|
params(
|
|
33
44
|
dependencies: T::Array[Dependency],
|
|
@@ -35,7 +46,10 @@ module Dependabot
|
|
|
35
46
|
target_branch: T.nilable(String),
|
|
36
47
|
separator: String,
|
|
37
48
|
prefix: String,
|
|
38
|
-
max_length: T.nilable(Integer)
|
|
49
|
+
max_length: T.nilable(Integer),
|
|
50
|
+
word_separator: T.nilable(String),
|
|
51
|
+
branch_name_case: T.nilable(String),
|
|
52
|
+
template: T.nilable(String)
|
|
39
53
|
)
|
|
40
54
|
.void
|
|
41
55
|
end
|
|
@@ -45,7 +59,10 @@ module Dependabot
|
|
|
45
59
|
target_branch:,
|
|
46
60
|
separator: "/",
|
|
47
61
|
prefix: "dependabot",
|
|
48
|
-
max_length: nil
|
|
62
|
+
max_length: nil,
|
|
63
|
+
word_separator: nil,
|
|
64
|
+
branch_name_case: nil,
|
|
65
|
+
template: nil
|
|
49
66
|
)
|
|
50
67
|
@dependencies = dependencies
|
|
51
68
|
@files = files
|
|
@@ -53,6 +70,9 @@ module Dependabot
|
|
|
53
70
|
@separator = separator
|
|
54
71
|
@prefix = prefix
|
|
55
72
|
@max_length = max_length
|
|
73
|
+
@word_separator = word_separator
|
|
74
|
+
@branch_name_case = branch_name_case
|
|
75
|
+
@template = template
|
|
56
76
|
end
|
|
57
77
|
|
|
58
78
|
sig { overridable.returns(String) }
|
|
@@ -62,6 +82,25 @@ module Dependabot
|
|
|
62
82
|
|
|
63
83
|
private
|
|
64
84
|
|
|
85
|
+
sig do
|
|
86
|
+
params(
|
|
87
|
+
vars: T::Hash[String, String],
|
|
88
|
+
strategy: Symbol,
|
|
89
|
+
digest: T.nilable(String)
|
|
90
|
+
).returns(String)
|
|
91
|
+
end
|
|
92
|
+
def render_from_template(vars:, strategy:, digest: nil)
|
|
93
|
+
rendered = BranchNameTemplate.render(
|
|
94
|
+
T.must(template),
|
|
95
|
+
vars,
|
|
96
|
+
strategy: strategy,
|
|
97
|
+
digest: digest
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# Apply post-processing (separator, word_separator, case) and max-length
|
|
101
|
+
sanitize_branch_name(rendered)
|
|
102
|
+
end
|
|
103
|
+
|
|
65
104
|
sig { params(ref_name: String).returns(String) }
|
|
66
105
|
def sanitize_branch_name(ref_name)
|
|
67
106
|
# General git ref validation
|
|
@@ -70,6 +109,27 @@ module Dependabot
|
|
|
70
109
|
# Some users need branch names without slashes
|
|
71
110
|
sanitized_name = sanitized_name.gsub("/", separator)
|
|
72
111
|
|
|
112
|
+
# Apply word_separator and case transformation only to content after the prefix,
|
|
113
|
+
# preserving the user-configured prefix as-is.
|
|
114
|
+
if word_separator || branch_name_case
|
|
115
|
+
prefix_with_sep = "#{prefix}#{separator}"
|
|
116
|
+
prefix_part = sanitized_name.start_with?(prefix_with_sep) ? prefix_with_sep : ""
|
|
117
|
+
content = sanitized_name.delete_prefix(prefix_with_sep)
|
|
118
|
+
|
|
119
|
+
# Replace underscores with word_separator in the content after prefix
|
|
120
|
+
content = content.gsub("_", T.must(word_separator)) if word_separator
|
|
121
|
+
|
|
122
|
+
# Apply case transformation to content after prefix
|
|
123
|
+
case branch_name_case
|
|
124
|
+
when "lower"
|
|
125
|
+
content = content.downcase
|
|
126
|
+
when "upper"
|
|
127
|
+
content = content.upcase
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
sanitized_name = "#{prefix_part}#{content}"
|
|
131
|
+
end
|
|
132
|
+
|
|
73
133
|
# Shorten the ref in case users refs have length limits
|
|
74
134
|
branch_name_max_length = max_length
|
|
75
135
|
if branch_name_max_length && (sanitized_name.length > branch_name_max_length)
|
|
@@ -19,7 +19,10 @@ module Dependabot
|
|
|
19
19
|
includes_security_fixes: T::Boolean,
|
|
20
20
|
separator: String,
|
|
21
21
|
prefix: String,
|
|
22
|
-
max_length: T.nilable(Integer)
|
|
22
|
+
max_length: T.nilable(Integer),
|
|
23
|
+
word_separator: T.nilable(String),
|
|
24
|
+
branch_name_case: T.nilable(String),
|
|
25
|
+
template: T.nilable(String)
|
|
23
26
|
)
|
|
24
27
|
.void
|
|
25
28
|
end
|
|
@@ -31,7 +34,10 @@ module Dependabot
|
|
|
31
34
|
includes_security_fixes:,
|
|
32
35
|
separator: "/",
|
|
33
36
|
prefix: "dependabot",
|
|
34
|
-
max_length: nil
|
|
37
|
+
max_length: nil,
|
|
38
|
+
word_separator: nil,
|
|
39
|
+
branch_name_case: nil,
|
|
40
|
+
template: nil
|
|
35
41
|
)
|
|
36
42
|
super(
|
|
37
43
|
dependencies: dependencies,
|
|
@@ -40,6 +46,9 @@ module Dependabot
|
|
|
40
46
|
separator: separator,
|
|
41
47
|
prefix: prefix,
|
|
42
48
|
max_length: max_length,
|
|
49
|
+
word_separator: word_separator,
|
|
50
|
+
branch_name_case: branch_name_case,
|
|
51
|
+
template: template,
|
|
43
52
|
)
|
|
44
53
|
|
|
45
54
|
@dependency_group = dependency_group
|
|
@@ -48,6 +57,14 @@ module Dependabot
|
|
|
48
57
|
|
|
49
58
|
sig { override.returns(String) }
|
|
50
59
|
def new_branch_name
|
|
60
|
+
if template
|
|
61
|
+
return render_from_template(
|
|
62
|
+
vars: template_vars,
|
|
63
|
+
strategy: :group,
|
|
64
|
+
digest: dependency_digest
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
|
|
51
68
|
sanitize_branch_name(File.join(prefixes, group_name_with_dependency_digest))
|
|
52
69
|
end
|
|
53
70
|
|
|
@@ -56,6 +73,24 @@ module Dependabot
|
|
|
56
73
|
sig { returns(Dependabot::DependencyGroup) }
|
|
57
74
|
attr_reader :dependency_group
|
|
58
75
|
|
|
76
|
+
sig { returns(T::Hash[String, String]) }
|
|
77
|
+
def template_vars
|
|
78
|
+
directory_part = (directory || "/").sub(%r{^/}, "")
|
|
79
|
+
directory_part = "root" if directory_part.empty?
|
|
80
|
+
|
|
81
|
+
group_name = sanitize_ref(dependency_group.name.tr(" ", "-"))
|
|
82
|
+
|
|
83
|
+
vars = {
|
|
84
|
+
"prefix" => prefix,
|
|
85
|
+
"package_manager" => package_manager,
|
|
86
|
+
"directory" => directory_part,
|
|
87
|
+
"group_name" => group_name,
|
|
88
|
+
"name" => group_name,
|
|
89
|
+
"target_branch" => target_branch || ""
|
|
90
|
+
}
|
|
91
|
+
vars
|
|
92
|
+
end
|
|
93
|
+
|
|
59
94
|
sig { returns(T::Array[String]) }
|
|
60
95
|
def prefixes
|
|
61
96
|
[
|
|
@@ -19,7 +19,10 @@ module Dependabot
|
|
|
19
19
|
multi_ecosystem_name: String,
|
|
20
20
|
separator: String,
|
|
21
21
|
prefix: String,
|
|
22
|
-
max_length: T.nilable(Integer)
|
|
22
|
+
max_length: T.nilable(Integer),
|
|
23
|
+
word_separator: T.nilable(String),
|
|
24
|
+
branch_name_case: T.nilable(String),
|
|
25
|
+
template: T.nilable(String)
|
|
23
26
|
)
|
|
24
27
|
.void
|
|
25
28
|
end
|
|
@@ -31,7 +34,10 @@ module Dependabot
|
|
|
31
34
|
multi_ecosystem_name:,
|
|
32
35
|
separator: "/",
|
|
33
36
|
prefix: "dependabot",
|
|
34
|
-
max_length: nil
|
|
37
|
+
max_length: nil,
|
|
38
|
+
word_separator: nil,
|
|
39
|
+
branch_name_case: nil,
|
|
40
|
+
template: nil
|
|
35
41
|
)
|
|
36
42
|
super(
|
|
37
43
|
dependencies: dependencies,
|
|
@@ -40,6 +46,9 @@ module Dependabot
|
|
|
40
46
|
separator: separator,
|
|
41
47
|
prefix: prefix,
|
|
42
48
|
max_length: max_length,
|
|
49
|
+
word_separator: word_separator,
|
|
50
|
+
branch_name_case: branch_name_case,
|
|
51
|
+
template: template,
|
|
43
52
|
)
|
|
44
53
|
|
|
45
54
|
@multi_ecosystem_name = multi_ecosystem_name
|
|
@@ -48,6 +57,14 @@ module Dependabot
|
|
|
48
57
|
|
|
49
58
|
sig { override.returns(String) }
|
|
50
59
|
def new_branch_name
|
|
60
|
+
if template
|
|
61
|
+
return render_from_template(
|
|
62
|
+
vars: template_vars,
|
|
63
|
+
strategy: :multi_ecosystem,
|
|
64
|
+
digest: dependency_digest
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
|
|
51
68
|
sanitize_branch_name(File.join(prefixes, group_name_with_dependency_digest))
|
|
52
69
|
end
|
|
53
70
|
|
|
@@ -56,6 +73,19 @@ module Dependabot
|
|
|
56
73
|
sig { returns(String) }
|
|
57
74
|
attr_reader :multi_ecosystem_name
|
|
58
75
|
|
|
76
|
+
sig { returns(T::Hash[String, String]) }
|
|
77
|
+
def template_vars
|
|
78
|
+
multi_name = sanitize_ref(multi_ecosystem_name.tr(" ", "-"))
|
|
79
|
+
|
|
80
|
+
vars = {
|
|
81
|
+
"prefix" => prefix,
|
|
82
|
+
"group_name" => multi_name,
|
|
83
|
+
"name" => multi_name,
|
|
84
|
+
"target_branch" => target_branch || ""
|
|
85
|
+
}
|
|
86
|
+
vars
|
|
87
|
+
end
|
|
88
|
+
|
|
59
89
|
sig { returns(T::Array[String]) }
|
|
60
90
|
def prefixes
|
|
61
91
|
[
|
|
@@ -15,26 +15,18 @@ module Dependabot
|
|
|
15
15
|
|
|
16
16
|
sig { override.returns(String) }
|
|
17
17
|
def new_branch_name
|
|
18
|
+
if template
|
|
19
|
+
return render_from_template(
|
|
20
|
+
vars: template_vars,
|
|
21
|
+
strategy: :solo
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
|
|
18
25
|
return short_branch_name if branch_name_might_be_long?
|
|
19
26
|
|
|
20
27
|
@name ||=
|
|
21
28
|
T.let(
|
|
22
|
-
|
|
23
|
-
dependency_name_part =
|
|
24
|
-
if dependencies.count > 1 && updating_a_property?
|
|
25
|
-
property_name
|
|
26
|
-
elsif dependencies.count > 1 && updating_a_dependency_set?
|
|
27
|
-
dependency_set.fetch(:group)
|
|
28
|
-
else
|
|
29
|
-
dependencies
|
|
30
|
-
.map(&:name)
|
|
31
|
-
.join("-and-")
|
|
32
|
-
.tr(":[]", "-")
|
|
33
|
-
.tr("@", "")
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
"#{dependency_name_part}-#{branch_version_suffix}"
|
|
37
|
-
end,
|
|
29
|
+
"#{template_dependency_name}-#{branch_version_suffix}",
|
|
38
30
|
T.nilable(String)
|
|
39
31
|
)
|
|
40
32
|
|
|
@@ -53,6 +45,40 @@ module Dependabot
|
|
|
53
45
|
].compact
|
|
54
46
|
end
|
|
55
47
|
|
|
48
|
+
sig { returns(T::Hash[String, String]) }
|
|
49
|
+
def template_vars
|
|
50
|
+
dep_name = template_dependency_name
|
|
51
|
+
version = branch_version_suffix || ""
|
|
52
|
+
|
|
53
|
+
vars = {
|
|
54
|
+
"prefix" => prefix,
|
|
55
|
+
"package_manager" => package_manager,
|
|
56
|
+
"directory" => sanitized_directory,
|
|
57
|
+
"dependency" => dep_name,
|
|
58
|
+
"version" => version,
|
|
59
|
+
"name" => "#{dep_name}-#{version}",
|
|
60
|
+
"target_branch" => target_branch || ""
|
|
61
|
+
}
|
|
62
|
+
vars
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
sig { returns(String) }
|
|
66
|
+
def template_dependency_name
|
|
67
|
+
if dependencies.count > 1 && updating_a_property?
|
|
68
|
+
property_name
|
|
69
|
+
elsif dependencies.count > 1 && updating_a_dependency_set?
|
|
70
|
+
dependency_set.fetch(:group)
|
|
71
|
+
else
|
|
72
|
+
dependencies.map(&:name).join("-and-").tr(":[]", "-").tr("@", "")
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
sig { returns(String) }
|
|
77
|
+
def sanitized_directory
|
|
78
|
+
dir = (files.first&.directory&.tr(" ", "-") || "/").sub(%r{^/}, "")
|
|
79
|
+
dir.empty? ? "root" : dir
|
|
80
|
+
end
|
|
81
|
+
|
|
56
82
|
sig { returns(String) }
|
|
57
83
|
def package_manager
|
|
58
84
|
T.must(dependencies.first).package_manager
|
|
@@ -9,6 +9,7 @@ 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
11
|
require "dependabot/pull_request_creator/branch_namer/multi_ecosystem_strategy"
|
|
12
|
+
require "dependabot/pull_request_creator/branch_name_template"
|
|
12
13
|
|
|
13
14
|
module Dependabot
|
|
14
15
|
class PullRequestCreator
|
|
@@ -33,6 +34,15 @@ module Dependabot
|
|
|
33
34
|
sig { returns(T.nilable(Integer)) }
|
|
34
35
|
attr_reader :max_length
|
|
35
36
|
|
|
37
|
+
sig { returns(T.nilable(String)) }
|
|
38
|
+
attr_reader :word_separator
|
|
39
|
+
|
|
40
|
+
sig { returns(T.nilable(String)) }
|
|
41
|
+
attr_reader :branch_name_case
|
|
42
|
+
|
|
43
|
+
sig { returns(T.nilable(String)) }
|
|
44
|
+
attr_reader :template
|
|
45
|
+
|
|
36
46
|
sig { returns(T.nilable(Dependabot::DependencyGroup)) }
|
|
37
47
|
attr_reader :dependency_group
|
|
38
48
|
|
|
@@ -51,6 +61,9 @@ module Dependabot
|
|
|
51
61
|
separator: String,
|
|
52
62
|
prefix: String,
|
|
53
63
|
max_length: T.nilable(Integer),
|
|
64
|
+
word_separator: T.nilable(String),
|
|
65
|
+
branch_name_case: T.nilable(String),
|
|
66
|
+
template: T.nilable(String),
|
|
54
67
|
includes_security_fixes: T::Boolean,
|
|
55
68
|
multi_ecosystem_name: T.nilable(String)
|
|
56
69
|
)
|
|
@@ -64,6 +77,9 @@ module Dependabot
|
|
|
64
77
|
separator: "/",
|
|
65
78
|
prefix: "dependabot",
|
|
66
79
|
max_length: nil,
|
|
80
|
+
word_separator: nil,
|
|
81
|
+
branch_name_case: nil,
|
|
82
|
+
template: nil,
|
|
67
83
|
includes_security_fixes: false,
|
|
68
84
|
multi_ecosystem_name: nil
|
|
69
85
|
)
|
|
@@ -74,6 +90,9 @@ module Dependabot
|
|
|
74
90
|
@separator = separator
|
|
75
91
|
@prefix = prefix
|
|
76
92
|
@max_length = max_length
|
|
93
|
+
@word_separator = word_separator
|
|
94
|
+
@branch_name_case = branch_name_case
|
|
95
|
+
@template = template
|
|
77
96
|
@includes_security_fixes = includes_security_fixes
|
|
78
97
|
@multi_ecosystem_name = multi_ecosystem_name
|
|
79
98
|
end
|
|
@@ -109,6 +128,9 @@ module Dependabot
|
|
|
109
128
|
separator: separator,
|
|
110
129
|
prefix: prefix,
|
|
111
130
|
max_length: max_length,
|
|
131
|
+
word_separator: word_separator,
|
|
132
|
+
branch_name_case: branch_name_case,
|
|
133
|
+
template: template,
|
|
112
134
|
multi_ecosystem_name: T.must(multi_ecosystem_name)
|
|
113
135
|
)
|
|
114
136
|
end
|
|
@@ -121,7 +143,10 @@ module Dependabot
|
|
|
121
143
|
target_branch: target_branch,
|
|
122
144
|
separator: separator,
|
|
123
145
|
prefix: prefix,
|
|
124
|
-
max_length: max_length
|
|
146
|
+
max_length: max_length,
|
|
147
|
+
word_separator: word_separator,
|
|
148
|
+
branch_name_case: branch_name_case,
|
|
149
|
+
template: template
|
|
125
150
|
)
|
|
126
151
|
end
|
|
127
152
|
|
|
@@ -135,7 +160,10 @@ module Dependabot
|
|
|
135
160
|
includes_security_fixes: includes_security_fixes,
|
|
136
161
|
separator: separator,
|
|
137
162
|
prefix: prefix,
|
|
138
|
-
max_length: max_length
|
|
163
|
+
max_length: max_length,
|
|
164
|
+
word_separator: word_separator,
|
|
165
|
+
branch_name_case: branch_name_case,
|
|
166
|
+
template: template
|
|
139
167
|
)
|
|
140
168
|
end
|
|
141
169
|
end
|
|
@@ -45,10 +45,10 @@ module Dependabot
|
|
|
45
45
|
sig { returns(T.nilable(String)) }
|
|
46
46
|
attr_reader :pr_message_footer
|
|
47
47
|
|
|
48
|
-
sig { returns(T.nilable(T::Hash[Symbol, T.
|
|
48
|
+
sig { returns(T.nilable(T::Hash[Symbol, T.anything])) }
|
|
49
49
|
attr_reader :commit_message_options
|
|
50
50
|
|
|
51
|
-
sig { returns(T::Hash[String, T
|
|
51
|
+
sig { returns(T::Hash[String, T::Array[T::Hash[String, String]]]) }
|
|
52
52
|
attr_reader :vulnerabilities_fixed
|
|
53
53
|
|
|
54
54
|
sig { returns(T.nilable(String)) }
|
|
@@ -79,8 +79,8 @@ module Dependabot
|
|
|
79
79
|
credentials: T::Array[Dependabot::Credential],
|
|
80
80
|
pr_message_header: T.nilable(String),
|
|
81
81
|
pr_message_footer: T.nilable(String),
|
|
82
|
-
commit_message_options: T.nilable(T::Hash[Symbol, T.
|
|
83
|
-
vulnerabilities_fixed: T::Hash[String, T
|
|
82
|
+
commit_message_options: T.nilable(T::Hash[Symbol, T.anything]),
|
|
83
|
+
vulnerabilities_fixed: T::Hash[String, T::Array[T::Hash[String, String]]],
|
|
84
84
|
github_redirection_service: T.nilable(String),
|
|
85
85
|
dependency_group: T.nilable(Dependabot::DependencyGroup),
|
|
86
86
|
pr_message_max_length: T.nilable(Integer),
|
|
@@ -379,7 +379,7 @@ module Dependabot
|
|
|
379
379
|
|
|
380
380
|
sig { returns(T.nilable(String)) }
|
|
381
381
|
def custom_trailers
|
|
382
|
-
trailers = commit_message_options&.dig(:trailers)
|
|
382
|
+
trailers = T.cast(commit_message_options&.dig(:trailers), T.nilable(Object))
|
|
383
383
|
return if trailers.nil?
|
|
384
384
|
raise("Commit trailers must be a Hash object") unless trailers.is_a?(Hash)
|
|
385
385
|
|
|
@@ -395,7 +395,7 @@ module Dependabot
|
|
|
395
395
|
|
|
396
396
|
sig { returns(T.nilable(String)) }
|
|
397
397
|
def signoff_message
|
|
398
|
-
signoff_details = commit_message_options&.dig(:signoff_details)
|
|
398
|
+
signoff_details = T.cast(commit_message_options&.dig(:signoff_details), T.nilable(Object))
|
|
399
399
|
return unless signoff_details.is_a?(Hash)
|
|
400
400
|
return unless signoff_details[:name] && signoff_details[:email]
|
|
401
401
|
|
|
@@ -404,7 +404,7 @@ module Dependabot
|
|
|
404
404
|
|
|
405
405
|
sig { returns(T.nilable(String)) }
|
|
406
406
|
def on_behalf_of_message
|
|
407
|
-
signoff_details = commit_message_options&.dig(:signoff_details)
|
|
407
|
+
signoff_details = T.cast(commit_message_options&.dig(:signoff_details), T.nilable(Object))
|
|
408
408
|
return unless signoff_details.is_a?(Hash)
|
|
409
409
|
return unless signoff_details[:org_name] && signoff_details[:org_email]
|
|
410
410
|
|