kuby-core 0.10.1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/Gemfile +1 -0
- data/README.md +4 -2
- data/kuby-core.gemspec +2 -1
- data/lib/kuby-core.rb +1 -0
- data/lib/kuby.rb +7 -0
- data/lib/kuby/basic_logger.rb +1 -0
- data/lib/kuby/cli_base.rb +1 -0
- data/lib/kuby/commands.rb +1 -0
- data/lib/kuby/definition.rb +1 -0
- data/lib/kuby/dev_setup.rb +1 -0
- data/lib/kuby/docker.rb +3 -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 +36 -2
- data/lib/kuby/docker/cli.rb +36 -2
- 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 +82 -18
- data/lib/kuby/docker/distro.rb +43 -0
- data/lib/kuby/docker/dockerfile.rb +66 -18
- data/lib/kuby/docker/errors.rb +8 -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 +43 -6
- data/lib/kuby/docker/local_tags.rb +23 -2
- data/lib/kuby/docker/metadata.rb +35 -7
- 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 +35 -4
- data/lib/kuby/docker/spec.rb +89 -13
- 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 +4 -0
- data/lib/kuby/kubernetes.rb +1 -0
- data/lib/kuby/kubernetes/deploy_task.rb +1 -0
- data/lib/kuby/kubernetes/deployer.rb +1 -0
- data/lib/kuby/kubernetes/docker_config.rb +1 -0
- data/lib/kuby/kubernetes/docker_desktop_provider.rb +1 -0
- data/lib/kuby/kubernetes/errors.rb +1 -0
- data/lib/kuby/kubernetes/manifest.rb +1 -0
- data/lib/kuby/kubernetes/provider.rb +1 -0
- data/lib/kuby/kubernetes/registry_secret.rb +1 -0
- data/lib/kuby/kubernetes/spec.rb +1 -0
- 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 +1 -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 +9 -7
- data/lib/kuby/plugins/rails_app/generators/kuby.rb +43 -40
- data/lib/kuby/plugins/rails_app/mysql.rb +1 -0
- data/lib/kuby/plugins/rails_app/plugin.rb +10 -5
- 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 +1 -0
- data/lib/kuby/railtie.rb +1 -0
- data/lib/kuby/tasks.rb +1 -0
- data/lib/kuby/trailing_hash.rb +5 -3
- data/lib/kuby/version.rb +3 -1
- data/spec/docker/metadata_spec.rb +1 -0
- data/spec/docker/spec_spec.rb +37 -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 +10 -0
- 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 +20 -4
data/lib/kuby/docker/dev_spec.rb
CHANGED
@@ -1,63 +1,121 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
1
3
|
module Kuby
|
2
4
|
module Docker
|
3
5
|
class WebserverDevPhase < Layer
|
4
|
-
|
6
|
+
extend T::Sig
|
7
|
+
|
8
|
+
DEFAULT_PORT = T.let('3000'.freeze, String)
|
9
|
+
|
10
|
+
sig { params(port: String).void }
|
11
|
+
attr_writer :port
|
5
12
|
|
6
|
-
|
13
|
+
sig { params(environment: Environment).void }
|
14
|
+
def initialize(environment)
|
15
|
+
super
|
16
|
+
|
17
|
+
@port = T.let(@port, T.nilable(String))
|
18
|
+
end
|
7
19
|
|
20
|
+
sig { override.params(dockerfile: Dockerfile).void }
|
8
21
|
def apply_to(dockerfile)
|
9
22
|
dockerfile.expose(port)
|
10
23
|
end
|
11
24
|
|
25
|
+
sig { returns(String) }
|
12
26
|
def port
|
13
27
|
@port || DEFAULT_PORT
|
14
28
|
end
|
15
29
|
end
|
16
30
|
|
17
31
|
class DevSpec
|
32
|
+
extend T::Sig
|
33
|
+
|
34
|
+
sig { returns(Environment) }
|
18
35
|
attr_reader :environment
|
19
36
|
|
37
|
+
sig { params(environment: Environment).void }
|
20
38
|
def initialize(environment)
|
21
39
|
@environment = environment
|
40
|
+
|
41
|
+
@setup_phase = T.let(@setup_phase, T.nilable(SetupPhase))
|
42
|
+
@package_phase = T.let(@package_phase, T.nilable(PackagePhase))
|
43
|
+
@webserver_phase = T.let(@webserver_phase, T.nilable(WebserverDevPhase))
|
44
|
+
@metadata = T.let(@metadata, T.nilable(Metadata))
|
45
|
+
@distro_spec = T.let(@distro_spec, T.nilable(Distro))
|
46
|
+
@cli = T.let(@cli, T.nilable(CLI))
|
47
|
+
@tags = T.let(@tags, T.nilable(LocalTags))
|
48
|
+
@layer_stack = T.let(@layer_stack, T.nilable(Docker::LayerStack))
|
22
49
|
end
|
23
50
|
|
51
|
+
sig { params(dir: String).void }
|
24
52
|
def working_dir(dir)
|
25
53
|
setup_phase.working_dir = dir
|
26
54
|
end
|
27
55
|
|
56
|
+
sig { params(env: String).void }
|
28
57
|
def rails_env(env)
|
29
58
|
setup_phase.rails_env = env
|
30
59
|
end
|
31
60
|
|
32
|
-
|
33
|
-
|
61
|
+
sig {
|
62
|
+
params(
|
63
|
+
package_name: Symbol,
|
64
|
+
version: T.nilable(String)
|
65
|
+
)
|
66
|
+
.void
|
67
|
+
}
|
68
|
+
def package(package_name, version = nil)
|
69
|
+
package_phase.add(package_name, version)
|
34
70
|
end
|
35
71
|
|
72
|
+
sig { params(distro_name: Symbol).void }
|
36
73
|
def distro(distro_name)
|
37
74
|
metadata.distro = distro_name
|
38
75
|
@distro_spec = nil
|
39
76
|
end
|
40
77
|
|
78
|
+
sig { params(port: String).void }
|
41
79
|
def port(port)
|
42
80
|
webserver_phase.port = port
|
43
81
|
end
|
44
82
|
|
45
|
-
|
46
|
-
|
83
|
+
sig {
|
84
|
+
params(
|
85
|
+
name: Symbol,
|
86
|
+
layer: T.nilable(Layer),
|
87
|
+
block: T.nilable(T.proc.params(df: Dockerfile).void)
|
88
|
+
)
|
89
|
+
.void
|
90
|
+
}
|
91
|
+
def use(name, layer = nil, &block)
|
92
|
+
layer_stack.use(name, layer, &block)
|
47
93
|
end
|
48
94
|
|
49
|
-
|
50
|
-
|
95
|
+
sig {
|
96
|
+
params(
|
97
|
+
name: Symbol,
|
98
|
+
layer: T.nilable(T.any(Layer, T::Hash[Symbol, T.untyped])),
|
99
|
+
options: T::Hash[Symbol, T.untyped],
|
100
|
+
block: T.nilable(T.proc.params(df: Dockerfile).void)
|
101
|
+
)
|
102
|
+
.void
|
103
|
+
}
|
104
|
+
def insert(name, layer = nil, options = {}, &block)
|
105
|
+
layer_stack.insert(name, layer, options, &block)
|
51
106
|
end
|
52
107
|
|
53
|
-
|
54
|
-
|
108
|
+
sig { params(name: Symbol).void }
|
109
|
+
def delete(name)
|
110
|
+
layer_stack.delete(name)
|
55
111
|
end
|
56
112
|
|
57
|
-
|
58
|
-
|
113
|
+
sig { params(name: Symbol).returns(T::Boolean) }
|
114
|
+
def exists?(name)
|
115
|
+
layer_stack.includes?(name)
|
59
116
|
end
|
60
117
|
|
118
|
+
sig { returns(Dockerfile) }
|
61
119
|
def to_dockerfile
|
62
120
|
Dockerfile.new.tap do |df|
|
63
121
|
layer_stack.each { |layer| layer.apply_to(df) }
|
@@ -65,26 +123,27 @@ module Kuby
|
|
65
123
|
end
|
66
124
|
end
|
67
125
|
|
126
|
+
sig { returns(SetupPhase) }
|
68
127
|
def setup_phase
|
69
128
|
@setup_phase ||= SetupPhase.new(environment)
|
70
129
|
end
|
71
130
|
|
131
|
+
sig { returns(PackagePhase) }
|
72
132
|
def package_phase
|
73
133
|
@package_phase ||= PackagePhase.new(environment)
|
74
134
|
end
|
75
135
|
|
136
|
+
sig { returns(WebserverDevPhase) }
|
76
137
|
def webserver_phase
|
77
138
|
@webserver_phase ||= WebserverDevPhase.new(environment)
|
78
139
|
end
|
79
140
|
|
141
|
+
sig { returns(Metadata) }
|
80
142
|
def metadata
|
81
143
|
@metadata ||= Metadata.new(environment)
|
82
144
|
end
|
83
145
|
|
84
|
-
|
85
|
-
@cli ||= Docker::CLI.new
|
86
|
-
end
|
87
|
-
|
146
|
+
sig { returns(Distro) }
|
88
147
|
def distro_spec
|
89
148
|
@distro_spec ||= if distro_klass = Kuby.distros[metadata.distro]
|
90
149
|
distro_klass.new(self)
|
@@ -93,6 +152,7 @@ module Kuby
|
|
93
152
|
end
|
94
153
|
end
|
95
154
|
|
155
|
+
sig { returns(String) }
|
96
156
|
def tag
|
97
157
|
t = ENV.fetch('KUBY_DOCKER_TAG') do
|
98
158
|
tags.latest_timestamp_tag
|
@@ -105,22 +165,26 @@ module Kuby
|
|
105
165
|
t.to_s
|
106
166
|
end
|
107
167
|
|
108
|
-
|
168
|
+
sig { params(current_tag: String).returns(String) }
|
169
|
+
def previous_tag(current_tag)
|
109
170
|
raise MissingTagError, 'cannot roll back in the development environment'
|
110
171
|
end
|
111
172
|
|
173
|
+
sig { returns(CLI) }
|
112
174
|
def cli
|
113
175
|
@cli ||= Docker::CLI.new
|
114
176
|
end
|
115
177
|
|
116
178
|
private
|
117
179
|
|
180
|
+
sig { returns(LocalTags) }
|
118
181
|
def tags
|
119
182
|
@tags ||= LocalTags.new(cli, metadata)
|
120
183
|
end
|
121
184
|
|
185
|
+
sig { returns(Docker::LayerStack) }
|
122
186
|
def layer_stack
|
123
|
-
@layer_stack ||= LayerStack.new.tap do |stack|
|
187
|
+
@layer_stack ||= Docker::LayerStack.new.tap do |stack|
|
124
188
|
stack.use(:setup_phase, setup_phase)
|
125
189
|
stack.use(:package_phase, package_phase)
|
126
190
|
stack.use(:webserver_phase, webserver_phase)
|
@@ -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,28 +1,43 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
1
3
|
require 'digest'
|
2
4
|
|
3
5
|
module Kuby
|
4
6
|
module Docker
|
5
7
|
class Dockerfile
|
8
|
+
extend T::Sig
|
9
|
+
|
6
10
|
class Command
|
11
|
+
extend T::Sig
|
12
|
+
|
13
|
+
sig { returns(T::Array[String]) }
|
7
14
|
attr_reader :args
|
8
15
|
|
9
|
-
|
16
|
+
sig { params(args: T::Array[String]).void }
|
17
|
+
def initialize(args)
|
10
18
|
@args = args
|
11
19
|
end
|
12
20
|
|
21
|
+
sig { returns(String) }
|
13
22
|
def to_s
|
14
23
|
args.join(' ')
|
15
24
|
end
|
16
25
|
end
|
17
26
|
|
18
27
|
class From < Command
|
19
|
-
|
28
|
+
sig { returns(String) }
|
29
|
+
attr_reader :image_url
|
30
|
+
|
31
|
+
sig { returns(T.nilable(String)) }
|
32
|
+
attr_reader :as
|
20
33
|
|
34
|
+
sig { params(image_url: String, as: T.nilable(String)).void }
|
21
35
|
def initialize(image_url, as: nil)
|
22
36
|
@image_url = image_url
|
23
37
|
@as = as
|
24
38
|
end
|
25
39
|
|
40
|
+
sig { returns(String) }
|
26
41
|
def to_s
|
27
42
|
str = "FROM #{image_url}"
|
28
43
|
str << " AS #{as}" if as
|
@@ -31,26 +46,38 @@ module Kuby
|
|
31
46
|
end
|
32
47
|
|
33
48
|
class Workdir < Command
|
49
|
+
sig { returns(String) }
|
34
50
|
def to_s; "WORKDIR #{super}"; end
|
35
51
|
end
|
36
52
|
|
37
53
|
class Env < Command
|
54
|
+
sig { returns(String) }
|
38
55
|
def to_s; "ENV #{super}"; end
|
39
56
|
end
|
40
57
|
|
41
58
|
class Run < Command
|
59
|
+
sig { returns(String) }
|
42
60
|
def to_s; "RUN #{super}"; end
|
43
61
|
end
|
44
62
|
|
45
63
|
class Copy < Command
|
46
|
-
|
64
|
+
sig { returns(String) }
|
65
|
+
attr_reader :source
|
47
66
|
|
67
|
+
sig { returns(String) }
|
68
|
+
attr_reader :dest
|
69
|
+
|
70
|
+
sig { returns(T.nilable(String)) }
|
71
|
+
attr_reader :from
|
72
|
+
|
73
|
+
sig { params(source: String, dest: String, from: T.nilable(String)).void }
|
48
74
|
def initialize(source, dest, from: nil)
|
49
75
|
@source = source
|
50
76
|
@dest = dest
|
51
77
|
@from = from
|
52
78
|
end
|
53
79
|
|
80
|
+
sig { returns(String) }
|
54
81
|
def to_s
|
55
82
|
cmd = ['COPY']
|
56
83
|
cmd << "--from=#{from}" if from
|
@@ -60,72 +87,92 @@ module Kuby
|
|
60
87
|
end
|
61
88
|
|
62
89
|
class Expose < Command
|
90
|
+
sig { returns(String) }
|
63
91
|
def to_s; "EXPOSE #{super}"; end
|
64
92
|
end
|
65
93
|
|
66
94
|
class Cmd < Command
|
95
|
+
sig { returns(String) }
|
67
96
|
def to_s; "CMD #{super}"; end
|
68
97
|
end
|
69
98
|
|
70
99
|
class Arg < Command
|
100
|
+
sig { returns(String) }
|
71
101
|
def to_s; "ARG #{super}"; end
|
72
102
|
end
|
73
103
|
|
74
|
-
|
104
|
+
sig { returns(T::Array[Command]) }
|
105
|
+
attr_reader :commands
|
106
|
+
|
107
|
+
sig { returns(Integer) }
|
108
|
+
attr_reader :cursor
|
75
109
|
|
110
|
+
sig { void }
|
76
111
|
def initialize
|
77
|
-
@commands = []
|
78
|
-
@cursor = 0
|
112
|
+
@commands = T.let([], T::Array[Command])
|
113
|
+
@cursor = T.let(0, Integer)
|
79
114
|
end
|
80
115
|
|
81
|
-
|
82
|
-
|
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)
|
83
119
|
end
|
84
120
|
|
121
|
+
sig { params(args: String).void }
|
85
122
|
def workdir(*args)
|
86
|
-
add Workdir.new(
|
123
|
+
add Workdir.new(args)
|
87
124
|
end
|
88
125
|
|
126
|
+
sig { params(args: String).void }
|
89
127
|
def env(*args)
|
90
|
-
add Env.new(
|
128
|
+
add Env.new(args)
|
91
129
|
end
|
92
130
|
|
131
|
+
sig { params(args: String).void }
|
93
132
|
def arg(*args)
|
94
|
-
add Arg.new(
|
133
|
+
add Arg.new(args)
|
95
134
|
end
|
96
135
|
|
136
|
+
sig { params(args: String).void }
|
97
137
|
def run(*args)
|
98
|
-
add Run.new(
|
138
|
+
add Run.new(args)
|
99
139
|
end
|
100
140
|
|
101
|
-
|
102
|
-
|
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)
|
103
144
|
end
|
104
145
|
|
146
|
+
sig { params(args: String).void }
|
105
147
|
def expose(*args)
|
106
|
-
add Expose.new(
|
148
|
+
add Expose.new(args)
|
107
149
|
end
|
108
150
|
|
151
|
+
sig { params(args: String).void }
|
109
152
|
def cmd(*args)
|
110
|
-
add Cmd.new(
|
153
|
+
add Cmd.new(args)
|
111
154
|
end
|
112
155
|
|
156
|
+
sig { returns(String) }
|
113
157
|
def to_s
|
114
158
|
# ensure trailing newline
|
115
159
|
"#{commands.map(&:to_s).join("\n")}\n"
|
116
160
|
end
|
117
161
|
|
162
|
+
sig { returns(String) }
|
118
163
|
def checksum
|
119
164
|
Digest::SHA256.hexdigest(to_s)
|
120
165
|
end
|
121
166
|
|
167
|
+
sig { returns(T::Array[String]) }
|
122
168
|
def exposed_ports
|
123
169
|
commands
|
124
170
|
.select { |c| c.is_a?(Expose) }
|
125
|
-
.map { |c| c.args.first }
|
171
|
+
.map { |c| T.must(c.args.first) }
|
126
172
|
end
|
127
173
|
|
128
|
-
|
174
|
+
sig { params(pos: Integer, block: T.proc.void).void }
|
175
|
+
def insert_at(pos, &block)
|
129
176
|
@cursor = pos
|
130
177
|
yield
|
131
178
|
ensure
|
@@ -134,6 +181,7 @@ module Kuby
|
|
134
181
|
|
135
182
|
private
|
136
183
|
|
184
|
+
sig { params(cmd: Command).void }
|
137
185
|
def add(cmd)
|
138
186
|
commands.insert(cursor, cmd)
|
139
187
|
@cursor += 1
|
data/lib/kuby/docker/errors.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
1
3
|
module Kuby
|
2
4
|
module Docker
|
3
5
|
class BuildError < StandardError; end
|
@@ -6,12 +8,18 @@ module Kuby
|
|
6
8
|
class LoginError < StandardError; end
|
7
9
|
|
8
10
|
class MissingTagError < StandardError
|
11
|
+
extend T::Sig
|
12
|
+
|
13
|
+
sig { returns(String) }
|
9
14
|
attr_reader :tag
|
10
15
|
|
16
|
+
sig { params(tag: String).void }
|
11
17
|
def initialize(tag)
|
12
18
|
@tag = tag
|
19
|
+
@message = T.let(@message, T.nilable(String))
|
13
20
|
end
|
14
21
|
|
22
|
+
sig { returns(String) }
|
15
23
|
def message
|
16
24
|
@message ||= "Could not find tag '#{tag}'."
|
17
25
|
end
|