dependabot-common 0.236.0 → 0.238.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/dependabot/clients/azure.rb +3 -3
- data/lib/dependabot/clients/codecommit.rb +1 -0
- data/lib/dependabot/config/file.rb +17 -6
- data/lib/dependabot/config/update_config.rb +23 -5
- data/lib/dependabot/dependency.rb +137 -27
- data/lib/dependabot/dependency_file.rb +84 -14
- data/lib/dependabot/dependency_group.rb +29 -5
- data/lib/dependabot/errors.rb +335 -13
- data/lib/dependabot/file_fetchers/base.rb +227 -93
- data/lib/dependabot/file_updaters/base.rb +1 -1
- data/lib/dependabot/git_commit_checker.rb +6 -0
- data/lib/dependabot/git_metadata_fetcher.rb +58 -20
- data/lib/dependabot/git_ref.rb +71 -0
- data/lib/dependabot/metadata_finders/base/changelog_finder.rb +13 -6
- data/lib/dependabot/pull_request_creator/github.rb +11 -8
- data/lib/dependabot/pull_request_creator/message.rb +21 -2
- data/lib/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer.rb +37 -16
- data/lib/dependabot/pull_request_creator/message_builder/metadata_presenter.rb +4 -2
- data/lib/dependabot/pull_request_creator/message_builder.rb +54 -4
- data/lib/dependabot/pull_request_creator/pr_name_prefixer.rb +10 -4
- data/lib/dependabot/shared_helpers.rb +117 -33
- data/lib/dependabot/simple_instrumentor.rb +22 -3
- data/lib/dependabot/source.rb +65 -17
- data/lib/dependabot/update_checkers/version_filters.rb +12 -1
- data/lib/dependabot/utils.rb +21 -2
- data/lib/dependabot/workspace/base.rb +42 -7
- data/lib/dependabot/workspace/change_attempt.rb +31 -3
- data/lib/dependabot/workspace/git.rb +34 -4
- data/lib/dependabot/workspace.rb +16 -2
- data/lib/dependabot.rb +1 -1
- metadata +38 -9
@@ -1,13 +1,47 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strong
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "pathname"
|
5
|
+
require "sorbet-runtime"
|
5
6
|
|
6
7
|
module Dependabot
|
7
8
|
class DependencyFile
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
sig { returns(String) }
|
12
|
+
attr_accessor :name
|
13
|
+
|
14
|
+
sig { returns(T.nilable(String)) }
|
15
|
+
attr_accessor :content
|
16
|
+
|
17
|
+
sig { returns(String) }
|
18
|
+
attr_accessor :directory
|
19
|
+
|
20
|
+
sig { returns(String) }
|
21
|
+
attr_accessor :type
|
22
|
+
|
23
|
+
sig { returns(T::Boolean) }
|
24
|
+
attr_accessor :support_file
|
25
|
+
|
26
|
+
sig { returns(T::Boolean) }
|
27
|
+
attr_accessor :vendored_file
|
28
|
+
|
29
|
+
sig { returns(T.nilable(String)) }
|
30
|
+
attr_accessor :symlink_target
|
31
|
+
|
32
|
+
sig { returns(String) }
|
33
|
+
attr_accessor :content_encoding
|
34
|
+
|
35
|
+
sig { returns(String) }
|
36
|
+
attr_accessor :operation
|
37
|
+
|
38
|
+
sig { returns(T.nilable(String)) }
|
39
|
+
attr_accessor :mode
|
40
|
+
|
41
|
+
# The directory that this file was fetched for. This is useful for multi-directory
|
42
|
+
# updates, where a set of files that are related to each other are updated together.
|
43
|
+
sig { returns(T.nilable(String)) }
|
44
|
+
attr_accessor :job_directory
|
11
45
|
|
12
46
|
class ContentEncoding
|
13
47
|
UTF_8 = "utf-8"
|
@@ -25,18 +59,36 @@ module Dependabot
|
|
25
59
|
SUBMODULE = "160000"
|
26
60
|
end
|
27
61
|
|
62
|
+
sig do
|
63
|
+
params(
|
64
|
+
name: String,
|
65
|
+
content: T.nilable(String),
|
66
|
+
directory: String,
|
67
|
+
type: String,
|
68
|
+
support_file: T::Boolean,
|
69
|
+
vendored_file: T::Boolean,
|
70
|
+
symlink_target: T.nilable(String),
|
71
|
+
content_encoding: String,
|
72
|
+
deleted: T::Boolean,
|
73
|
+
operation: String,
|
74
|
+
mode: T.nilable(String),
|
75
|
+
job_directory: T.nilable(String)
|
76
|
+
)
|
77
|
+
.void
|
78
|
+
end
|
28
79
|
def initialize(name:, content:, directory: "/", type: "file",
|
29
80
|
support_file: false, vendored_file: false, symlink_target: nil,
|
30
81
|
content_encoding: ContentEncoding::UTF_8, deleted: false,
|
31
|
-
operation: Operation::UPDATE, mode: nil)
|
82
|
+
operation: Operation::UPDATE, mode: nil, job_directory: nil)
|
32
83
|
@name = name
|
33
84
|
@content = content
|
34
|
-
@directory = clean_directory(directory)
|
85
|
+
@directory = T.let(clean_directory(directory), String)
|
35
86
|
@symlink_target = symlink_target
|
36
87
|
@support_file = support_file
|
37
88
|
@vendored_file = vendored_file
|
38
89
|
@content_encoding = content_encoding
|
39
90
|
@operation = operation
|
91
|
+
@job_directory = job_directory
|
40
92
|
|
41
93
|
# Make deleted override the operation. Deleted is kept when operation
|
42
94
|
# was introduced to keep compatibility with downstream dependants.
|
@@ -50,7 +102,7 @@ module Dependabot
|
|
50
102
|
@type = type
|
51
103
|
|
52
104
|
begin
|
53
|
-
@mode = File.stat(realpath).mode.to_s(8)
|
105
|
+
@mode = T.let(File.stat(realpath).mode.to_s(8), T.nilable(String))
|
54
106
|
rescue StandardError
|
55
107
|
@mode = mode
|
56
108
|
end
|
@@ -61,6 +113,7 @@ module Dependabot
|
|
61
113
|
raise "Only symlinked files must specify a target!" if symlink_target
|
62
114
|
end
|
63
115
|
|
116
|
+
sig { returns(T::Hash[String, T.untyped]) }
|
64
117
|
def to_h
|
65
118
|
details = {
|
66
119
|
"name" => name,
|
@@ -74,66 +127,83 @@ module Dependabot
|
|
74
127
|
"mode" => mode
|
75
128
|
}
|
76
129
|
|
130
|
+
details["job_directory"] = job_directory if job_directory
|
77
131
|
details["symlink_target"] = symlink_target if symlink_target
|
78
132
|
details
|
79
133
|
end
|
80
134
|
|
135
|
+
sig { returns(String) }
|
81
136
|
def path
|
82
137
|
Pathname.new(File.join(directory, name)).cleanpath.to_path
|
83
138
|
end
|
84
139
|
|
140
|
+
sig { returns(String) }
|
85
141
|
def realpath
|
86
142
|
(symlink_target || path).sub(%r{^/}, "")
|
87
143
|
end
|
88
144
|
|
145
|
+
sig { params(other: BasicObject).returns(T::Boolean) }
|
89
146
|
def ==(other)
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
147
|
+
case other
|
148
|
+
when DependencyFile
|
149
|
+
my_hash = to_h.reject { |k| k == "support_file" }
|
150
|
+
their_hash = other.to_h.reject { |k| k == "support_file" }
|
151
|
+
my_hash == their_hash
|
152
|
+
else
|
153
|
+
false
|
154
|
+
end
|
95
155
|
end
|
96
156
|
|
157
|
+
sig { returns(Integer) }
|
97
158
|
def hash
|
98
159
|
to_h.hash
|
99
160
|
end
|
100
161
|
|
162
|
+
sig { params(other: BasicObject).returns(T::Boolean) }
|
101
163
|
def eql?(other)
|
102
164
|
self == other
|
103
165
|
end
|
104
166
|
|
167
|
+
sig { returns(T::Boolean) }
|
105
168
|
def support_file?
|
106
169
|
@support_file
|
107
170
|
end
|
108
171
|
|
172
|
+
sig { returns(T::Boolean) }
|
109
173
|
def vendored_file?
|
110
174
|
@vendored_file
|
111
175
|
end
|
112
176
|
|
177
|
+
sig { returns(T::Boolean) }
|
113
178
|
def deleted
|
114
179
|
@operation == Operation::DELETE
|
115
180
|
end
|
116
181
|
|
182
|
+
sig { params(deleted: T::Boolean).void }
|
117
183
|
def deleted=(deleted)
|
118
184
|
@operation = deleted ? Operation::DELETE : Operation::UPDATE
|
119
185
|
end
|
120
186
|
|
187
|
+
sig { returns(T::Boolean) }
|
121
188
|
def deleted?
|
122
189
|
deleted
|
123
190
|
end
|
124
191
|
|
192
|
+
sig { returns(T::Boolean) }
|
125
193
|
def binary?
|
126
194
|
content_encoding == ContentEncoding::BASE64
|
127
195
|
end
|
128
196
|
|
197
|
+
sig { returns(String) }
|
129
198
|
def decoded_content
|
130
|
-
return Base64.decode64(content) if binary?
|
199
|
+
return Base64.decode64(T.must(content)) if binary?
|
131
200
|
|
132
|
-
content
|
201
|
+
T.must(content)
|
133
202
|
end
|
134
203
|
|
135
204
|
private
|
136
205
|
|
206
|
+
sig { params(directory: String).returns(String) }
|
137
207
|
def clean_directory(directory)
|
138
208
|
# Directory should always start with a `/`
|
139
209
|
directory.sub(%r{^/*}, "/")
|
@@ -1,23 +1,41 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "dependabot/experiments"
|
5
5
|
require "dependabot/config/ignore_condition"
|
6
6
|
require "dependabot/logger"
|
7
7
|
|
8
|
+
require "sorbet-runtime"
|
8
9
|
require "wildcard_matcher"
|
9
10
|
require "yaml"
|
10
11
|
|
11
12
|
module Dependabot
|
12
13
|
class DependencyGroup
|
13
|
-
|
14
|
+
extend T::Sig
|
14
15
|
|
16
|
+
sig { returns(String) }
|
17
|
+
attr_reader :name
|
18
|
+
|
19
|
+
sig { returns(T::Hash[String, T.any(String, T::Array[String])]) }
|
20
|
+
attr_reader :rules
|
21
|
+
|
22
|
+
sig { returns(T::Array[Dependabot::Dependency]) }
|
23
|
+
attr_reader :dependencies
|
24
|
+
|
25
|
+
sig do
|
26
|
+
params(
|
27
|
+
name: String,
|
28
|
+
rules: T::Hash[String, T.untyped]
|
29
|
+
)
|
30
|
+
.void
|
31
|
+
end
|
15
32
|
def initialize(name:, rules:)
|
16
33
|
@name = name
|
17
34
|
@rules = rules
|
18
|
-
@dependencies = []
|
35
|
+
@dependencies = T.let([], T::Array[Dependabot::Dependency])
|
19
36
|
end
|
20
37
|
|
38
|
+
sig { params(dependency: Dependabot::Dependency).returns(T::Boolean) }
|
21
39
|
def contains?(dependency)
|
22
40
|
return true if @dependencies.include?(dependency)
|
23
41
|
return false if matches_excluded_pattern?(dependency.name)
|
@@ -25,11 +43,13 @@ module Dependabot
|
|
25
43
|
matches_pattern?(dependency.name) && matches_dependency_type?(dependency)
|
26
44
|
end
|
27
45
|
|
46
|
+
sig { returns(T::Hash[String, String]) }
|
28
47
|
def to_h
|
29
48
|
{ "name" => name }
|
30
49
|
end
|
31
50
|
|
32
51
|
# Provides a debug utility to view the group as it appears in the config file.
|
52
|
+
sig { returns(String) }
|
33
53
|
def to_config_yaml
|
34
54
|
{
|
35
55
|
"groups" => { name => rules }
|
@@ -38,18 +58,21 @@ module Dependabot
|
|
38
58
|
|
39
59
|
private
|
40
60
|
|
61
|
+
sig { params(dependency_name: String).returns(T::Boolean) }
|
41
62
|
def matches_pattern?(dependency_name)
|
42
63
|
return true unless rules.key?("patterns") # If no patterns are defined, we pass this check by default
|
43
64
|
|
44
|
-
rules["patterns"].any? { |rule| WildcardMatcher.match?(rule, dependency_name) }
|
65
|
+
T.unsafe(rules["patterns"]).any? { |rule| WildcardMatcher.match?(rule, dependency_name) }
|
45
66
|
end
|
46
67
|
|
68
|
+
sig { params(dependency_name: String).returns(T::Boolean) }
|
47
69
|
def matches_excluded_pattern?(dependency_name)
|
48
70
|
return false unless rules.key?("exclude-patterns") # If there are no exclusions, fail by default
|
49
71
|
|
50
|
-
rules["exclude-patterns"].any? { |rule| WildcardMatcher.match?(rule, dependency_name) }
|
72
|
+
T.unsafe(rules["exclude-patterns"]).any? { |rule| WildcardMatcher.match?(rule, dependency_name) }
|
51
73
|
end
|
52
74
|
|
75
|
+
sig { params(dependency: Dependabot::Dependency).returns(T::Boolean) }
|
53
76
|
def matches_dependency_type?(dependency)
|
54
77
|
return true unless rules.key?("dependency-type") # If no dependency-type is set, match by default
|
55
78
|
|
@@ -60,6 +83,7 @@ module Dependabot
|
|
60
83
|
end
|
61
84
|
end
|
62
85
|
|
86
|
+
sig { returns(T::Boolean) }
|
63
87
|
def experimental_rules_enabled?
|
64
88
|
Dependabot::Experiments.enabled?(:grouped_updates_experimental_rules)
|
65
89
|
end
|