squared 0.5.5 → 0.5.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e2f535f6c08d8ee1abce8aeefe9f0bd9ead9af0c6ef8cf3925561b1235606017
4
- data.tar.gz: 2517079e95af88ddcb835c564b7c4e0d429823ca1bde22a403afa54e2cba56fd
3
+ metadata.gz: 40b39041151c559d38910aa11e68b6aa9cc28d1bb67176559193da4005cdda15
4
+ data.tar.gz: cc6753a83f0390110e723cf92830cbb4c441d0e0c794d837fe5c20956cab713a
5
5
  SHA512:
6
- metadata.gz: 07da4a2cb18fdf2a2aef060a60e03a1dba007937ae4300abb29aee8708b9be5d16472f09a6e9762aead5ad99de66ef1724c8be3842a4039b94ed73eacfa1ada4
7
- data.tar.gz: 86c0b904ce9aa176a3aa1a7950e44a5b4e178adac6387a3aa25773ed680c07d567249ed593b4389376598aca05800e5bfce304d02b1c7ff858e4abb8733d5320
6
+ metadata.gz: 36c3de2c6763c0d66b28a353cf36fca2de5eb5fe90de5eee457bf1802d23b18db8ac4a2e78d01799a993cf370cb96b068f2d4acda4cc049c1e70f2f5cbcfb004
7
+ data.tar.gz: 0e8d0aee698b441c8c4b3eec2a79cb52cf6e22e0a4aad88567defd0d8587dc16f678fdde318048220edb33ef5aa80ff7f2b253ede61fa3a03aac71849ba8179e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.6] - 2025-08-30
4
+
5
+ ### Added
6
+
7
+ - Docker command compose parameter services is interactive.
8
+ - Workspace with public method has conditional pass parameter.
9
+
10
+ ## [0.4.19] - 2025-08-30
11
+
12
+ ### Added
13
+
14
+ - Docker command options were updated to 28.3.
15
+ - Docker command compose action down was implemented.
16
+ - Docker containers conflicting with options can be prefixed with colon.
17
+ - Git command stash action push option message is interactive.
18
+ - Repo commands init and sync inherit any positional options.
19
+
20
+ ### Fixed
21
+
22
+ - Docker did not ignore pre-defined file with COMPOSE_FILE.
23
+ - Docker did not support multiple config files.
24
+ - Repo did not transfer arguments to supplement tasks.
25
+ - Node public method version caused a recursive loop.
26
+ - Node command bump action minor without major was revised.
27
+
3
28
  ## [0.5.5] - 2025-08-23
4
29
 
5
30
  ### Added
@@ -33,7 +58,7 @@
33
58
  - Workspace pipe and verbose interprets $DEBUG AND $VERBOSE modes.
34
59
  - Git response status did not check for STDIN stream.
35
60
  - Common format method puts_oe was renamed log_console.
36
- - Global task git:all is disabled for single project workspaces.
61
+ - Global task git:all is disabled for single project workspaces.
37
62
 
38
63
  ## [0.3.14] - 2025-08-23
39
64
 
@@ -1000,6 +1025,7 @@
1000
1025
 
1001
1026
  - Changelog was created.
1002
1027
 
1028
+ [0.5.6]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.6
1003
1029
  [0.5.5]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.5
1004
1030
  [0.5.4]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.4-ruby
1005
1031
  [0.5.3]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.3-ruby
@@ -159,7 +159,8 @@ module Squared
159
159
  when Logger::WARN then :warn
160
160
  when Logger::ERROR then :error
161
161
  when Logger::FATAL then :fatal
162
- else :unknown end
162
+ else :unknown
163
+ end
163
164
  else
164
165
  level.to_s.downcase.to_sym
165
166
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.5.5'
4
+ VERSION = '0.5.6'
5
5
  end
@@ -179,7 +179,9 @@ module Squared
179
179
  self
180
180
  end
181
181
 
182
- def with(*val, group: nil, **kwargs, &blk)
182
+ def with(*val, pass: false, group: nil, **kwargs, &blk)
183
+ return self if pass == true || (pass && Array(pass).map(&:to_s).any? { |s| respond_to?(s) && __send__(s) })
184
+
183
185
  @group = nil
184
186
  @ref = nil
185
187
  @withargs = kwargs.empty? ? nil : kwargs
@@ -274,9 +274,9 @@ module Squared
274
274
  -1
275
275
  elsif h.any? { |val| e.include?(val) }
276
276
  1
277
- elsif e.any? { |val| f.include?(val) }
277
+ elsif e.any? { |val| f.include?(val) } # rubocop:disable Lint/DuplicateBranch
278
278
  -1
279
- elsif f.any? { |val| e.include?(val) }
279
+ elsif f.any? { |val| e.include?(val) } # rubocop:disable Lint/DuplicateBranch
280
280
  1
281
281
  elsif @index >= 0 && (i = other.instance_variable_get(:@index)) >= 0
282
282
  @index <=> i
@@ -336,10 +336,10 @@ module Squared
336
336
  out, done = graph(args, out: [])
337
337
  out.map! do |val|
338
338
  done.each_with_index do |proj, i|
339
- if val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/)
340
- val += " (#{i.succ})"
341
- break
342
- end
339
+ next unless val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/)
340
+
341
+ val += " (#{i.succ})"
342
+ break
343
343
  end
344
344
  val
345
345
  end
@@ -387,7 +387,9 @@ module Squared
387
387
  args.extras
388
388
  else
389
389
  version, opts = choice_index('Select a version',
390
- @asdf[1].children.map(&:basename).push('latest'),
390
+ @asdf[1].children
391
+ .map(&:basename)
392
+ .append('latest', 'system'),
391
393
  force: true, accept: [['Confirm?', false, true]],
392
394
  values: ['Options'])
393
395
  OptionPartition.strip(opts)
@@ -2136,8 +2138,8 @@ module Squared
2136
2138
  workspace.series.name_get(action).yield_self { |name| name != action && invoked_sync?(name) }
2137
2139
  end
2138
2140
 
2139
- def success?(ret)
2140
- ret == true && stdout? && banner?
2141
+ def success?(ret, display = true)
2142
+ ret == true && display && stdout? && banner?
2141
2143
  end
2142
2144
 
2143
2145
  def banner?
@@ -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 compose.yml docker-compose.yml].freeze
7
+ COMPOSEFILE = %w[compose.yaml compose.yml docker-compose.yaml 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,56 +12,57 @@ module Squared
12
12
  tlskey=p].freeze,
13
13
  buildx: {
14
14
  common: %w[builder=b D|debug],
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
15
+ build: %w[add-host=q annotation=q attest=q build-arg=qq build-context=qq cache-from=q cache-to=q
16
+ cgroup-parent=b ent=q iidfile=p label=q a-file=p network=b no-cache-filter=b o|output=q platform=b
17
+ q|quiet secret=qq shm-size=b ssh=qq t|tag=b target=b ulimit=q].freeze,
18
+ bake: %w[print list=q set=q].freeze,
19
+ shared: %w[check load no-cache pull push allow=q call=b? f|file=p metadata-file=p progress=b provenance=q
20
+ sbom=q].freeze
20
21
  }.freeze,
