kuby-core 0.8.1 → 0.11.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/CHANGELOG.md +41 -1
- data/Gemfile +1 -0
- data/README.md +15 -3
- data/bin/kuby +4 -0
- data/kuby-core.gemspec +7 -3
- data/lib/kuby-core.rb +1 -0
- data/lib/kuby.rb +60 -18
- data/lib/kuby/basic_logger.rb +14 -0
- data/lib/kuby/cli_base.rb +126 -4
- data/lib/kuby/commands.rb +245 -0
- data/lib/kuby/definition.rb +2 -3
- data/lib/kuby/dev_setup.rb +256 -0
- data/lib/kuby/docker.rb +4 -0
- data/lib/kuby/docker/alpine.rb +16 -12
- data/lib/kuby/docker/assets_phase.rb +5 -0
- data/lib/kuby/docker/bundler_phase.rb +39 -5
- data/lib/kuby/docker/cli.rb +60 -3
- data/lib/kuby/docker/copy_phase.rb +11 -3
- data/lib/kuby/docker/credentials.rb +1 -0
- data/lib/kuby/docker/debian.rb +14 -10
- data/lib/kuby/docker/dev_spec.rb +195 -0
- data/lib/kuby/docker/distro.rb +43 -0
- data/lib/kuby/docker/dockerfile.rb +81 -18
- data/lib/kuby/docker/errors.rb +9 -0
- data/lib/kuby/docker/inline_layer.rb +7 -0
- data/lib/kuby/docker/layer.rb +11 -0
- data/lib/kuby/docker/layer_stack.rb +47 -6
- data/lib/kuby/docker/local_tags.rb +27 -2
- data/lib/kuby/docker/metadata.rb +35 -29
- data/lib/kuby/docker/package_list.rb +22 -3
- data/lib/kuby/docker/package_phase.rb +25 -5
- data/lib/kuby/docker/packages.rb +1 -0
- data/lib/kuby/docker/packages/managed_package.rb +20 -2
- data/lib/kuby/docker/packages/nodejs.rb +8 -0
- data/lib/kuby/docker/packages/package.rb +15 -1
- data/lib/kuby/docker/packages/simple_managed_package.rb +10 -1
- data/lib/kuby/docker/packages/yarn.rb +14 -0
- data/lib/kuby/docker/remote_tags.rb +21 -2
- data/lib/kuby/docker/setup_phase.rb +37 -5
- data/lib/kuby/docker/spec.rb +114 -12
- data/lib/kuby/docker/tags.rb +37 -2
- data/lib/kuby/docker/timestamp_tag.rb +14 -2
- data/lib/kuby/docker/webserver_phase.rb +40 -5
- data/lib/kuby/docker/yarn_phase.rb +5 -0
- data/lib/kuby/environment.rb +14 -1
- data/lib/kuby/kubernetes.rb +10 -9
- data/lib/kuby/kubernetes/deploy_task.rb +5 -0
- data/lib/kuby/kubernetes/deployer.rb +67 -11
- data/lib/kuby/kubernetes/docker_config.rb +1 -0
- data/lib/kuby/kubernetes/{minikube_provider.rb → docker_desktop_provider.rb} +5 -4
- data/lib/kuby/kubernetes/errors.rb +1 -0
- data/lib/kuby/kubernetes/manifest.rb +1 -0
- data/lib/kuby/kubernetes/provider.rb +9 -4
- data/lib/kuby/kubernetes/registry_secret.rb +1 -0
- data/lib/kuby/kubernetes/spec.rb +24 -22
- data/lib/kuby/middleware.rb +1 -0
- data/lib/kuby/middleware/health_check.rb +1 -0
- data/lib/kuby/plugin.rb +1 -0
- data/lib/kuby/plugin_registry.rb +28 -0
- data/lib/kuby/plugins.rb +1 -0
- data/lib/kuby/plugins/nginx_ingress.rb +1 -0
- data/lib/kuby/plugins/rails_app.rb +1 -0
- data/lib/kuby/plugins/rails_app/asset_copy_task.rb +1 -0
- data/lib/kuby/plugins/rails_app/assets.rb +1 -0
- data/lib/kuby/plugins/rails_app/database.rb +10 -9
- data/lib/kuby/plugins/rails_app/generators/kuby.rb +45 -44
- data/lib/kuby/plugins/rails_app/mysql.rb +1 -3
- data/lib/kuby/plugins/rails_app/plugin.rb +244 -44
- data/lib/kuby/plugins/rails_app/postgres.rb +1 -0
- data/lib/kuby/plugins/rails_app/rewrite_db_config.rb +1 -0
- data/lib/kuby/plugins/rails_app/sqlite.rb +1 -0
- data/lib/kuby/rails_commands.rb +84 -0
- data/lib/kuby/railtie.rb +1 -4
- data/lib/kuby/tasks.rb +78 -23
- data/lib/kuby/trailing_hash.rb +5 -3
- data/lib/kuby/version.rb +3 -1
- data/spec/docker/metadata_spec.rb +1 -108
- data/spec/docker/spec_spec.rb +303 -0
- data/spec/docker/timestamp_tag_spec.rb +1 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +1 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +1 -0
- data/spec/dummy/app/controllers/application_controller.rb +1 -0
- data/spec/dummy/app/helpers/application_helper.rb +1 -0
- data/spec/dummy/app/jobs/application_job.rb +1 -0
- data/spec/dummy/app/mailers/application_mailer.rb +1 -0
- data/spec/dummy/app/models/application_record.rb +1 -0
- data/spec/dummy/config/application.rb +1 -0
- data/spec/dummy/config/boot.rb +1 -0
- data/spec/dummy/config/environment.rb +1 -0
- data/spec/dummy/config/environments/development.rb +1 -0
- data/spec/dummy/config/environments/production.rb +1 -0
- data/spec/dummy/config/environments/test.rb +1 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +1 -0
- data/spec/dummy/config/initializers/assets.rb +1 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +1 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +1 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +1 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +1 -0
- data/spec/dummy/config/initializers/inflections.rb +1 -0
- data/spec/dummy/config/initializers/mime_types.rb +1 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +1 -0
- data/spec/dummy/config/puma.rb +1 -0
- data/spec/dummy/config/routes.rb +1 -0
- data/spec/dummy/config/spring.rb +1 -0
- data/spec/dummy/db/seeds.rb +1 -0
- data/spec/dummy/test/application_system_test_case.rb +1 -0
- data/spec/dummy/test/channels/application_cable/connection_test.rb +1 -0
- data/spec/dummy/test/test_helper.rb +1 -0
- data/spec/spec_helper.rb +18 -1
- data/spec/support/docker/fake_cli.rb +1 -0
- data/spec/support/docker/remote/fake_client.rb +1 -0
- data/spec/trailing_hash_spec.rb +2 -0
- metadata +62 -11
- data/lib/kuby/tasks/kuby.rake +0 -70
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
3
|
+
module Kuby
|
|
4
|
+
module Docker
|
|
5
|
+
class Distro
|
|
6
|
+
extend T::Sig
|
|
7
|
+
extend T::Helpers
|
|
8
|
+
|
|
9
|
+
abstract!
|
|
10
|
+
|
|
11
|
+
PackageImpl = T.type_alias {
|
|
12
|
+
T.any(Packages::Package, Packages::ManagedPackage, Packages::SimpleManagedPackage)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
ManagedPackageImpl = T.type_alias {
|
|
16
|
+
T.any(Packages::ManagedPackage, Packages::SimpleManagedPackage)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
sig { params(phase: Layer).void }
|
|
20
|
+
def initialize(phase)
|
|
21
|
+
@phase = phase
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
sig { params(packages: T::Array[PackageImpl], into: Dockerfile).void }
|
|
25
|
+
def install(packages, into:)
|
|
26
|
+
raise NotImplementedError,
|
|
27
|
+
"#{__method__} must be defined in derived classes"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
sig { returns(T::Array[[Symbol, T.nilable(String)]]) }
|
|
31
|
+
def default_packages
|
|
32
|
+
raise NotImplementedError,
|
|
33
|
+
"#{__method__} must be defined in derived classes"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
sig { returns(String) }
|
|
37
|
+
def shell_exe
|
|
38
|
+
raise NotImplementedError,
|
|
39
|
+
"#{__method__} must be defined in derived classes"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -1,26 +1,43 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
3
|
+
require 'digest'
|
|
4
|
+
|
|
1
5
|
module Kuby
|
|
2
6
|
module Docker
|
|
3
7
|
class Dockerfile
|
|
8
|
+
extend T::Sig
|
|
9
|
+
|
|
4
10
|
class Command
|
|
11
|
+
extend T::Sig
|
|
12
|
+
|
|
13
|
+
sig { returns(T::Array[String]) }
|
|
5
14
|
attr_reader :args
|
|
6
15
|
|
|
7
|
-
|
|
16
|
+
sig { params(args: T::Array[String]).void }
|
|
17
|
+
def initialize(args)
|
|
8
18
|
@args = args
|
|
9
19
|
end
|
|
10
20
|
|
|
21
|
+
sig { returns(String) }
|
|
11
22
|
def to_s
|
|
12
23
|
args.join(' ')
|
|
13
24
|
end
|
|
14
25
|
end
|
|
15
26
|
|
|
16
27
|
class From < Command
|
|
17
|
-
|
|
28
|
+
sig { returns(String) }
|
|
29
|
+
attr_reader :image_url
|
|
18
30
|
|
|
31
|
+
sig { returns(T.nilable(String)) }
|
|
32
|
+
attr_reader :as
|
|
33
|
+
|
|
34
|
+
sig { params(image_url: String, as: T.nilable(String)).void }
|
|
19
35
|
def initialize(image_url, as: nil)
|
|
20
36
|
@image_url = image_url
|
|
21
37
|
@as = as
|
|
22
38
|
end
|
|
23
39
|
|
|
40
|
+
sig { returns(String) }
|
|
24
41
|
def to_s
|
|
25
42
|
str = "FROM #{image_url}"
|
|
26
43
|
str << " AS #{as}" if as
|
|
@@ -29,26 +46,38 @@ module Kuby
|
|
|
29
46
|
end
|
|
30
47
|
|
|
31
48
|
class Workdir < Command
|
|
49
|
+
sig { returns(String) }
|
|
32
50
|
def to_s; "WORKDIR #{super}"; end
|
|
33
51
|
end
|
|
34
52
|
|
|
35
53
|
class Env < Command
|
|
54
|
+
sig { returns(String) }
|
|
36
55
|
def to_s; "ENV #{super}"; end
|
|
37
56
|
end
|
|
38
57
|
|
|
39
58
|
class Run < Command
|
|
59
|
+
sig { returns(String) }
|
|
40
60
|
def to_s; "RUN #{super}"; end
|
|
41
61
|
end
|
|
42
62
|
|
|
43
63
|
class Copy < Command
|
|
44
|
-
|
|
64
|
+
sig { returns(String) }
|
|
65
|
+
attr_reader :source
|
|
66
|
+
|
|
67
|
+
sig { returns(String) }
|
|
68
|
+
attr_reader :dest
|
|
69
|
+
|
|
70
|
+
sig { returns(T.nilable(String)) }
|
|
71
|
+
attr_reader :from
|
|
45
72
|
|
|
73
|
+
sig { params(source: String, dest: String, from: T.nilable(String)).void }
|
|
46
74
|
def initialize(source, dest, from: nil)
|
|
47
75
|
@source = source
|
|
48
76
|
@dest = dest
|
|
49
77
|
@from = from
|
|
50
78
|
end
|
|
51
79
|
|
|
80
|
+
sig { returns(String) }
|
|
52
81
|
def to_s
|
|
53
82
|
cmd = ['COPY']
|
|
54
83
|
cmd << "--from=#{from}" if from
|
|
@@ -58,59 +87,92 @@ module Kuby
|
|
|
58
87
|
end
|
|
59
88
|
|
|
60
89
|
class Expose < Command
|
|
90
|
+
sig { returns(String) }
|
|
61
91
|
def to_s; "EXPOSE #{super}"; end
|
|
62
92
|
end
|
|
63
93
|
|
|
64
94
|
class Cmd < Command
|
|
95
|
+
sig { returns(String) }
|
|
65
96
|
def to_s; "CMD #{super}"; end
|
|
66
97
|
end
|
|
67
98
|
|
|
68
|
-
|
|
99
|
+
class Arg < Command
|
|
100
|
+
sig { returns(String) }
|
|
101
|
+
def to_s; "ARG #{super}"; end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
sig { returns(T::Array[Command]) }
|
|
105
|
+
attr_reader :commands
|
|
69
106
|
|
|
107
|
+
sig { returns(Integer) }
|
|
108
|
+
attr_reader :cursor
|
|
109
|
+
|
|
110
|
+
sig { void }
|
|
70
111
|
def initialize
|
|
71
|
-
@commands = []
|
|
72
|
-
@cursor = 0
|
|
112
|
+
@commands = T.let([], T::Array[Command])
|
|
113
|
+
@cursor = T.let(0, Integer)
|
|
73
114
|
end
|
|
74
115
|
|
|
75
|
-
|
|
76
|
-
|
|
116
|
+
sig { params(image_url: String, as: T.nilable(String)).void }
|
|
117
|
+
def from(image_url, as: nil)
|
|
118
|
+
add From.new(image_url, as: as)
|
|
77
119
|
end
|
|
78
120
|
|
|
121
|
+
sig { params(args: String).void }
|
|
79
122
|
def workdir(*args)
|
|
80
|
-
add Workdir.new(
|
|
123
|
+
add Workdir.new(args)
|
|
81
124
|
end
|
|
82
125
|
|
|
126
|
+
sig { params(args: String).void }
|
|
83
127
|
def env(*args)
|
|
84
|
-
add Env.new(
|
|
128
|
+
add Env.new(args)
|
|
85
129
|
end
|
|
86
130
|
|
|
131
|
+
sig { params(args: String).void }
|
|
132
|
+
def arg(*args)
|
|
133
|
+
add Arg.new(args)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
sig { params(args: String).void }
|
|
87
137
|
def run(*args)
|
|
88
|
-
add Run.new(
|
|
138
|
+
add Run.new(args)
|
|
89
139
|
end
|
|
90
140
|
|
|
91
|
-
|
|
92
|
-
|
|
141
|
+
sig { params(source: String, dest: String, from: T.nilable(String)).void }
|
|
142
|
+
def copy(source, dest, from: nil)
|
|
143
|
+
add Copy.new(source, dest, from: from)
|
|
93
144
|
end
|
|
94
145
|
|
|
146
|
+
sig { params(args: String).void }
|
|
95
147
|
def expose(*args)
|
|
96
|
-
add Expose.new(
|
|
148
|
+
add Expose.new(args)
|
|
97
149
|
end
|
|
98
150
|
|
|
151
|
+
sig { params(args: String).void }
|
|
99
152
|
def cmd(*args)
|
|
100
|
-
add Cmd.new(
|
|
153
|
+
add Cmd.new(args)
|
|
101
154
|
end
|
|
102
155
|
|
|
156
|
+
sig { returns(String) }
|
|
103
157
|
def to_s
|
|
104
|
-
|
|
158
|
+
# ensure trailing newline
|
|
159
|
+
"#{commands.map(&:to_s).join("\n")}\n"
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
sig { returns(String) }
|
|
163
|
+
def checksum
|
|
164
|
+
Digest::SHA256.hexdigest(to_s)
|
|
105
165
|
end
|
|
106
166
|
|
|
167
|
+
sig { returns(T::Array[String]) }
|
|
107
168
|
def exposed_ports
|
|
108
169
|
commands
|
|
109
170
|
.select { |c| c.is_a?(Expose) }
|
|
110
|
-
.map { |c| c.args.first }
|
|
171
|
+
.map { |c| T.must(c.args.first) }
|
|
111
172
|
end
|
|
112
173
|
|
|
113
|
-
|
|
174
|
+
sig { params(pos: Integer, block: T.proc.void).void }
|
|
175
|
+
def insert_at(pos, &block)
|
|
114
176
|
@cursor = pos
|
|
115
177
|
yield
|
|
116
178
|
ensure
|
|
@@ -119,6 +181,7 @@ module Kuby
|
|
|
119
181
|
|
|
120
182
|
private
|
|
121
183
|
|
|
184
|
+
sig { params(cmd: Command).void }
|
|
122
185
|
def add(cmd)
|
|
123
186
|
commands.insert(cursor, cmd)
|
|
124
187
|
@cursor += 1
|
data/lib/kuby/docker/errors.rb
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
1
3
|
module Kuby
|
|
2
4
|
module Docker
|
|
3
5
|
class BuildError < StandardError; end
|
|
4
6
|
class PushError < StandardError; end
|
|
7
|
+
class PullError < StandardError; end
|
|
5
8
|
class LoginError < StandardError; end
|
|
6
9
|
|
|
7
10
|
class MissingTagError < StandardError
|
|
11
|
+
extend T::Sig
|
|
12
|
+
|
|
13
|
+
sig { returns(String) }
|
|
8
14
|
attr_reader :tag
|
|
9
15
|
|
|
16
|
+
sig { params(tag: String).void }
|
|
10
17
|
def initialize(tag)
|
|
11
18
|
@tag = tag
|
|
19
|
+
@message = T.let(@message, T.nilable(String))
|
|
12
20
|
end
|
|
13
21
|
|
|
22
|
+
sig { returns(String) }
|
|
14
23
|
def message
|
|
15
24
|
@message ||= "Could not find tag '#{tag}'."
|
|
16
25
|
end
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
1
3
|
module Kuby
|
|
2
4
|
module Docker
|
|
3
5
|
class InlineLayer < Layer
|
|
6
|
+
extend T::Sig
|
|
7
|
+
|
|
8
|
+
sig { returns(T.proc.params(df: Dockerfile).void) }
|
|
4
9
|
attr_reader :block
|
|
5
10
|
|
|
11
|
+
sig { params(block: T.proc.params(df: Dockerfile).void).void }
|
|
6
12
|
def initialize(block)
|
|
7
13
|
@block = block
|
|
8
14
|
end
|
|
9
15
|
|
|
16
|
+
sig { override.params(dockerfile: Dockerfile).void }
|
|
10
17
|
def apply_to(dockerfile)
|
|
11
18
|
block.call(dockerfile)
|
|
12
19
|
end
|
data/lib/kuby/docker/layer.rb
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
1
3
|
module Kuby
|
|
2
4
|
module Docker
|
|
3
5
|
class Layer
|
|
6
|
+
extend T::Sig
|
|
7
|
+
extend T::Helpers
|
|
8
|
+
|
|
9
|
+
abstract!
|
|
10
|
+
|
|
11
|
+
sig { returns(Environment) }
|
|
4
12
|
attr_reader :environment
|
|
5
13
|
|
|
14
|
+
sig { params(environment: Environment).void }
|
|
6
15
|
def initialize(environment)
|
|
7
16
|
@environment = environment
|
|
8
17
|
end
|
|
9
18
|
|
|
19
|
+
sig { params(dockerfile: Dockerfile).void }
|
|
10
20
|
def apply_to(dockerfile)
|
|
11
21
|
raise NotImplementedError,
|
|
12
22
|
"#{__method__} must be defined in derived classes"
|
|
@@ -14,6 +24,7 @@ module Kuby
|
|
|
14
24
|
|
|
15
25
|
private
|
|
16
26
|
|
|
27
|
+
sig { returns(Metadata) }
|
|
17
28
|
def metadata
|
|
18
29
|
environment.docker.metadata
|
|
19
30
|
end
|
|
@@ -1,20 +1,46 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
1
3
|
module Kuby
|
|
2
4
|
module Docker
|
|
3
5
|
class LayerStack
|
|
6
|
+
extend T::Sig
|
|
7
|
+
extend T::Generic
|
|
8
|
+
|
|
9
|
+
Elem = type_member(fixed: Layer)
|
|
10
|
+
|
|
4
11
|
include Enumerable
|
|
5
12
|
|
|
6
|
-
|
|
13
|
+
sig { returns(T::Array[Symbol]) }
|
|
14
|
+
attr_reader :stack
|
|
7
15
|
|
|
16
|
+
sig { returns(T::Hash[Symbol, Layer]) }
|
|
17
|
+
attr_reader :layers
|
|
18
|
+
|
|
19
|
+
sig { void }
|
|
8
20
|
def initialize
|
|
9
|
-
@stack = []
|
|
10
|
-
@layers = {}
|
|
21
|
+
@stack = T.let([], T::Array[Symbol])
|
|
22
|
+
@layers = T.let({}, T::Hash[Symbol, Layer])
|
|
11
23
|
end
|
|
12
24
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
25
|
+
sig {
|
|
26
|
+
override.params(
|
|
27
|
+
block: T.nilable(T.proc.params(layer: Layer).void)
|
|
28
|
+
)
|
|
29
|
+
.void
|
|
30
|
+
}
|
|
31
|
+
def each(&block)
|
|
32
|
+
return to_enum(T.must(__method__)) unless block_given?
|
|
33
|
+
@stack.each { |name| yield T.must(layers[name]) }
|
|
16
34
|
end
|
|
17
35
|
|
|
36
|
+
sig {
|
|
37
|
+
params(
|
|
38
|
+
name: Symbol,
|
|
39
|
+
layer: T.nilable(Layer),
|
|
40
|
+
block: T.nilable(T.proc.params(df: Dockerfile).void)
|
|
41
|
+
)
|
|
42
|
+
.void
|
|
43
|
+
}
|
|
18
44
|
def use(name, layer = nil, &block)
|
|
19
45
|
stack << name
|
|
20
46
|
|
|
@@ -27,6 +53,15 @@ module Kuby
|
|
|
27
53
|
end
|
|
28
54
|
end
|
|
29
55
|
|
|
56
|
+
sig {
|
|
57
|
+
params(
|
|
58
|
+
name: Symbol,
|
|
59
|
+
layer: T.nilable(T.any(Layer, T::Hash[Symbol, T.untyped])),
|
|
60
|
+
options: T::Hash[Symbol, T.untyped],
|
|
61
|
+
block: T.nilable(T.proc.params(df: Dockerfile).void)
|
|
62
|
+
)
|
|
63
|
+
.void
|
|
64
|
+
}
|
|
30
65
|
def insert(name, layer = nil, options = {}, &block)
|
|
31
66
|
# this is truly gross but it's the only way I can think of to be able
|
|
32
67
|
# to call insert these two ways:
|
|
@@ -59,10 +94,16 @@ module Kuby
|
|
|
59
94
|
end
|
|
60
95
|
end
|
|
61
96
|
|
|
97
|
+
sig { params(name: Symbol).void }
|
|
62
98
|
def delete(name)
|
|
63
99
|
stack.delete(name)
|
|
64
100
|
layers.delete(name)
|
|
65
101
|
end
|
|
102
|
+
|
|
103
|
+
sig { params(name: Symbol).returns(T::Boolean) }
|
|
104
|
+
def includes?(name)
|
|
105
|
+
layers.include?(name)
|
|
106
|
+
end
|
|
66
107
|
end
|
|
67
108
|
end
|
|
68
109
|
end
|
|
@@ -1,18 +1,37 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
1
3
|
module Kuby
|
|
2
4
|
module Docker
|
|
3
5
|
class LocalTags
|
|
4
|
-
|
|
6
|
+
extend T::Sig
|
|
7
|
+
|
|
8
|
+
sig { returns CLI }
|
|
9
|
+
attr_reader :cli
|
|
10
|
+
|
|
11
|
+
sig { returns(Metadata) }
|
|
12
|
+
attr_reader :metadata
|
|
5
13
|
|
|
14
|
+
sig {
|
|
15
|
+
params(
|
|
16
|
+
cli: CLI,
|
|
17
|
+
metadata: Metadata
|
|
18
|
+
)
|
|
19
|
+
.void
|
|
20
|
+
}
|
|
6
21
|
def initialize(cli, metadata)
|
|
7
22
|
@cli = cli
|
|
8
23
|
@metadata = metadata
|
|
24
|
+
|
|
25
|
+
@latest_timestamp_tag = T.let(@latest_timestamp_tag, T.nilable(TimestampTag))
|
|
9
26
|
end
|
|
10
27
|
|
|
28
|
+
sig { returns(T::Array[String]) }
|
|
11
29
|
def tags
|
|
12
30
|
images = cli.images(metadata.image_url)
|
|
13
|
-
images.map { |image| image[:tag] }
|
|
31
|
+
images.map { |image| T.must(image[:tag]) }
|
|
14
32
|
end
|
|
15
33
|
|
|
34
|
+
sig { returns(T::Array[String]) }
|
|
16
35
|
def latest_tags
|
|
17
36
|
# find "latest" tag
|
|
18
37
|
images = cli.images(metadata.image_url)
|
|
@@ -30,9 +49,15 @@ module Kuby
|
|
|
30
49
|
end
|
|
31
50
|
end
|
|
32
51
|
|
|
52
|
+
sig { returns(T::Array[TimestampTag]) }
|
|
33
53
|
def timestamp_tags
|
|
34
54
|
tags.map { |t| TimestampTag.try_parse(t) }.compact
|
|
35
55
|
end
|
|
56
|
+
|
|
57
|
+
sig { returns(T.nilable(TimestampTag)) }
|
|
58
|
+
def latest_timestamp_tag
|
|
59
|
+
@latest_timestamp_tag ||= timestamp_tags.sort.last
|
|
60
|
+
end
|
|
36
61
|
end
|
|
37
62
|
end
|
|
38
63
|
end
|