squared 0.4.19 → 0.5.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 +62 -261
- data/README.md +1280 -647
- data/README.ruby.md +722 -0
- data/lib/squared/common/base.rb +8 -9
- data/lib/squared/common/format.rb +7 -16
- data/lib/squared/common/prompt.rb +38 -42
- data/lib/squared/common/shell.rb +10 -10
- data/lib/squared/common/system.rb +31 -35
- data/lib/squared/common/utils.rb +3 -28
- data/lib/squared/common.rb +2 -1
- data/lib/squared/config.rb +19 -19
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +55 -89
- data/lib/squared/workspace/project/base.rb +262 -403
- data/lib/squared/workspace/project/docker.rb +156 -183
- data/lib/squared/workspace/project/git.rb +337 -481
- data/lib/squared/workspace/project/node.rb +96 -141
- data/lib/squared/workspace/project/python.rb +73 -299
- data/lib/squared/workspace/project/ruby.rb +158 -238
- data/lib/squared/workspace/project/support/class.rb +79 -136
- data/lib/squared/workspace/project.rb +0 -10
- data/lib/squared/workspace/repo.rb +52 -93
- data/lib/squared/workspace/series.rb +16 -16
- data/lib/squared/workspace/support/data.rb +3 -2
- data/lib/squared/workspace/support.rb +0 -1
- data/lib/squared/workspace.rb +1 -1
- data/squared.gemspec +5 -5
- metadata +7 -8
- data/lib/squared/common/class.rb +0 -110
- data/lib/squared/workspace/support/base.rb +0 -17
@@ -4,7 +4,7 @@ module Squared
|
|
4
4
|
module Workspace
|
5
5
|
module Project
|
6
6
|
class Docker < Base
|
7
|
-
COMPOSEFILE = %w[compose.yaml compose.yml docker-compose.yaml docker-compose.yml].freeze
|
7
|
+
COMPOSEFILE = %w[compose.yaml compose.yml docker-compose.yaml compose.yml docker-compose.yml].freeze
|
8
8
|
BAKEFILE = %w[docker-bake.json docker-bake.hcl docker-bake.override.json docker-bake.override.hcl].freeze
|
9
9
|
DIR_DOCKER = (COMPOSEFILE + BAKEFILE).freeze
|
10
10
|
OPT_DOCKER = {
|
@@ -12,59 +12,57 @@ module Squared
|
|
12
12
|
tlskey=p].freeze,
|
13
13
|
buildx: {
|
14
14
|
common: %w[builder=b D|debug],
|
15
|
-
build: %w[add-host=q annotation=q attest=q build-arg=qq
|
16
|
-
|
17
|
-
|
18
|
-
bake: %w[print list=q set=q].freeze,
|
19
|
-
shared: %w[check
|
20
|
-
sbom=q].freeze
|
15
|
+
build: %w[load pull push add-host=q annotation=q attest=q build-arg=qq ent=q iidfile=p label=q a-file=p
|
16
|
+
network=b no-cache-filter=b o|output=q platform=b q|quiet secret=qq shm-size=b ssh=qq t|tag=b
|
17
|
+
target=b ulimit=q].freeze,
|
18
|
+
bake: %w[load print pull push list=q metadata-file=p set=q].freeze,
|
19
|
+
shared: %w[check no-cache allow=q call=b? f|file=p progress=b provenance=q sbom=q].freeze
|
21
20
|
}.freeze,
|
22
21
|
compose: {
|
23
|
-
common: %w[all-resources compatibility dry-run ansi|b env-file=p f|file=p parallel=
|
22
|
+
common: %w[all-resources compatibility dry-run ansi|b env-file=p f|file=p parallel=b profile=b progress=b
|
24
23
|
project-directory=p p|project-name=e].freeze,
|
25
|
-
build: %w[
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
exit-code-from=b no-attach=b pull=b scale=i t|timeout=i wait-timeout=i].freeze,
|
35
|
-
down: %w[remove-orphans v|volumes rmi=b t|timeout=i].freeze
|
24
|
+
build: %w[no-cache pull push with-dependencies q|quiet build-arg=qq builder=b m|memory=b ssh=qq].freeze,
|
25
|
+
exec: %w[dry-run privileged d|detach e|env=qq index=i T|no-TTY=b? user=e w|workdir=q].freeze,
|
26
|
+
run: %w[build dry-run no-deps quiet-pull remove-orphans rm P|service-ports use-aliases cap-add=b cap-drop=b
|
27
|
+
d|detach entrypoint=q e|env=qq i|interactive=b? l|label=q name=b T|no-TTY=b? p|publish=e pull=b
|
28
|
+
u|user=e v|volume=q w|workdir=q].freeze,
|
29
|
+
up: %w[y abort-on-container-exit abort-on-container-failure always-recreate-deps attach-dependencies build
|
30
|
+
d|detach dry-run force-recreate menu no-build no-color no-deps no-log-prefix no-recreate no-start
|
31
|
+
quiet-pull remove-orphans V|renew-anon-volumes timestamps wait w|watch attach=b exit-code-from=b
|
32
|
+
no-attach=b pull=b scale=i t|timeout=i wait-timeout=i].freeze
|
36
33
|
}.freeze,
|
37
34
|
container: {
|
38
35
|
create: %w[init i|interactive no-healthcheck oom-kill-disable privileged P|publish-all q|quiet read-only
|
39
|
-
rm runtime t|tty use-api-socket io-maxbandwidth=b io-maxiops=b add-host=q annotation=q
|
40
|
-
blkio-weight=i blkio-weight-device=i cap-add=b cap-drop=b cgroup-parent=b cgroupns=b
|
41
|
-
device=q device-cgroup-rule=q device-read-bps=q device-read-iops=q device-write-bps=q
|
36
|
+
rm runtime t|tty use-api-socket io-maxbandwidth=b io-maxiops=b add-host=q annotation=q
|
37
|
+
a|attach=b blkio-weight=i blkio-weight-device=i cap-add=b cap-drop=b cgroup-parent=b cgroupns=b
|
38
|
+
cidfile=p device=q device-cgroup-rule=q device-read-bps=q device-read-iops=q device-write-bps=q
|
42
39
|
device-write-iops=q disable-content-trust=b? dns=e dns-option=e dns-search=e domainname=b
|
43
|
-
entrypoint=q e|env=qq env-file=p expose=e gpus=q group-add=b health-cmd=q health-interval=b
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
40
|
+
entrypoint=q e|env=qq env-file=p expose=e gpus=q group-add=b health-cmd=q health-interval=b
|
41
|
+
health-retries=i health-start-interval=b health-start-period=b health-timeout=b h|hostname=e ip=b
|
42
|
+
ip6=e ipc=b isolation=b kernel-memory=b l|label=q label-file=p link=b link-local-ip=b
|
43
|
+
log-driver=b log-opt=q mac-address=e m|memory=b memory-reservation=b memory-swap=n
|
44
|
+
memory-swappiness=n mount=qq name=b network=b network-alias=b oom-score-adj=b pid=b pids-limit=n
|
45
|
+
platform=b p|publish=e pull=b restart=b runtime=b security-opt=q shm-size=b stop-signal=b
|
46
|
+
stop-timeout=i storage-opt=q sysctl=q tmpfs=q ulimit=q u|user=b userns=b uts=b v|volume=q
|
47
|
+
volume-driver=b volumes-from=b w|workdir=q].freeze,
|
50
48
|
run: %w[d|detach detach-keys=q sig-proxy=b?].freeze,
|
49
|
+
exec: %w[d|detach i|interactive privileged t|tty detach-keys=q e|env=qq env-file=p user=e
|
50
|
+
w|workdir=q].freeze,
|
51
51
|
update: %w[blkio-weight=i cpu-period=i cpu-quota=i cpu-rt-period=i cpu-rt-runtime=i c|cpu-shares=i cpus=f
|
52
52
|
cpuset-cpus=b cpuset-mems=b m|memory=b memory-reservation=b memory-swap=b pids-limit=n
|
53
53
|
restart=q].freeze,
|
54
|
-
exec: %w[d|detach i|interactive privileged t|tty detach-keys=q e|env=qq env-file=p user=e
|
55
|
-
w|workdir=q].freeze,
|
56
54
|
commit: %w[a|author=q c|change=q m|message=q pause=b?].freeze,
|
57
55
|
inspect: %w[s|size f|format=q].freeze,
|
58
56
|
start: %w[a|attach i|interactive detach-keys=q].freeze,
|
59
|
-
stop: %w[s|signal=b t|time=i
|
60
|
-
restart: %w[s|signal=b t|time=i
|
57
|
+
stop: %w[s|signal=b t|time=i].freeze,
|
58
|
+
restart: %w[s|signal=b t|time=i].freeze,
|
61
59
|
kill: %w[s|signal=b].freeze,
|
62
|
-
stats: %w[
|
60
|
+
stats: %w[no-trunc format|q].freeze
|
63
61
|
}.freeze,
|
64
62
|
image: {
|
65
|
-
list: %w[a|all
|
63
|
+
list: %w[a|all digests no-trunc f|filter=q format=q].freeze,
|
66
64
|
push: %w[a|all-tags disable-content-trust=b? platform=b q|quiet].freeze,
|
67
|
-
rm: %w[f|force no-prune
|
65
|
+
rm: %w[f|force no-prune].freeze,
|
68
66
|
save: %w[o|output=p platform=b].freeze
|
69
67
|
}.freeze,
|
70
68
|
network: {
|
@@ -74,11 +72,8 @@ module Squared
|
|
74
72
|
}.freeze
|
75
73
|
VAL_DOCKER = {
|
76
74
|
run: {
|
77
|
-
|
78
|
-
|
79
|
-
volume: %w[volume-subpath volume-nocopy volume-opt].freeze,
|
80
|
-
tmpfs: %w[tmpfs-size tmpfs-mode].freeze,
|
81
|
-
image: %w[image-path].freeze
|
75
|
+
bind: %w[type source src destination dst target readonly ro bind-propagation].freeze,
|
76
|
+
tmpfs: %w[type destination dst target tmpfs-size tmpfs-mode].freeze
|
82
77
|
}.freeze
|
83
78
|
}.freeze
|
84
79
|
private_constant :COMPOSEFILE, :BAKEFILE, :OPT_DOCKER, :VAL_DOCKER
|
@@ -96,9 +91,8 @@ module Squared
|
|
96
91
|
end
|
97
92
|
|
98
93
|
subtasks({
|
99
|
-
'build' => %i[tag context].freeze,
|
100
|
-
'compose' => %i[build run exec up
|
101
|
-
'bake' => %i[build check].freeze,
|
94
|
+
'build' => %i[tag context bake].freeze,
|
95
|
+
'compose' => %i[build run exec up].freeze,
|
102
96
|
'image' => %i[list rm push tag save].freeze,
|
103
97
|
'container' => %i[run create exec update commit inspect diff start stop restart pause unpause top stats kill
|
104
98
|
rm].freeze,
|
@@ -117,6 +111,7 @@ module Squared
|
|
117
111
|
@mounts = mounts
|
118
112
|
@secrets = secrets
|
119
113
|
@registry = tagjoin registry, kwargs[:username]
|
114
|
+
@file = nil
|
120
115
|
initialize_ref Docker.ref
|
121
116
|
initialize_logger(**kwargs)
|
122
117
|
initialize_env(**kwargs)
|
@@ -129,11 +124,11 @@ module Squared
|
|
129
124
|
|
130
125
|
def populate(*, **)
|
131
126
|
super
|
132
|
-
return unless ref?(Docker.ref)
|
127
|
+
return unless ref?(Docker.ref)
|
133
128
|
|
134
129
|
namespace name do
|
135
130
|
Docker.subtasks do |action, flags|
|
136
|
-
next if
|
131
|
+
next if @pass.include?(action)
|
137
132
|
|
138
133
|
namespace action do
|
139
134
|
flags.each do |flag|
|
@@ -146,39 +141,26 @@ module Squared
|
|
146
141
|
param = param_guard(action, flag, args: args, key: flag)
|
147
142
|
buildx(:build, args.extras, "#{flag}": param)
|
148
143
|
end
|
149
|
-
|
150
|
-
|
151
|
-
break unless bake?
|
152
|
-
|
153
|
-
case flag
|
154
|
-
when :build
|
155
|
-
format_desc action, flag, 'opts*,target*,context?|:'
|
144
|
+
when :bake
|
145
|
+
format_desc action, flag, ':?,opts*,target*,context?'
|
156
146
|
task flag do |_, args|
|
157
147
|
args = args.to_a
|
158
148
|
if args.first == ':'
|
159
149
|
choice_command :bake
|
160
150
|
else
|
161
|
-
buildx
|
151
|
+
buildx flag, args
|
162
152
|
end
|
163
153
|
end
|
164
|
-
when :check
|
165
|
-
format_desc action, flag, 'target'
|
166
|
-
task flag, [:target] do |_, args|
|
167
|
-
target = param_guard(action, flag, args: args, key: :target)
|
168
|
-
buildx :bake, ['allow=fs.read=*', 'call=check', target]
|
169
|
-
end
|
170
154
|
end
|
171
155
|
when 'compose'
|
172
|
-
break unless compose?
|
173
|
-
|
174
156
|
case flag
|
175
|
-
when :build, :up
|
157
|
+
when :build, :up
|
176
158
|
format_desc action, flag, 'opts*,service*'
|
177
159
|
task flag do |_, args|
|
178
160
|
compose! flag, args.to_a
|
179
161
|
end
|
180
162
|
when :exec, :run
|
181
|
-
format_desc action, flag, "service,command#{flag == :exec ? '' : '?'}
|
163
|
+
format_desc action, flag, "service,command#{flag == :exec ? '' : '?'},args*,opts*"
|
182
164
|
task flag, [:service] do |_, args|
|
183
165
|
service = param_guard(action, flag, args: args, key: :service)
|
184
166
|
compose!(flag, args.extras, service: service)
|
@@ -216,15 +198,14 @@ module Squared
|
|
216
198
|
when :push
|
217
199
|
format_desc action, flag, 'tag,registry/username?,opts*'
|
218
200
|
task flag, [:tag] do |_, args|
|
219
|
-
|
220
|
-
image(flag, args.extras, id:
|
201
|
+
id = param_guard(action, flag, args: args, key: :tag)
|
202
|
+
image(flag, args.extras, id: id)
|
221
203
|
end
|
222
204
|
else
|
223
205
|
format_desc(action, flag, case flag
|
224
206
|
when :rm, :save then 'id*,opts*'
|
225
207
|
when :tag then 'version?'
|
226
|
-
else 'opts*,args*'
|
227
|
-
end)
|
208
|
+
else 'opts*,args*' end)
|
228
209
|
task flag do |_, args|
|
229
210
|
args = args.to_a
|
230
211
|
if args.empty? && flag != :list
|
@@ -261,11 +242,12 @@ module Squared
|
|
261
242
|
|
262
243
|
ret = docker_session
|
263
244
|
if from == :run
|
264
|
-
|
245
|
+
case (n = filetype)
|
246
|
+
when 1, 2
|
265
247
|
ret << 'buildx' << 'bake'
|
266
248
|
append_file n
|
267
249
|
from = :bake
|
268
|
-
|
250
|
+
when 3, 4
|
269
251
|
ret << 'compose' << 'build'
|
270
252
|
append_file n
|
271
253
|
from = :compose
|
@@ -283,11 +265,10 @@ module Squared
|
|
283
265
|
when Enumerable
|
284
266
|
ret.merge(opts.to_a)
|
285
267
|
end
|
268
|
+
|
286
269
|
[args, flags].each_with_index do |target, index|
|
287
|
-
if target
|
288
|
-
ret
|
289
|
-
elsif (target = append_any(target, target: []))
|
290
|
-
ret.merge(target.map { |arg| index == 0 ? fill_option(arg) : quote_option('build-arg', arg) })
|
270
|
+
if (data = append_any(target, target: []))
|
271
|
+
ret.merge(data.map { |arg| index == 0 ? fill_option(arg) : quote_option('build-arg', arg) })
|
291
272
|
end
|
292
273
|
end
|
293
274
|
case from
|
@@ -297,12 +278,12 @@ module Squared
|
|
297
278
|
ret << quote_option('secret', @secrets, double: true)
|
298
279
|
when Hash
|
299
280
|
append = lambda do |type|
|
300
|
-
|
281
|
+
as_a(@secrets[type]).each { |arg| ret << quote_option('secret', "type=#{type},#{arg}", double: true) }
|
301
282
|
end
|
302
283
|
append.call(:file)
|
303
284
|
append.call(:env)
|
304
285
|
else
|
305
|
-
|
286
|
+
as_a(@secrets).each { |arg| ret << quote_option('secret', arg) }
|
306
287
|
end
|
307
288
|
if (val = option('tag', ignore: false))
|
308
289
|
append_tag val
|
@@ -311,8 +292,8 @@ module Squared
|
|
311
292
|
end
|
312
293
|
append_context
|
313
294
|
when :bake, :compose
|
314
|
-
|
315
|
-
ret.merge(split_escape(
|
295
|
+
option(from == :bake ? 'target' : 'service', ignore: false) do |a|
|
296
|
+
ret.merge(split_escape(a).map! { |b| shell_escape(b) })
|
316
297
|
end
|
317
298
|
end
|
318
299
|
ret
|
@@ -325,20 +306,20 @@ module Squared
|
|
325
306
|
op.parse(OPT_DOCKER[:buildx][flag == :bake ? :bake : :build] + OPT_DOCKER[:buildx][:shared])
|
326
307
|
case flag
|
327
308
|
when :build, :context
|
328
|
-
append_tag(tag || option('tag', ignore: false) ||
|
309
|
+
append_tag(tag || option('tag', ignore: false) || @tag)
|
329
310
|
append_context context
|
330
311
|
when :bake
|
331
312
|
unless op.empty?
|
332
313
|
args = op.dup
|
333
|
-
op.
|
314
|
+
op.extras.clear
|
334
315
|
if Dir.exist?(args.last)
|
335
316
|
if projectpath?(val = args.pop)
|
336
317
|
context = val
|
337
318
|
else
|
338
|
-
op.
|
319
|
+
op.extras << val
|
339
320
|
end
|
340
321
|
end
|
341
|
-
op.append(args, escape: true
|
322
|
+
op.append(args, escape: true)
|
342
323
|
contextdir context if context
|
343
324
|
end
|
344
325
|
end
|
@@ -351,14 +332,15 @@ module Squared
|
|
351
332
|
op = OptionPartition.new(opts, OPT_DOCKER[:compose][:common], cmd, project: self)
|
352
333
|
append_file filetype unless op.arg?('f', 'file')
|
353
334
|
op << flag
|
354
|
-
op.parse(OPT_DOCKER[:compose]
|
335
|
+
op.parse(OPT_DOCKER[:compose][flag])
|
336
|
+
from = :"compose:#{flag}"
|
355
337
|
case flag
|
356
|
-
when :build, :up
|
357
|
-
op.append(escape: true
|
338
|
+
when :build, :up
|
339
|
+
op.append(escape: true)
|
358
340
|
when :exec, :run
|
359
|
-
append_command
|
341
|
+
append_command(flag, service, op.extras, from: from)
|
360
342
|
end
|
361
|
-
run(from:
|
343
|
+
run(from: from)
|
362
344
|
end
|
363
345
|
|
364
346
|
def container(flag, opts = [], id: nil)
|
@@ -373,54 +355,44 @@ module Squared
|
|
373
355
|
when :run, :create, :exec
|
374
356
|
if rc && !op.arg?('mount')
|
375
357
|
run = VAL_DOCKER[:run]
|
376
|
-
|
377
|
-
|
378
|
-
|
358
|
+
both = run[:bind] + run[:tmpfs]
|
359
|
+
diff = run[:bind].reject { |val| run[:tmpfs].include?(val) }
|
360
|
+
delim = Regexp.new(",\\s*(?=#{both.join('|')})")
|
361
|
+
as_a(@mounts).each do |val|
|
379
362
|
args = []
|
380
|
-
|
363
|
+
tmpfs = true
|
381
364
|
val.split(delim).each do |opt|
|
382
365
|
k, v, q = split_option opt
|
383
|
-
|
384
|
-
case v
|
385
|
-
when 'bind', 'volume', 'image', 'tmpfs'
|
386
|
-
type = v
|
387
|
-
else
|
388
|
-
raise_error("unknown type: #{v}", hint: flag)
|
389
|
-
end
|
390
|
-
elsif all.include?(k)
|
391
|
-
unless type
|
392
|
-
run.each_pair do |key, val|
|
393
|
-
next unless val.include?(k)
|
366
|
+
next unless both.include?(k)
|
394
367
|
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
when 'readonly', 'ro'
|
401
|
-
args << k
|
402
|
-
next
|
403
|
-
when 'source', 'src', 'destination', 'dst', 'target', 'volume-subpath', 'image-path'
|
404
|
-
v = path + v
|
405
|
-
v = shell_quote(v, option: false, force: false) if q == ''
|
406
|
-
end
|
407
|
-
args << "#{k}=#{q + v + q}"
|
408
|
-
elsif verbose
|
409
|
-
log_message(Logger::INFO, 'unrecognized option', subject: from, hint: k)
|
368
|
+
if k == 'type'
|
369
|
+
tmpfs = false if v == 'bind'
|
370
|
+
next
|
371
|
+
elsif diff.include?(k)
|
372
|
+
tmpfs = false
|
410
373
|
end
|
374
|
+
case k
|
375
|
+
when 'readonly', 'ro'
|
376
|
+
args << k
|
377
|
+
next
|
378
|
+
when 'source', 'src', 'destination', 'dst', 'target'
|
379
|
+
v = path + v
|
380
|
+
v = shell_quote(v, option: false, force: false) if q == ''
|
381
|
+
tmpfs = false if k[0] == 's'
|
382
|
+
end
|
383
|
+
args << "#{k}=#{q + v + q}"
|
411
384
|
end
|
412
|
-
|
413
|
-
cmd << "--mount type=#{type},#{args.join(',')}"
|
385
|
+
cmd << "--mount type=#{tmpfs ? 'tmpfs' : 'bind'},#{args.join(',')}"
|
414
386
|
end
|
415
387
|
end
|
416
|
-
append_command(flag, id || tagmain, op.extras)
|
388
|
+
append_command(flag, id || tagmain, op.extras, from: from)
|
417
389
|
when :update
|
418
|
-
raise_error('missing container', hint:
|
419
|
-
op.append(escape: true
|
390
|
+
raise_error('missing container', hint: from) if op.empty?
|
391
|
+
op.append(escape: true)
|
420
392
|
when :commit
|
421
393
|
latest = op.shift || tagmain
|
422
394
|
cmd << id << latest
|
423
|
-
raise_error("unknown args: #{op.join(', ')}", hint:
|
395
|
+
raise_error("unknown args: #{op.join(', ')}", hint: from) unless op.empty?
|
424
396
|
return unless confirm_command(cmd.to_s, title: from, target: id, as: latest)
|
425
397
|
|
426
398
|
registry = option('registry') || @registry
|
@@ -463,13 +435,13 @@ module Squared
|
|
463
435
|
when :rm
|
464
436
|
status = %w[created exited dead]
|
465
437
|
end
|
466
|
-
ps = docker_output('ps -a', *status.map { |s|
|
438
|
+
ps = docker_output('ps -a', *status.map { |s| "--filter=\"status=#{s}\"" })
|
467
439
|
list_image(flag, ps, no: no, hint: "status: #{status.join(', ')}", from: from) do |img|
|
468
440
|
run(cmd.temp(img), from: from)
|
469
441
|
end
|
470
442
|
return
|
471
443
|
else
|
472
|
-
op.append(escape: true
|
444
|
+
op.append(escape: true)
|
473
445
|
end
|
474
446
|
end
|
475
447
|
run(from: from)
|
@@ -527,10 +499,10 @@ module Squared
|
|
527
499
|
when :push
|
528
500
|
id ||= option('tag', ignore: false) || tagmain
|
529
501
|
registry ||= op.shift || option('registry') || @registry
|
530
|
-
raise_error(id ? "unknown args: #{op.join(', ')}" : 'no id/tag given', hint:
|
531
|
-
raise_error('username/registry not provided', hint:
|
502
|
+
raise_error(id ? "unknown args: #{op.join(', ')}" : 'no id/tag given', hint: from) unless id && op.empty?
|
503
|
+
raise_error('username/registry not provided', hint: from) unless registry
|
532
504
|
registry.chomp!('/')
|
533
|
-
uri = shell_quote
|
505
|
+
uri = shell_quote "#{registry}/#{id}"
|
534
506
|
op << uri
|
535
507
|
img = docker_output 'image', 'tag', id, uri
|
536
508
|
return unless confirm_command(img.to_s, cmd.to_s, target: id, as: registry, title: from)
|
@@ -546,7 +518,7 @@ module Squared
|
|
546
518
|
|
547
519
|
def network(flag, opts = [], target: nil)
|
548
520
|
cmd, opts = docker_session('network', flag, opts: opts)
|
549
|
-
op = OptionPartition.new(opts, OPT_DOCKER[:network]
|
521
|
+
op = OptionPartition.new(opts, OPT_DOCKER[:network][flag], cmd, project: self)
|
550
522
|
op.clear
|
551
523
|
from = :"network:#{flag}"
|
552
524
|
list_image(flag, docker_output('ps -a'), from: from) do |img|
|
@@ -562,18 +534,6 @@ module Squared
|
|
562
534
|
super || dockerfile.exist?
|
563
535
|
end
|
564
536
|
|
565
|
-
def compose?(file = dockerfile)
|
566
|
-
return file == 3 || file == 4 if file.is_a?(Numeric)
|
567
|
-
|
568
|
-
COMPOSEFILE.include?(File.basename(file))
|
569
|
-
end
|
570
|
-
|
571
|
-
def bake?(file = dockerfile)
|
572
|
-
return file == 1 || file == 2 if file.is_a?(Numeric)
|
573
|
-
|
574
|
-
BAKEFILE.include?(File.basename(file))
|
575
|
-
end
|
576
|
-
|
577
537
|
def dockerfile(val = nil)
|
578
538
|
if val == 'Dockerfile'
|
579
539
|
@file = false
|
@@ -603,41 +563,35 @@ module Squared
|
|
603
563
|
session('docker', *cmd, main: false, options: false, **kwargs)
|
604
564
|
end
|
605
565
|
|
606
|
-
def append_command(flag, val, list, target: @session)
|
607
|
-
if
|
608
|
-
list << readline('Enter command [args]', force: true)
|
609
|
-
elsif (args = env('DOCKER_ARGS'))
|
566
|
+
def append_command(flag, val, list, target: @session, from: nil)
|
567
|
+
if (args = env('DOCKER_ARGS'))
|
610
568
|
list << args
|
611
569
|
end
|
612
570
|
case flag
|
613
571
|
when :run
|
614
572
|
unless session_arg?('name', target: target)
|
615
|
-
target << basic_option('name', dnsname("#{name}_%s" %
|
573
|
+
target << basic_option('name', dnsname("#{name}_%s" % if RUBY_VERSION >= '3.1'
|
574
|
+
require 'random/formatter'
|
575
|
+
Random.new.alphanumeric(6)
|
576
|
+
else
|
577
|
+
(0...6).map { rand(97..122).chr }.join
|
578
|
+
end))
|
616
579
|
end
|
617
580
|
when :exec
|
618
|
-
raise_error('no command args', hint:
|
581
|
+
raise_error('no command args', hint: from) if list.empty?
|
619
582
|
end
|
620
583
|
target << val << list.shift
|
621
584
|
target << list.join(' && ') unless list.empty?
|
622
585
|
end
|
623
586
|
|
624
587
|
def append_file(type, target: @session)
|
625
|
-
return
|
588
|
+
return unless type == 2 || type == 4 || @file.is_a?(Array)
|
626
589
|
|
627
|
-
|
628
|
-
case type
|
629
|
-
when 2, 4
|
630
|
-
return
|
631
|
-
when 3
|
632
|
-
return unless COMPOSEFILE.map { |val| path + val }.select(&:exist?).size > 1
|
633
|
-
end
|
634
|
-
end
|
635
|
-
files = Array(@file).map { |val| quote_option('file', path + val) }
|
590
|
+
files = as_a(@file).map { |val| quote_option('file', path + val) }
|
636
591
|
if target.is_a?(Set)
|
637
|
-
|
638
|
-
target.clear.merge(opts)
|
592
|
+
target.merge(files)
|
639
593
|
else
|
640
|
-
target.
|
594
|
+
target.concat(files)
|
641
595
|
end
|
642
596
|
end
|
643
597
|
|
@@ -649,18 +603,20 @@ module Squared
|
|
649
603
|
end
|
650
604
|
|
651
605
|
def append_tag(val, target: @session)
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
606
|
+
case val
|
607
|
+
when String
|
608
|
+
val.split(',')
|
609
|
+
when Array
|
610
|
+
val
|
611
|
+
else
|
612
|
+
[]
|
613
|
+
end.yield_self do |list|
|
614
|
+
ver = option('version', target: target, ignore: false)
|
615
|
+
list.each do |s|
|
616
|
+
s = "#{s}:#{ver}" if ver && (!s.include?(':') || s.delete_suffix!(':latest'))
|
617
|
+
target << basic_option('tag', tagname(s))
|
618
|
+
end
|
619
|
+
target
|
664
620
|
end
|
665
621
|
end
|
666
622
|
|
@@ -670,7 +626,7 @@ module Squared
|
|
670
626
|
index = 0
|
671
627
|
all = option('all', prefix: 'docker')
|
672
628
|
y = from == :'image:rm' && option('y', prefix: 'docker')
|
673
|
-
pat =
|
629
|
+
pat = /^(?:#{dnsname(name)}|#{tagname(project)}|#{tagmain.split(':', 2).first})(?:[_.,:-]|$)/
|
674
630
|
IO.popen(session_done(cmd << '--format=json')).each do |line|
|
675
631
|
data = JSON.parse(line)
|
676
632
|
id = data['ID']
|
@@ -707,7 +663,7 @@ module Squared
|
|
707
663
|
cols.each do |key|
|
708
664
|
next if (key == 'Tag' && !dd) || (key == 'Size' && data[key] == '0B')
|
709
665
|
|
710
|
-
puts "#{g + f} #{key}: #{
|
666
|
+
puts "#{g + f} #{key}: #{as_a(data[key]).join(', ')}" unless data[key].to_s.empty?
|
711
667
|
end
|
712
668
|
w = 9 + flag.to_s.size + 4 + ee.size
|
713
669
|
puts g + sub_style(ARG[:BORDER][6] + (ARG[:BORDER][1] * w), styles: theme[:inline])
|
@@ -719,10 +675,14 @@ module Squared
|
|
719
675
|
end
|
720
676
|
yield id
|
721
677
|
end
|
722
|
-
puts log_message(Logger::INFO, 'none detected', subject: name, hint: hint
|
678
|
+
puts log_message(Logger::INFO, 'none detected', subject: "#{name}:#{from}", hint: hint) if found || y
|
723
679
|
end
|
724
680
|
rescue StandardError => e
|
725
|
-
|
681
|
+
log.error e
|
682
|
+
ret = on(:error, from, e)
|
683
|
+
raise if exception && ret != true
|
684
|
+
|
685
|
+
warn log_message(Logger::WARN, e, pass: true) if warning?
|
726
686
|
end
|
727
687
|
|
728
688
|
def confirm_command(*args, title: nil, target: nil, as: nil)
|
@@ -779,7 +739,7 @@ module Squared
|
|
779
739
|
cmd = docker_output ctx
|
780
740
|
case flag
|
781
741
|
when :tag
|
782
|
-
args = tagjoin @registry, tag
|
742
|
+
args = tagjoin @registry, @tag
|
783
743
|
when :save
|
784
744
|
opts = "#{opts}.tar" unless opts.end_with?('.tar')
|
785
745
|
cmd << quote_option('output', File.expand_path(opts))
|
@@ -790,9 +750,13 @@ module Squared
|
|
790
750
|
else
|
791
751
|
cmd << opts << '--'
|
792
752
|
end
|
793
|
-
cmd.merge(
|
753
|
+
cmd.merge(if out.is_a?(Array)
|
754
|
+
out.map! { |val| parse.call(val) }
|
755
|
+
else
|
756
|
+
[parse.call(out)]
|
757
|
+
end)
|
794
758
|
cmd << args
|
795
|
-
print_success if success?(run(cmd)) && ctx.
|
759
|
+
print_success if success?(run(cmd)) && ctx.start_with?(/(?:network|tag|save)/)
|
796
760
|
end
|
797
761
|
end
|
798
762
|
|
@@ -802,7 +766,7 @@ module Squared
|
|
802
766
|
bake?(val) ? 1 : 2
|
803
767
|
when '.yml', '.yaml'
|
804
768
|
if compose?(val)
|
805
|
-
|
769
|
+
path.children.any? { |file| bake?(file) } ? 1 : 3
|
806
770
|
else
|
807
771
|
4
|
808
772
|
end
|
@@ -822,9 +786,10 @@ module Squared
|
|
822
786
|
|
823
787
|
def tagname(val)
|
824
788
|
val = val.split(':').map! { |s| charname(s.sub(/^\W+/, '')) }
|
825
|
-
|
826
|
-
|
827
|
-
|
789
|
+
val.join(':').yield_self do |s|
|
790
|
+
s = val.first if val.size > 1 && s.size > 128
|
791
|
+
s[0..127]
|
792
|
+
end
|
828
793
|
end
|
829
794
|
|
830
795
|
def dnsname(val)
|
@@ -838,6 +803,14 @@ module Squared
|
|
838
803
|
def tagmain
|
839
804
|
tag.is_a?(Array) ? tag.first : tag
|
840
805
|
end
|
806
|
+
|
807
|
+
def compose?(file = dockerfile)
|
808
|
+
COMPOSEFILE.include?(File.basename(file))
|
809
|
+
end
|
810
|
+
|
811
|
+
def bake?(file = dockerfile)
|
812
|
+
BAKEFILE.include?(File.basename(file))
|
813
|
+
end
|
841
814
|
end
|
842
815
|
|
843
816
|
Application.implement Docker
|