squared 0.4.18 → 0.4.20

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: f1b0859a60110d19550ba8436a184dbf5475d9103cc844d4bcab7850f2065dc5
4
+ data.tar.gz: 887a31b94a66e59b0981f6dcbe64544e1f721b07cb5d82d9a71b8bbbc209820e
5
5
  SHA512:
6
- metadata.gz: a7a419bf6297c047a0b062e85b6c0f397919bb65c2ef426c89c765e177e3c55f0c461c4529e7cde9fa32161b5be33bfd8e0217b23d514dd4646eb4c7ec99cc34
7
- data.tar.gz: fc5e91cafb09e0963287ffa1dad25e57992d07a5e2942a3cddc3740f760079268aab1bb2d6d9f8d6a50169f5826d66b584fe388727fa725a8012930857f6f292
6
+ metadata.gz: 5936f90594961c71af2f1420607ed9c739bd0f182a440aff4c2d474a8bcc9bbb3e0db1c2bfa6ba27052823414d2f6db981f4251a32c09769595b89a561ecfc84
7
+ data.tar.gz: 19cc6e69dda54b8d0a3f2cb43606bfb23e25f1f20c071b8e47421156af30d5763162f4a5b14df5f8787a465e53bbabf18b0a9943e7a3c809c31a9825e885e32a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.20] - 2025-09-14
4
+
5
+ ### Changed
6
+
7
+ - Project banners when requested return consistent arguments.
8
+
9
+ ### Fixed
10
+
11
+ - Workspace global as command alias used undefined parameter.
12
+ - Python did not separate dependency manager and build backend.
13
+ - Gem command build did not validate gemspec was located.
14
+ - Project class Ruby used glob methods not available in Ruby 2.4.
15
+ - Shell options support using boolean as values.
16
+ - Git command merge action commit failed when using interactive menu.
17
+ - NPM command line options did not support boolean flags.
18
+
19
+ ## [0.4.19] - 2025-08-30
20
+
21
+ ### Added
22
+
23
+ - Docker command options were updated to 28.3.
24
+ - Docker command compose action down was implemented.
25
+ - Docker containers conflicting with options can be prefixed with colon.
26
+ - Git command stash action push option message is interactive.
27
+ - Repo commands init and sync inherit any positional options.
28
+
29
+ ### Fixed
30
+
31
+ - Docker did not ignore pre-defined file with COMPOSE_FILE.
32
+ - Docker did not support multiple config files.
33
+ - Repo did not transfer arguments to supplement tasks.
34
+ - Node public method version caused a recursive loop.
35
+ - Node command bump action minor without major was revised.
36
+
3
37
  ## [0.4.18] - 2025-08-23
4
38
 
5
39
  ### Added
@@ -14,7 +48,7 @@
14
48
  - Workspace pipe and verbose interprets $DEBUG AND $VERBOSE modes.
15
49
  - Git response status did not check for STDIN stream.
16
50
  - Common format method puts_oe was renamed log_console.
17
- - Global task git:all is disabled for single project workspaces.
51
+ - Global task git:all is disabled for single project workspaces.
18
52
 
19
53
  ## [0.3.14] - 2025-08-23
20
54
 
@@ -928,6 +962,8 @@
928
962
 
929
963
  - Changelog was created.
930
964
 
965
+ [0.4.20]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.20
966
+ [0.4.19]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.19
931
967
  [0.4.18]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.18
932
968
  [0.4.17]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.17-ruby
933
969
  [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
@@ -74,7 +74,7 @@ module Squared
74
74
  a = '--'
75
75
  b = '='
76
76
  end
77
- "#{a}#{flag}#{if val
77
+ "#{a}#{flag}#{unless val.nil?
78
78
  "#{b}#{if escape
79
79
  shell_escape(val, quote: quote, double: double, override: override)
80
80
  elsif quote
@@ -94,8 +94,8 @@ module Squared
94
94
 
95
95
  def shell_bin(name, env: true)
96
96
  key = name.upcase
97
- shell_quote((env && ENV["PATH_#{key}"]) || PATH[key] || PATH[key.to_sym] || name,
98
- option: false, force: false)
97
+ shell_quote((env && ENV["PATH_#{key}"]) || PATH[key] || PATH[key.to_sym] || name, option: false, force: false,
98
+ double: true)
99
99
  end
100
100
 
101
101
  def fill_option(val, **kwargs)
@@ -61,10 +61,9 @@ module Squared
61
61
  files.clear
62
62
  items.each do |file|
63
63
  if file.exist?
64
- if file.symlink?
65
- next unless force
66
- else
64
+ if !file.symlink?
67
65
  files << file
66
+ elsif !force
68
67
  next
69
68
  end
70
69
  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.20'
5
5
  end
@@ -98,6 +98,7 @@ module Squared
98
98
  @ref = []
99
99
  @children = []
100
100
  @events = hashobj.update({ first: first, last: last, error: error })
101
+ @as = hashobj
101
102
  @envname = env_key(@name).freeze
102
103
  @desc = (@name.include?(':') ? @name.split(':').join(ARG[:SPACE]) : @name).freeze
103
104
  @parent = nil
@@ -262,9 +263,9 @@ module Squared
262
263
  -1
263
264
  elsif h.any? { |val| e.include?(val) }
264
265
  1
265
- elsif e.any? { |val| f.include?(val) }
266
+ elsif e.any? { |val| f.include?(val) } # rubocop:disable Lint/DuplicateBranch
266
267
  -1
267
- elsif f.any? { |val| e.include?(val) }
268
+ elsif f.any? { |val| e.include?(val) } # rubocop:disable Lint/DuplicateBranch
268
269
  1
269
270
  elsif @index >= 0 && (i = other.instance_variable_get(:@index)) >= 0
270
271
  @index <=> i
@@ -476,7 +477,7 @@ module Squared
476
477
  else
477
478
  next unless respond_to?(:compose)
478
479
 
479
- cmd << a if (a = compose(as_get(b), d, script: true, args: e, from: from))
480
+ cmd << a if (a = compose(as_get(b, from), d, script: true, args: e, from: from))
480
481
  end
481
482
  var.merge!(c) if c.is_a?(Hash)
482
483
  end
@@ -485,7 +486,7 @@ module Squared
485
486
  cmd, opts, var, flags, extra = args
486
487
  end
487
488
  if cmd
488
- cmd = as_get cmd
489
+ cmd = as_get(cmd, from)
489
490
  opts = compose(opts, script: false) if opts && respond_to?(:compose)
490
491
  flags = append_hash(flags).join(' ') if flags.is_a?(Hash)
491
492
  case opts
@@ -502,7 +503,7 @@ module Squared
502
503
  else
503
504
  return unless (opts || extra) && respond_to?(:compose)
504
505
 
505
- cmd = compose(as_get(opts), flags, script: true, args: extra, from: from)
506
+ cmd = compose(as_get(opts, from), flags, script: true, args: extra, from: from)
506
507
  from = :script if from == :run && script?
507
508
  end
508
509
  run(cmd, var, sync: sync, from: from, banner: banner)
@@ -788,9 +789,8 @@ module Squared
788
789
  end
789
790
 
790
791
  def as(cmd, script, to = nil)
791
- script = { "#{script}": to } if to
792
- data = (@as ||= {})[cmd.to_sym] ||= {}
793
- script.each { |key, val| data[key.to_s] = val }
792
+ data = @as[cmd.to_sym]
793
+ (to ? [[script, to]] : script).each { |key, val| data[key.to_s] = val }
794
794
  self
795
795
  end
796
796
 
@@ -2010,10 +2010,8 @@ module Squared
2010
2010
  end
2011
2011
  end
2012
2012
 
2013
- def as_get(val)
2014
- return unless val
2015
-
2016
- @global && (ret = @as && @as[from] && @as[from][val]) ? ret : val
2013
+ def as_get(val, from)
2014
+ (@global && @as[from][val]) || val
2017
2015
  end
2018
2016
 
2019
2017
  def task_build(keys)
@@ -2103,8 +2101,8 @@ module Squared
2103
2101
  val != action && invoked_sync?(val)
2104
2102
  end
2105
2103
 
2106
- def success?(ret)
2107
- ret == true && stdout? && banner?
2104
+ def success?(ret, display = true)
2105
+ ret == true && display && stdout? && banner?
2108
2106
  end
2109
2107
 
2110
2108
  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)
@@ -520,7 +520,7 @@ module Squared
520
520
  list_image(flag, docker_output('image ls -a'), from: from) do |val|
521
521
  op << val
522
522
  if flag == :tag
523
- op << tagname("#{@project}:#{op.extras.first}")
523
+ op << tagname("#{@project}:#{op.first}")
524
524
  break
525
525
  end
526
526
  end
@@ -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
@@ -541,7 +542,7 @@ module Squared
541
542
  commit1 = commithead args.commit1
542
543
  if commit1
543
544
  commit2 = commithead param_guard(action, flag, args: args, key: :commit2)
544
- args = args.extras.to_a
545
+ args = args.extras
545
546
  range = [commit1, commit2]
546
547
  else
547
548
  range, opts, refs = choice_commit(multiple: view ? true : 2, values: %w[Options Pathspec])
@@ -751,11 +752,12 @@ module Squared
751
752
  args = args.extras
752
753
  else
753
754
  commit, mode = choice_commit(values: ['Mode [mixed|soft|hard|N]'])
754
- args = args.extras.to_a.concat(case mode&.downcase
755
- when 'h', 'hard' then ['hard']
756
- when 's', 'soft' then ['soft']
757
- when 'n', 'N' then ['mixed', 'N']
758
- else ['mixed'] end)
755
+ args = args.extras.concat(case mode&.downcase
756
+ when 'h', 'hard' then ['hard']
757
+ when 's', 'soft' then ['soft']
758
+ when 'n', 'N' then ['mixed', 'N']
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?
@@ -1024,7 +1028,7 @@ module Squared
1024
1028
  return unless upstream
1025
1029
 
1026
1030
  op = OptionPartition.new(opts, OPT_GIT[:rebase], cmd, project: self, no: OPT_GIT[:no][:rebase])
1027
- cmd << upstream
1031
+ op << upstream
1028
1032
  append_head op.shift
1029
1033
  op.clear(pass: false)
1030
1034
  when :onto
@@ -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(':')
@@ -1105,7 +1110,7 @@ module Squared
1105
1110
  if op.empty?
1106
1111
  values = [['Branch name', true]]
1107
1112
  else
1108
- op << op.pop
1113
+ op << op.shift
1109
1114
  end
1110
1115
  end
1111
1116
  out = choice_index('Choose a stash', git_spawn('stash list', stdout: false),
@@ -1116,7 +1121,7 @@ module Squared
1116
1121
  op << out
1117
1122
  end
1118
1123
  elsif !op.empty?
1119
- op << op.pop
1124
+ op << op.shift
1120
1125
  elsif flag == :branch
1121
1126
  raise_error 'no branch name'
1122
1127
  end
@@ -1260,7 +1265,6 @@ module Squared
1260
1265
  end
1261
1266
  when :patch
1262
1267
  cmd << '--patch'
1263
- append_pathspec(refs, pass: false)
1264
1268
  when :undo
1265
1269
  cmd << '--hard HEAD@{1}'
1266
1270
  ref = false
@@ -1477,15 +1481,16 @@ module Squared
1477
1481
 
1478
1482
  def merge(flag, opts = [], command: nil, branch: nil)
1479
1483
  cmd, opts = git_session('merge', opts: opts)
1484
+ display = false
1480
1485
  case flag
1481
1486
  when :commit, :'no-commit'
1482
1487
  op = OptionPartition.new(opts, OPT_GIT[:merge], cmd, project: self, no: OPT_GIT[:no][:merge])
1483
- raise_error 'no branch/commit' if op.empty?
1484
1488
  op << "--#{flag}" << '--'
1485
1489
  if branch
1486
1490
  op << branch
1487
1491
  op.clear(pass: false)
1488
1492
  else
1493
+ raise_error 'no branch/commit' if op.empty?
1489
1494
  append_commit(*op.extras)
1490
1495
  end
1491
1496
  else
@@ -1496,8 +1501,9 @@ module Squared
1496
1501
  return unless VAL_GIT[:merge][:send].include?(command)
1497
1502
 
1498
1503
  cmd << "--#{command}"
1504
+ display = command == 'abort'
1499
1505
  end
1500
- source
1506
+ print_success if success?(source, display)
1501
1507
  end
1502
1508
 
1503
1509
  def branch(flag = nil, opts = [], refs: [], ref: nil, target: nil, remote: nil)
@@ -1737,7 +1743,8 @@ module Squared
1737
1743
  project: self, no: OPT_GIT[:no][flag], first: case flag
1738
1744
  when :blame, :revert
1739
1745
  nil
1740
- else matchpathspec end)
1746
+ else matchpathspec
1747
+ end)
1741
1748
  case flag
1742
1749
  when :blame
1743
1750
  raise_error 'no file found' unless (n = op.index { |s| (path + s).file? })
@@ -1772,8 +1779,7 @@ module Squared
1772
1779
  end
1773
1780
  return source(git_session('status -s'), banner: false) unless append_pathspec(op.extras)
1774
1781
 
1775
- verbose = flag == :add && !op.arg?('verbose')
1776
- print_success if success?(source) && verbose
1782
+ print_success if success?(source, flag == :add && !op.arg?('verbose'))
1777
1783
  return
1778
1784
  when :mv
1779
1785
  refs = projectmap op.extras
@@ -1806,9 +1812,12 @@ module Squared
1806
1812
  from = nil
1807
1813
  banner = nil
1808
1814
  else
1809
- banner = nil if banner && (multiple || !banner?)
1815
+ if banner
1816
+ banner = nil unless banner? && !multiple
1817
+ args = true
1818
+ end
1810
1819
  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/) })
1820
+ if from.nil? && (from = cmd.drop(1).find { |val| val.match?(/\A[a-z]{1,2}[a-z-]*\z/) })
1812
1821
  from = :"git:#{from}"
1813
1822
  end
1814
1823
  banner &&= cmd.temp { |val| val.start_with?('--work-tree') || val.start_with?('--git-dir') }
@@ -1819,17 +1828,14 @@ module Squared
1819
1828
  log&.info cmd
1820
1829
  banner = if banner
1821
1830
  banner = (banner.is_a?(String) ? banner : cmd).gsub(File.join(path, ''), '')
1822
- format_banner(hint ? "#{banner} (#{hint})" : banner, banner: true)
1831
+ format_banner(hint ? "#{banner} (#{hint})" : banner)
1823
1832
  end
1824
1833
  on :first, from
1825
1834
  begin
1826
1835
  if io
1827
- ret = if stdout
1828
- `#{cmd}`
1829
- else
1830
- banner ? [IO.popen(cmd), banner, from] : IO.popen(cmd)
1831
- end
1832
- return ret
1836
+ return `#{cmd}` if stdout
1837
+
1838
+ return args ? [IO.popen(cmd), banner || '', from] : IO.popen(cmd)
1833
1839
  elsif stdin? ? sync : stdout
1834
1840
  print_item banner unless multiple
1835
1841
  ret = `#{cmd}`
@@ -5,15 +5,17 @@ module Squared
5
5
  module Project
6
6
  class Node < Git