21
22
  compose: {
22
- common: %w[all-resources compatibility dry-run ansi|b env-file=p f|file=p parallel=b profile=b progress=b
23
+ common: %w[all-resources compatibility dry-run ansi|b env-file=p f|file=p parallel=n profile=b progress=b
23
24
  project-directory=p p|project-name=e].freeze,
24
- build: %w[check no-cache pull push with-dependencies q|quiet build-arg=qq builder=b m|memory=b
25
- ssh=qq].freeze,
26
- exec: %w[dry-run privileged d|detach e|env=qq index=i T|no-TTY=b? user=e w|workdir=q].freeze,
27
- run: %w[build dry-run no-deps quiet-pull remove-orphans rm P|service-ports use-aliases cap-add=b cap-drop=b
28
- d|detach entrypoint=q e|env=qq i|interactive=b? l|label=q name=b T|no-TTY=b? p|publish=e pull=b
29
- u|user=e v|volume=q w|workdir=q].freeze,
30
- up: %w[y abort-on-container-exit abort-on-container-failure always-recreate-deps attach-dependencies build
31
- d|detach dry-run force-recreate menu no-build no-color no-deps no-log-prefix no-recreate no-start
32
- quiet-pull remove-orphans V|renew-anon-volumes timestamps wait w|watch attach=b exit-code-from=b
33
- no-attach=b pull=b scale=i t|timeout=i wait-timeout=i].freeze
25
+ build: %w[check no-cache print pull push with-dependencies q|quiet build-arg=qq builder=b m|memory=b
26
+ provenance=q sbom=q ssh=qq].freeze,
27
+ exec: %w[d|detach privileged e|env=qq index=i T|no-TTY=b? user=e w|workdir=q].freeze,
28
+ run: %w[build d|detach no-deps q|quiet quiet-build quiet-pull remove-orphans rm P|service-ports use-aliases
29
+ cap-add=b cap-drop=b q e|env=qq env-from-file=p i|interactive=b? l|label=q name=b T|no-TTY=b?
30
+ p|publish=e pull=b u|user=e v|volume=q w|workdir=q].freeze,
31
+ up: %w[abort-on-container-exit abort-on-container-failure always-recreate-deps attach-dependencies build
32
+ d|detach force-recreate menu no-build no-color no-deps no-log-prefix no-recreate no-start quiet-build
33
+ quiet-pull remove-orphans V|renew-anon-volumes timestamps wait w|watch y|yes attach=b
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
34
36
  }.freeze,
35
37
  container: {
36
38
  create: %w[init i|interactive no-healthcheck oom-kill-disable privileged P|publish-all q|quiet read-only
37
- rm runtime t|tty use-api-socket io-maxbandwidth=b io-maxiops=b add-host=q annotation=q
38
- a|attach=b blkio-weight=i blkio-weight-device=i cap-add=b cap-drop=b cgroup-parent=b cgroupns=b
39
- cidfile=p device=q device-cgroup-rule=q device-read-bps=q device-read-iops=q device-write-bps=q
39
+ rm runtime t|tty use-api-socket io-maxbandwidth=b io-maxiops=b add-host=q annotation=q a|attach=b
40
+ blkio-weight=i blkio-weight-device=i cap-add=b cap-drop=b cgroup-parent=b cgroupns=b cidfile=p
41
+ device=q device-cgroup-rule=q device-read-bps=q device-read-iops=q device-write-bps=q
40
42
  device-write-iops=q disable-content-trust=b? dns=e dns-option=e dns-search=e domainname=b
41
- entrypoint=q e|env=qq env-file=p expose=e gpus=q group-add=b health-cmd=q health-interval=b
42
- health-retries=i health-start-interval=b health-start-period=b health-timeout=b h|hostname=e ip=b
43
- ip6=e ipc=b isolation=b kernel-memory=b l|label=q label-file=p link=b link-local-ip=b
44
- log-driver=b log-opt=q mac-address=e m|memory=b memory-reservation=b memory-swap=n
45
- memory-swappiness=n mount=qq name=b network=b network-alias=b oom-score-adj=b pid=b pids-limit=n
46
- platform=b p|publish=e pull=b restart=b runtime=b security-opt=q shm-size=b stop-signal=b
47
- stop-timeout=i storage-opt=q sysctl=q tmpfs=q ulimit=q u|user=b userns=b uts=b v|volume=q
48
- volume-driver=b volumes-from=b w|workdir=q].freeze,
43
+ entrypoint=q e|env=qq env-file=p expose=e gpus=q group-add=b health-cmd=q health-interval=b ip6=e
44
+ ipc=b isolation=b kernel-memory=b l|label=q label-file=p link=b link-local-ip=b log-driver=b
45
+ log-opt=q mac-address=e m|memory=b memory-reservation=b memory-swap=n memory-swappiness=n
46
+ mount=qq name=b network=b network-alias=b oom-score-adj=b pid=b pids-limit=n platform=b
47
+ p|publish=e pull=b restart=b runtime=b security-opt=q shm-size=b stop-signal=b stop-timeout=i
48
+ storage-opt=q sysctl=q tmpfs=q ulimit=q u|user=b userns=b uts=b v|volume=q volume-driver=b
49
+ volumes-from=b w|workdir=q].freeze,
49
50
  run: %w[d|detach detach-keys=q sig-proxy=b?].freeze,
50
- exec: %w[d|detach i|interactive privileged t|tty detach-keys=q e|env=qq env-file=p user=e
51
- w|workdir=q].freeze,
52
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
53
52
  cpuset-cpus=b cpuset-mems=b m|memory=b memory-reservation=b memory-swap=b pids-limit=n
54
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,
55
56
  commit: %w[a|author=q c|change=q m|message=q pause=b?].freeze,
56
57
  inspect: %w[s|size f|format=q].freeze,
57
58
  start: %w[a|attach i|interactive detach-keys=q].freeze,
58
59
  stop: %w[s|signal=b t|time=i t|timeout=i].freeze,
59
60
  restart: %w[s|signal=b t|time=i t|timeout=i].freeze,
60
61
  kill: %w[s|signal=b].freeze,
61
- stats: %w[no-trunc format|q].freeze
62
+ stats: %w[a|all no-stream no-trunc format|q].freeze
62
63
  }.freeze,
63
64
  image: {
64
- list: %w[a|all digests no-trunc f|filter=q format=q].freeze,
65
+ list: %w[a|all q|quiet digests no-trunc tree f|filter=q format=q].freeze,
65
66
  push: %w[a|all-tags disable-content-trust=b? platform=b q|quiet].freeze,
66
67
  rm: %w[f|force no-prune platform=b].freeze,
67
68
  save: %w[o|output=p platform=b].freeze
@@ -96,7 +97,7 @@ module Squared
96
97
 
97
98
  subtasks({
98
99
  'build' => %i[tag context].freeze,
99
- 'compose' => %i[build run exec up].freeze,
100
+ 'compose' => %i[build run exec up down].freeze,
100
101
  'bake' => %i[build check].freeze,
101
102
  'image' => %i[list rm push tag save].freeze,
102
103
  'container' => %i[run create exec update commit inspect diff start stop restart pause unpause top stats kill
@@ -151,7 +152,7 @@ module Squared
151
152
 
152
153
  case flag
153
154
  when :build
154
- format_desc action, flag, ':?,opts*,target*,context?'
155
+ format_desc action, flag, 'opts*,target*,context?|:'
155
156
  task flag do |_, args|
156
157
  args = args.to_a
157
158
  if args.first == ':'
@@ -171,13 +172,13 @@ module Squared
171
172
  break unless compose?
172
173
 
173
174
  case flag
174
- when :build, :up
175
- format_desc action, flag, 'opts*,service*'
175
+ when :build, :up, :down
176
+ format_desc action, flag, 'opts*,service*|:'
176
177
  task flag do |_, args|
177
178
  compose! flag, args.to_a
178
179
  end
179
180
  when :exec, :run
180
- format_desc action, flag, "service,command#{flag == :exec ? '' : '?'}|:,args*,opts*"
181
+ format_desc action, flag, "service|:,command#{flag == :exec ? '' : '?'}|::,args*,opts*"
181
182
  task flag, [:service] do |_, args|
182
183
  service = param_guard(action, flag, args: args, key: :service)
183
184
  compose!(flag, args.extras, service: service)
@@ -186,7 +187,7 @@ module Squared
186
187
  when 'container'
187
188
  case flag
188
189
  when :exec, :commit
189
- format_desc(action, flag, flag == :exec ? 'id/name,opts*,args+' : 'id/name,tag?,opts*')
190
+ format_desc(action, flag, flag == :exec ? 'id/name,opts*,args+|:' : 'id/name,tag?,opts*')
190
191
  task flag, [:id] do |_, args|
191
192
  if flag == :exec && !args.id
192
193
  choice_command flag
@@ -196,7 +197,7 @@ module Squared
196
197
  end
197
198
  end
198
199
  when :run, :create
199
- format_desc action, flag, 'image,opts*,args*'
200
+ format_desc action, flag, 'image,opts*,args*|:'
200
201
  task flag, [:image] do |_, args|
201
202
  if args.image
202
203
  container(flag, args.extras, id: args.image)
@@ -222,7 +223,8 @@ module Squared
222
223
  format_desc(action, flag, case flag
223
224
  when :rm, :save then 'id*,opts*'
224
225
  when :tag then 'version?'
225
- else 'opts*,args*' end)
226
+ else 'opts*,args*'
227
+ end)
226
228
  task flag do |_, args|
227
229
  args = args.to_a
228
230
  if args.empty? && flag != :list
@@ -259,12 +261,11 @@ module Squared
259
261
 
260
262
  ret = docker_session
261
263
  if from == :run
262
- case (n = filetype)
263
- when 1, 2
264
+ if bake?(n = filetype)
264
265
  ret << 'buildx' << 'bake'
265
266
  append_file n
266
267
  from = :bake
267
- when 3, 4
268
+ elsif compose?(n)
268
269
  ret << 'compose' << 'build'
269
270
  append_file n
270
271
  from = :compose
@@ -335,7 +336,7 @@ module Squared
335
336
  op.push(val)
336
337
  end
337
338
  end
338
- op.append(args, escape: true)
339
+ op.append(args, escape: true, strip: /^:/)
339
340
  contextdir context if context
340
341
  end
341
342
  end
@@ -348,15 +349,27 @@ module Squared
348
349
  op = OptionPartition.new(opts, OPT_DOCKER[:compose][:common], cmd, project: self)
349
350
  append_file filetype unless op.arg?('f', 'file')
350
351
  op << flag
351
- op.parse(OPT_DOCKER[:compose][flag])
352
- from = :"compose:#{flag}"
353
- case flag
354
- when :build, :up
355
- op.append(escape: true)
356
- when :exec, :run
357
- append_command flag, service, op.extras
352
+ op.parse(OPT_DOCKER[:compose].fetch(flag, []))
353
+ multiple = case flag
354
+ when :build, :up, :down then true
355
+ else false
356
+ end
357
+ if op.remove(':') || service == ':'
358
+ keys = Set.new
359
+ read_composefile('services', target: op.values_of('f', 'file')) { |data| keys.merge(data.keys) }
360
+ service = unless keys.empty?
361
+ choice_index('Add services', keys, multiple: multiple, force: !multiple,
362
+ attempts: multiple ? 1 : 5)
363
+ end
358
364
  end
359
- run(from: from)
365
+ if multiple
366
+ op.concat(service) if service
367
+ op.append(delim: true, escape: true, strip: /^:/)
368
+ else
369
+ raise_error('no services were found', hint: flag) unless service
370
+ append_command(flag, service, op.extras, prompt: '::')
371
+ end
372
+ run(from: :"compose:#{flag}")
360
373
  end
361
374
 
362
375
  def container(flag, opts = [], id: nil)
@@ -388,10 +401,10 @@ module Squared
388
401
  elsif all.include?(k)
389
402
  unless type
390
403
  run.each_pair do |key, val|
391
- if val.include?(k)
392
- type = key.to_s unless key == :common
393
- break
394
- end
404
+ next unless val.include?(k)
405
+
406
+ type = key.to_s unless key == :common
407
+ break
395
408
  end
396
409
  end
397
410
  case k
@@ -414,7 +427,7 @@ module Squared
414
427
  append_command(flag, id || tagmain, op.extras)
415
428
  when :update
416
429
  raise_error('missing container', hint: flag) if op.empty?
417
- op.append(escape: true)
430
+ op.append(escape: true, strip: /^:/)
418
431
  when :commit
419
432
  latest = op.shift || tagmain
420
433
  cmd << id << latest
@@ -467,7 +480,7 @@ module Squared
467
480
  end
468
481
  return
469
482
  else
470
- op.append(escape: true)
483
+ op.append(escape: true, strip: /^:/)
471
484
  end
472
485
  end
473
486
  run(from: from)
@@ -544,7 +557,7 @@ module Squared
544
557
 
545
558
  def network(flag, opts = [], target: nil)
546
559
  cmd, opts = docker_session('network', flag, opts: opts)
547
- op = OptionPartition.new(opts, OPT_DOCKER[:network][flag], cmd, project: self)
560
+ op = OptionPartition.new(opts, OPT_DOCKER[:network].fetch(flag, []), cmd, project: self)
548
561
  op.clear
549
562
  from = :"network:#{flag}"
550
563
  list_image(flag, docker_output('ps -a'), from: from) do |img|
@@ -561,10 +574,14 @@ module Squared
561
574
  end
562
575
 
563
576
  def compose?(file = dockerfile)
577
+ return file == 3 || file == 4 if file.is_a?(Numeric)
578
+
564
579
  COMPOSEFILE.include?(File.basename(file))
565
580
  end
566
581
 
567
582
  def bake?(file = dockerfile)
583
+ return file == 1 || file == 2 if file.is_a?(Numeric)
584
+
568
585
  BAKEFILE.include?(File.basename(file))
569
586
  end
570
587
 
@@ -585,6 +602,21 @@ module Squared
585
602
 
586
603
  private
587
604
 
605
+ def read_composefile(*keys, target: nil)
606
+ require 'yaml'
607
+ target = ENV['COMPOSE_FILE']&.split(workspace.windows? ? ';' : ':') if !target || target.empty?
608
+ Array(target || dockerfile).each do |val|
609
+ doc = YAML.load_file(path + val)
610
+ if keys.empty?
611
+ yield doc
612
+ elsif (data = doc.dig(*keys))
613
+ yield data
614
+ end
615
+ rescue StandardError => e
616
+ log.debug e
617
+ end
618
+ end
619
+
588
620
  def docker_session(*cmd, opts: nil)
589
621
  return session('docker', *cmd) unless opts
590
622
 
@@ -597,9 +629,9 @@ module Squared
597
629
  session('docker', *cmd, main: false, options: false, **kwargs)
598
630
  end
599
631
 
600
- def append_command(flag, val, list, target: @session)
601
- if list.delete(':')
602
- list << readline('Enter command [args]', force: true)
632
+ def append_command(flag, val, list, target: @session, prompt: ':')
633
+ if list.delete(prompt)
634
+ list << readline('Enter command [args]', force: flag == :exec)
603
635
  elsif (args = env('DOCKER_ARGS'))
604
636
  list << args
605
637
  end
@@ -616,13 +648,22 @@ module Squared
616
648
  end
617
649
 
618
650
  def append_file(type, target: @session)
619
- return unless type == 2 || type == 4 || @file.is_a?(Array)
651
+ return if ENV['COMPOSE_FILE'] && compose?(type)
620
652
 
653
+ unless @file.is_a?(Array)
654
+ case type
655
+ when 2, 4
656
+ return
657
+ when 3
658
+ return unless COMPOSEFILE.map { |val| path + val }.select(&:exist?).size > 1
659
+ end
660
+ end
621
661
  files = Array(@file).map { |val| quote_option('file', path + val) }
622
662
  if target.is_a?(Set)
623
- target.merge(files)
663
+ opts = target.to_a.insert(2, *files)
664
+ target.clear.merge(opts)
624
665
  else
625
- target.concat(files)
666
+ target.insert(2, *files)
626
667
  end
627
668
  end
628
669
 
@@ -788,7 +829,7 @@ module Squared
788
829
  bake?(val) ? 1 : 2
789
830
  when '.yml', '.yaml'
790
831
  if compose?(val)
791
- path.children.any? { |file| bake?(file) } ? 1 : 3
832
+ @only&.include?('compose') || path.children.none? { |file| bake?(file) } ? 3 : 1
792
833
  else
793
834
  4
794
835
  end
@@ -503,10 +503,11 @@ module Squared
503
503
  end
504
504
  when 'stash'
505
505
  format_desc(action, flag, 'opts*', after: case flag
506
- when :push then 'pathspec*'
506
+ when :push then 'pathspec*,:'
507
507
  when :branch then 'name,stash?|:'
508
508
  when :clear, :list, :all then nil
509
- else 'stash?|:' end)
509
+ else 'stash?|:'
510
+ end)
510
511
  task flag do |_, args|
511
512
  stash flag, args.to_a
512
513
  end
@@ -755,7 +756,8 @@ module Squared
755
756
  when 'h', 'hard' then ['hard']
756
757
  when 's', 'soft' then ['soft']
757
758
  when 'n', 'N' then ['mixed', 'N']
758
- else ['mixed'] end)
759
+ else ['mixed']
760
+ end)
759
761
  end
760
762
  print_success if success?(reset(flag, args, commit: commit))
761
763
  end
@@ -921,7 +923,8 @@ module Squared
921
923
  before = case flag
922
924
  when :blame then 'file'
923
925
  when :mv then 'source+,destination'
924
- when :revert then 'commit+' end
926
+ when :revert then 'commit+'
927
+ end
925
928
  format_desc(action, flag, 'opts*', before: before, after: case flag
926
929
  when :add
927
930
  'pathspec*,pattern*'
@@ -975,6 +978,7 @@ module Squared
975
978
  elsif !(force = confirm('Force checkout?', 'N'))
976
979
  return
977
980
  end
981
+ printsucc
978
982
  end
979
983
  op = OptionPartition.new(opts, OPT_GIT[:pull], cmd, project: self, no: OPT_GIT[:no][:pull])
980
984
  reg = if op.empty?
@@ -1105,6 +1109,7 @@ module Squared
1105
1109
  op = OptionPartition.new(opts, list, cmd, project: self, no: no, first: flag == :push ? matchpathspec : nil)
1106
1110
  case flag
1107
1111
  when :push
1112
+ op.append?('message', readline('Enter message', force: true), force: true) if op.remove(':')
1108
1113
  append_pathspec op.extras
1109
1114
  when :pop, :apply, :drop, :branch
1110
1115
  if op.remove(':')
@@ -1481,6 +1486,7 @@ module Squared
1481
1486
 
1482
1487
  def merge(flag, opts = [], command: nil, branch: nil)
1483
1488
  cmd, opts = git_session('merge', opts: opts)
1489
+ display = false
1484
1490
  case flag
1485
1491
  when :commit, :'no-commit'
1486
1492
  op = OptionPartition.new(opts, OPT_GIT[:merge], cmd, project: self, no: OPT_GIT[:no][:merge])
@@ -1500,8 +1506,9 @@ module Squared
1500
1506
  return unless VAL_GIT[:merge][:send].include?(command)
1501
1507
 
1502
1508
  cmd << "--#{command}"
1509
+ display = command == 'abort'
1503
1510
  end
1504
- source
1511
+ print_success if success?(source, display)
1505
1512
  end
1506
1513
 
1507
1514
  def branch(flag = nil, opts = [], refs: [], ref: nil, target: nil, remote: nil)
@@ -1736,7 +1743,8 @@ module Squared
1736
1743
  project: self, no: OPT_GIT[:no][flag], first: case flag
1737
1744
  when :blame, :revert
1738
1745
  nil
1739
- else matchpathspec end)
1746
+ else matchpathspec
1747
+ end)
1740
1748
  case flag
1741
1749
  when :blame
1742
1750
  raise_error 'no file found' unless (n = op.index { |s| (path + s).file? })
@@ -1771,8 +1779,7 @@ module Squared
1771
1779
  end
1772
1780
  return source(git_session('status -s'), banner: false) unless append_pathspec(op.extras)
1773
1781
 
1774
- verbose = flag == :add && !op.arg?('verbose')
1775
- print_success if success?(source) && verbose
1782
+ print_success if success?(source, flag == :add && !op.arg?('verbose'))
1776
1783
  return
1777
1784
  when :mv
1778
1785
  refs = projectmap op.extras
@@ -1807,7 +1814,7 @@ module Squared
1807
1814
  else
1808
1815
  banner = nil if banner && (multiple || !banner?)
1809
1816
  if cmd.respond_to?(:done)
1810
- if from.nil? && (from = cmd.drop(1).find { |val| val.match?(/\A[a-z]{1,2}[a-z\-]*\z/) })
1817
+ if from.nil? && (from = cmd.drop(1).find { |val| val.match?(/\A[a-z]{1,2}[a-z-]*\z/) })
1811
1818
  from = :"git:#{from}"
1812
1819
  end
1813
1820
  banner &&= cmd.temp { |val| val.start_with?(/--(?:work-tree|git-dir)/) }
@@ -767,8 +767,8 @@ module Squared
767
767
  seg[4] &&= seg[4].succ
768
768
  else
769
769
  seg[2] = seg[2].succ
770
+ seg[4] &&= '0'
770
771
  end
771
- seg[4] = '0'
772
772
  when :patch
773
773
  seg[4] &&= seg[4].succ
774
774
  end
@@ -936,7 +936,7 @@ module Squared
936
936
  end
937
937
 
938
938
  def version
939
- self.version ||= read_packagemanager(:version)
939
+ @version ||= read_packagemanager(:version)
940
940
  end
941
941
 
942
942
  def packagename
@@ -183,7 +183,8 @@ module Squared
183
183
  else
184
184
  format_desc(action, nil, 'opts*', before: case action
185
185
  when 'cache', 'check' then nil
186
- else 'command+' end)
186
+ else 'command+'
187
+ end)
187
188
  task action do |_, args|
188
189
  bundle(action, *args.to_a)
189
190
  end
@@ -448,7 +449,7 @@ module Squared
448
449
  def update(flag, opts = [])
449
450
  bundle_session 'update', "--#{flag}"
450
451
  append_bundle(opts, OPT_BUNDLE[:install_base] + OPT_BUNDLE[:update] + OPT_BUNDLE[:common],
451
- append: flag == :all ? nil : /\A[a-z\-]+=/)
452
+ append: flag == :all ? nil : /\A[a-z-]+=/)
452
453
  run_rb(from: :update)
453
454
  end
454
455
 
@@ -502,7 +503,7 @@ module Squared
502
503
  c < d ? -1 : 1
503
504
  end
504
505
  end
505
- .push('')
506
+ .append('')
506
507
  .each do |val|
507
508
  next unless val.empty? || File.exist?(val.sub('$HOME', Dir.home))
508
509
 
@@ -18,10 +18,14 @@ module Squared
18
18
  include Shell
19
19
  include Prompt
20
20
 
21
- def append(target, *args, delim: false, escape: false, quote: true, **)
21
+ def append(target, *args, delim: false, escape: false, quote: true, strip: nil, **)
22
22
  return if (ret = args.flatten).empty?
23
23
 
24
24
  target << '--' if delim && !target.include?('--')
25
+ if strip
26
+ pat, s = Array(strip)
27
+ ret.map! { |val| val.gsub(pat, s || '') }
28
+ end
25
29
  ret.map! { |val| escape ? shell_escape(val, quote: quote) : shell_quote(val) } if escape || quote
26
30
  if target.is_a?(Set)
27
31
  target.merge(ret)
@@ -77,7 +81,7 @@ module Squared
77
81
  def_delegators :@target, :+, :-, :<<, :any?, :none?, :include?, :add, :add?, :find, :find_all, :find_index,
78
82
  :merge, :delete, :delete?, :delete_if, :grep, :grep_v, :inspect, :to_a, :to_s
79
83
  def_delegators :@extras, :empty?, :each, :each_with_index, :partition, :dup, :first, :last, :shift, :unshift,
80
- :pop, :push, :concat, :index, :delete_at, :join, :map, :map!, :select, :reject, :size
84
+ :pop, :push, :concat, :index, :delete_at, :join, :map, :map!, :select, :select!, :reject, :size
81
85
 
82
86
  def_delegator :@extras, :delete, :remove
83
87
  def_delegator :@extras, :delete_if, :remove_if
@@ -212,6 +216,36 @@ module Squared
212
216
  self
213
217
  end
214
218
 
219
+ def values_of(*args, strict: true, first: false, last: false)
220
+ eq, s = strict ? ['=', '[^ ]+'] : ['(?:=| +)', '[^-][^ ]*']
221
+ grp = ["\"((?:[^\"]|(?<=\\\\)\"(?!$#{Rake::Win32.windows? ? '| ' : ''}))*)\""]
222
+ grp << "'((?:[^']|'\\\\'')*)'" unless Rake::Win32.windows?
223
+ grp << "(#{s})"
224
+ args.map! do |opt|
225
+ if opt.size == 1
226
+ /(?:\A| )-#{opt} ?([^ ]+)/
227
+ else
228
+ /(?:\A| )--#{opt + eq}(?:#{grp.join('|')})/
229
+ end
230
+ end
231
+ ret = []
232
+ target.each do |opt|
233
+ args.each do |pat|
234
+ next unless opt =~ pat
235
+
236
+ ret << ($1 || $2 || $3)
237
+ break
238
+ end
239
+ end
240
+ return ret unless first || last
241
+
242
+ if last
243
+ last.is_a?(Numeric) ? ret.last(last) : ret.last
244
+ else
245
+ first.is_a?(Numeric) ? ret.first(first) : ret.first
246
+ end
247
+ end
248
+
215
249
  def uniq(list)
216
250
  items = map { |val| nameonly(val) }
217
251
  list.reject do |val|
@@ -304,30 +338,30 @@ module Squared
304
338
  self
305
339
  end
306
340
 
307
- def append?(key, val = nil, type: nil, **kwargs)
308
- return false if arg?(key)
341
+ def reset(errors: false)
342
+ extras.clear
343
+ clear(errors: true) if errors
344
+ self
345
+ end
346
+
347
+ def append?(key, val = nil, type: nil, force: false, **kwargs)
348
+ return false unless force || !arg?(key)
309
349
 
310
350
  val = yield self if block_given?
311
351
  return false unless val
312
352
 
313
353
  type ||= :quote if kwargs.empty?
314
- op << case type
315
- when :quote
316
- quote_option(key, val)
317
- when :basic
318
- basic_option(key, val)
319
- else
320
- shell_option(key, val, **kwargs)
321
- end
354
+ add case type
355
+ when :quote
356
+ quote_option(key, val)
357
+ when :basic
358
+ basic_option(key, val)
359
+ else
360
+ shell_option(key, val, **kwargs)
361
+ end
322
362
  true
323
363
  end
324
364
 
325
- def reset(errors: false)
326
- extras.clear
327
- clear(errors: true) if errors
328
- self
329
- end
330
-
331
365
  def arg?(*args, **kwargs)
332
366
  OptionPartition.arg?(target, *args, **kwargs)
333
367
  end
@@ -117,7 +117,6 @@ module Squared
117
117
  path = ns.scope.path
118
118
  branch = env('REPO_MANIFEST') || Repo.read_manifest(root)
119
119
  target = branch || manifest
120
- cmd = nil
121
120
  stage = nil
122
121
  opts = %w[force rebase detach submodules fail no-update gc]
123
122
  newline = ARGV.any?(/^repo:/)
@@ -132,9 +131,8 @@ module Squared
132
131
 
133
132
  desc.call('all[{0}]')
134
133
  task 'all' do |_, args|
135
- cmd ||= repo_opts args
136
134
  stage ||= 'all'
137
- ns['sync'].invoke
135
+ ns['sync'].invoke(*args.to_a)
138
136
  next if env('REPO_STAGE', equals: '1')
139
137
 
140
138
  @project.select do |_, proj|
@@ -162,39 +160,55 @@ module Squared
162
160
  args = args.to_a
163
161
  u = env('REPO_URL') || manifest_url
164
162
  m = args.first && !opts.include?(args.first) ? args.shift : target
165
- g = case (g = env('REPO_GROUPS'))
163
+ g = args.first && !opts.include?(args.first) ? args.shift : nil
164
+ g = case (val = env('REPO_GROUPS'))
165
+ when '', NilClass
166
+ g
166
167
  when '0', 'false'
167
168
  nil
168
169
  else
169
- g || (args.first && !opts.include?(args.first) ? args.shift : nil)
170
- end
171
- cmd = repo_opts args
172
- s = case (s = env('REPO_SUBMODULES'))
173
- when '0', 'false'
174
- false
175
- else
176
- s ? true : cmd.include?('--fetch-submodules')
170
+ val
177
171
  end
178
172
  stage = 'init'
179
173
  puts if newline
180
- args = ["-u #{u}", "-m #{m}.xml"]
181
- args << "-g #{g}" if g
182
- args << '--submodules' if s
183
- Common::System.shell("#{repo_bin} init #{args.join(' ')}", chdir: root)
174
+ opts = repo_opts "-u #{u}", "-m #{m}.xml"
175
+ opts << "-g #{g}" if g
176
+ opts << '--submodules' if repo_submodules?(args.include?('submodules'))
177
+ repo_run "#{repo_bin} init #{opts.uniq.join(' ')}"
184
178
  next if env('REPO_STAGE', equals: '0')
185
179
 
186
- ns['all'].invoke
180
+ ns['all'].invoke(*args)
187
181
  end
188
182
 
189
183
  desc.call('sync[{0}]')
190
184
  task 'sync' do |t, args|
191
- raise_error 'repo not initialized' unless branch || stage == 'init'
192
- cmd ||= repo_opts args
193
- cmd << "-j#{ENV.fetch('REPO_JOBS', Rake::CpuCounter.count)}"
185
+ opts = if stage == 'init'
186
+ []
187
+ else
188
+ raise_error 'repo not initialized' unless branch
189
+ repo_opts
190
+ end
191
+ args.to_a.each do |val|
192
+ case val
193
+ when 'force'
194
+ opts << '--force-checkout'
195
+ when 'rebase', 'detach'
196
+ opts << "--#{val}"
197
+ when 'submodules'
198
+ opts << '--fetch-submodules' if repo_submodules?(true)
199
+ when 'fail'
200
+ opts << '--fail-fast'
201
+ when 'no-update'
202
+ opts << '--no-manifest-update'
203
+ when 'gc'
204
+ opts << '--auto-gc'
205
+ end
206
+ end
207
+ opts << "-j#{ENV.fetch('REPO_JOBS', Rake::CpuCounter.count)}" unless opts.any?(/^--?j(?:obs)?/)
208
+ opts << '--fetch-submodules' if repo_submodules?
194
209
  puts unless !newline || stage == 'init'
195
210
  begin
196
- Common::System.shell("#{repo_bin} sync #{cmd.join(' ')}", chdir: root,
197
- exception: cmd.include?('--fail-fast'))
211
+ repo_run("#{repo_bin} sync #{opts.uniq.join(' ')}", exception: opts.include?('--fail-fast'))
198
212
  rescue Errno::ENOENT => e
199
213
  emphasize(e, title: root)
200
214
  raise
@@ -223,35 +237,34 @@ module Squared
223
237
  )
224
238
  end
225
239
 
226
- def repo_opts(args)
227
- ret = []
228
- args.to_a.each do |val|
229
- case val
230
- when 'force'
231
- ret << '--force-checkout'
232
- when 'rebase', 'detach'
233
- ret << "--#{val}"
234
- when 'submodules'
235
- ret << '--fetch-submodules'
236
- when 'fail'
237
- ret << '--fail-fast'
238
- when 'no-update'
239
- ret << '--no-manifest-update'
240
- when 'gc'
241
- ret << '--auto-gc'
242
- end
243
- end
244
- ret
240
+ def repo_run(cmd, exception: false)
241
+ puts log_message(Logger::INFO, cmd, subject: main, hint: root) if verbose
242
+ Common::System.shell(cmd, chdir: root, exception: exception)
245
243
  end
246
244
 
247
245
  def repo_bin
248
- Common::System.shell_bin('repo')
246
+ Common::Shell.shell_bin('repo')
247
+ end
248
+
249
+ def repo_opts(*args)
250
+ return args unless (n = ARGV.index('--'))
251
+
252
+ ARGV[(n + 1)..-1].concat(args)
249
253
  end
250
254
 
251
255
  def repo?
252
256
  !manifest_url.nil? && (repo_install? || @repo_override == true)
253
257
  end
254
258
 
259
+ def repo_submodules?(val = false)
260
+ case (s = env('REPO_SUBMODULES'))
261
+ when '0', 'false'
262
+ false
263
+ else
264
+ s ? true : val
265
+ end
266
+ end
267
+
255
268
  def repo_install?(dir = root, parent: false)
256
269
  return true if root?(dir, pass: ['.repo']) || dir.join('.repo').directory?
257
270
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squared
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham