kuby-core 0.17.0 → 0.18.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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -0
  3. data/Gemfile +6 -2
  4. data/Rakefile +5 -3
  5. data/bin/tapioca +29 -0
  6. data/kuby-core.gemspec +9 -11
  7. data/lib/kuby/basic_logger.rb +34 -34
  8. data/lib/kuby/cli_base.rb +43 -43
  9. data/lib/kuby/commands.rb +94 -11
  10. data/lib/kuby/definition.rb +12 -12
  11. data/lib/kuby/dependable.rb +20 -0
  12. data/lib/kuby/dependency.rb +14 -0
  13. data/lib/kuby/docker/alpine.rb +10 -10
  14. data/lib/kuby/docker/app_image.rb +11 -11
  15. data/lib/kuby/docker/app_phase.rb +36 -0
  16. data/lib/kuby/docker/assets_phase.rb +2 -2
  17. data/lib/kuby/docker/bundler_phase.rb +42 -40
  18. data/lib/kuby/docker/cli.rb +71 -43
  19. data/lib/kuby/docker/copy_phase.rb +7 -7
  20. data/lib/kuby/docker/credentials.rb +1 -0
  21. data/lib/kuby/docker/debian.rb +10 -10
  22. data/lib/kuby/docker/distro.rb +13 -13
  23. data/lib/kuby/docker/docker_uri.rb +20 -20
  24. data/lib/kuby/docker/dockerfile.rb +48 -39
  25. data/lib/kuby/docker/image.rb +66 -54
  26. data/lib/kuby/docker/inline_layer.rb +4 -4
  27. data/lib/kuby/docker/layer.rb +6 -6
  28. data/lib/kuby/docker/layer_stack.rb +35 -35
  29. data/lib/kuby/docker/local_tags.rb +16 -16
  30. data/lib/kuby/docker/package_list.rb +16 -16
  31. data/lib/kuby/docker/package_phase.rb +16 -16
  32. data/lib/kuby/docker/packages/managed_package.rb +13 -13
  33. data/lib/kuby/docker/packages/nodejs.rb +5 -5
  34. data/lib/kuby/docker/packages/package.rb +8 -8
  35. data/lib/kuby/docker/packages/simple_managed_package.rb +7 -7
  36. data/lib/kuby/docker/packages/yarn.rb +6 -6
  37. data/lib/kuby/docker/remote_tags.rb +16 -16
  38. data/lib/kuby/docker/setup_phase.rb +18 -20
  39. data/lib/kuby/docker/spec.rb +93 -72
  40. data/lib/kuby/docker/timestamp_tag.rb +16 -11
  41. data/lib/kuby/docker/timestamped_image.rb +59 -40
  42. data/lib/kuby/docker/webserver_phase.rb +20 -20
  43. data/lib/kuby/docker/yarn_phase.rb +29 -5
  44. data/lib/kuby/docker.rb +2 -1
  45. data/lib/kuby/kubernetes/bare_metal_provider.rb +9 -9
  46. data/lib/kuby/kubernetes/deployer.rb +22 -10
  47. data/lib/kuby/kubernetes/docker_config.rb +1 -0
  48. data/lib/kuby/kubernetes/provider.rb +1 -0
  49. data/lib/kuby/kubernetes/spec.rb +47 -7
  50. data/lib/kuby/plugin.rb +22 -1
  51. data/lib/kuby/plugins/nginx_ingress.rb +8 -6
  52. data/lib/kuby/plugins/rails_app/assets.rb +16 -4
  53. data/lib/kuby/plugins/rails_app/assets_image.rb +17 -8
  54. data/lib/kuby/plugins/rails_app/crdb/plugin.rb +473 -0
  55. data/lib/kuby/plugins/rails_app/crdb.rb +9 -0
  56. data/lib/kuby/plugins/rails_app/database.rb +12 -8
  57. data/lib/kuby/plugins/rails_app/generators/kuby.rb +17 -16
  58. data/lib/kuby/plugins/rails_app/plugin.rb +29 -18
  59. data/lib/kuby/plugins/rails_app/sqlite.rb +7 -3
  60. data/lib/kuby/plugins/rails_app/tasks.rake +25 -12
  61. data/lib/kuby/plugins/rails_app.rb +1 -0
  62. data/lib/kuby/plugins/system.rb +16 -0
  63. data/lib/kuby/plugins.rb +1 -0
  64. data/lib/kuby/railtie.rb +31 -1
  65. data/lib/kuby/tasks.rb +72 -5
  66. data/lib/kuby/trailing_hash.rb +2 -2
  67. data/lib/kuby/utils/sem_ver/constraint.rb +68 -0
  68. data/lib/kuby/utils/sem_ver/constraint_set.rb +25 -0
  69. data/lib/kuby/utils/sem_ver/version.rb +49 -0
  70. data/lib/kuby/utils/sem_ver.rb +17 -0
  71. data/lib/kuby/utils/which.rb +65 -0
  72. data/lib/kuby/utils.rb +7 -1
  73. data/lib/kuby/version.rb +1 -1
  74. data/lib/kuby.rb +37 -2
  75. data/rbi/kuby-core.rbi +2128 -0
  76. data/spec/docker/spec_spec.rb +50 -26
  77. data/spec/dummy/app/channels/application_cable/channel.rb +2 -1
  78. data/spec/dummy/app/channels/application_cable/connection.rb +2 -1
  79. data/spec/dummy/app/controllers/application_controller.rb +2 -1
  80. data/spec/dummy/app/jobs/application_job.rb +2 -1
  81. data/spec/dummy/app/mailers/application_mailer.rb +2 -1
  82. data/spec/dummy/app/models/application_record.rb +2 -1
  83. data/spec/dummy/config/application.rb +2 -1
  84. data/spec/dummy/config/initializers/wrap_parameters.rb +2 -1
  85. data/spec/dummy/config/routes.rb +2 -1
  86. data/spec/dummy/test/application_system_test_case.rb +2 -1
  87. data/spec/dummy/test/channels/application_cable/connection_test.rb +2 -1
  88. data/spec/spec_helper.rb +13 -1
  89. metadata +44 -39
  90. data/lib/kuby/plugins/rails_app/mysql.rb +0 -158
  91. data/lib/kuby/plugins/rails_app/postgres.rb +0 -163
@@ -2,23 +2,23 @@
2
2
 
3
3
  module Kuby
4
4
  class Definition
5
- extend T::Sig
5
+ # extend T::Sig
6
6
 
7
- sig { returns(String) }
7
+ # T::Sig::WithoutRuntime.sig { returns(String) }
8
8
  attr_reader :app_name
9
9
 
10
- sig { params(app_name: String, block: T.nilable(T.proc.void)).void }
10
+ # T::Sig::WithoutRuntime.sig { params(app_name: String, block: T.nilable(T.proc.void)).void }
11
11
  def initialize(app_name, &block)
12
12
  @app_name = app_name
13
- @environments = T.let(@environments, T.nilable(T::Hash[Symbol, Environment]))
13
+ # @environments = T.let(@environments, T.nilable(T::Hash[Symbol, Environment]))
14
14
  end
15
15
 
16
- sig {
17
- params(
18
- name: Symbol,
19
- block: T.nilable(T.proc.void)
20
- ).returns(Environment)
21
- }
16
+ # T::Sig::WithoutRuntime.sig {
17
+ # params(
18
+ # name: Symbol,
19
+ # block: T.nilable(T.proc.void)
20
+ # ).returns(Kuby::Environment)
21
+ # }
22
22
  def environment(name = Kuby.env, &block)
23
23
  name = name.to_s
24
24
 
@@ -28,10 +28,10 @@ module Kuby
28
28
  environments[name].instance_eval(&block)
29
29
  end
30
30
 
31
- T.must(environments[name])
31
+ environments[name]
32
32
  end
33
33
 
34
- sig { returns(T::Hash[Symbol, Environment]) }
34
+ # T::Sig::WithoutRuntime.sig { returns(T::Hash[Symbol, Kuby::Environment]) }
35
35
  def environments
36
36
  @environments ||= {}
37
37
  end
@@ -0,0 +1,20 @@
1
+ module Kuby
2
+ class Dependable
3
+ attr_reader :name, :version_or_callable
4
+
5
+ def initialize(name, version_or_callable)
6
+ @name = name
7
+ @version_or_callable = version_or_callable
8
+ end
9
+
10
+ def version
11
+ @version ||= Kuby::Utils::SemVer.parse_version(
12
+ if version_or_callable.respond_to?(:call)
13
+ version_or_callable.call
14
+ else
15
+ version_or_callable
16
+ end
17
+ )
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ module Kuby
2
+ class Dependency
3
+ attr_reader :name, :constraints
4
+
5
+ def initialize(name, *constraints)
6
+ @name = name
7
+ @constraints = Kuby::Utils::SemVer.parse_constraints(*constraints)
8
+ end
9
+
10
+ def satisfied_by?(dependable)
11
+ constraints.satisfied_by?(dependable.version)
12
+ end
13
+ end
14
+ end
@@ -3,42 +3,42 @@
3
3
  module Kuby
4
4
  module Docker
5
5
  class Alpine < Distro
6
- SHELL_EXE = T.let('/bin/sh'.freeze, String)
6
+ SHELL_EXE = '/bin/sh'.freeze
7
7
 
8
- DEFAULT_PACKAGES = T.let([
8
+ DEFAULT_PACKAGES = [
9
9
  [:ca_certificates, nil],
10
10
  [:nodejs, '12.14.1'],
11
11
  [:yarn, '1.21.1'],
12
12
  [:c_toolchain, nil],
13
13
  [:tzdata, nil],
14
14
  [:git, nil]
15
- ].freeze, T::Array[[Symbol, T.nilable(String)]])
15
+ ].freeze
16
16
 
17
- sig { returns(Layer) }
17
+ # T::Sig::WithoutRuntime.sig { returns(Layer) }
18
18
  attr_reader :phase
19
19
 
20
- sig { override.params(packages: T::Array[Distro::PackageImpl], into: Dockerfile).void }
20
+ # T::Sig::WithoutRuntime.sig { override.params(packages: T::Array[Distro::PackageImpl], into: Dockerfile).void }
21
21
  def install(packages, into:)
22
22
  dockerfile = into
23
23
  install_managed(packages, dockerfile)
24
24
  install_unmanaged(packages, dockerfile)
25
25
  end
26
26
 
27
- sig { override.returns(T::Array[[Symbol, T.nilable(String)]]) }
27
+ # T::Sig::WithoutRuntime.sig { override.returns(T::Array[[Symbol, T.nilable(String)]]) }
28
28
  def default_packages
29
29
  DEFAULT_PACKAGES
30
30
  end
31
31
 
32
- sig { override.returns(String) }
32
+ # T::Sig::WithoutRuntime.sig { override.returns(String) }
33
33
  def shell_exe
34
34
  SHELL_EXE
35
35
  end
36
36
 
37
37
  private
38
38
 
39
- sig { params(packages: T::Array[Distro::PackageImpl], dockerfile: Dockerfile).void }
39
+ # T::Sig::WithoutRuntime.sig { params(packages: T::Array[Distro::PackageImpl], dockerfile: Dockerfile).void }
40
40
  def install_managed(packages, dockerfile)
41
- pkgs = T.cast(packages.select(&:managed?), T::Array[Distro::ManagedPackageImpl])
41
+ pkgs = packages.select(&:managed?)
42
42
 
43
43
  unless pkgs.empty?
44
44
  package_names = pkgs.map { |pkg| pkg.package_name_for(:alpine) }
@@ -48,7 +48,7 @@ module Kuby
48
48
  end
49
49
  end
50
50
 
51
- sig { params(packages: T::Array[Distro::PackageImpl], dockerfile: Dockerfile).void }
51
+ # T::Sig::WithoutRuntime.sig { params(packages: T::Array[Distro::PackageImpl], dockerfile: Dockerfile).void }
52
52
  def install_unmanaged(packages, dockerfile)
53
53
  packages
54
54
  .reject(&:managed?)
@@ -4,18 +4,18 @@
4
4
  module Kuby
5
5
  module Docker
6
6
  class AppImage < ::Kuby::Docker::TimestampedImage
7
- extend T::Sig
7
+ # extend T::Sig
8
8
 
9
- sig {
10
- params(
11
- dockerfile: T.any(Dockerfile, T.proc.returns(Dockerfile)),
12
- image_url: String,
13
- credentials: Credentials,
14
- registry_index_url: T.nilable(String),
15
- main_tag: T.nilable(String),
16
- alias_tags: T::Array[String]
17
- ).void
18
- }
9
+ # T::Sig::WithoutRuntime.sig {
10
+ # params(
11
+ # dockerfile: T.any(Dockerfile, T.proc.returns(Dockerfile)),
12
+ # image_url: String,
13
+ # credentials: Credentials,
14
+ # registry_index_url: T.nilable(String),
15
+ # main_tag: T.nilable(String),
16
+ # alias_tags: T::Array[String]
17
+ # ).void
18
+ # }
19
19
  def initialize(dockerfile, image_url, credentials, registry_index_url = nil, main_tag = nil, alias_tags = [])
20
20
  super
21
21
  @identifier = "app"
@@ -0,0 +1,36 @@
1
+ # typed: strict
2
+
3
+ module Kuby
4
+ module Docker
5
+ class AppPhase < Layer
6
+ # extend T::Sig
7
+
8
+ # T::Sig::WithoutRuntime.sig { params(environment: Environment).void }
9
+ def initialize(environment)
10
+ super
11
+
12
+ @env_vars = {}
13
+ end
14
+
15
+ # T::Sig::WithoutRuntime.sig { override.params(dockerfile: Dockerfile).void }
16
+ def apply_to(dockerfile)
17
+ @env_vars.each_pair do |key, value|
18
+ dockerfile.env("#{key}='#{value}'")
19
+ end
20
+
21
+ absolute_app_root = Pathname(dockerfile.current_workdir)
22
+ .join(environment.docker.app_root_path)
23
+ .to_s
24
+
25
+ if dockerfile.current_workdir != absolute_app_root
26
+ dockerfile.workdir(absolute_app_root)
27
+ end
28
+ end
29
+
30
+ # T::Sig::WithoutRuntime.sig { params(key: String, value: String).void }
31
+ def env(key, value)
32
+ @env_vars[key] = value
33
+ end
34
+ end
35
+ end
36
+ end
@@ -3,9 +3,9 @@
3
3
  module Kuby
4
4
  module Docker
5
5
  class AssetsPhase < Layer
6
- extend T::Sig
6
+ # extend T::Sig
7
7
 
8
- sig { override.params(dockerfile: Dockerfile).void }
8
+ # T::Sig::WithoutRuntime.sig { override.params(dockerfile: Dockerfile).void }
9
9
  def apply_to(dockerfile)
10
10
  dockerfile.run(
11
11
  'bundle', 'exec', 'rake', 'assets:precompile'
@@ -5,101 +5,103 @@ require 'pathname'
5
5
  module Kuby
6
6
  module Docker
7
7
  class BundlerPhase < Layer
8
- extend T::Sig
8
+ # extend T::Sig
9
9
 
10
- DEFAULT_WITHOUT = T.let(
11
- ['development', 'test', 'deploy'].freeze, T::Array[String]
12
- )
10
+ DEFAULT_GEMFILE = 'Gemfile'.freeze
11
+ DEFAULT_WITHOUT =
12
+ ['development', 'test', 'deploy'].freeze
13
+
13
14
 
14
- sig { returns(T.nilable(String)) }
15
+ # T::Sig::WithoutRuntime.sig { returns(T.nilable(String)) }
15
16
  attr_reader :version
16
17
 
17
- sig { params(version: String).void }
18
+ # T::Sig::WithoutRuntime.sig { params(version: String).returns(String) }
18
19
  attr_writer :version
19
20
 
20
- sig { returns(T.nilable(String)) }
21
+ # T::Sig::WithoutRuntime.sig { returns(T.nilable(String)) }
21
22
  attr_reader :gemfile
22
23
 
23
- sig { params(gemfile: String).void }
24
+ # T::Sig::WithoutRuntime.sig { params(gemfile: String).returns(String) }
24
25
  attr_writer :gemfile
25
26
 
26
- sig { returns(T.nilable(T::Array[String])) }
27
+ # T::Sig::WithoutRuntime.sig { returns(T.nilable(T::Array[String])) }
27
28
  attr_reader :without
28
29
 
29
- sig { params(without: T::Array[String]).void }
30
+ # T::Sig::WithoutRuntime.sig { params(without: T::Array[String]).returns(T::Array[String]) }
30
31
  attr_writer :without
31
32
 
32
- sig { returns(T.nilable(String)) }
33
+ # T::Sig::WithoutRuntime.sig { returns(T.nilable(String)) }
33
34
  attr_reader :executable
34
35
 
35
- sig { params(executable: String).void }
36
+ # T::Sig::WithoutRuntime.sig { params(executable: String).returns(String) }
36
37
  attr_writer :executable
37
38
 
38
- sig { params(environment: Environment).void }
39
+ # T::Sig::WithoutRuntime.sig { params(environment: Environment).void }
39
40
  def initialize(environment)
40
41
  super
41
42
 
42
- @version = T.let(@version, T.nilable(String))
43
- @gemfile = T.let(@gemfile, T.nilable(String))
44
- @gemfiles = T.let([], T::Array[String])
45
- @without = T.let(@without, T.nilable(T::Array[String]))
46
- @executable = T.let(@executable, T.nilable(String))
43
+ # @version = T.let(@version, T.nilable(String))
44
+ # @gemfile = T.let(@gemfile, T.nilable(String))
45
+ @gemfiles = []
46
+ # @without = T.let(@without, T.nilable(T::Array[String]))
47
+ # @executable = T.let(@executable, T.nilable(String))
47
48
  end
48
49
 
49
- sig { override.params(dockerfile: Dockerfile).void }
50
+ # T::Sig::WithoutRuntime.sig { override.params(dockerfile: Dockerfile).void }
50
51
  def apply_to(dockerfile)
51
- gf = gemfile || default_gemfile
52
+ gf = gemfile || DEFAULT_GEMFILE
52
53
  lf = "#{gf}.lock"
53
54
  v = version || default_version
54
55
  wo = without || DEFAULT_WITHOUT
55
56
 
56
- dockerfile.run('gem', 'install', 'bundler', '-v', v)
57
+ host_path = Pathname(environment.docker.app_root_path)
58
+ container_path = Pathname(dockerfile.current_workdir).join(environment.docker.app_root_path)
57
59
 
58
- # bundle install
59
- dockerfile.copy(gf, '.')
60
- dockerfile.copy(lf, '.')
60
+ dockerfile.run('gem', 'install', 'bundler', '-v', v)
61
61
 
62
+ dockerfile.copy(host_path.join(gf), container_path.join(gf))
63
+ dockerfile.copy(host_path.join(lf), container_path.join(lf))
62
64
  @gemfiles.each do |file|
63
- dockerfile.copy(file, file)
65
+ dockerfile.copy(host_path.join(file), container_path.join(file))
66
+ extra_lf = host_path.join("#{file}.lock")
67
+
68
+ if extra_lf.exist?
69
+ dockerfile.copy(extra_lf, container_path.join("#{file}.lock"))
70
+ end
64
71
  end
65
72
 
73
+ dockerfile.env("BUNDLE_GEMFILE=#{container_path.join(gf)}")
74
+
66
75
  unless wo.empty?
67
76
  dockerfile.env("BUNDLE_WITHOUT='#{wo.join(' ')}'")
68
77
  end
69
78
 
79
+ dockerfile.run(
80
+ executable || 'bundle', 'lock', '--lockfile', container_path.join(lf)
81
+ )
82
+
70
83
  dockerfile.run(
71
84
  executable || 'bundle', 'install',
72
85
  '--jobs', '$(nproc)',
73
- '--retry', '3',
74
- '--gemfile', gf
86
+ '--retry', '3'
75
87
  )
76
88
 
77
89
  # generate binstubs and add the bin directory to our path
78
90
  dockerfile.run(executable || 'bundle', 'binstubs', '--all')
79
- dockerfile.env("PATH=./bin:$PATH")
91
+ dockerfile.env("PATH=#{container_path.join('bin')}:$PATH")
80
92
  end
81
93
 
82
- sig { params(paths: String).void }
94
+ # T::Sig::WithoutRuntime.sig { params(paths: String).void }
83
95
  def gemfiles(*paths)
84
96
  @gemfiles.concat(paths)
85
97
  end
86
98
 
87
99
  private
88
100
 
89
- sig { returns(String) }
101
+ # T::Sig::WithoutRuntime.sig { returns(String) }
90
102
  def default_version
91
103
  Bundler::VERSION
92
104
  end
93
-
94
- sig { returns(String) }
95
- def default_gemfile
96
- Bundler
97
- .definition
98
- .gemfiles
99
- .first
100
- .relative_path_from(Pathname(Dir.getwd))
101
- .to_s
102
- end
103
105
  end
104
106
  end
105
107
  end
@@ -7,29 +7,29 @@ require 'shellwords'
7
7
  module Kuby
8
8
  module Docker
9
9
  class CLI < CLIBase
10
- extend T::Sig
10
+ # extend T::Sig
11
11
 
12
- sig { returns(String) }
12
+ # T::Sig::WithoutRuntime.sig { returns(String) }
13
13
  attr_reader :executable
14
14
 
15
- sig { params(executable: T.nilable(String)).void }
15
+ # T::Sig::WithoutRuntime.sig { params(executable: T.nilable(String)).void }
16
16
  def initialize(executable = nil)
17
- @executable = T.let(executable || `which docker`.strip, String)
17
+ @executable = executable || Kuby::Utils.which('docker')
18
18
  end
19
19
 
20
- sig { returns(T.nilable(String)) }
20
+ # T::Sig::WithoutRuntime.sig { returns(T.nilable(String)) }
21
21
  def config_file
22
22
  if File.exist?(default_config_file)
23
23
  default_config_file
24
24
  end
25
25
  end
26
26
 
27
- sig { returns(String) }
27
+ # T::Sig::WithoutRuntime.sig { returns(String) }
28
28
  def default_config_file
29
29
  File.join(Dir.home, '.docker', 'config.json')
30
30
  end
31
31
 
32
- sig { params(url: String, username: String, password: String).void }
32
+ # T::Sig::WithoutRuntime.sig { params(url: String, username: String, password: String).void }
33
33
  def login(url:, username:, password:)
34
34
  cmd = [
35
35
  executable, 'login', url, '--username', username, '--password-stdin'
@@ -39,35 +39,43 @@ module Kuby
39
39
  stdin.puts(password)
40
40
  end
41
41
 
42
- unless T.must(last_status).success?
42
+ unless last_status.success?
43
43
  raise LoginError, 'build failed: docker command exited with '\
44
- "status code #{T.must(last_status).exitstatus}"
44
+ "status code #{last_status.exitstatus}"
45
45
  end
46
46
  end
47
47
 
48
- sig { returns(T::Array[String]) }
48
+ # T::Sig::WithoutRuntime.sig { returns(T::Array[String]) }
49
49
  def auths
50
50
  return [] unless config_file
51
51
 
52
- config = JSON.parse(File.read(T.must(config_file)))
52
+ config = JSON.parse(File.read(config_file))
53
53
  config.fetch('auths', {}).keys
54
54
  end
55
55
 
56
- sig {
57
- params(
58
- image: Image,
59
- build_args: T::Hash[T.any(Symbol, String), String],
60
- docker_args: T::Array[String],
61
- context: T.nilable(String)
62
- ).void
63
- }
64
- def build(image, build_args: {}, docker_args: [], context: nil)
56
+ # T::Sig::WithoutRuntime.sig {
57
+ # params(
58
+ # image: Image,
59
+ # build_args: T::Hash[T.any(Symbol, String), String],
60
+ # docker_args: T::Array[String],
61
+ # context: T.nilable(String),
62
+ # cache_from: T.nilable(String)
63
+ # ).void
64
+ # }
65
+ def build(image, build_args: {}, docker_args: [], context: nil, cache_from: nil)
65
66
  cmd = [
66
67
  executable, 'build',
67
68
  *image.tags.flat_map { |tag| ['-t', "#{image.image_url}:#{tag}"] },
68
69
  *build_args.flat_map do |arg, val|
69
70
  ['--build-arg', Shellwords.shellescape("#{arg}=#{val}")]
70
- end,
71
+ end
72
+ ]
73
+
74
+ if cache_from
75
+ cmd += ['--cache-from', cache_from]
76
+ end
77
+
78
+ cmd += [
71
79
  '-f-',
72
80
  *docker_args,
73
81
  context || '.'
@@ -77,21 +85,21 @@ module Kuby
77
85
  stdin.puts(image.dockerfile.to_s)
78
86
  end
79
87
 
80
- unless T.must(last_status).success?
88
+ unless last_status.success?
81
89
  raise BuildError, 'build failed: docker command exited with '\
82
- "status code #{T.must(last_status).exitstatus}"
90
+ "status code #{last_status.exitstatus}"
83
91
  end
84
92
  end
85
93
 
86
- sig {
87
- params(
88
- image_url: String,
89
- tag: String,
90
- env: T::Hash[T.any(Symbol, String), String],
91
- ports: T::Array[T.any(String, Integer)]
92
- )
93
- .void
94
- }
94
+ # T::Sig::WithoutRuntime.sig {
95
+ # params(
96
+ # image_url: String,
97
+ # tag: String,
98
+ # env: T::Hash[T.any(Symbol, String), String],
99
+ # ports: T::Array[T.any(String, Integer)]
100
+ # )
101
+ # .void
102
+ # }
95
103
  def run(image_url:, tag: 'latest', env: {}, ports: [])
96
104
  cmd = [
97
105
  executable, 'run',
@@ -105,13 +113,33 @@ module Kuby
105
113
  execc(cmd)
106
114
  end
107
115
 
108
- sig { params(image_url: String).returns(T::Array[T::Hash[Symbol, String]]) }
109
- def images(image_url)
116
+ # T::Sig::WithoutRuntime.sig { params(container: String, command: String, tty: T::Boolean).returns(String) }
117
+ def exec_capture(container:, command:, tty: true)
118
+ cmd = [executable, 'exec']
119
+ cmd << '-it' if tty
120
+ cmd += [container, command]
121
+
122
+ backticks(cmd)
123
+ end
124
+
125
+ # T::Sig::WithoutRuntime.sig { params(image_url: String, tag: String, format: T.nilable(String)).returns(String) }
126
+ def inspect(image_url:, tag: 'latest', format: nil)
127
+ cmd = [executable, 'inspect']
128
+ cmd += ['--format', "'#{format}'"]
129
+ cmd << "#{image_url}:#{tag}"
130
+
131
+ backticks(cmd)
132
+ end
133
+
134
+ # T::Sig::WithoutRuntime.sig { params(image_url: String, digests: T::Boolean).returns(T::Array[T::Hash[Symbol, String]]) }
135
+ def images(image_url, digests: true)
110
136
  cmd = [
111
137
  executable, 'images', image_url,
112
138
  '--format', '"{{json . }}"'
113
139
  ]
114
140
 
141
+ cmd << '--digests' if digests
142
+
115
143
  backticks(cmd).split("\n").map do |image_data|
116
144
  JSON.parse(image_data).each_with_object({}) do |(k, v), ret|
117
145
  ret[k.underscore.to_sym] = v
@@ -119,41 +147,41 @@ module Kuby
119
147
  end
120
148
  end
121
149
 
122
- sig { params(image_url: String, tag: String).void }
150
+ # T::Sig::WithoutRuntime.sig { params(image_url: String, tag: String).void }
123
151
  def push(image_url, tag)
124
152
  systemm([
125
153
  executable, 'push', "#{image_url}:#{tag}"
126
154
  ])
127
155
 
128
- unless T.must(last_status).success?
156
+ unless last_status.success?
129
157
  raise PushError, 'push failed: docker command exited with '\
130
- "status code #{T.must(last_status).exitstatus}"
158
+ "status code #{last_status.exitstatus}"
131
159
  end
132
160
  end
133
161
 
134
- sig { params(image_url: String, tag: String).void }
162
+ # T::Sig::WithoutRuntime.sig { params(image_url: String, tag: String).void }
135
163
  def pull(image_url, tag)
136
164
  systemm([
137
165
  executable, 'pull', "#{image_url}:#{tag}"
138
166
  ])
139
167
 
140
- unless T.must(last_status).success?
168
+ unless last_status.success?
141
169
  raise PullError, 'pull failed: docker command exited with '\
142
- "status code #{T.must(last_status).exitstatus}"
170
+ "status code #{last_status.exitstatus}"
143
171
  end
144
172
  end
145
173
 
146
- sig { returns(Symbol) }
174
+ # T::Sig::WithoutRuntime.sig { returns(Symbol) }
147
175
  def status_key
148
176
  :kuby_docker_cli_last_status
149
177
  end
150
178
 
151
- sig { returns(Symbol) }
179
+ # T::Sig::WithoutRuntime.sig { returns(Symbol) }
152
180
  def stdout_key
153
181
  :kuby_docker_stdout
154
182
  end
155
183
 
156
- sig { returns(Symbol) }
184
+ # T::Sig::WithoutRuntime.sig { returns(Symbol) }
157
185
  def stderr_key
158
186
  :kuby_docker_stderr
159
187
  end
@@ -3,25 +3,25 @@
3
3
  module Kuby
4
4
  module Docker
5
5
  class CopyPhase < Layer
6
- extend T::Sig
6
+ # extend T::Sig
7
7
 
8
- DEFAULT_PATHS = T.let(['./'].freeze, T::Array[String])
8
+ DEFAULT_PATHS = ['./'].freeze
9
9
 
10
- sig { returns(T::Array[String]) }
10
+ # T::Sig::WithoutRuntime.sig { returns(T::Array[String]) }
11
11
  attr_reader :paths
12
12
 
13
- sig { params(environment: Environment).void }
13
+ # T::Sig::WithoutRuntime.sig { params(environment: Environment).void }
14
14
  def initialize(environment)
15
15
  super
16
- @paths = T.let([], T::Array[String])
16
+ @paths = []
17
17
  end
18
18
 
19
- sig { params(path: String).void }
19
+ # T::Sig::WithoutRuntime.sig { params(path: String).void }
20
20
  def <<(path)
21
21
  paths << path
22
22
  end
23
23
 
24
- sig { params(dockerfile: Dockerfile).void }
24
+ # T::Sig::WithoutRuntime.sig { params(dockerfile: Dockerfile).void }
25
25
  def apply_to(dockerfile)
26
26
  to_copy = paths.empty? ? DEFAULT_PATHS : paths
27
27
  to_copy.each { |path| dockerfile.copy(path, '.') }
@@ -1,4 +1,5 @@
1
1
  # typed: strict
2
+
2
3
  require 'kube-dsl'
3
4
 
4
5
  module Kuby