dependabot-devcontainers 0.242.1 → 0.243.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/devcontainers/file_fetcher.rb +18 -4
- data/lib/dependabot/devcontainers/file_parser/feature_dependency_parser.rb +26 -2
- data/lib/dependabot/devcontainers/file_parser.rb +15 -4
- data/lib/dependabot/devcontainers/file_updater/config_updater.rb +47 -2
- data/lib/dependabot/devcontainers/file_updater.rb +29 -8
- data/lib/dependabot/devcontainers/metadata_finder.rb +6 -1
- data/lib/dependabot/devcontainers/requirement.rb +5 -4
- data/lib/dependabot/devcontainers/update_checker.rb +39 -6
- data/lib/dependabot/devcontainers/utils.rb +8 -1
- data/lib/dependabot/devcontainers/version.rb +9 -1
- data/lib/dependabot/devcontainers.rb +0 -3
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d7528b485992d8e78ec3e0569772f6c7514074c1c861a639fe7228089c1d291
|
4
|
+
data.tar.gz: 4ebec7698561a2a2813cb119aedf3527cc06d06690a38c1e5f6940f019cfaa4c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8795cda17d2b9b87ebb02da515390994a42d33e31263f89eabc2d28c52d3a6579af104f516416fe8c15c8051da7481a403f6ca39452870d08421b23806a8ef73
|
7
|
+
data.tar.gz: d3a5f5db65fa19ff0f1f73142c632a93c3916e4e75d631127153c08db40f97eef8342de64af2f8c49d984905d682c7d5ce73270d436fd5b5b4278ab16161fa9f
|
@@ -1,6 +1,7 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
4
5
|
require "dependabot/file_fetchers"
|
5
6
|
require "dependabot/file_fetchers/base"
|
6
7
|
require "dependabot/devcontainers/utils"
|
@@ -8,16 +9,21 @@ require "dependabot/devcontainers/utils"
|
|
8
9
|
module Dependabot
|
9
10
|
module Devcontainers
|
10
11
|
class FileFetcher < Dependabot::FileFetchers::Base
|
12
|
+
extend T::Sig
|
13
|
+
|
14
|
+
sig { override.params(filenames: T::Array[String]).returns(T::Boolean) }
|
11
15
|
def self.required_files_in?(filenames)
|
12
16
|
# There's several other places a devcontainer.json can be checked into
|
13
17
|
# See: https://containers.dev/implementors/spec/#devcontainerjson
|
14
18
|
filenames.any? { |f| f.end_with?("devcontainer.json") }
|
15
19
|
end
|
16
20
|
|
21
|
+
sig { override.returns(String) }
|
17
22
|
def self.required_files_message
|
18
23
|
"Repo must contain a dev container configuration file."
|
19
24
|
end
|
20
25
|
|
26
|
+
sig { override.returns(T::Array[Dependabot::DependencyFile]) }
|
21
27
|
def fetch_files
|
22
28
|
fetched_files = []
|
23
29
|
fetched_files += root_files
|
@@ -34,16 +40,19 @@ module Dependabot
|
|
34
40
|
|
35
41
|
private
|
36
42
|
|
43
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
37
44
|
def root_files
|
38
45
|
fetch_config_and_lockfile_from(".")
|
39
46
|
end
|
40
47
|
|
48
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
41
49
|
def scoped_files
|
42
50
|
return [] unless devcontainer_directory
|
43
51
|
|
44
52
|
fetch_config_and_lockfile_from(".devcontainer")
|
45
53
|
end
|
46
54
|
|
55
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
47
56
|
def custom_directory_files
|
48
57
|
return [] unless devcontainer_directory
|
49
58
|
|
@@ -52,16 +61,21 @@ module Dependabot
|
|
52
61
|
end
|
53
62
|
end
|
54
63
|
|
64
|
+
sig { returns(T::Array[T.untyped]) }
|
55
65
|
def custom_directories
|
56
66
|
repo_contents(dir: ".devcontainer").select { |f| f.type == "dir" && f.name != ".devcontainer" }
|
57
67
|
end
|
58
68
|
|
69
|
+
sig { returns(T.untyped) }
|
59
70
|
def devcontainer_directory
|
60
|
-
|
61
|
-
|
62
|
-
|
71
|
+
@devcontainer_directory ||=
|
72
|
+
T.let(
|
73
|
+
repo_contents.find { |f| f.type == "dir" && f.name == ".devcontainer" },
|
74
|
+
T.untyped
|
75
|
+
)
|
63
76
|
end
|
64
77
|
|
78
|
+
sig { params(directory: String).returns(T::Array[Dependabot::DependencyFile]) }
|
65
79
|
def fetch_config_and_lockfile_from(directory)
|
66
80
|
files = []
|
67
81
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "dependabot/devcontainers/requirement"
|
@@ -6,18 +6,30 @@ require "dependabot/file_parsers/base"
|
|
6
6
|
require "dependabot/shared_helpers"
|
7
7
|
require "dependabot/dependency"
|
8
8
|
require "json"
|
9
|
+
require "sorbet-runtime"
|
9
10
|
require "uri"
|
10
11
|
|
11
12
|
module Dependabot
|
12
13
|
module Devcontainers
|
13
14
|
class FileParser < Dependabot::FileParsers::Base
|
14
15
|
class FeatureDependencyParser
|
16
|
+
extend T::Sig
|
17
|
+
|
18
|
+
sig do
|
19
|
+
params(
|
20
|
+
config_dependency_file: Dependabot::DependencyFile,
|
21
|
+
repo_contents_path: T.nilable(String),
|
22
|
+
credentials: T::Array[Dependabot::Credential]
|
23
|
+
)
|
24
|
+
.void
|
25
|
+
end
|
15
26
|
def initialize(config_dependency_file:, repo_contents_path:, credentials:)
|
16
27
|
@config_dependency_file = config_dependency_file
|
17
28
|
@repo_contents_path = repo_contents_path
|
18
29
|
@credentials = credentials
|
19
30
|
end
|
20
31
|
|
32
|
+
sig { returns(T::Array[Dependabot::Dependency]) }
|
21
33
|
def parse
|
22
34
|
SharedHelpers.in_a_temporary_repo_directory(base_dir, repo_contents_path) do
|
23
35
|
SharedHelpers.with_git_configured(credentials: credentials) do
|
@@ -28,19 +40,23 @@ module Dependabot
|
|
28
40
|
|
29
41
|
private
|
30
42
|
|
43
|
+
sig { returns(String) }
|
31
44
|
def base_dir
|
32
45
|
File.dirname(config_dependency_file.path)
|
33
46
|
end
|
34
47
|
|
48
|
+
sig { returns(String) }
|
35
49
|
def config_name
|
36
50
|
File.basename(config_dependency_file.path)
|
37
51
|
end
|
38
52
|
|
53
|
+
sig { returns(T.nilable(String)) }
|
39
54
|
def config_contents
|
40
55
|
config_dependency_file.content
|
41
56
|
end
|
42
57
|
|
43
58
|
# https://github.com/devcontainers/cli/blob/9444540283b236298c28f397dea879e7ec222ca1/src/spec-node/devContainersSpecCLI.ts#L1072
|
59
|
+
sig { returns(T::Hash[String, T.untyped]) }
|
44
60
|
def evaluate_with_cli
|
45
61
|
raise "config_name must be a string" unless config_name.is_a?(String) && !config_name.empty?
|
46
62
|
|
@@ -55,6 +71,7 @@ module Dependabot
|
|
55
71
|
JSON.parse(json)
|
56
72
|
end
|
57
73
|
|
74
|
+
sig { params(json: T::Hash[String, T.untyped]).returns(T::Array[Dependabot::Dependency]) }
|
58
75
|
def parse_cli_json(json)
|
59
76
|
dependencies = []
|
60
77
|
|
@@ -90,7 +107,14 @@ module Dependabot
|
|
90
107
|
dependencies
|
91
108
|
end
|
92
109
|
|
93
|
-
|
110
|
+
sig { returns(Dependabot::DependencyFile) }
|
111
|
+
attr_reader :config_dependency_file
|
112
|
+
|
113
|
+
sig { returns(T.nilable(String)) }
|
114
|
+
attr_reader :repo_contents_path
|
115
|
+
|
116
|
+
sig { returns(T::Array[Dependabot::Credential]) }
|
117
|
+
attr_reader :credentials
|
94
118
|
end
|
95
119
|
end
|
96
120
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strong
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
4
6
|
require "dependabot/file_parsers"
|
5
7
|
require "dependabot/file_parsers/base"
|
6
8
|
require "dependabot/devcontainers/version"
|
@@ -9,8 +11,11 @@ require "dependabot/devcontainers/file_parser/feature_dependency_parser"
|
|
9
11
|
module Dependabot
|
10
12
|
module Devcontainers
|
11
13
|
class FileParser < Dependabot::FileParsers::Base
|
14
|
+
extend T::Sig
|
15
|
+
|
12
16
|
require "dependabot/file_parsers/base/dependency_set"
|
13
17
|
|
18
|
+
sig { override.returns(T::Array[Dependabot::Dependency]) }
|
14
19
|
def parse
|
15
20
|
dependency_set = DependencySet.new
|
16
21
|
|
@@ -25,12 +30,14 @@ module Dependabot
|
|
25
30
|
|
26
31
|
private
|
27
32
|
|
33
|
+
sig { override.void }
|
28
34
|
def check_required_files
|
29
35
|
return if config_dependency_files.any?
|
30
36
|
|
31
37
|
raise "No dev container configuration!"
|
32
38
|
end
|
33
39
|
|
40
|
+
sig { params(config_dependency_file: Dependabot::DependencyFile).returns(T::Array[Dependabot::Dependency]) }
|
34
41
|
def parse_features(config_dependency_file)
|
35
42
|
FeatureDependencyParser.new(
|
36
43
|
config_dependency_file: config_dependency_file,
|
@@ -39,10 +46,14 @@ module Dependabot
|
|
39
46
|
).parse
|
40
47
|
end
|
41
48
|
|
49
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
42
50
|
def config_dependency_files
|
43
|
-
@config_dependency_files ||=
|
44
|
-
f
|
45
|
-
|
51
|
+
@config_dependency_files ||= T.let(
|
52
|
+
dependency_files.select do |f|
|
53
|
+
f.name.end_with?("devcontainer.json")
|
54
|
+
end,
|
55
|
+
T.nilable(T::Array[Dependabot::DependencyFile])
|
56
|
+
)
|
46
57
|
end
|
47
58
|
end
|
48
59
|
end
|
@@ -1,15 +1,31 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strong
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
4
6
|
require "dependabot/file_updaters/base"
|
5
7
|
require "dependabot/shared_helpers"
|
6
8
|
require "dependabot/logger"
|
7
9
|
require "dependabot/devcontainers/utils"
|
10
|
+
require "dependabot/devcontainers/version"
|
8
11
|
|
9
12
|
module Dependabot
|
10
13
|
module Devcontainers
|
11
14
|
class FileUpdater < Dependabot::FileUpdaters::Base
|
12
15
|
class ConfigUpdater
|
16
|
+
extend T::Sig
|
17
|
+
|
18
|
+
sig do
|
19
|
+
params(
|
20
|
+
feature: String,
|
21
|
+
requirement: T.any(String, Dependabot::Devcontainers::Version),
|
22
|
+
version: String,
|
23
|
+
manifest: Dependabot::DependencyFile,
|
24
|
+
repo_contents_path: String,
|
25
|
+
credentials: T::Array[Dependabot::Credential]
|
26
|
+
)
|
27
|
+
.void
|
28
|
+
end
|
13
29
|
def initialize(feature:, requirement:, version:, manifest:, repo_contents_path:, credentials:)
|
14
30
|
@feature = feature
|
15
31
|
@requirement = requirement
|
@@ -19,6 +35,7 @@ module Dependabot
|
|
19
35
|
@credentials = credentials
|
20
36
|
end
|
21
37
|
|
38
|
+
sig { returns(T::Array[String]) }
|
22
39
|
def update
|
23
40
|
SharedHelpers.in_a_temporary_repo_directory(base_dir, repo_contents_path) do
|
24
41
|
SharedHelpers.with_git_configured(credentials: credentials) do
|
@@ -34,18 +51,28 @@ module Dependabot
|
|
34
51
|
|
35
52
|
private
|
36
53
|
|
54
|
+
sig { returns(String) }
|
37
55
|
def base_dir
|
38
56
|
File.dirname(manifest.path)
|
39
57
|
end
|
40
58
|
|
59
|
+
sig { returns(String) }
|
41
60
|
def manifest_name
|
42
61
|
File.basename(manifest.path)
|
43
62
|
end
|
44
63
|
|
64
|
+
sig { returns(String) }
|
45
65
|
def lockfile_name
|
46
66
|
Utils.expected_lockfile_name(manifest_name)
|
47
67
|
end
|
48
68
|
|
69
|
+
sig do
|
70
|
+
params(
|
71
|
+
target_requirement: T.any(String, Dependabot::Devcontainers::Version),
|
72
|
+
target_version: String
|
73
|
+
)
|
74
|
+
.void
|
75
|
+
end
|
49
76
|
def update_manifests(target_requirement:, target_version:)
|
50
77
|
# First force target version to upgrade lockfile.
|
51
78
|
run_devcontainer_upgrade(target_version)
|
@@ -55,10 +82,12 @@ module Dependabot
|
|
55
82
|
force_target_requirement(lockfile_name, from: target_version, to: target_requirement)
|
56
83
|
end
|
57
84
|
|
85
|
+
sig { params(file_name: String, from: String, to: T.any(String, Dependabot::Devcontainers::Version)).void }
|
58
86
|
def force_target_requirement(file_name, from:, to:)
|
59
87
|
File.write(file_name, File.read(file_name).gsub("#{feature}:#{from}", "#{feature}:#{to}"))
|
60
88
|
end
|
61
89
|
|
90
|
+
sig { params(target_version: String).void }
|
62
91
|
def run_devcontainer_upgrade(target_version)
|
63
92
|
cmd = "devcontainer upgrade " \
|
64
93
|
"--workspace-folder . " \
|
@@ -71,7 +100,23 @@ module Dependabot
|
|
71
100
|
SharedHelpers.run_shell_command(cmd, stderr_to_stdout: false)
|
72
101
|
end
|
73
102
|
|
74
|
-
|
103
|
+
sig { returns(String) }
|
104
|
+
attr_reader :feature
|
105
|
+
|
106
|
+
sig { returns(T.any(String, Dependabot::Devcontainers::Version)) }
|
107
|
+
attr_reader :requirement
|
108
|
+
|
109
|
+
sig { returns(String) }
|
110
|
+
attr_reader :version
|
111
|
+
|
112
|
+
sig { returns(Dependabot::DependencyFile) }
|
113
|
+
attr_reader :manifest
|
114
|
+
|
115
|
+
sig { returns(String) }
|
116
|
+
attr_reader :repo_contents_path
|
117
|
+
|
118
|
+
sig { returns(T::Array[Dependabot::Credential]) }
|
119
|
+
attr_reader :credentials
|
75
120
|
end
|
76
121
|
end
|
77
122
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
4
6
|
require "dependabot/file_updaters"
|
5
7
|
require "dependabot/file_updaters/base"
|
6
8
|
require "dependabot/devcontainers/file_updater/config_updater"
|
@@ -8,6 +10,9 @@ require "dependabot/devcontainers/file_updater/config_updater"
|
|
8
10
|
module Dependabot
|
9
11
|
module Devcontainers
|
10
12
|
class FileUpdater < Dependabot::FileUpdaters::Base
|
13
|
+
extend T::Sig
|
14
|
+
|
15
|
+
sig { override.returns(T::Array[Regexp]) }
|
11
16
|
def self.updated_files_regex
|
12
17
|
[
|
13
18
|
/^\.?devcontainer\.json$/,
|
@@ -15,6 +20,7 @@ module Dependabot
|
|
15
20
|
]
|
16
21
|
end
|
17
22
|
|
23
|
+
sig { override.returns(T::Array[Dependabot::DependencyFile]) }
|
18
24
|
def updated_dependency_files
|
19
25
|
updated_files = []
|
20
26
|
|
@@ -24,7 +30,7 @@ module Dependabot
|
|
24
30
|
|
25
31
|
config_contents, lockfile_contents = update(manifest, requirement)
|
26
32
|
|
27
|
-
updated_files << updated_file(file: manifest, content: config_contents) if file_changed?(manifest)
|
33
|
+
updated_files << updated_file(file: manifest, content: T.must(config_contents)) if file_changed?(manifest)
|
28
34
|
|
29
35
|
lockfile = lockfile_for(manifest)
|
30
36
|
|
@@ -36,23 +42,30 @@ module Dependabot
|
|
36
42
|
|
37
43
|
private
|
38
44
|
|
45
|
+
sig { returns(Dependabot::Dependency) }
|
39
46
|
def dependency
|
40
47
|
# TODO: Handle one dependency at a time
|
41
|
-
dependencies.first
|
48
|
+
T.must(dependencies.first)
|
42
49
|
end
|
43
50
|
|
51
|
+
sig { override.void }
|
44
52
|
def check_required_files
|
45
53
|
return if dependency_files.any?
|
46
54
|
|
47
55
|
raise "No dev container configuration!"
|
48
56
|
end
|
49
57
|
|
58
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
50
59
|
def manifests
|
51
|
-
@manifests ||=
|
52
|
-
f
|
53
|
-
|
60
|
+
@manifests ||= T.let(
|
61
|
+
dependency_files.select do |f|
|
62
|
+
f.name.end_with?("devcontainer.json")
|
63
|
+
end,
|
64
|
+
T.nilable(T::Array[Dependabot::DependencyFile])
|
65
|
+
)
|
54
66
|
end
|
55
67
|
|
68
|
+
sig { params(manifest: Dependabot::DependencyFile).returns(T.nilable(Dependabot::DependencyFile)) }
|
56
69
|
def lockfile_for(manifest)
|
57
70
|
lockfile_name = lockfile_name_for(manifest)
|
58
71
|
|
@@ -61,6 +74,7 @@ module Dependabot
|
|
61
74
|
end
|
62
75
|
end
|
63
76
|
|
77
|
+
sig { params(manifest: Dependabot::DependencyFile).returns(String) }
|
64
78
|
def lockfile_name_for(manifest)
|
65
79
|
basename = File.basename(manifest.name)
|
66
80
|
lockfile_name = Utils.expected_lockfile_name(basename)
|
@@ -68,13 +82,20 @@ module Dependabot
|
|
68
82
|
manifest.name.delete_suffix(basename).concat(lockfile_name)
|
69
83
|
end
|
70
84
|
|
85
|
+
sig do
|
86
|
+
params(
|
87
|
+
manifest: Dependabot::DependencyFile,
|
88
|
+
requirement: T::Hash[Symbol, T.untyped]
|
89
|
+
)
|
90
|
+
.returns(T::Array[String])
|
91
|
+
end
|
71
92
|
def update(manifest, requirement)
|
72
93
|
ConfigUpdater.new(
|
73
94
|
feature: dependency.name,
|
74
95
|
requirement: requirement[:requirement],
|
75
|
-
version: dependency.version,
|
96
|
+
version: T.must(dependency.version),
|
76
97
|
manifest: manifest,
|
77
|
-
repo_contents_path: repo_contents_path,
|
98
|
+
repo_contents_path: T.must(repo_contents_path),
|
78
99
|
credentials: credentials
|
79
100
|
).update
|
80
101
|
end
|
@@ -1,14 +1,19 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strong
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
4
6
|
require "dependabot/metadata_finders"
|
5
7
|
require "dependabot/metadata_finders/base"
|
6
8
|
|
7
9
|
module Dependabot
|
8
10
|
module Devcontainers
|
9
11
|
class MetadataFinder < Dependabot::MetadataFinders::Base
|
12
|
+
extend T::Sig
|
13
|
+
|
10
14
|
private
|
11
15
|
|
16
|
+
sig { override.returns(T.nilable(Dependabot::Source)) }
|
12
17
|
def look_up_source
|
13
18
|
# TODO: Make upstream changes to dev container CLI to point to docs.
|
14
19
|
# Specifically, 'devcontainers features info' can be augmented to expose documentationUrl
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strong
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "sorbet-runtime"
|
@@ -14,17 +14,18 @@ module Dependabot
|
|
14
14
|
# For consistency with other languages, we define a requirements array.
|
15
15
|
# Devcontainers don't have an `OR` separator for requirements, so it
|
16
16
|
# always contains a single element.
|
17
|
-
sig { override.params(requirement_string: T.nilable(String)).returns(T::Array[Requirement]) }
|
17
|
+
sig { override.params(requirement_string: T.nilable(String)).returns(T::Array[Dependabot::Requirement]) }
|
18
18
|
def self.requirements_array(requirement_string)
|
19
19
|
[new(requirement_string)]
|
20
20
|
end
|
21
21
|
|
22
22
|
# Patches Gem::Requirement to make it accept requirement strings like
|
23
23
|
# "~> 4.2.5, >= 4.2.5.1" without first needing to split them.
|
24
|
+
sig { params(requirements: T.nilable(String)).void }
|
24
25
|
def initialize(*requirements)
|
25
26
|
requirements = requirements.flatten.flat_map do |req_string|
|
26
|
-
req_string
|
27
|
-
end
|
27
|
+
req_string&.split(",")&.map(&:strip)
|
28
|
+
end.compact
|
28
29
|
|
29
30
|
super(requirements)
|
30
31
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
4
6
|
require "dependabot/update_checkers"
|
5
7
|
require "dependabot/update_checkers/base"
|
6
8
|
require "dependabot/devcontainers/version"
|
@@ -10,14 +12,19 @@ require "dependabot/devcontainers/requirement"
|
|
10
12
|
module Dependabot
|
11
13
|
module Devcontainers
|
12
14
|
class UpdateChecker < Dependabot::UpdateCheckers::Base
|
15
|
+
extend T::Sig
|
16
|
+
|
17
|
+
sig { returns(T.nilable(Gem::Version)) }
|
13
18
|
def latest_version
|
14
|
-
@latest_version ||= fetch_latest_version
|
19
|
+
@latest_version ||= T.let(fetch_latest_version, T.nilable(Gem::Version))
|
15
20
|
end
|
16
21
|
|
22
|
+
sig { returns(T.nilable(Gem::Version)) }
|
17
23
|
def latest_resolvable_version
|
18
24
|
latest_version # TODO
|
19
25
|
end
|
20
26
|
|
27
|
+
sig { override.returns(T::Array[T::Hash[Symbol, T.untyped]]) }
|
21
28
|
def updated_requirements
|
22
29
|
dependency.requirements.map do |requirement|
|
23
30
|
required_version = version_class.new(requirement[:requirement])
|
@@ -32,41 +39,61 @@ module Dependabot
|
|
32
39
|
end
|
33
40
|
end
|
34
41
|
|
42
|
+
sig { override.returns(T.nilable(Dependabot::Version)) }
|
35
43
|
def latest_resolvable_version_with_no_unlock
|
36
44
|
raise NotImplementedError
|
37
45
|
end
|
38
46
|
|
39
47
|
private
|
40
48
|
|
49
|
+
sig { returns(T::Array[Dependabot::Devcontainers::Version]) }
|
41
50
|
def viable_candidates
|
42
|
-
@viable_candidates ||=
|
51
|
+
@viable_candidates ||= T.let(
|
52
|
+
fetch_viable_candidates,
|
53
|
+
T.nilable(T::Array[Dependabot::Devcontainers::Version])
|
54
|
+
)
|
43
55
|
end
|
44
56
|
|
57
|
+
sig { returns(T::Array[Dependabot::Devcontainers::Version]) }
|
45
58
|
def fetch_viable_candidates
|
46
59
|
candidates = comparable_versions_from_registry
|
47
60
|
candidates = filter_ignored(candidates)
|
48
61
|
candidates.sort
|
49
62
|
end
|
50
63
|
|
64
|
+
sig { returns(Dependabot::Devcontainers::Version) }
|
51
65
|
def fetch_latest_version
|
52
66
|
return current_version unless viable_candidates.any?
|
53
67
|
|
54
|
-
viable_candidates.last
|
68
|
+
T.must(viable_candidates.last)
|
55
69
|
end
|
56
70
|
|
71
|
+
sig do
|
72
|
+
params(
|
73
|
+
versions: T::Array[Dependabot::Devcontainers::Version],
|
74
|
+
required_version: Dependabot::Devcontainers::Version
|
75
|
+
)
|
76
|
+
.returns(T::Array[Dependabot::Devcontainers::Version])
|
77
|
+
end
|
57
78
|
def remove_precision_changes(versions, required_version)
|
58
79
|
versions.select do |version|
|
59
80
|
version.same_precision?(required_version)
|
60
81
|
end
|
61
82
|
end
|
62
83
|
|
84
|
+
sig do
|
85
|
+
params(
|
86
|
+
versions: T::Array[Dependabot::Devcontainers::Version]
|
87
|
+
)
|
88
|
+
.returns(T::Array[Dependabot::Devcontainers::Version])
|
89
|
+
end
|
63
90
|
def filter_ignored(versions)
|
64
91
|
filtered =
|
65
92
|
versions.reject do |version|
|
66
93
|
ignore_requirements.any? { |r| version.satisfies?(r) }
|
67
94
|
end
|
68
95
|
|
69
|
-
if
|
96
|
+
if raise_on_ignored &&
|
70
97
|
filter_lower_versions(filtered).empty? &&
|
71
98
|
filter_lower_versions(versions).any?
|
72
99
|
raise AllVersionsIgnored
|
@@ -75,16 +102,19 @@ module Dependabot
|
|
75
102
|
filtered
|
76
103
|
end
|
77
104
|
|
105
|
+
sig { returns(T::Array[Dependabot::Devcontainers::Version]) }
|
78
106
|
def comparable_versions_from_registry
|
79
107
|
tags_from_registry.filter_map do |tag|
|
80
108
|
version_class.correct?(tag) && version_class.new(tag)
|
81
109
|
end
|
82
110
|
end
|
83
111
|
|
112
|
+
sig { returns(T::Array[String]) }
|
84
113
|
def tags_from_registry
|
85
|
-
@tags_from_registry ||= fetch_tags_from_registry
|
114
|
+
@tags_from_registry ||= T.let(fetch_tags_from_registry, T.nilable(T::Array[String]))
|
86
115
|
end
|
87
116
|
|
117
|
+
sig { returns(T::Array[String]) }
|
88
118
|
def fetch_tags_from_registry
|
89
119
|
cmd = "devcontainer features info tags #{dependency.name} --output-format json"
|
90
120
|
|
@@ -95,16 +125,19 @@ module Dependabot
|
|
95
125
|
JSON.parse(output).fetch("publishedTags")
|
96
126
|
end
|
97
127
|
|
128
|
+
sig { params(versions: T::Array[Gem::Version]).returns(T::Array[Gem::Version]) }
|
98
129
|
def filter_lower_versions(versions)
|
99
130
|
versions.select do |version|
|
100
131
|
version > current_version
|
101
132
|
end
|
102
133
|
end
|
103
134
|
|
135
|
+
sig { override.returns(T::Boolean) }
|
104
136
|
def latest_version_resolvable_with_full_unlock?
|
105
137
|
false # TODO
|
106
138
|
end
|
107
139
|
|
140
|
+
sig { override.returns(T::Array[Dependabot::Dependency]) }
|
108
141
|
def updated_dependencies_after_full_unlock
|
109
142
|
raise NotImplementedError
|
110
143
|
end
|
@@ -1,17 +1,24 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strong
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
4
6
|
module Dependabot
|
5
7
|
module Devcontainers
|
6
8
|
module Utils
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
sig { params(directory: String).returns(String) }
|
7
12
|
def self.expected_config_basename(directory)
|
8
13
|
root_directory?(directory) ? ".devcontainer.json" : "devcontainer.json"
|
9
14
|
end
|
10
15
|
|
16
|
+
sig { params(directory: String).returns(T::Boolean) }
|
11
17
|
def self.root_directory?(directory)
|
12
18
|
Pathname.new(directory).cleanpath.to_path == Pathname.new(".").cleanpath.to_path
|
13
19
|
end
|
14
20
|
|
21
|
+
sig { params(config_file_name: String).returns(String) }
|
15
22
|
def self.expected_lockfile_name(config_file_name)
|
16
23
|
if config_file_name.start_with?(".")
|
17
24
|
".devcontainer-lock.json"
|
@@ -1,20 +1,27 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "sorbet-runtime"
|
5
|
+
|
4
6
|
require "dependabot/version"
|
5
7
|
require "dependabot/utils"
|
6
8
|
|
7
9
|
module Dependabot
|
8
10
|
module Devcontainers
|
9
11
|
class Version < Dependabot::Version
|
12
|
+
extend T::Sig
|
13
|
+
|
14
|
+
sig { params(other: Dependabot::Devcontainers::Version).returns(T::Boolean) }
|
10
15
|
def same_precision?(other)
|
11
16
|
precision == other.precision
|
12
17
|
end
|
13
18
|
|
19
|
+
sig { params(requirement: Dependabot::Requirement).returns(T::Boolean) }
|
14
20
|
def satisfies?(requirement)
|
15
21
|
requirement.satisfied_by?(self)
|
16
22
|
end
|
17
23
|
|
24
|
+
sig { params(other: BasicObject).returns(T.nilable(Integer)) }
|
18
25
|
def <=>(other)
|
19
26
|
if self == other
|
20
27
|
precision <=> other.precision
|
@@ -25,6 +32,7 @@ module Dependabot
|
|
25
32
|
|
26
33
|
protected
|
27
34
|
|
35
|
+
sig { returns(Integer) }
|
28
36
|
def precision
|
29
37
|
segments.size
|
30
38
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dependabot-devcontainers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.243.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dependabot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dependabot-common
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.243.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.243.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: debug
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -243,7 +243,7 @@ licenses:
|
|
243
243
|
- Nonstandard
|
244
244
|
metadata:
|
245
245
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
246
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
246
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.243.0
|
247
247
|
post_install_message:
|
248
248
|
rdoc_options: []
|
249
249
|
require_paths:
|