donce 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87e27e95378a5ad34a9ba6a7ef7c8578efb3d24990998beada04097c1a46d5c1
4
- data.tar.gz: 0ea31ae8977024be7abdbc164a3250a8eb907511ea24b5427b2eb3f8960b2912
3
+ metadata.gz: 77e8fc303600f62224be74352774a1d7d2a0e151cf4935316112874bf2b4c39f
4
+ data.tar.gz: 220d2d7b9fcdcd4702fb594daf2211a0268f54a7fc21231bbf8e4a670f75d796
5
5
  SHA512:
6
- metadata.gz: df41062bb8aea186f7bafc2df0070d7abbf1238d2eea5270f49a62e1901a495b0d50afca4659b5314ea0ea0117a299241b8757369a07b5e384cd8595abf956f2
7
- data.tar.gz: 2d6de2cde5d5df5dc3048bb7e9d68cc8b866ec76842f9ce7f9441a4b3b1f683a58e65428c558244c02ab2bcf1a6760606f1e63cea7a7c1a77f08778a18c59fd4
6
+ metadata.gz: 5e70dc715fb1b8166a6bf0805639b7f384e5f346438fdd8c030444d02a7fee8bcfb042ccd1bf71ef095ca201f1dbb4f586a30fe50a102686eb5b4dff6e6e2ee8
7
+ data.tar.gz: 2a4bf49df247f331a36dfaffb055a66f38e207dda78133c49d7db95e7178be4421253803d456e931cb40227802142c7f5d7363b11cb36345d85c662d79f00800
data/Gemfile CHANGED
@@ -28,7 +28,7 @@ gem 'minitest', '5.25.4', require: false
28
28
  gem 'minitest-reporters', '1.7.1', require: false
29
29
  gem 'minitest-retry', '0.2.5', require: false
30
30
  gem 'rake', '13.2.1', require: false
31
- gem 'rspec-rails', '7.1.0', require: false
31
+ gem 'rspec-rails', '7.1.1', require: false
32
32
  gem 'rubocop', '1.71.2', require: false
33
33
  gem 'rubocop-minitest', '0.36.0', require: false
34
34
  gem 'rubocop-performance', '1.23.1', require: false
data/Gemfile.lock CHANGED
@@ -134,7 +134,7 @@ GEM
134
134
  reline (0.6.0)
135
135
  io-console (~> 0.5)
136
136
  rexml (3.4.0)
137
- rspec-core (3.13.2)
137
+ rspec-core (3.13.3)
138
138
  rspec-support (~> 3.13.0)
139
139
  rspec-expectations (3.13.3)
140
140
  diff-lcs (>= 1.2.0, < 2.0)
@@ -142,7 +142,7 @@ GEM
142
142
  rspec-mocks (3.13.2)
143
143
  diff-lcs (>= 1.2.0, < 2.0)
144
144
  rspec-support (~> 3.13.0)
145
- rspec-rails (7.1.0)
145
+ rspec-rails (7.1.1)
146
146
  actionpack (>= 7.0)
147
147
  activesupport (>= 7.0)
148
148
  railties (>= 7.0)
@@ -213,7 +213,7 @@ DEPENDENCIES
213
213
  minitest-reporters (= 1.7.1)
214
214
  minitest-retry (= 0.2.5)
215
215
  rake (= 13.2.1)
216
- rspec-rails (= 7.1.0)
216
+ rspec-rails (= 7.1.1)
217
217
  rubocop (= 1.71.2)
218
218
  rubocop-minitest (= 0.36.0)
219
219
  rubocop-performance (= 1.23.1)
data/donce.gemspec CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
26
26
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
27
27
  s.required_ruby_version = '>=3.0'
28
28
  s.name = 'donce'
29
- s.version = '0.0.4'
29
+ s.version = '0.1.0'
30
30
  s.license = 'MIT'
31
31
  s.summary = 'Builds and starts temporary Docker containers'
32
32
  s.description =
data/lib/donce.rb CHANGED
@@ -68,18 +68,21 @@ module Kernel
68
68
 
69
69
  # Build Docker image (or use existing one), run Docker container, and then clean up.
70
70
  #
71
- # @param [String] dockerfile The content of the +Dockerfile+
71
+ # @param [String] dockerfile The content of the +Dockerfile+ (if array is provided, it will be concatenated)
72
72
  # @param [String] home The directory with Dockerfile and all other necessary files
73
73
  # @param [String] image The name of Docker image, e.g. "ubuntu:24.04"
74
74
  # @param [Logger] log The logging destination, can be +$stdout+
75
75
  # @param [String|Array<String>] args List of extra arguments for the +docker+ command
76
76
  # @param [Hash<String,String>] env Environment variables going into the container
77
+ # @param [Hash<String,String>] volumes Local to container volumes mapping
78
+ # @param [Hash<String,String>] ports Local to container port mapping
79
+ # @param [Hash<String,String>] build_args Arguments for +docker build+ as +--build-arg+ may need
77
80
  # @param [Boolean] root Let user inside the container be "root"?
78
81
  # @param [String|Array<String>] command The command for the script inside the container
79
82
  # @param [Integer] timeout Maximum seconds to spend on each +docker+ call
80
83
  # @return [String] The stdout of the container
81
84
  def donce(dockerfile: nil, image: nil, home: nil, log: $stdout, args: '', env: {}, root: false, command: '',
82
- timeout: 10)
85
+ timeout: 10, volumes: {}, ports: {}, build_args: {})
83
86
  raise 'Either use "dockerfile" or "home"' if dockerfile && home
84
87
  raise 'Either use "dockerfile" or "image"' if dockerfile && image
85
88
  raise 'Either use "image" or "home"' if home && image
@@ -90,13 +93,20 @@ module Kernel
90
93
  image
91
94
  else
92
95
  i = "donce-#{SecureRandom.hex(6)}"
96
+ a = [
97
+ "--tag #{i}",
98
+ build_args.map { |k, v| "--build-arg #{Shellwords.escape("#{k}=#{v}")}" }.join(' ')
99
+ ].join(' ')
93
100
  if dockerfile
94
101
  Dir.mktmpdir do |tmp|
102
+ dockerfile = dockerfile.join("\n") if dockerfile.is_a?(Array)
95
103
  File.write(File.join(tmp, 'Dockerfile'), dockerfile)
96
- qbash("#{docker} build #{Shellwords.escape(tmp)} -t #{i}", log:)
104
+ qbash("#{docker} build #{a} #{Shellwords.escape(tmp)}", log:)
97
105
  end
106
+ elsif home
107
+ qbash("#{docker} build #{a} #{Shellwords.escape(home)}", log:)
98
108
  else
99
- qbash("#{docker} build #{Shellwords.escape(home)} -t #{i}", log:)
109
+ raise 'Either "dockerfile" or "home" must be provided'
100
110
  end
101
111
  i
102
112
  end
@@ -107,15 +117,17 @@ module Kernel
107
117
  begin
108
118
  cmd = [
109
119
  docker, 'run',
110
- block_given? ? '-d' : '',
120
+ block_given? ? '--detach' : nil,
111
121
  '--name', Shellwords.escape(container),
112
- OS.linux? ? '' : "--add-host #{donce_host}:host-gateway",
122
+ OS.linux? ? nil : "--add-host #{donce_host}:host-gateway",
113
123
  args,
114
- env.map { |k, v| "-e #{Shellwords.escape("#{k}=#{v}")}" }.join(' '),
115
- root ? '' : "--user=#{Shellwords.escape("#{Process.uid}:#{Process.gid}")}",
124
+ env.map { |k, v| "--env #{Shellwords.escape("#{k}=#{v}")}" }.join(' '),
125
+ ports.map { |k, v| "--publish #{Shellwords.escape("#{k}:#{v}")}" }.join(' '),
126
+ volumes.map { |k, v| "--volume #{Shellwords.escape("#{k}:#{v}")}" }.join(' '),
127
+ root ? nil : "--user=#{Shellwords.escape("#{Process.uid}:#{Process.gid}")}",
116
128
  Shellwords.escape(img),
117
129
  command
118
- ].join(' ')
130
+ ].compact.join(' ')
119
131
  stdout, code =
120
132
  Timeout.timeout(timeout) do
121
133
  qbash(
@@ -140,7 +152,7 @@ module Kernel
140
152
  log:
141
153
  )
142
154
  stdout = logs if block_given?
143
- qbash("#{docker} rm -f #{Shellwords.escape(container)}", log:)
155
+ qbash("#{docker} rm --force #{Shellwords.escape(container)}", log:)
144
156
  end
145
157
  stdout
146
158
  ensure
data/test/test_donce.rb CHANGED
@@ -34,6 +34,20 @@ class TestDonce < Minitest::Test
34
34
  assert_equal("hello\n", stdout)
35
35
  end
36
36
 
37
+ def test_prints_build_args
38
+ stdout = donce(
39
+ dockerfile: [
40
+ 'FROM ubuntu',
41
+ 'ARG FOO=what?',
42
+ 'RUN echo $FOO > /tmp/foo',
43
+ 'CMD cat /tmp/foo'
44
+ ],
45
+ build_args: { 'FOO' => 'hello' },
46
+ log: Loog::NULL
47
+ )
48
+ assert_equal("hello\n", stdout)
49
+ end
50
+
37
51
  def test_runs_existing_image
38
52
  stdout = donce(image: 'ubuntu:24.04', command: 'echo hello', log: Loog::NULL)
39
53
  assert_equal("hello\n", stdout)
@@ -47,6 +61,24 @@ class TestDonce < Minitest::Test
47
61
  end
48
62
  end
49
63
 
64
+ def test_copies_resources
65
+ content = 'hello!'
66
+ Dir.mktmpdir do |home|
67
+ File.write(File.join(home, 'test.txt'), content)
68
+ File.write(
69
+ File.join(home, 'Dockerfile'),
70
+ [
71
+ 'FROM ubuntu',
72
+ 'WORKDIR /foo',
73
+ 'COPY test.txt .',
74
+ 'CMD cat test.txt'
75
+ ].join("\n")
76
+ )
77
+ stdout = donce(home:, log: Loog::NULL)
78
+ assert_equal(content, stdout)
79
+ end
80
+ end
81
+
50
82
  def test_runs_daemon
51
83
  seen = false
52
84
  donce(dockerfile: "FROM ubuntu\nCMD while true; do sleep 1; echo sleeping; done", log: Loog::NULL) do |id|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: donce
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-02-06 00:00:00.000000000 Z
11
+ date: 2025-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace