kuber_kit 0.1.5 → 0.2.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/Gemfile.lock +4 -2
- data/README.md +16 -3
- data/TODO.md +5 -4
- data/example/app_data/env_file.yml +10 -0
- data/example/configurations/review.rb +2 -1
- data/example/images/app_sources/Dockerfile +1 -1
- data/example/images/ruby_app/image.rb +4 -4
- data/example/infrastructure/build_servers.rb +8 -0
- data/example/infrastructure/templates.rb +5 -0
- data/example/services/env_file.rb +6 -0
- data/kuber_kit.gemspec +1 -0
- data/lib/kuber_kit.rb +51 -23
- data/lib/kuber_kit/actions/configuration_loader.rb +11 -2
- data/lib/kuber_kit/actions/env_file_reader.rb +8 -5
- data/lib/kuber_kit/actions/image_compiler.rb +18 -22
- data/lib/kuber_kit/actions/kubectl_applier.rb +6 -1
- data/lib/kuber_kit/actions/kubectl_attacher.rb +19 -0
- data/lib/kuber_kit/actions/service_deployer.rb +13 -3
- data/lib/kuber_kit/actions/service_reader.rb +9 -6
- data/lib/kuber_kit/actions/template_reader.rb +5 -0
- data/lib/kuber_kit/cli.rb +51 -20
- data/lib/kuber_kit/configs.rb +24 -22
- data/lib/kuber_kit/container.rb +43 -19
- data/lib/kuber_kit/core/artifacts/artifact_store.rb +12 -23
- data/lib/kuber_kit/core/build_servers/abstract_build_server.rb +21 -0
- data/lib/kuber_kit/core/build_servers/build_server.rb +24 -0
- data/lib/kuber_kit/core/build_servers/build_server_store.rb +18 -0
- data/lib/kuber_kit/core/configuration.rb +14 -4
- data/lib/kuber_kit/core/configuration_definition.rb +22 -1
- data/lib/kuber_kit/core/configuration_factory.rb +11 -1
- data/lib/kuber_kit/core/configuration_store.rb +14 -24
- data/lib/kuber_kit/core/context_helper/base_helper.rb +12 -7
- data/lib/kuber_kit/core/context_helper/context_helper_factory.rb +11 -8
- data/lib/kuber_kit/core/context_helper/service_helper.rb +7 -6
- data/lib/kuber_kit/core/env_files/env_file_store.rb +8 -23
- data/lib/kuber_kit/core/image_store.rb +8 -18
- data/lib/kuber_kit/core/registries/registry_store.rb +8 -23
- data/lib/kuber_kit/core/service.rb +6 -2
- data/lib/kuber_kit/core/service_factory.rb +4 -1
- data/lib/kuber_kit/core/service_store.rb +13 -23
- data/lib/kuber_kit/core/store.rb +48 -0
- data/lib/kuber_kit/core/templates/template_store.rb +12 -23
- data/lib/kuber_kit/env_file_reader/action_handler.rb +12 -0
- data/lib/kuber_kit/env_file_reader/reader.rb +4 -4
- data/lib/kuber_kit/env_file_reader/{abstract_env_file_reader.rb → strategies/abstract.rb} +1 -1
- data/lib/kuber_kit/env_file_reader/{artifact_file_reader.rb → strategies/artifact_file.rb} +1 -1
- data/lib/kuber_kit/image_compiler/action_handler.rb +21 -0
- data/lib/kuber_kit/image_compiler/build_server_pool.rb +30 -0
- data/lib/kuber_kit/image_compiler/build_server_pool_factory.rb +13 -0
- data/lib/kuber_kit/image_compiler/compiler.rb +2 -5
- data/lib/kuber_kit/image_compiler/image_build_dir_creator.rb +13 -7
- data/lib/kuber_kit/image_compiler/image_dependency_resolver.rb +25 -5
- data/lib/kuber_kit/preprocessing/file_preprocessor.rb +5 -4
- data/lib/kuber_kit/preprocessing/text_preprocessor.rb +1 -1
- data/lib/kuber_kit/service_deployer/action_handler.rb +16 -0
- data/lib/kuber_kit/service_deployer/deployer.rb +28 -6
- data/lib/kuber_kit/service_deployer/strategies/abstract.rb +1 -1
- data/lib/kuber_kit/service_deployer/strategies/kubernetes.rb +9 -4
- data/lib/kuber_kit/service_deployer/strategy_detector.rb +6 -0
- data/lib/kuber_kit/service_reader/action_handler.rb +13 -0
- data/lib/kuber_kit/{service_deployer/service_reader.rb → service_reader/reader.rb} +1 -1
- data/lib/kuber_kit/shell/abstract_shell.rb +4 -0
- data/lib/kuber_kit/shell/{bash_commands.rb → commands/bash_commands.rb} +1 -1
- data/lib/kuber_kit/shell/{docker_commands.rb → commands/docker_commands.rb} +1 -1
- data/lib/kuber_kit/shell/{git_commands.rb → commands/git_commands.rb} +1 -1
- data/lib/kuber_kit/shell/{kubectl_commands.rb → commands/kubectl_commands.rb} +25 -1
- data/lib/kuber_kit/shell/commands/rsync_commands.rb +32 -0
- data/lib/kuber_kit/shell/local_shell.rb +24 -5
- data/lib/kuber_kit/shell/ssh_session.rb +60 -0
- data/lib/kuber_kit/shell/ssh_shell.rb +77 -0
- data/lib/kuber_kit/tools/file_presence_checker.rb +6 -2
- data/lib/kuber_kit/ui/interactive.rb +8 -0
- data/lib/kuber_kit/ui/simple.rb +6 -0
- data/lib/kuber_kit/version.rb +2 -2
- metadata +41 -13
- data/lib/kuber_kit/preprocessing/dir_preprocessor.rb +0 -19
- data/lib/kuber_kit/service_deployer/service_restarter.rb +0 -37
- data/lib/kuber_kit/shell/rsync_commands.rb +0 -20
- data/lib/kuber_kit/tools/files_sync.rb +0 -10
@@ -1,19 +1,6 @@
|
|
1
1
|
class KuberKit::Core::Registries::RegistryStore
|
2
|
-
NotFoundError = Class.new(KuberKit::NotFoundError)
|
3
|
-
AlreadyAddedError = Class.new(KuberKit::Error)
|
4
|
-
|
5
2
|
def add(registry)
|
6
|
-
|
7
|
-
|
8
|
-
if !registry.is_a?(KuberKit::Core::Registries::AbstractRegistry)
|
9
|
-
raise ArgumentError.new("should be an instance of KuberKit::Core::Registries::AbstractRegistry, got: #{registry.inspect}")
|
10
|
-
end
|
11
|
-
|
12
|
-
unless @@registries[registry.name].nil?
|
13
|
-
raise AlreadyAddedError, "registry #{registry.name} was already added"
|
14
|
-
end
|
15
|
-
|
16
|
-
@@registries[registry.name] = registry
|
3
|
+
store.add(registry.name, registry)
|
17
4
|
end
|
18
5
|
|
19
6
|
def get(registry_name)
|
@@ -24,14 +11,7 @@ class KuberKit::Core::Registries::RegistryStore
|
|
24
11
|
end
|
25
12
|
|
26
13
|
def get_global(registry_name)
|
27
|
-
|
28
|
-
registry = @@registries[registry_name]
|
29
|
-
|
30
|
-
if registry.nil?
|
31
|
-
raise NotFoundError, "registry '#{registry_name}' not found"
|
32
|
-
end
|
33
|
-
|
34
|
-
registry
|
14
|
+
store.get(registry_name)
|
35
15
|
end
|
36
16
|
|
37
17
|
def get_from_configuration(registry_name)
|
@@ -44,6 +24,11 @@ class KuberKit::Core::Registries::RegistryStore
|
|
44
24
|
end
|
45
25
|
|
46
26
|
def reset!
|
47
|
-
|
27
|
+
store.reset!
|
48
28
|
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def store
|
32
|
+
@@store ||= KuberKit::Core::Store.new(KuberKit::Core::Registries::AbstractRegistry)
|
33
|
+
end
|
49
34
|
end
|
@@ -22,11 +22,15 @@ class KuberKit::Core::Service
|
|
22
22
|
name.to_s.gsub("_", "-")
|
23
23
|
end
|
24
24
|
|
25
|
-
def attribute(attribute_name)
|
26
|
-
|
25
|
+
def attribute(attribute_name, default: nil)
|
26
|
+
if !attributes.has_key?(attribute_name.to_sym) && default.nil?
|
27
27
|
raise AttributeNotSet, "attribute #{attribute_name} was not set"
|
28
28
|
end
|
29
29
|
|
30
|
+
if !attributes.has_key?(attribute_name.to_sym) && !default.nil?
|
31
|
+
return default
|
32
|
+
end
|
33
|
+
|
30
34
|
attributes[attribute_name.to_sym]
|
31
35
|
end
|
32
36
|
end
|
@@ -8,12 +8,15 @@ class KuberKit::Core::ServiceFactory
|
|
8
8
|
raise AttributeNotSetError, "Please set template for service using #template method"
|
9
9
|
end
|
10
10
|
|
11
|
+
configuration_attributes = KuberKit.current_configuration.service_attributes(service_attrs.name)
|
12
|
+
attributes = (service_attrs.attributes || {}).merge(configuration_attributes)
|
13
|
+
|
11
14
|
KuberKit::Core::Service.new(
|
12
15
|
name: service_attrs.name,
|
13
16
|
template_name: service_attrs.template_name,
|
14
17
|
tags: service_attrs.tags,
|
15
18
|
images: service_attrs.images,
|
16
|
-
attributes:
|
19
|
+
attributes: attributes
|
17
20
|
)
|
18
21
|
end
|
19
22
|
end
|
@@ -1,7 +1,4 @@
|
|
1
1
|
class KuberKit::Core::ServiceStore
|
2
|
-
NotFoundError = Class.new(KuberKit::Error)
|
3
|
-
AlreadyAddedError = Class.new(KuberKit::Error)
|
4
|
-
|
5
2
|
include KuberKit::Import[
|
6
3
|
"core.service_factory",
|
7
4
|
"core.service_definition_factory",
|
@@ -16,24 +13,12 @@ class KuberKit::Core::ServiceStore
|
|
16
13
|
end
|
17
14
|
|
18
15
|
def add_definition(service_definition)
|
19
|
-
|
20
|
-
|
21
|
-
unless @@service_definitions[service_definition.service_name].nil?
|
22
|
-
raise AlreadyAddedError, "service #{service_definition.service_name} was already added"
|
23
|
-
end
|
24
|
-
|
25
|
-
@@service_definitions[service_definition.service_name] = service_definition
|
16
|
+
definitions_store.add(service_definition.service_name, service_definition)
|
26
17
|
end
|
27
18
|
|
28
19
|
Contract Symbol => Any
|
29
20
|
def get_definition(service_name)
|
30
|
-
|
31
|
-
|
32
|
-
if @@service_definitions[service_name].nil?
|
33
|
-
raise NotFoundError, "service '#{service_name}' not found"
|
34
|
-
end
|
35
|
-
|
36
|
-
@@service_definitions[service_name]
|
21
|
+
definitions_store.get(service_name)
|
37
22
|
end
|
38
23
|
|
39
24
|
Contract Symbol => Any
|
@@ -57,18 +42,23 @@ class KuberKit::Core::ServiceStore
|
|
57
42
|
end
|
58
43
|
|
59
44
|
def reset!
|
60
|
-
|
45
|
+
definitions_store.reset!
|
61
46
|
end
|
62
47
|
|
63
|
-
def
|
64
|
-
|
48
|
+
def count
|
49
|
+
definitions_store.size
|
65
50
|
end
|
66
51
|
|
67
|
-
def
|
68
|
-
|
52
|
+
def all_definitions
|
53
|
+
definitions_store.items
|
69
54
|
end
|
70
55
|
|
71
56
|
def exists?(service_name)
|
72
|
-
|
57
|
+
definitions_store.exists?(service_name)
|
73
58
|
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def definitions_store
|
62
|
+
@@definitions_store ||= KuberKit::Core::Store.new(KuberKit::Core::ServiceDefinition)
|
63
|
+
end
|
74
64
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class KuberKit::Core::Store
|
2
|
+
NotFoundError = Class.new(KuberKit::NotFoundError)
|
3
|
+
AlreadyAddedError = Class.new(KuberKit::Error)
|
4
|
+
|
5
|
+
attr_reader :object_class_name
|
6
|
+
|
7
|
+
def initialize(object_class_name)
|
8
|
+
@object_class_name = object_class_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def add(item_name, item)
|
12
|
+
unless item.is_a?(object_class_name)
|
13
|
+
raise ArgumentError.new("#{self.object_class_name}: should be an instance of #{object_class_name}, got: #{item.inspect}")
|
14
|
+
end
|
15
|
+
|
16
|
+
unless items[item_name].nil?
|
17
|
+
raise AlreadyAddedError, "#{self.object_class_name}: item with name #{item_name} was already added"
|
18
|
+
end
|
19
|
+
|
20
|
+
items[item_name] = item
|
21
|
+
end
|
22
|
+
|
23
|
+
def get(item_name)
|
24
|
+
item = items[item_name]
|
25
|
+
|
26
|
+
if item.nil?
|
27
|
+
raise NotFoundError, "#{self.object_class_name}: item '#{item_name}' not found"
|
28
|
+
end
|
29
|
+
|
30
|
+
item
|
31
|
+
end
|
32
|
+
|
33
|
+
def items
|
34
|
+
@items ||= {}
|
35
|
+
end
|
36
|
+
|
37
|
+
def reset!
|
38
|
+
@items = {}
|
39
|
+
end
|
40
|
+
|
41
|
+
def size
|
42
|
+
items.count
|
43
|
+
end
|
44
|
+
|
45
|
+
def exists?(name)
|
46
|
+
!items[name].nil?
|
47
|
+
end
|
48
|
+
end
|
@@ -1,19 +1,6 @@
|
|
1
1
|
class KuberKit::Core::Templates::TemplateStore
|
2
|
-
NotFoundError = Class.new(KuberKit::NotFoundError)
|
3
|
-
AlreadyAddedError = Class.new(KuberKit::Error)
|
4
|
-
|
5
2
|
def add(template)
|
6
|
-
|
7
|
-
|
8
|
-
if !template.is_a?(KuberKit::Core::Templates::AbstractTemplate)
|
9
|
-
raise ArgumentError.new("should be an instance of KuberKit::Core::Templates::AbstractTemplate, got: #{template.inspect}")
|
10
|
-
end
|
11
|
-
|
12
|
-
unless @@templates[template.name].nil?
|
13
|
-
raise AlreadyAddedError, "template #{template.name} was already added"
|
14
|
-
end
|
15
|
-
|
16
|
-
@@templates[template.name] = template
|
3
|
+
store.add(template.name, template)
|
17
4
|
end
|
18
5
|
|
19
6
|
def get(template_name)
|
@@ -24,14 +11,7 @@ class KuberKit::Core::Templates::TemplateStore
|
|
24
11
|
end
|
25
12
|
|
26
13
|
def get_global(template_name)
|
27
|
-
|
28
|
-
template = @@templates[template_name]
|
29
|
-
|
30
|
-
if template.nil?
|
31
|
-
raise NotFoundError, "template '#{template_name}' not found"
|
32
|
-
end
|
33
|
-
|
34
|
-
template
|
14
|
+
store.get(template_name)
|
35
15
|
end
|
36
16
|
|
37
17
|
def get_from_configuration(template_name)
|
@@ -40,6 +20,15 @@ class KuberKit::Core::Templates::TemplateStore
|
|
40
20
|
end
|
41
21
|
|
42
22
|
def reset!
|
43
|
-
|
23
|
+
store.reset!
|
24
|
+
end
|
25
|
+
|
26
|
+
def exists?(template_name)
|
27
|
+
store.exists?(template_name)
|
44
28
|
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def store
|
32
|
+
@@store ||= KuberKit::Core::Store.new(KuberKit::Core::Templates::AbstractTemplate)
|
33
|
+
end
|
45
34
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class KuberKit::EnvFileReader::ActionHandler
|
2
|
+
include KuberKit::Import[
|
3
|
+
"env_file_reader.reader",
|
4
|
+
"core.env_file_store",
|
5
|
+
]
|
6
|
+
|
7
|
+
Contract KuberKit::Shell::AbstractShell, Symbol => Any
|
8
|
+
def call(shell, env_file_name)
|
9
|
+
env_file = env_file_store.get(env_file_name)
|
10
|
+
reader.read(shell, env_file)
|
11
|
+
end
|
12
|
+
end
|
@@ -2,14 +2,14 @@ class KuberKit::EnvFileReader::Reader
|
|
2
2
|
ReaderNotFoundError = Class.new(KuberKit::NotFoundError)
|
3
3
|
|
4
4
|
include KuberKit::Import[
|
5
|
-
"env_file_reader.
|
5
|
+
"env_file_reader.strategies.artifact_file",
|
6
6
|
]
|
7
7
|
|
8
8
|
def use_reader(env_file_reader, env_file_class:)
|
9
9
|
@@readers ||= {}
|
10
10
|
|
11
|
-
if !env_file_reader.is_a?(KuberKit::EnvFileReader::
|
12
|
-
raise ArgumentError.new("should be an instance of KuberKit::EnvFileReader::
|
11
|
+
if !env_file_reader.is_a?(KuberKit::EnvFileReader::Strategies::Abstract)
|
12
|
+
raise ArgumentError.new("should be an instance of KuberKit::EnvFileReader::Strategies::Abstract, got: #{env_file_reader.inspect}")
|
13
13
|
end
|
14
14
|
|
15
15
|
@@readers[env_file_class] = env_file_reader
|
@@ -26,7 +26,7 @@ class KuberKit::EnvFileReader::Reader
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def add_default_readers
|
29
|
-
use_reader(
|
29
|
+
use_reader(artifact_file, env_file_class: KuberKit::Core::EnvFiles::ArtifactFile)
|
30
30
|
end
|
31
31
|
|
32
32
|
def reset!
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class KuberKit::ImageCompiler::ActionHandler
|
2
|
+
include KuberKit::Import[
|
3
|
+
"image_compiler.compiler",
|
4
|
+
"core.image_store",
|
5
|
+
"configs",
|
6
|
+
]
|
7
|
+
|
8
|
+
Contract KuberKit::Shell::AbstractShell, Symbol, String => Any
|
9
|
+
def call(shell, image_name, build_id)
|
10
|
+
image = image_store.get_image(image_name)
|
11
|
+
|
12
|
+
compile_dir = generate_compile_dir(build_id: build_id)
|
13
|
+
|
14
|
+
compiler.compile(shell, image, compile_dir)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def generate_compile_dir(build_id:)
|
19
|
+
File.join(configs.image_compile_dir, build_id)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class KuberKit::ImageCompiler::BuildServerPool
|
2
|
+
attr_reader :ssh_shells, :local_shell
|
3
|
+
|
4
|
+
def initialize(local_shell:, build_servers:, ssh_shell_class:)
|
5
|
+
@local_shell = local_shell
|
6
|
+
@ssh_shell_class = ssh_shell_class
|
7
|
+
@ssh_shells = connect_to_ssh_shells(build_servers)
|
8
|
+
end
|
9
|
+
|
10
|
+
def get_shell
|
11
|
+
if @ssh_shells.any?
|
12
|
+
@ssh_shells.sample
|
13
|
+
else
|
14
|
+
@local_shell
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def disconnect_all
|
19
|
+
@ssh_shells.each(&:disconnect)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
def connect_to_ssh_shells(build_servers)
|
24
|
+
build_servers.map do |bs|
|
25
|
+
shell = @ssh_shell_class.new
|
26
|
+
shell.connect(host: bs.host, user: bs.user, port: bs.port)
|
27
|
+
shell
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class KuberKit::ImageCompiler::BuildServerPoolFactory
|
2
|
+
include KuberKit::Import[
|
3
|
+
"shell.local_shell",
|
4
|
+
]
|
5
|
+
|
6
|
+
def create(ssh_shell_class: KuberKit::Shell::SshShell)
|
7
|
+
KuberKit::ImageCompiler::BuildServerPool.new(
|
8
|
+
local_shell: local_shell,
|
9
|
+
build_servers: KuberKit.current_configuration.build_servers,
|
10
|
+
ssh_shell_class: ssh_shell_class,
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
@@ -3,13 +3,10 @@ class KuberKit::ImageCompiler::Compiler
|
|
3
3
|
"image_compiler.image_build_dir_creator",
|
4
4
|
"image_compiler.image_builder",
|
5
5
|
"core.context_helper_factory",
|
6
|
-
"core.image_store"
|
7
6
|
]
|
8
7
|
|
9
|
-
Contract KuberKit::Shell::AbstractShell,
|
10
|
-
def compile(shell,
|
11
|
-
image = image_store.get_image(image_name)
|
12
|
-
|
8
|
+
Contract KuberKit::Shell::AbstractShell, KuberKit::Core::Image, String => Any
|
9
|
+
def compile(shell, image, builds_dir)
|
13
10
|
image_build_dir = File.join(builds_dir, image.name.to_s)
|
14
11
|
|
15
12
|
context_helper = context_helper_factory.build_image_context(shell)
|
@@ -1,8 +1,8 @@
|
|
1
1
|
class KuberKit::ImageCompiler::ImageBuildDirCreator
|
2
2
|
include KuberKit::Import[
|
3
|
-
"preprocessing.dir_preprocessor",
|
4
3
|
"preprocessing.file_preprocessor",
|
5
4
|
"shell.bash_commands",
|
5
|
+
"shell.local_shell",
|
6
6
|
"configs"
|
7
7
|
]
|
8
8
|
|
@@ -14,16 +14,22 @@ class KuberKit::ImageCompiler::ImageBuildDirCreator
|
|
14
14
|
bash_commands.mkdir_p(shell, build_dir)
|
15
15
|
|
16
16
|
if image.build_context_dir
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
)
|
17
|
+
# Sync build context and then preprocess
|
18
|
+
shell.sync(image.build_context_dir, build_dir)
|
19
|
+
|
20
|
+
shell.recursive_list_files(build_dir).each do |file_path|
|
21
|
+
file_preprocessor.compile(
|
22
|
+
shell, file_path,
|
23
|
+
context_helper: context_helper
|
24
|
+
)
|
25
|
+
end
|
21
26
|
end
|
22
27
|
|
28
|
+
# Sync dockerfile and then preprocess
|
23
29
|
target_dockerfile = File.join(build_dir, configs.image_dockerfile_name)
|
30
|
+
shell.sync(image.dockerfile_path, target_dockerfile)
|
24
31
|
file_preprocessor.compile(
|
25
|
-
shell,
|
26
|
-
destination_path: target_dockerfile,
|
32
|
+
shell, target_dockerfile,
|
27
33
|
context_helper: context_helper
|
28
34
|
)
|
29
35
|
|
@@ -3,20 +3,40 @@ class KuberKit::ImageCompiler::ImageDependencyResolver
|
|
3
3
|
DependencyNotFoundError = Class.new(KuberKit::NotFoundError)
|
4
4
|
|
5
5
|
include KuberKit::Import[
|
6
|
-
"core.image_store"
|
6
|
+
"core.image_store",
|
7
|
+
"configs"
|
7
8
|
]
|
9
|
+
|
10
|
+
Contract Or[Symbol, ArrayOf[Symbol]], Proc => Any
|
11
|
+
def each_with_deps(image_names, &block)
|
12
|
+
compile_limit = configs.compile_simultaneous_limit
|
13
|
+
|
14
|
+
resolved_dependencies = []
|
15
|
+
next_dependencies = get_next(image_names, limit: compile_limit)
|
16
|
+
|
17
|
+
while (next_dependencies - resolved_dependencies).any?
|
18
|
+
block.call(next_dependencies)
|
19
|
+
resolved_dependencies += next_dependencies
|
20
|
+
next_dependencies = get_next(image_names, resolved: resolved_dependencies, limit: compile_limit)
|
21
|
+
end
|
22
|
+
|
23
|
+
block.call(image_names - resolved_dependencies)
|
24
|
+
end
|
8
25
|
|
9
|
-
Contract
|
10
|
-
resolved: Optional[ArrayOf[Symbol]]
|
26
|
+
Contract Or[Symbol, ArrayOf[Symbol]], KeywordArgs[
|
27
|
+
resolved: Optional[ArrayOf[Symbol]],
|
28
|
+
limit: Optional[Maybe[Num]]
|
11
29
|
] => Any
|
12
|
-
def get_next(image_names, resolved: [])
|
30
|
+
def get_next(image_names, resolved: [], limit: nil)
|
13
31
|
deps = Array(image_names).map { |i| get_recursive_deps(i) }.flatten.uniq
|
14
32
|
|
15
33
|
ready_to_resolve = deps.select do |dep_name|
|
16
34
|
unresolved_deps = get_deps(dep_name) - resolved
|
17
35
|
unresolved_deps.empty?
|
18
36
|
end
|
19
|
-
ready_to_resolve - resolved
|
37
|
+
unresolved_deps = ready_to_resolve - resolved
|
38
|
+
unresolved_deps = unresolved_deps.take(limit) if limit
|
39
|
+
unresolved_deps
|
20
40
|
end
|
21
41
|
|
22
42
|
def get_recursive_deps(image_name, dependency_tree: [])
|