7
7
  OPT_NPM = {
8
- common: %w[dry-run include-workspace-root workspaces=b? w|workspace=v].freeze,
9
- install: %w[prefer-dedupe package-lock-only cpu=b libc=b os=b].freeze,
10
- install_base: %w[ignore-scripts install-links strict-peer-deps include=b omit=b install-strategy=b].freeze,
8
+ common: %w[dry-run=!? include-workspace-root=!? workspaces=!? w|workspace=v].freeze,
9
+ install: %w[prefer-dedupe=!? package-lock-only=!? audit=! bin-links=! cpu=b fund=! libc=b os=b
10
+ package-lock=!].freeze,
11
+ install_base: %w[ignore-scripts=!? install-links=!? strict-peer-deps=!? include=b omit=b
12
+ install-strategy=b].freeze,
11
13
  install_no: %w[audit bin-links fund package-lock].freeze,
12
- install_as: %w[foreground-scripts g|global no-save save save-bundle save-dev E|save-exact save-optional
13
- save-peer S|save-prod].freeze,
14
- run: %w[foreground-scripts if-present ignore-scripts script-shell=p].freeze,
14
+ install_as: %w[no-save save-bundle save-dev save-optional save-peer save-prod foreground-scripts=!?
15
+ g|global=!? S|save=!? E|save-exact=!?].freeze,
16
+ run: %w[foreground-scripts=!? if-present=!? ignore-scripts=!? script-shell=p].freeze,
15
17
  exec: %w[c|call=q package=b].freeze,
16
- pack: %w[json ignore-scripts pack-destination=p].freeze
18
+ pack: %w[json=!? pack-destination=p].freeze
17
19
  }.freeze
18
20
  OPT_PNPM = {
19
21
  common: %w[aggregate-output color no-color stream use-stderr C|dir=p loglevel=b w|workspace-root].freeze,
@@ -670,13 +672,13 @@ module Squared
670
672
  if sync
671
673
  run(from: from, sync: sync, interactive: !dryrun && "Publish #{sub_style(npmname, styles: theme[:active])}")
672
674
  else
675
+ require 'open3'
673
676
  on :first, from
674
677
  pwd_set(from: from, dryrun: dryrun) do
675
- require 'open3'
676
- banner = format_banner cmd.to_s
677
- Open3.popen2e(cmd.done) do |_, out|
678
- write_lines(out, sub: npmnotice + [pat: /^(.+)(Tarball .+)$/, styles: color(:blue), index: 2],
679
- banner: banner)
678
+ cmd = session_done cmd
679
+ Open3.popen2e(cmd) do |_, out|
680
+ write_lines(out, banner: format_banner(cmd),
681
+ sub: npmnotice + [pat: /^(.+)(Tarball .+)$/, styles: color(:bright_blue), index: 2])
680
682
  end
681
683
  end
682
684
  on :last, from
@@ -758,8 +760,8 @@ module Squared
758
760
  seg[4] &&= seg[4].succ
759
761
  else
760
762
  seg[2] = seg[2].succ
763
+ seg[4] &&= '0'
761
764
  end
762
- seg[4] = '0'
763
765
  when :patch
764
766
  seg[4] &&= seg[4].succ
765
767
  end
@@ -928,7 +930,7 @@ module Squared
928
930
  end
929
931
 
930
932
  def version
931
- self.version ||= read_packagemanager(:version)
933
+ @version ||= read_packagemanager(:version)
932
934
  end
933
935
 
934
936
  def packagename
@@ -1025,9 +1027,9 @@ module Squared
1025
1027
 
1026
1028
  def npmnotice
1027
1029
  [
1028
- { pat: /^(npm error )(code|\d+)(.+)$/, styles: color(:cyan), index: 2 },
1029
- { pat: /^(npm )(error)(.*)$/, styles: color(:red), index: 2 },
1030
- { pat: /^(npm )(notice)(.*)$/, styles: color(:cyan), index: 2 },
1030
+ { pat: /^(npm error )(code|\d+)(.+)$/, styles: color(:bright_cyan), index: 2 },
1031
+ { pat: /^(npm )(error)(.*)$/, styles: color(:bright_red), index: 2 },
1032
+ { pat: /^(npm )(notice)(.*)$/, styles: color(:bright_cyan), index: 2 },
1031
1033
  { pat: /^(npm )(.+)$/, styles: :bold }
1032
1034
  ]
1033
1035
  end
@@ -37,8 +37,8 @@ module Squared
37
37
  common: %w[I|ignore-python no-cache n|non-interactive].freeze,
38
38
  build: %w[C=bm no-clean no-isolation no-sdist no-wheel quiet verbose config-setting=q d|dest=p p|project=p
39
39
  k|skip=b].freeze,
40
- publish: %w[no-build no-very-ssl quiet S|sign skip-existing verbose ca-certs=p c|comment=q d|dest=p identity=b
41
- p|password=q p|project=p r|repository=q k|skip=b u|username=b].freeze
40
+ publish: %w[no-build no-very-ssl quiet S|sign skip-existing verbose ca-certs=p c|comment=q d|dest=p
41
+ i|identity=b P|password=q p|project=p r|repository=q k|skip=b u|username=b].freeze
42
42
  }.freeze
43
43
  OPT_HATCH = {
44
44
  common: %w[color interactive no-color no-interactive cache-dir=p config=p data-dir=p e|env=b p|project=b
@@ -303,7 +303,7 @@ module Squared
303
303
  when 'build'
304
304
  case flag
305
305
  when :poetry
306
- next unless poetry?
306
+ next unless build_backend == 'poetry.core.masonry.api'
307
307
  when :pdm
308
308
  next unless build_backend == 'pdm.backend'
309
309
  when :hatch
@@ -888,7 +888,7 @@ module Squared
888
888
  end
889
889
 
890
890
  def poetry?
891
- build_backend ? build_backend == 'poetry.core.masonry.api' : dependtype == 1
891
+ dependtype == 1
892
892
  end
893
893
 
894
894
  def requirements?
@@ -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
 
@@ -701,6 +702,7 @@ module Squared
701
702
  return
702
703
  when :build
703
704
  if op.empty?
705
+ raise_error('gemspec not found', hint: project) unless gemfile
704
706
  op.add_path(gemfile)
705
707
  else
706
708
  op.add_path(op.shift)
@@ -711,7 +713,8 @@ module Squared
711
713
  file = path + (if (spec = gemspec)
712
714
  "#{spec.name}-#{spec.version}.gem"
713
715
  else
714
- choice_index('Select a file', Dir.glob('*.gem', base: path), force: true)
716
+ gems = Dir.glob(path.join('*.gem')).map { |val| File.basename(val) }
717
+ choice_index('Select a file', gems, force: true)
715
718
  end)
716
719
  else
717
720
  file = path + op.shift
@@ -753,9 +756,8 @@ module Squared
753
756
  else
754
757
  op.clear
755
758
  end
756
- elsif (n = op.extras.find_index { |val| val.match?(/(\A|[a-z])@\d/) })
757
- items = op.extras.to_a
758
- name = items.delete_at(n)
759
+ elsif (n = op.index { |val| val.match?(/(\A|[a-z])@\d/) })
760
+ name = op.delete_at(n)
759
761
  if (n = name.index('@')) == 0
760
762
  pre = gemname
761
763
  ver = name[1..-1]
@@ -764,8 +766,7 @@ module Squared
764
766
  ver = name[(n + 1)..-1]
765
767
  end
766
768
  op.adjoin(pre, shell_option('version', ver))
767
- .clear(items)
768
- .reset
769
+ .clear
769
770
  elsif flag != :install
770
771
  op.adjoin
771
772
  end
@@ -830,8 +831,8 @@ module Squared
830
831
  def gemspec
831
832
  return @gemspec unless @gemspec.nil?
832
833
 
833
- @gemspec = if (file = gemfile)
834
- Gem::Specification.load(file.to_s) rescue false
834
+ @gemspec = if gemfile
835
+ Gem::Specification.load(gemfile.to_s) rescue false
835
836
  else
836
837
  false
837
838
  end
@@ -1036,7 +1037,7 @@ module Squared
1036
1037
  return @gemfile unless @gemfile.nil?
1037
1038
 
1038
1039
  @gemfile = [project, name].map! { |val| path + "#{val}.gemspec" }
1039
- .concat(path.glob('*.gemspec'))
1040
+ .concat(Dir.glob(path.join('*.gemspec')))
1040
1041
  .find { |file| File.exist?(file) } || false
1041
1042
  end
1042
1043
 
@@ -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,14 @@ 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
86
+ def_delegator :@extras, :delete_at, :remove_at
82
87
  def_delegator :@extras, :delete_if, :remove_if
83
88
 
84
89
  def initialize(opts, list, target = Set.new, project: nil, path: nil, **kwargs, &blk)
85
- @target = target.is_a?(Set) ? target : Set.new(target)
90
+ @target = target.is_a?(Set) ? target : target.to_set
86
91
  @project = project
87
92
  @path = path || project&.path
88
93
  @errors = []
@@ -103,6 +108,7 @@ module Squared
103
108
  i = []
104
109
  f = []
105
110
  si = []
111
+ bl = []
106
112
  list.flat_map do |val|
107
113
  x, y = val.split('|', 2)
108
114
  if y
@@ -137,6 +143,8 @@ module Squared
137
143
  si << flag
138
144
  when 'v'
139
145
  @values << Regexp.escape(flag)
146
+ when '!'
147
+ bl << flag
140
148
  else
141
149
  next
142
150
  end
@@ -176,7 +184,7 @@ module Squared
176
184
  add quote_option(key, val, double: qq.include?(key), merge: merge)
177
185
  elsif p.include?(key) && path
178
186
  add quote_option(key, path + val, merge: merge)
179
- elsif b.include?(key) || numcheck.call(key, val)
187
+ elsif b.include?(key) || (bl.include?(key) && %w[true false].include?(val)) || numcheck.call(key, val)
180
188
  add basic_option(key, val, merge: merge)
181
189
  elsif merge
182
190
  add basic_option(key, val, merge: true)
@@ -303,30 +311,30 @@ module Squared
303
311
  self
304
312
  end
305
313
 
306
- def append?(key, val = nil, type: nil, **kwargs)
307
- return false if arg?(key)
314
+ def reset(errors: false)
315
+ extras.clear
316
+ clear(errors: true) if errors
317
+ self
318
+ end
319
+
320
+ def append?(key, val = nil, type: nil, force: false, **kwargs)
321
+ return false unless force || !arg?(key)
308
322
 
309
323
  val = yield self if block_given?
310
324
  return false unless val
311
325
 
312
326
  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
327
+ add case type
328
+ when :quote
329
+ quote_option(key, val)
330
+ when :basic
331
+ basic_option(key, val)
332
+ else
333
+ shell_option(key, val, **kwargs)
334
+ end
321
335
  true
322
336
  end
323
337
 
324
- def reset(errors: false)
325
- extras.clear
326
- clear(errors: true) if errors
327
- self
328
- end
329
-
330
338
  def arg?(*args, **kwargs)
331
339
  OptionPartition.arg?(target, *args, **kwargs)
332
340
  end
@@ -117,10 +117,8 @@ 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
124
122
  desc = lambda do |val, alt = nil|
125
123
  if (ver = branch || alt)
126
124
  val = val.sub('{0}', "opts*=#{opts.join(',')}")
@@ -132,9 +130,8 @@ module Squared
132
130
 
133
131
  desc.call('all[{0}]')
134
132
  task 'all' do |_, args|
135
- cmd ||= repo_opts args
136
133
  stage ||= 'all'
137
- ns['sync'].invoke
134
+ ns['sync'].invoke(*args.to_a)
138
135
  next if env('REPO_STAGE', equals: '1')
139
136
 
140
137
  @project.select do |_, proj|
@@ -162,39 +159,53 @@ module Squared
162
159
  args = args.to_a
163
160
  u = env('REPO_URL') || manifest_url
164
161
  m = args.first && !opts.include?(args.first) ? args.shift : target
165
- g = case (g = env('REPO_GROUPS'))
162
+ g = args.first && !opts.include?(args.first) ? args.shift : nil
163
+ g = case (val = env('REPO_GROUPS'))
164
+ when '', NilClass
165
+ g
166
166
  when '0', 'false'
167
167
  nil
168
168
  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')
169
+ val
177
170
  end
178
171
  stage = 'init'
179
- 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)
172
+ opts = repo_opts "-u #{u}", "-m #{m}.xml"
173
+ opts << "-g #{g}" if g
174
+ opts << '--submodules' if repo_submodules?(args.include?('submodules'))
175
+ repo_run "#{repo_bin} init #{opts.uniq.join(' ')}"
184
176
  next if env('REPO_STAGE', equals: '0')
185
177
 
186
- ns['all'].invoke
178
+ ns['all'].invoke(*args)
187
179
  end
188
180
 
189
181
  desc.call('sync[{0}]')
190
182
  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)}"
194
- puts unless !newline || stage == 'init'
183
+ opts = if stage == 'init'
184
+ []
185
+ else
186
+ raise_error 'repo not initialized' unless branch
187
+ repo_opts
188
+ end
189
+ args.to_a.each do |val|
190
+ case val
191
+ when 'force'
192
+ opts << '--force-checkout'
193
+ when 'rebase', 'detach'
194
+ opts << "--#{val}"
195
+ when 'submodules'
196
+ opts << '--fetch-submodules' if repo_submodules?(true)
197
+ when 'fail'
198
+ opts << '--fail-fast'
199
+ when 'no-update'
200
+ opts << '--no-manifest-update'
201
+ when 'gc'
202
+ opts << '--auto-gc'
203
+ end
204
+ end
205
+ opts << "-j#{ENV.fetch('REPO_JOBS', Rake::CpuCounter.count)}" unless opts.grep(/^--?j(?:obs)?/).empty?
206
+ opts << '--fetch-submodules' if repo_submodules?
195
207
  begin
196
- Common::System.shell("#{repo_bin} sync #{cmd.join(' ')}", chdir: root,
197
- exception: cmd.include?('--fail-fast'))
208
+ repo_run("#{repo_bin} sync #{opts.uniq.join(' ')}", exception: opts.include?('--fail-fast'))
198
209
  rescue Errno::ENOENT => e
199
210
  emphasize(e, title: root)
200
211
  raise
@@ -223,35 +234,34 @@ module Squared
223
234
  )
224
235
  end
225
236
 
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
237
+ def repo_run(cmd, exception: false)
238
+ puts log_message(Logger::INFO, cmd, subject: main, hint: root) if verbose
239
+ Common::System.shell(cmd, chdir: root, exception: exception)
245
240
  end
246
241
 
247
242
  def repo_bin
248
243
  Common::Shell.shell_bin('repo')
249
244
  end
250
245
 
246
+ def repo_opts(*args)
247
+ return args unless (n = ARGV.index('--'))
248
+
249
+ ARGV[(n + 1)..-1].concat(args)
250
+ end
251
+
251
252
  def repo?
252
253
  !manifest_url.nil? && (repo_install? || @repo_override == true)
253
254
  end
254
255
 
256
+ def repo_submodules?(val = false)
257
+ case (s = env('REPO_SUBMODULES'))
258
+ when '0', 'false'
259
+ false
260
+ else
261
+ s ? true : val
262
+ end
263
+ end
264
+
255
265
  def repo_install?(dir = root, parent: false)
256
266
  return true if root?(dir, pass: ['.repo']) || dir.join('.repo').directory?
257
267
 
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.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham