dependabot-common 0.235.0 → 0.237.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/config/file.rb +32 -9
- data/lib/dependabot/config/file_fetcher.rb +3 -3
- data/lib/dependabot/config/ignore_condition.rb +34 -8
- data/lib/dependabot/config/update_config.rb +42 -6
- data/lib/dependabot/config.rb +1 -1
- data/lib/dependabot/dependency_file.rb +89 -14
- data/lib/dependabot/dependency_group.rb +29 -5
- data/lib/dependabot/errors.rb +101 -13
- data/lib/dependabot/file_fetchers/base.rb +250 -93
- data/lib/dependabot/file_updaters/artifact_updater.rb +37 -10
- data/lib/dependabot/file_updaters/vendor_updater.rb +13 -3
- data/lib/dependabot/logger.rb +7 -2
- data/lib/dependabot/metadata_finders/base/changelog_finder.rb +13 -6
- data/lib/dependabot/pull_request_creator/commit_signer.rb +33 -7
- data/lib/dependabot/pull_request_creator/github.rb +13 -10
- 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 +5 -3
- data/lib/dependabot/pull_request_creator/message_builder.rb +5 -18
- data/lib/dependabot/pull_request_creator/pr_name_prefixer.rb +10 -4
- data/lib/dependabot/pull_request_updater/github.rb +2 -2
- 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 +37 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e29557fff3ec856a4ebcb95a2b53dd70f91b5d7f2ea66cd6230e90dbcbbc2dc0
|
4
|
+
data.tar.gz: f6b2ce2a845422872e58b37681909fb4357bb1ebcac22c1085db113dc2429426
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 367d715ab3cb1b0c2c498555419e2212e9986c8e824128ce56695c00cdc190371fa0b7b9115258146ff0573f2e4a8461e1c66651b9d84bb2fdb7b0fe00b901ff
|
7
|
+
data.tar.gz: 4e5b3e040476f17cb7cf268ccc0cae90f17178da6a5954b14ca2a2ce280cf0f067b1ce8b88ecc8da5c04ae919cc34b670258b1555f9bfb707fb061cc8439acb3
|
@@ -271,9 +271,9 @@ module Dependabot
|
|
271
271
|
)
|
272
272
|
)
|
273
273
|
|
274
|
-
raise InternalServerError if response
|
275
|
-
raise BadGateway if response
|
276
|
-
raise ServiceNotAvailable if response
|
274
|
+
raise InternalServerError if response.status == 500
|
275
|
+
raise BadGateway if response.status == 502
|
276
|
+
raise ServiceNotAvailable if response.status == 503
|
277
277
|
end
|
278
278
|
|
279
279
|
raise Unauthorized if response&.status == 401
|
@@ -1,19 +1,37 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "dependabot/config/update_config"
|
5
|
+
require "sorbet-runtime"
|
5
6
|
|
6
7
|
module Dependabot
|
7
8
|
module Config
|
8
9
|
# Configuration for the repository, a parsed dependabot.yaml.
|
9
10
|
class File
|
10
|
-
|
11
|
+
extend T::Sig
|
11
12
|
|
13
|
+
sig { returns(T::Array[T::Hash[Symbol, String]]) }
|
14
|
+
attr_reader :updates
|
15
|
+
|
16
|
+
sig { returns T::Array[T.untyped] }
|
17
|
+
attr_reader :registries
|
18
|
+
|
19
|
+
sig do
|
20
|
+
params(
|
21
|
+
updates: T.nilable(T::Array[T::Hash[Symbol, String]]),
|
22
|
+
registries: T.nilable(T::Array[T.untyped])
|
23
|
+
)
|
24
|
+
.void
|
25
|
+
end
|
12
26
|
def initialize(updates:, registries: nil)
|
13
|
-
@updates = updates || []
|
14
|
-
@registries = registries || []
|
27
|
+
@updates = T.let(updates || [], T::Array[T::Hash[Symbol, String]])
|
28
|
+
@registries = T.let(registries || [], T::Array[T.untyped])
|
15
29
|
end
|
16
30
|
|
31
|
+
sig do
|
32
|
+
params(package_manager: String, directory: T.nilable(String), target_branch: T.nilable(String))
|
33
|
+
.returns(UpdateConfig)
|
34
|
+
end
|
17
35
|
def update_config(package_manager, directory: nil, target_branch: nil)
|
18
36
|
dir = directory || "/"
|
19
37
|
package_ecosystem = PACKAGE_MANAGER_LOOKUP.invert.fetch(package_manager)
|
@@ -21,13 +39,14 @@ module Dependabot
|
|
21
39
|
u[:"package-ecosystem"] == package_ecosystem && u[:directory] == dir &&
|
22
40
|
(target_branch.nil? || u[:"target-branch"] == target_branch)
|
23
41
|
end
|
24
|
-
|
42
|
+
UpdateConfig.new(
|
25
43
|
ignore_conditions: ignore_conditions(cfg),
|
26
44
|
commit_message_options: commit_message_options(cfg)
|
27
45
|
)
|
28
46
|
end
|
29
47
|
|
30
48
|
# Parse the YAML config file
|
49
|
+
sig { params(config: String).returns(File) }
|
31
50
|
def self.parse(config)
|
32
51
|
parsed = YAML.safe_load(config, symbolize_names: true)
|
33
52
|
version = parsed[:version]
|
@@ -38,7 +57,7 @@ module Dependabot
|
|
38
57
|
|
39
58
|
private
|
40
59
|
|
41
|
-
PACKAGE_MANAGER_LOOKUP = {
|
60
|
+
PACKAGE_MANAGER_LOOKUP = T.let({
|
42
61
|
"bundler" => "bundler",
|
43
62
|
"cargo" => "cargo",
|
44
63
|
"composer" => "composer",
|
@@ -56,12 +75,13 @@ module Dependabot
|
|
56
75
|
"pub" => "pub",
|
57
76
|
"swift" => "swift",
|
58
77
|
"terraform" => "terraform"
|
59
|
-
}.freeze
|
78
|
+
}.freeze, T::Hash[String, String])
|
60
79
|
|
80
|
+
sig { params(cfg: T.nilable(T::Hash[Symbol, T.untyped])).returns(T::Array[IgnoreCondition]) }
|
61
81
|
def ignore_conditions(cfg)
|
62
82
|
ignores = cfg&.dig(:ignore) || []
|
63
83
|
ignores.map do |ic|
|
64
|
-
|
84
|
+
IgnoreCondition.new(
|
65
85
|
dependency_name: ic[:"dependency-name"],
|
66
86
|
versions: ic[:versions],
|
67
87
|
update_types: ic[:"update-types"]
|
@@ -69,9 +89,12 @@ module Dependabot
|
|
69
89
|
end
|
70
90
|
end
|
71
91
|
|
92
|
+
sig do
|
93
|
+
params(cfg: T.nilable(T::Hash[Symbol, T.untyped])).returns(UpdateConfig::CommitMessageOptions)
|
94
|
+
end
|
72
95
|
def commit_message_options(cfg)
|
73
96
|
commit_message = cfg&.dig(:"commit-message") || {}
|
74
|
-
|
97
|
+
UpdateConfig::CommitMessageOptions.new(
|
75
98
|
prefix: commit_message[:prefix],
|
76
99
|
prefix_development: commit_message[:"prefix-development"] || commit_message[:prefix],
|
77
100
|
include: commit_message[:include]
|
@@ -6,7 +6,7 @@ require "dependabot/config/file"
|
|
6
6
|
|
7
7
|
module Dependabot
|
8
8
|
module Config
|
9
|
-
class FileFetcher <
|
9
|
+
class FileFetcher < FileFetchers::Base
|
10
10
|
CONFIG_FILE_PATHS = %w(.github/dependabot.yml .github/dependabot.yaml).freeze
|
11
11
|
|
12
12
|
def self.required_files_in?(filenames)
|
@@ -35,13 +35,13 @@ module Dependabot
|
|
35
35
|
fetched_files << config_file
|
36
36
|
break
|
37
37
|
end
|
38
|
-
rescue
|
38
|
+
rescue DependencyFileNotFound
|
39
39
|
next
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
unless self.class.required_files_in?(fetched_files.map(&:name))
|
44
|
-
raise
|
44
|
+
raise DependencyFileNotFound.new(nil, self.class.required_files_message)
|
45
45
|
end
|
46
46
|
|
47
47
|
fetched_files
|
@@ -1,24 +1,43 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
4
6
|
module Dependabot
|
5
7
|
module Config
|
6
8
|
# Filters versions that should not be considered for dependency updates
|
7
9
|
class IgnoreCondition
|
10
|
+
extend T::Sig
|
11
|
+
|
8
12
|
PATCH_VERSION_TYPE = "version-update:semver-patch"
|
9
13
|
MINOR_VERSION_TYPE = "version-update:semver-minor"
|
10
14
|
MAJOR_VERSION_TYPE = "version-update:semver-major"
|
11
15
|
|
12
16
|
ALL_VERSIONS = ">= 0"
|
13
17
|
|
14
|
-
|
18
|
+
sig { returns(String) }
|
19
|
+
attr_reader :dependency_name
|
20
|
+
|
21
|
+
sig { returns(T::Array[String]) }
|
22
|
+
attr_reader :versions
|
15
23
|
|
24
|
+
sig { returns(T::Array[String]) }
|
25
|
+
attr_reader :update_types
|
26
|
+
|
27
|
+
sig do
|
28
|
+
params(
|
29
|
+
dependency_name: String,
|
30
|
+
versions: T.any(NilClass, T::Array[String]),
|
31
|
+
update_types: T.any(NilClass, T::Array[String])
|
32
|
+
).void
|
33
|
+
end
|
16
34
|
def initialize(dependency_name:, versions: nil, update_types: nil)
|
17
|
-
@dependency_name = dependency_name
|
18
|
-
@versions = versions || []
|
19
|
-
@update_types = update_types || []
|
35
|
+
@dependency_name = T.let(dependency_name, String)
|
36
|
+
@versions = T.let(versions || [], T::Array[String])
|
37
|
+
@update_types = T.let(update_types || [], T::Array[String])
|
20
38
|
end
|
21
39
|
|
40
|
+
sig { params(dependency: Dependency, security_updates_only: T::Boolean).returns(T::Array[String]) }
|
22
41
|
def ignored_versions(dependency, security_updates_only)
|
23
42
|
return versions if security_updates_only
|
24
43
|
return [ALL_VERSIONS] if versions.empty? && transformed_update_types.empty?
|
@@ -28,10 +47,12 @@ module Dependabot
|
|
28
47
|
|
29
48
|
private
|
30
49
|
|
50
|
+
sig { returns(T::Array[String]) }
|
31
51
|
def transformed_update_types
|
32
52
|
update_types.map(&:downcase).filter_map(&:strip)
|
33
53
|
end
|
34
54
|
|
55
|
+
sig { params(dependency: Dependency).returns(T::Array[T.untyped]) }
|
35
56
|
def versions_by_type(dependency)
|
36
57
|
version = correct_version_for(dependency)
|
37
58
|
return [] unless version
|
@@ -52,9 +73,10 @@ module Dependabot
|
|
52
73
|
end.compact
|
53
74
|
end
|
54
75
|
|
76
|
+
sig { params(version: String).returns(T::Array[String]) }
|
55
77
|
def ignore_patch(version)
|
56
78
|
parts = version.split(".")
|
57
|
-
version_parts = parts.fill(0, parts.length...2)
|
79
|
+
version_parts = parts.fill("0", parts.length...2)
|
58
80
|
upper_parts = version_parts.first(1) + [version_parts[1].to_i + 1]
|
59
81
|
lower_bound = "> #{version}"
|
60
82
|
upper_bound = "< #{upper_parts.join('.')}"
|
@@ -62,9 +84,10 @@ module Dependabot
|
|
62
84
|
["#{lower_bound}, #{upper_bound}"]
|
63
85
|
end
|
64
86
|
|
87
|
+
sig { params(version: String).returns(T::Array[String]) }
|
65
88
|
def ignore_minor(version)
|
66
89
|
parts = version.split(".")
|
67
|
-
version_parts = parts.fill(0, parts.length...2)
|
90
|
+
version_parts = parts.fill("0", parts.length...2)
|
68
91
|
lower_parts = version_parts.first(1) + [version_parts[1].to_i + 1] + ["a"]
|
69
92
|
upper_parts = version_parts.first(0) + [version_parts[0].to_i + 1]
|
70
93
|
lower_bound = ">= #{lower_parts.join('.')}"
|
@@ -73,6 +96,7 @@ module Dependabot
|
|
73
96
|
["#{lower_bound}, #{upper_bound}"]
|
74
97
|
end
|
75
98
|
|
99
|
+
sig { params(version: String).returns(T::Array[String]) }
|
76
100
|
def ignore_major(version)
|
77
101
|
version_parts = version.split(".")
|
78
102
|
lower_parts = [version_parts[0].to_i + 1] + ["a"]
|
@@ -81,6 +105,7 @@ module Dependabot
|
|
81
105
|
[lower_bound]
|
82
106
|
end
|
83
107
|
|
108
|
+
sig { params(dependency: Dependency).returns(T.nilable(Version)) }
|
84
109
|
def correct_version_for(dependency)
|
85
110
|
version = dependency.version
|
86
111
|
return if version.nil? || version.empty?
|
@@ -91,10 +116,11 @@ module Dependabot
|
|
91
116
|
version_class.new(version)
|
92
117
|
end
|
93
118
|
|
119
|
+
sig { params(package_manager: String).returns(T.class_of(Version)) }
|
94
120
|
def version_class_for(package_manager)
|
95
121
|
Utils.version_class_for_package_manager(package_manager)
|
96
122
|
rescue StandardError
|
97
|
-
|
123
|
+
Version
|
98
124
|
end
|
99
125
|
end
|
100
126
|
end
|
@@ -1,30 +1,46 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "dependabot/config/ignore_condition"
|
5
|
+
require "sorbet-runtime"
|
5
6
|
|
6
7
|
module Dependabot
|
7
8
|
module Config
|
8
9
|
# Configuration for a single ecosystem
|
9
10
|
class UpdateConfig
|
10
|
-
|
11
|
+
extend T::Sig
|
12
|
+
|
13
|
+
sig { returns(T.nilable(CommitMessageOptions)) }
|
14
|
+
attr_reader :commit_message_options
|
15
|
+
|
16
|
+
sig { returns(T::Array[IgnoreCondition]) }
|
17
|
+
attr_reader :ignore_conditions
|
18
|
+
|
19
|
+
sig do
|
20
|
+
params(
|
21
|
+
ignore_conditions: T.nilable(T::Array[IgnoreCondition]),
|
22
|
+
commit_message_options: T.nilable(CommitMessageOptions)
|
23
|
+
).void
|
24
|
+
end
|
11
25
|
def initialize(ignore_conditions: nil, commit_message_options: nil)
|
12
|
-
@ignore_conditions = ignore_conditions || []
|
26
|
+
@ignore_conditions = T.let(ignore_conditions || [], T::Array[IgnoreCondition])
|
13
27
|
@commit_message_options = commit_message_options
|
14
28
|
end
|
15
29
|
|
30
|
+
sig { params(dependency: Dependency, security_updates_only: T::Boolean).returns(T::Array[String]) }
|
16
31
|
def ignored_versions_for(dependency, security_updates_only: false)
|
17
32
|
normalizer = name_normaliser_for(dependency)
|
18
|
-
dep_name = normalizer.call(dependency.name)
|
33
|
+
dep_name = T.must(normalizer).call(dependency.name)
|
19
34
|
|
20
35
|
@ignore_conditions
|
21
|
-
.select { |ic| self.class.wildcard_match?(normalizer.call(ic.dependency_name), dep_name) }
|
36
|
+
.select { |ic| self.class.wildcard_match?(T.must(normalizer).call(ic.dependency_name), dep_name) }
|
22
37
|
.map { |ic| ic.ignored_versions(dependency, security_updates_only) }
|
23
38
|
.flatten
|
24
39
|
.compact
|
25
40
|
.uniq
|
26
41
|
end
|
27
42
|
|
43
|
+
sig { params(wildcard_string: T.nilable(String), candidate_string: T.nilable(String)).returns(T::Boolean) }
|
28
44
|
def self.wildcard_match?(wildcard_string, candidate_string)
|
29
45
|
return false unless wildcard_string && candidate_string
|
30
46
|
|
@@ -37,24 +53,44 @@ module Dependabot
|
|
37
53
|
|
38
54
|
private
|
39
55
|
|
56
|
+
sig { params(dep: Dependency).returns(T.nilable(T.proc.params(arg0: String).returns(String))) }
|
40
57
|
def name_normaliser_for(dep)
|
41
58
|
name_normaliser ||= {}
|
42
59
|
name_normaliser[dep] ||= Dependency.name_normaliser_for_package_manager(dep.package_manager)
|
43
60
|
end
|
44
61
|
|
45
62
|
class CommitMessageOptions
|
46
|
-
|
63
|
+
extend T::Sig
|
47
64
|
|
65
|
+
sig { returns(T.nilable(String)) }
|
66
|
+
attr_reader :prefix
|
67
|
+
|
68
|
+
sig { returns(T.nilable(String)) }
|
69
|
+
attr_reader :prefix_development
|
70
|
+
|
71
|
+
sig { returns(T.nilable(String)) }
|
72
|
+
attr_reader :include
|
73
|
+
|
74
|
+
sig do
|
75
|
+
params(
|
76
|
+
prefix: T.nilable(String),
|
77
|
+
prefix_development: T.nilable(String),
|
78
|
+
include: T.nilable(String)
|
79
|
+
)
|
80
|
+
.void
|
81
|
+
end
|
48
82
|
def initialize(prefix:, prefix_development:, include:)
|
49
83
|
@prefix = prefix
|
50
84
|
@prefix_development = prefix_development
|
51
85
|
@include = include
|
52
86
|
end
|
53
87
|
|
88
|
+
sig { returns(T::Boolean) }
|
54
89
|
def include_scope?
|
55
90
|
@include == "scope"
|
56
91
|
end
|
57
92
|
|
93
|
+
sig { returns(T::Hash[Symbol, String]) }
|
58
94
|
def to_h
|
59
95
|
{
|
60
96
|
prefix: @prefix,
|
data/lib/dependabot/config.rb
CHANGED
@@ -1,13 +1,47 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
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"
|
@@ -20,18 +54,41 @@ module Dependabot
|
|
20
54
|
DELETE = "delete"
|
21
55
|
end
|
22
56
|
|
57
|
+
class Mode
|
58
|
+
FILE = "100644"
|
59
|
+
SUBMODULE = "160000"
|
60
|
+
end
|
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
|
23
79
|
def initialize(name:, content:, directory: "/", type: "file",
|
24
80
|
support_file: false, vendored_file: false, symlink_target: nil,
|
25
81
|
content_encoding: ContentEncoding::UTF_8, deleted: false,
|
26
|
-
operation: Operation::UPDATE, mode: nil)
|
82
|
+
operation: Operation::UPDATE, mode: nil, job_directory: nil)
|
27
83
|
@name = name
|
28
84
|
@content = content
|
29
|
-
@directory = clean_directory(directory)
|
85
|
+
@directory = T.let(clean_directory(directory), String)
|
30
86
|
@symlink_target = symlink_target
|
31
87
|
@support_file = support_file
|
32
88
|
@vendored_file = vendored_file
|
33
89
|
@content_encoding = content_encoding
|
34
90
|
@operation = operation
|
91
|
+
@job_directory = job_directory
|
35
92
|
|
36
93
|
# Make deleted override the operation. Deleted is kept when operation
|
37
94
|
# was introduced to keep compatibility with downstream dependants.
|
@@ -45,7 +102,7 @@ module Dependabot
|
|
45
102
|
@type = type
|
46
103
|
|
47
104
|
begin
|
48
|
-
@mode = File.stat(realpath).mode.to_s(8)
|
105
|
+
@mode = T.let(File.stat(realpath).mode.to_s(8), T.nilable(String))
|
49
106
|
rescue StandardError
|
50
107
|
@mode = mode
|
51
108
|
end
|
@@ -56,6 +113,7 @@ module Dependabot
|
|
56
113
|
raise "Only symlinked files must specify a target!" if symlink_target
|
57
114
|
end
|
58
115
|
|
116
|
+
sig { returns(T::Hash[String, T.untyped]) }
|
59
117
|
def to_h
|
60
118
|
details = {
|
61
119
|
"name" => name,
|
@@ -69,66 +127,83 @@ module Dependabot
|
|
69
127
|
"mode" => mode
|
70
128
|
}
|
71
129
|
|
130
|
+
details["job_directory"] = job_directory if job_directory
|
72
131
|
details["symlink_target"] = symlink_target if symlink_target
|
73
132
|
details
|
74
133
|
end
|
75
134
|
|
135
|
+
sig { returns(String) }
|
76
136
|
def path
|
77
137
|
Pathname.new(File.join(directory, name)).cleanpath.to_path
|
78
138
|
end
|
79
139
|
|
140
|
+
sig { returns(String) }
|
80
141
|
def realpath
|
81
142
|
(symlink_target || path).sub(%r{^/}, "")
|
82
143
|
end
|
83
144
|
|
145
|
+
sig { params(other: BasicObject).returns(T::Boolean) }
|
84
146
|
def ==(other)
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
90
155
|
end
|
91
156
|
|
157
|
+
sig { returns(Integer) }
|
92
158
|
def hash
|
93
159
|
to_h.hash
|
94
160
|
end
|
95
161
|
|
162
|
+
sig { params(other: BasicObject).returns(T::Boolean) }
|
96
163
|
def eql?(other)
|
97
164
|
self == other
|
98
165
|
end
|
99
166
|
|
167
|
+
sig { returns(T::Boolean) }
|
100
168
|
def support_file?
|
101
169
|
@support_file
|
102
170
|
end
|
103
171
|
|
172
|
+
sig { returns(T::Boolean) }
|
104
173
|
def vendored_file?
|
105
174
|
@vendored_file
|
106
175
|
end
|
107
176
|
|
177
|
+
sig { returns(T::Boolean) }
|
108
178
|
def deleted
|
109
179
|
@operation == Operation::DELETE
|
110
180
|
end
|
111
181
|
|
182
|
+
sig { params(deleted: T::Boolean).void }
|
112
183
|
def deleted=(deleted)
|
113
184
|
@operation = deleted ? Operation::DELETE : Operation::UPDATE
|
114
185
|
end
|
115
186
|
|
187
|
+
sig { returns(T::Boolean) }
|
116
188
|
def deleted?
|
117
189
|
deleted
|
118
190
|
end
|
119
191
|
|
192
|
+
sig { returns(T::Boolean) }
|
120
193
|
def binary?
|
121
194
|
content_encoding == ContentEncoding::BASE64
|
122
195
|
end
|
123
196
|
|
197
|
+
sig { returns(String) }
|
124
198
|
def decoded_content
|
125
|
-
return Base64.decode64(content) if binary?
|
199
|
+
return Base64.decode64(T.must(content)) if binary?
|
126
200
|
|
127
|
-
content
|
201
|
+
T.must(content)
|
128
202
|
end
|
129
203
|
|
130
204
|
private
|
131
205
|
|
206
|
+
sig { params(directory: String).returns(String) }
|
132
207
|
def clean_directory(directory)
|
133
208
|
# Directory should always start with a `/`
|
134
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
|