squared 0.4.18 → 0.4.19

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: 2e8fe45c2b6a9cc6fa2b274de07af33c74afde0e6a203ca2c5c3dfd0c13267ed
4
- data.tar.gz: ca5bdcf32da9e2383c63bd20966eaf524b2400d88f4b0045947f6403315ac961
3
+ metadata.gz: 7768e317ba03b32b5b8efeede15034c9c1c6bff1e6bca94e48119236a9647de4
4
+ data.tar.gz: 592bca71ea7b863bfdbd8896e429688b1d7b38941e7eee14388eb868f6065486
5
5
  SHA512:
6
- metadata.gz: a7a419bf6297c047a0b062e85b6c0f397919bb65c2ef426c89c765e177e3c55f0c461c4529e7cde9fa32161b5be33bfd8e0217b23d514dd4646eb4c7ec99cc34
7
- data.tar.gz: fc5e91cafb09e0963287ffa1dad25e57992d07a5e2942a3cddc3740f760079268aab1bb2d6d9f8d6a50169f5826d66b584fe388727fa725a8012930857f6f292
6
+ metadata.gz: 2eb5c090afe6a6514fa4f579e41f2f3136720cf4279d4d0464df8828e88b150e15245e5b69395abfe5af2b33f5850ca6ca9c379bd8970c4fd1e54125688e365e
7
+ data.tar.gz: 5f537d9f3eb00dcfe5786092cf6752393a80b8caba758152a53e65e05f6222b89fd87959d094f2b9b1677cc4a65380ac3ade95dd204239fb5c51ab789bf1d6b4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.19] - 2025-08-30
4
+
5
+ ### Added
6
+
7
+ - Docker command options were updated to 28.3.
8
+ - Docker command compose action down was implemented.
9
+ - Docker containers conflicting with options can be prefixed with colon.
10
+ - Git command stash action push option message is interactive.
11
+ - Repo commands init and sync inherit any positional options.
12
+
13
+ ### Fixed
14
+
15
+ - Docker did not ignore pre-defined file with COMPOSE_FILE.
16
+ - Docker did not support multiple config files.
17
+ - Repo did not transfer arguments to supplement tasks.
18
+ - Node public method version caused a recursive loop.
19
+ - Node command bump action minor without major was revised.
20
+
3
21
  ## [0.4.18] - 2025-08-23
4
22
 
5
23
  ### Added
@@ -14,7 +32,7 @@
14
32
  - Workspace pipe and verbose interprets $DEBUG AND $VERBOSE modes.
15
33
  - Git response status did not check for STDIN stream.
16
34
  - Common format method puts_oe was renamed log_console.
17
- - Global task git:all is disabled for single project workspaces.
35
+ - Global task git:all is disabled for single project workspaces.
18
36
 
19
37
  ## [0.3.14] - 2025-08-23
20
38
 
@@ -928,6 +946,7 @@
928
946
 
929
947
  - Changelog was created.
930
948
 
949
+ [0.4.19]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.19
931
950
  [0.4.18]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.18
932
951
  [0.4.17]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.17-ruby
933
952
  [0.4.16]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.16-ruby
@@ -157,7 +157,8 @@ module Squared
157
157
  when Logger::WARN then :warn
158
158
  when Logger::ERROR then :error
159
159
  when Logger::FATAL then :fatal
160
- else :unknown end
160
+ else :unknown
161
+ end
161
162
  else
162
163
  level.to_s.downcase.to_sym
163
164
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.4.18'
4
+ VERSION = '0.4.19'
5
5
  end
@@ -262,9 +262,9 @@ module Squared
262
262
  -1
263
263
  elsif h.any? { |val| e.include?(val) }
264
264
  1
265
- elsif e.any? { |val| f.include?(val) }
265
+ elsif e.any? { |val| f.include?(val) } # rubocop:disable Lint/DuplicateBranch
266
266
  -1
267
- elsif f.any? { |val| e.include?(val) }
267
+ elsif f.any? { |val| e.include?(val) } # rubocop:disable Lint/DuplicateBranch
268
268
  1
269
269
  elsif @index >= 0 && (i = other.instance_variable_get(:@index)) >= 0
270
270
  @index <=> i
@@ -2103,8 +2103,8 @@ module Squared
2103
2103
  val != action && invoked_sync?(val)
2104
2104
  end
2105
2105
 
2106
- def success?(ret)
2107
- ret == true && stdout? && banner?
2106
+ def success?(ret, display = true)
2107
+ ret == true && display && stdout? && banner?
2108
2108
  end
2109
2109
 
2110
2110
  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,7 +172,7 @@ module Squared
171
172
  break unless compose?
172
173
 
173
174
  case flag
174
- when :build, :up
175
+ when :build, :up, :down
175
176
  format_desc action, flag, 'opts*,service*'
176
177
  task flag do |_, args|
177
178
  compose! flag, args.to_a
@@ -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
@@ -337,7 +338,7 @@ module Squared
337
338
  op.push(val)
338
339
  end
339
340
  end
340
- op.append(args, escape: true)
341
+ op.append(args, escape: true, strip: /^:/)
341
342
  contextdir context if context
342
343
  end
343
344
  end
@@ -350,15 +351,14 @@ module Squared
350
351
  op = OptionPartition.new(opts, OPT_DOCKER[:compose][:common], cmd, project: self)
351
352
  append_file filetype unless op.arg?('f', 'file')
352
353
  op << flag
353
- op.parse(OPT_DOCKER[:compose][flag])
354
- from = :"compose:#{flag}"
354
+ op.parse(OPT_DOCKER[:compose].fetch(flag, []))
355
355
  case flag
356
- when :build, :up
357
- op.append(escape: true)
356
+ when :build, :up, :down
357
+ op.append(escape: true, strip: /^:/)
358
358
  when :exec, :run
359
359
  append_command flag, service, op.extras
360
360
  end
361
- run(from: from)
361
+ run(from: :"compose:#{flag}")
362
362
  end
363
363
 
364
364
  def container(flag, opts = [], id: nil)
@@ -390,10 +390,10 @@ module Squared
390
390
  elsif all.include?(k)
391
391
  unless type
392
392
  run.each_pair do |key, val|
393
- if val.include?(k)
394
- type = key.to_s unless key == :common
395
- break
396
- end
393
+ next unless val.include?(k)
394
+
395
+ type = key.to_s unless key == :common
396
+ break
397
397
  end
398
398
  end
399
399
  case k
@@ -416,7 +416,7 @@ module Squared
416
416
  append_command(flag, id || tagmain, op.extras)
417
417
  when :update
418
418
  raise_error('missing container', hint: flag) if op.empty?
419
- op.append(escape: true)
419
+ op.append(escape: true, strip: /^:/)
420
420
  when :commit
421
421
  latest = op.shift || tagmain
422
422
  cmd << id << latest
@@ -469,7 +469,7 @@ module Squared
469
469
  end
470
470
  return
471
471
  else
472
- op.append(escape: true)
472
+ op.append(escape: true, strip: /^:/)
473
473
  end
474
474
  end
475
475
  run(from: from)
@@ -546,7 +546,7 @@ module Squared
546
546
 
547
547
  def network(flag, opts = [], target: nil)
548
548
  cmd, opts = docker_session('network', flag, opts: opts)
549
- op = OptionPartition.new(opts, OPT_DOCKER[:network][flag], cmd, project: self)
549
+ op = OptionPartition.new(opts, OPT_DOCKER[:network].fetch(flag, []), cmd, project: self)
550
550
  op.clear
551
551
  from = :"network:#{flag}"
552
552
  list_image(flag, docker_output('ps -a'), from: from) do |img|
@@ -563,10 +563,14 @@ module Squared
563
563
  end
564
564
 
565
565
  def compose?(file = dockerfile)
566
+ return file == 3 || file == 4 if file.is_a?(Numeric)
567
+
566
568
  COMPOSEFILE.include?(File.basename(file))
567
569
  end
568
570
 
569
571
  def bake?(file = dockerfile)
572
+ return file == 1 || file == 2 if file.is_a?(Numeric)
573
+
570
574
  BAKEFILE.include?(File.basename(file))
571
575
  end
572
576
 
@@ -618,13 +622,22 @@ module Squared
618
622
  end
619
623
 
620
624
  def append_file(type, target: @session)
621
- return unless type == 2 || type == 4 || @file.is_a?(Array)
625
+ return if ENV['COMPOSE_FILE'] && compose?(type)
622
626
 
627
+ unless @file.is_a?(Array)
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
623
635
  files = Array(@file).map { |val| quote_option('file', path + val) }
624
636
  if target.is_a?(Set)
625
- target.merge(files)
637
+ opts = target.to_a.insert(2, *files)
638
+ target.clear.merge(opts)
626
639
  else
627
- target.concat(files)
640
+ target.insert(2, *files)
628
641
  end
629
642
  end
630
643
 
@@ -789,7 +802,7 @@ module Squared
789
802
  bake?(val) ? 1 : 2
790
803
  when '.yml', '.yaml'
791
804
  if compose?(val)
792
- path.children.any? { |file| bake?(file) } ? 1 : 3
805
+ @only&.include?('compose') || path.children.none? { |file| bake?(file) } ? 3 : 1
793
806
  else
794
807
  4
795
808
  end
@@ -500,10 +500,11 @@ module Squared
500
500
  end
501
501
  when 'stash'
502
502
  format_desc(action, flag, 'opts*', after: case flag
503
- when :push then 'pathspec*'
503
+ when :push then 'pathspec*,:'
504
504
  when :branch then 'name,stash?|:'
505
505
  when :clear, :list then nil
506
- else 'stash?|:' end)
506
+ else 'stash?|:'
507
+ end)
507
508
  task flag do |_, args|
508
509
  stash flag, args.to_a
509
510
  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? [y/N] ', '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?
@@ -1098,6 +1102,7 @@ module Squared
1098
1102
  op = OptionPartition.new(opts, list, cmd, project: self, no: no, first: flag == :push ? matchpathspec : nil)
1099
1103
  case flag
1100
1104
  when :push
1105
+ op.append?('message', readline('Enter message', force: true), force: true) if op.remove(':')
1101
1106
  append_pathspec op.extras
1102
1107
  when :pop, :apply, :drop, :branch
1103
1108
  if op.remove(':')
@@ -1477,6 +1482,7 @@ module Squared
1477
1482
 
1478
1483
  def merge(flag, opts = [], command: nil, branch: nil)
1479
1484
  cmd, opts = git_session('merge', opts: opts)
1485
+ display = false
1480
1486
  case flag
1481
1487
  when :commit, :'no-commit'
1482
1488
  op = OptionPartition.new(opts, OPT_GIT[:merge], cmd, project: self, no: OPT_GIT[:no][:merge])
@@ -1496,8 +1502,9 @@ module Squared
1496
1502
  return unless VAL_GIT[:merge][:send].include?(command)
1497
1503
 
1498
1504
  cmd << "--#{command}"
1505
+ display = command == 'abort'
1499
1506
  end
1500
- source
1507
+ print_success if success?(source, display)
1501
1508
  end
1502
1509
 
1503
1510
  def branch(flag = nil, opts = [], refs: [], ref: nil, target: nil, remote: nil)
@@ -1737,7 +1744,8 @@ module Squared
1737
1744
  project: self, no: OPT_GIT[:no][flag], first: case flag
1738
1745
  when :blame, :revert
1739
1746
  nil
1740
- else matchpathspec end)
1747
+ else matchpathspec
1748
+ end)
1741
1749
  case flag
1742
1750
  when :blame
1743
1751
  raise_error 'no file found' unless (n = op.index { |s| (path + s).file? })
@@ -1772,8 +1780,7 @@ module Squared
1772
1780
  end
1773
1781
  return source(git_session('status -s'), banner: false) unless append_pathspec(op.extras)
1774
1782
 
1775
- verbose = flag == :add && !op.arg?('verbose')
1776
- print_success if success?(source) && verbose
1783
+ print_success if success?(source, flag == :add && !op.arg?('verbose'))
1777
1784
  return
1778
1785
  when :mv
1779
1786
  refs = projectmap op.extras
@@ -1808,7 +1815,7 @@ module Squared
1808
1815
  else
1809
1816
  banner = nil if banner && (multiple || !banner?)
1810
1817
  if cmd.respond_to?(:done)
1811
- if from.nil? && (from = cmd.drop(1).find { |val| val.match?(/\A[a-z]{1,2}[a-z\-]*\z/) })
1818
+ if from.nil? && (from = cmd.drop(1).find { |val| val.match?(/\A[a-z]{1,2}[a-z-]*\z/) })
1812
1819
  from = :"git:#{from}"
1813
1820
  end
1814
1821
  banner &&= cmd.temp { |val| val.start_with?('--work-tree') || val.start_with?('--git-dir') }
@@ -758,8 +758,8 @@ module Squared
758
758
  seg[4] &&= seg[4].succ
759
759
  else
760
760
  seg[2] = seg[2].succ
761
+ seg[4] &&= '0'
761
762
  end
762
- seg[4] = '0'
763
763
  when :patch
764
764
  seg[4] &&= seg[4].succ
765
765
  end
@@ -928,7 +928,7 @@ module Squared
928
928
  end
929
929
 
930
930
  def version
931
- self.version ||= read_packagemanager(:version)
931
+ @version ||= read_packagemanager(:version)
932
932
  end
933
933
 
934
934
  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\w+=/)
452
+ append: flag == :all ? nil : /\A[a-z-]+=/)
452
453
  run_rb(from: :update)
453
454
  end
454
455
 
@@ -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)
@@ -34,7 +38,7 @@ module Squared
34
38
  def clear(target, opts, pass: true, styles: nil, **kwargs)
35
39
  return if opts.empty?
36
40
 
37
- kwargs[:subject] ||= stripext(target.first)
41
+ kwargs[:subject] ||= stripext target.first
38
42
  kwargs[:hint] ||= 'unrecognized'
39
43
  append(target, opts, delim: true) if kwargs.delete(:append)
40
44
  warn log_message(Logger::WARN, opts.join(', '), pass: true, **kwargs)
@@ -60,10 +64,10 @@ module Squared
60
64
  def arg?(target, *args, value: false, **)
61
65
  r, s = args.partition { |val| val.is_a?(Regexp) }
62
66
  unless s.empty?
63
- s.map! { |val| Regexp.escape(shell_option(val)) }
67
+ s.map! { |val| Regexp.escape(val.start_with?('-') ? val : shell_option(val)) }
64
68
  r << /\A(?:#{s.join('|')})#{value ? '[ =].' : '(?: |=|\z)'}/
65
69
  end
66
- target.any? { |opt| r.any? { |val| opt&.match?(val) } }
70
+ Array(target).compact.any? { |val| r.any? { |pat| pat.match?(val.to_s) } }
67
71
  end
68
72
 
69
73
  def pattern?(val)
@@ -76,13 +80,13 @@ module Squared
76
80
  def_delegators :@target, :+, :-, :<<, :any?, :none?, :include?, :add, :add?, :find, :find_all, :find_index,
77
81
  :merge, :delete, :delete?, :delete_if, :grep, :grep_v, :inspect, :to_a, :to_s
78
82
  def_delegators :@extras, :empty?, :each, :each_with_index, :partition, :dup, :first, :last, :shift, :unshift,
79
- :pop, :push, :concat, :index, :delete_at, :join, :map, :map!, :select, :reject, :size
83
+ :pop, :push, :concat, :index, :delete_at, :join, :map, :map!, :select, :select!, :reject, :size
80
84
 
81
85
  def_delegator :@extras, :delete, :remove
82
86
  def_delegator :@extras, :delete_if, :remove_if
83
87
 
84
88
  def initialize(opts, list, target = Set.new, project: nil, path: nil, **kwargs, &blk)
85
- @target = target.is_a?(Set) ? target : Set.new(target)
89
+ @target = target.is_a?(Set) ? target : target.to_set
86
90
  @project = project
87
91
  @path = path || project&.path
88
92
  @errors = []
@@ -303,30 +307,30 @@ module Squared
303
307
  self
304
308
  end
305
309
 
306
- def append?(key, val = nil, type: nil, **kwargs)
307
- return false if arg?(key)
310
+ def reset(errors: false)
311
+ extras.clear
312
+ clear(errors: true) if errors
313
+ self
314
+ end
315
+
316
+ def append?(key, val = nil, type: nil, force: false, **kwargs)
317
+ return false unless force || !arg?(key)
308
318
 
309
319
  val = yield self if block_given?
310
320
  return false unless val
311
321
 
312
322
  type ||= :quote if kwargs.empty?
313
- op << case type
314
- when :quote
315
- quote_option(key, val)
316
- when :basic
317
- basic_option(key, val)
318
- else
319
- shell_option(key, val, **kwargs)
320
- end
323
+ add case type
324
+ when :quote
325
+ quote_option(key, val)
326
+ when :basic
327
+ basic_option(key, val)
328
+ else
329
+ shell_option(key, val, **kwargs)
330
+ end
321
331
  true
322
332
  end
323
333
 
324
- def reset(errors: false)
325
- extras.clear
326
- clear(errors: true) if errors
327
- self
328
- end
329
-
330
334
  def arg?(*args, **kwargs)
331
335
  OptionPartition.arg?(target, *args, **kwargs)
332
336
  end
@@ -117,10 +117,9 @@ 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
- newline = ARGV.index { |val| val.start_with?('repo:') }.to_i > 0
122
+ newline = !ARGV.grep(/^repo:/).empty?
124
123
  desc = lambda do |val, alt = nil|
125
124
  if (ver = branch || alt)
126
125
  val = val.sub('{0}', "opts*=#{opts.join(',')}")
@@ -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.grep(/^--?j(?:obs)?/).empty?
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
246
  Common::Shell.shell_bin('repo')
249
247
  end
250
248
 
249
+ def repo_opts(*args)
250
+ return args unless (n = ARGV.index('--'))
251
+
252
+ ARGV[(n + 1)..-1].concat(args)
253
+ end
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.4.18
4
+ version: 0.4.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham