squared 0.5.11 → 0.5.12

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: 56af2850e96c00e48e1511b20fc61c5f0d9969220b4b070a6c61c02ce6489e97
4
- data.tar.gz: 83749c3414fa0496dfa64fb3ec0846af2205b1c4483ecbd44e72ed2d976c7852
3
+ metadata.gz: e711136d645a7a32cb93a09fc7562525a7fd9bc725436c5db5846fa217ac013c
4
+ data.tar.gz: 9fe647b2d3021fb50a2d4d4a3983d12422ecbbdbcb92324461382faf5efcb4c7
5
5
  SHA512:
6
- metadata.gz: 4fbc69f9efe06c1d2ceba44c58854ca31b0a7e50a6fe89c01e3aeff05830efae2f7bf07f068163352f6c54f9d347a5db11b308a8f0b3f3b64914ac6b0035743b
7
- data.tar.gz: 7aada08d98786700e652f0a78e5ddeda72ada420ec9d89cffc937f706b27da4800374231d086b67be8ae748199d0229a02fb95a9dfaac349fff6c40997ab5099
6
+ metadata.gz: 58dee7d115025166ad1326dc11e76f9708ce4af715f1d85b53e2d19799b07aab81118eb82283913a2fee9401b005c0eb9c883f1c820d3b7bfadf9eed2a845013
7
+ data.tar.gz: 2bac7d7f87848d78327542d4be5f5535f4d8ed45e818afa27b5a408f921c90363655de8a88dcf4d49d5da44902b5c87c6628cc75b1afe8875eee5bdecc48e3c6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.12] - 2025-10-31
4
+
5
+ ### Changed
6
+
7
+ - Ruby task depend does not override bundle config without setting.
8
+
9
+ ### Fixed
10
+
11
+ - Node command run did nothing at all when called upon.
12
+
13
+ ## [0.4.26] - 2025-10-31
14
+
15
+ ### Added
16
+
17
+ - Docker command options were updated to 28.5.
18
+
19
+ ### Changed
20
+
21
+ - Node package manager does not override package.json with NODE_INSTALL.
22
+ - Node workspaces can specify more than one package manager through NODE_INSTALL.
23
+
24
+ ### Fixed
25
+
26
+ - Node command add did not provide optional save argument.
27
+ - Python command outdated did not detect synchronous output.
28
+ - Node command outdated auto-commit was completely dysfunctional.
29
+ - Project workspaces caused a complete meltdown on TruffleRuby.
30
+ - Project build initialization global flag was always incoherent.
31
+ - Project base setters did not accept direct values.
32
+ - Project base global graph tasks are not definable by a sub-project.
33
+
3
34
  ## [0.5.11] - 2025-10-18
4
35
 
5
36
  ### Fixed
@@ -1153,6 +1184,7 @@
1153
1184
 
1154
1185
  - Changelog was created.
1155
1186
 
1187
+ [0.5.12]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.12
1156
1188
  [0.5.11]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.11
1157
1189
  [0.5.10]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.10
1158
1190
  [0.5.9]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.9
@@ -1165,6 +1197,7 @@
1165
1197
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
1166
1198
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
1167
1199
  [0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
1200
+ [0.4.26]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.26
1168
1201
  [0.4.25]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.25
1169
1202
  [0.4.24]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.24
1170
1203
  [0.4.23]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.23
data/README.md CHANGED
@@ -688,7 +688,7 @@ GIT_AUTOSTASH_${NAME}=0 # rebase (project only)
688
688
 
689
689
  ### Docker
690
690
 
691
- * Version: [28.3](https://docs.docker.com/engine/release-notes/28)
691
+ * Version: [28.5](https://docs.docker.com/engine/release-notes/28)
692
692
 
693
693
  ```sh
694
694
  DOCKER_OPTIONS=q,no-cache # all
@@ -108,7 +108,7 @@ module Squared
108
108
  ret = wrap.call(ret, code) unless code.empty?
109
109
  return ret unless data
110
110
 
111
- out = ''.dup
111
+ out = +''
112
112
  data.to_a.each_with_index do |group, i|
113
113
  next if i == 0
114
114
 
@@ -53,11 +53,11 @@ module Squared
53
53
  end
54
54
  max = items.size
55
55
  raise_error 'empty selection list' if max == 0
56
- min = [min, max].min
56
+ min = grep ? 1 : [min, max].min
57
57
  if auto
58
- msg = "#{msg}: [1-#{max}#{if multiple
59
- "|,#{multiple.is_a?(::Numeric) ? "{#{multiple}}" : ''}"
60
- end}] "
58
+ msg = "#{msg + (force ? ':' : '?')} [#{min}-#{max}#{if (n = multiple)
59
+ "|,#{n.is_a?(::Numeric) ? "{#{n}}" : ''}"
60
+ end}] "
61
61
  end
62
62
  end
63
63
  valid = ->(s) { s.match?(/^\d+$/) && s.to_i.between?(min, max) }
@@ -81,8 +81,7 @@ module Squared
81
81
  b.flatten!
82
82
  b.uniq!
83
83
  b.sort!
84
- return b unless items
85
- return b.map! { |i| items[i - 1] } unless multiple.is_a?(::Numeric) && multiple != b.size
84
+ return items ? b.map! { |i| items[i - 1] } : b unless multiple.is_a?(::Numeric) && multiple != b.size
86
85
  end
87
86
  elsif valid.call(ch)
88
87
  return items ? items[ch.to_i - 1] : ch.to_i
@@ -103,7 +103,7 @@ module Squared
103
103
  end
104
104
 
105
105
  def line_width(lines)
106
- ret = [lines.max_by(&:size).size, 80].max
106
+ ret = [lines.empty? ? 0 : lines.max_by(&:size).size, 80].max
107
107
  [ret, Rake.application.terminal_width].min
108
108
  end
109
109
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.5.11'
4
+ VERSION = '0.5.12'
5
5
  end
@@ -147,13 +147,12 @@ module Squared
147
147
  def build(parallel: [], pass: nil, **kwargs)
148
148
  return self unless enabled? && !@closed
149
149
 
150
- if kwargs[:pattern].is_a?(Array)
151
- kwargs[:parallel] = parallel.map(&:to_s)
152
- else
153
- kwargs[:pattern] = []
154
- kwargs[:parallel] = parallel.reject { |val| val.is_a?(Regexp) && (kwargs[:pattern] << val) }
155
- .map(&:to_s)
156
- end
150
+ kwargs[:parallel] = if kwargs[:pattern].is_a?(Array)
151
+ parallel.map(&:to_s)
152
+ else
153
+ kwargs[:pattern] = []
154
+ parallel.reject { |val| kwargs[:pattern] << val if val.is_a?(Regexp) }.map!(&:to_s)
155
+ end
157
156
  @pass[:pattern].concat(pass.map { |val| val.is_a?(Regexp) ? val : val.to_s }) if pass
158
157
  @project.each_value do |proj|
159
158
  if proj.enabled?
@@ -626,9 +625,7 @@ module Squared
626
625
  end
627
626
 
628
627
  def home?
629
- return false unless (proj = find(home))
630
-
631
- proj.enabled?
628
+ !!find(home)&.enabled?
632
629
  end
633
630
 
634
631
  def windows?
@@ -82,6 +82,7 @@ module Squared
82
82
 
83
83
  attr_reader :name, :project, :workspace, :path, :theme, :group, :parent, :dependfile,
84
84
  :exception, :pipe, :verbose
85
+ attr_accessor :global
85
86
 
86
87
  def initialize(workspace, path, name, *, group: nil, first: {}, last: {}, error: {}, common: ARG[:COMMON],
87
88
  **kwargs)
@@ -99,9 +100,14 @@ module Squared
99
100
  @clean = kwargs[:clean]
100
101
  @release = kwargs[:release]
101
102
  self.version = kwargs[:version]
102
- self.exception = kwargs[:exception]
103
- self.pipe = kwargs[:pipe]
104
- self.verbose = kwargs[:verbose]
103
+ self.exception = env_bool(kwargs[:exception], workspace.exception, strict: true)
104
+ self.pipe = env_pipe(kwargs[:pipe], workspace.pipe, strict: true)
105
+ self.verbose = case (val = env('VERBOSE', kwargs[:verbose]))
106
+ when String
107
+ env_bool(val, workspace.verbose, strict: true, index: true)
108
+ else
109
+ val.nil? ? workspace.verbose : val
110
+ end
105
111
  @output = []
106
112
  @ref = []
107
113
  @children = []
@@ -152,8 +158,10 @@ module Squared
152
158
  data = @workspace.script_find(*@ref, @group)
153
159
  if @output[0].nil?
154
160
  if (scr = data[:script])
155
- @global = true
156
- script_set(scr, args: data.fetch(:args, kwargs[:args]), prod: kwargs[:prod])
161
+ unless kwargs[:script] == false
162
+ @global = true
163
+ script_set(scr, args: data.fetch(:args, kwargs[:args]), prod: kwargs[:prod])
164
+ end
157
165
  elsif (run = data[:run])
158
166
  @global = true
159
167
  run_set run
@@ -176,7 +184,6 @@ module Squared
176
184
  @global = true
177
185
  run_set data[:run]
178
186
  end
179
- @global = true
180
187
  end
181
188
 
182
189
  def initialize_events(ref, **)
@@ -293,21 +300,29 @@ module Squared
293
300
  end
294
301
 
295
302
  def exception=(val)
296
- @exception = env_bool(val, workspace.exception, strict: true)
303
+ @exception = case val
304
+ when Numeric, TrueClass, FalseClass
305
+ val
306
+ else
307
+ workspace.exception
308
+ end
297
309
  end
298
310
 
299
311
  def pipe=(val)
300
- @pipe = env_pipe(val, workspace.pipe, strict: true)
312
+ @pipe = case val
313
+ when Numeric, Pathname
314
+ val
315
+ else
316
+ workspace.pipe
317
+ end
301
318
  end
302
319
 
303
320
  def verbose=(val)
304
- @verbose = case (val = env('VERBOSE', val))
305
- when NilClass
306
- workspace.verbose
307
- when String
308
- env_bool(val, workspace.verbose, strict: true, index: true)
309
- else
321
+ @verbose = case val
322
+ when Numeric, TrueClass, FalseClass
310
323
  val
324
+ else
325
+ workspace.verbose
311
326
  end
312
327
  end
313
328
 
@@ -337,13 +352,8 @@ module Squared
337
352
  else
338
353
  out, done = graph(args, out: [])
339
354
  out.map! do |val|
340
- done.each_with_index do |proj, i|
341
- next unless val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/)
342
-
343
- val += " (#{i.succ})"
344
- break
345
- end
346
- val
355
+ n = done.index { |proj| val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/) }
356
+ n ? "#{val} (#{n.succ})" : val
347
357
  end
348
358
  emphasize(out, title: path, right: true, border: borderstyle, sub: [
349
359
  { pat: /\A(#{Regexp.escape(path.to_s)})(.*)\z/, styles: theme[:header] },
@@ -428,35 +438,33 @@ module Squared
428
438
  end
429
439
 
430
440
  def add(path, name = nil, **kwargs, &blk)
431
- if path.is_a?(String) && (seg = path[%r{\A(.+)[\\/]\*+\z}, 1])
432
- return self unless checkdir?(path = basepath(seg))
441
+ if path.is_a?(String) && path =~ %r{\A(.+)[\\/]\*+\z}
442
+ return self unless checkdir?(path = basepath($1))
433
443
 
434
444
  path = path.children.select { |val| checkdir?(val) }
435
445
  end
436
446
  if path.is_a?(Array)
437
- name = @name if name == true
447
+ name = self.name if name == true
438
448
  path.each { |val| add(val, name && task_join(name, File.basename(val)), **kwargs, &blk) }
439
- return self
440
- end
441
- return self unless projectpath?(path = basepath(path)) && checkdir?(path)
442
-
443
- kwargs = hashdup(@withargs).update(kwargs) if @withargs
444
- kwargs[:group] = group if group && !kwargs.key?(:group)
445
- kwargs[:ref] = ref unless kwargs.key?(:ref)
446
- parent = self
447
- proj = nil
448
- name = case name
449
- when String, Symbol
450
- name.to_s
451
- else
452
- path.basename
453
- end
454
- workspace.add(path, name, **kwargs) do
455
- __send__ :parent_set, parent
456
- proj = self
457
- instance_eval(&blk) if block_given?
458
- end
459
- @children << proj
449
+ elsif projectpath?(path = basepath(path)) && checkdir?(path)
450
+ kwargs = hashdup(@withargs).update(kwargs) if @withargs
451
+ kwargs[:group] = group if group && !kwargs.key?(:group)
452
+ kwargs[:ref] = ref unless kwargs.key?(:ref)
453
+ parent = self
454
+ proj = nil
455
+ name = case name
456
+ when String, Symbol
457
+ name.to_s
458
+ else
459
+ path.basename
460
+ end
461
+ workspace.add(path, name, **kwargs) do
462
+ __send__ :parent_set, parent
463
+ proj = self
464
+ instance_eval(&blk) if block_given?
465
+ end
466
+ @children << proj
467
+ end
460
468
  self
461
469
  end
462
470
 
@@ -466,13 +474,13 @@ module Squared
466
474
  end
467
475
 
468
476
  def inject(obj, *args, **kwargs, &blk)
469
- return self unless enabled?
470
-
471
- out = obj.link(self, *args, **kwargs, &blk) if obj.respond_to?(:link)
472
- if !out
473
- print_error('link not compatible', subject: obj, hint: name)
474
- elsif out.respond_to?(:build)
475
- out.build
477
+ if enabled?
478
+ out = obj.link(self, *args, **kwargs, &blk) if obj.respond_to?(:link)
479
+ if !out
480
+ print_error('link not compatible', subject: obj, hint: name)
481
+ elsif out.respond_to?(:build)
482
+ out.build
483
+ end
476
484
  end
477
485
  self
478
486
  end
@@ -556,7 +564,7 @@ module Squared
556
564
  next if @@graph[:_].include?(proj)
557
565
 
558
566
  if (val = ENV["PREREQS_#{proj.instance_variable_get(:@envname)}"] || ENV["PREREQS_#{proj.ref.upcase}"])
559
- val.split(/\s*,\s*/).each do |meth|
567
+ split_escape(val).each do |meth|
560
568
  if proj.respond_to?(meth.to_sym)
561
569
  begin
562
570
  proj.__send__(meth, sync: sync)
@@ -615,7 +623,7 @@ module Squared
615
623
  begin
616
624
  @clean.each { |cmd, opts| build(cmd.to_s, opts, sync: sync) }
617
625
  rescue StandardError => e
618
- on_error e, from
626
+ on_error e, :clean
619
627
  end
620
628
  else
621
629
  if @clean.is_a?(Enumerable) && !series?(@clean)
@@ -725,6 +733,8 @@ module Squared
725
733
  ext = 'tgz'
726
734
  when 'application/x-xz'
727
735
  ext = 'txz'
736
+ when 'application/x-7z-compressed'
737
+ ext = '7z'
728
738
  end
729
739
  end
730
740
  break uri = url if data
@@ -759,7 +769,7 @@ module Squared
759
769
  case ext
760
770
  when 'zip', 'aar'
761
771
  session 'unzip', shell_quote(file), quote_option('d', target)
762
- when 'tar', 'tgz', 'tar.gz', 'tar.xz', 'gz', 'xz'
772
+ when 'tar', 'tgz', 'txz', 'tar.gz', 'tar.xz', 'gz', 'xz'
763
773
  flags = +(verbose ? 'v' : '')
764
774
  if ext.end_with?('gz')
765
775
  flags += 'z'
@@ -869,7 +879,7 @@ module Squared
869
879
  end
870
880
 
871
881
  def run(cmd = @session, var = nil, exception: self.exception, sync: true, from: nil, banner: true, chdir: path,
872
- interactive: nil, hint: nil, **)
882
+ interactive: nil, hint: nil, series: true, **)
873
883
  unless cmd
874
884
  print_error('no command session started', subject: project, hint: from, pass: true)
875
885
  return
@@ -894,7 +904,7 @@ module Squared
894
904
  log&.warn "ENV discarded: #{var}" if var
895
905
  task_invoke(cmd, exception: exception, warning: warning?)
896
906
  else
897
- print_item format_banner(hint ? "#{cmd} (#{hint})" : cmd, banner: banner) if sync
907
+ print_item(format_banner(hint ? "#{cmd} (#{hint})" : cmd, banner: banner), series: series) if sync
898
908
  if var != false && (pre = runenv)
899
909
  case pre
900
910
  when Hash
@@ -1142,6 +1152,7 @@ module Squared
1142
1152
  def graph_branch(target, data, tasks = nil, out = nil, sync: true, pass: [], done: [], depth: 0,
1143
1153
  single: false, last: false, context: nil)
1144
1154
  tag = ->(proj) { "#{proj.name}#{SEM_VER.match?(proj.version) ? "@#{proj.version}" : ''}" }
1155
+ script = ->(proj) { workspace.script_get(:graph, group: proj.group, ref: proj.allref)&.fetch(:graph, nil) }
1145
1156
  check = ->(deps) { deps.reject { |val| done.include?(val) } }
1146
1157
  dedupe = lambda do |name|
1147
1158
  next [] unless (ret = data[name])
@@ -1192,10 +1203,7 @@ module Squared
1192
1203
  single: single, last: j == true, context: target)
1193
1204
  end
1194
1205
  if !out
1195
- if !tasks && (script = workspace.script_get(:graph, group: proj.group, ref: proj.allref))
1196
- tasks = script[:graph]
1197
- end
1198
- (tasks || (dev? ? ['build', 'copy'] : ['depend', 'build'])).each do |meth|
1206
+ (tasks || (subtasks = script.call(proj)) || (dev? ? %w[build copy] : %w[depend build])).each do |meth|
1199
1207
  next if pass.include?(meth)
1200
1208
 
1201
1209
  if workspace.task_defined?(cmd = task_join(proj.name, meth))
@@ -1206,7 +1214,7 @@ module Squared
1206
1214
  end
1207
1215
  run(cmd, sync: false, banner: false)
1208
1216
  ENV.delete(key) if key
1209
- elsif proj.has?(meth, tasks ? nil : workspace.baseref)
1217
+ elsif proj.has?(meth, tasks || subtasks ? nil : workspace.baseref)
1210
1218
  proj.__send__(meth.to_sym, sync: sync)
1211
1219
  end
1212
1220
  end
@@ -1351,9 +1359,9 @@ module Squared
1351
1359
  warn log_message(loglevel, *args, **kwargs) if warning?
1352
1360
  end
1353
1361
 
1354
- def print_item(*val)
1362
+ def print_item(*val, series: true)
1355
1363
  puts unless printfirst?
1356
- printsucc
1364
+ printsucc if series
1357
1365
  puts val unless val.empty? || (val.size == 1 && val.first.nil?)
1358
1366
  end
1359
1367
 
@@ -1388,7 +1396,7 @@ module Squared
1388
1396
  sub&.each { |h| s = sub_style(s, **h) }
1389
1397
  s
1390
1398
  end
1391
- ret = [sub_style(ARG[:BORDER][1] * n, styles: border), *lines]
1399
+ ret = [sub_style(ARG[:BORDER][1] * n, styles: border)].concat(lines)
1392
1400
  ret.reverse! if reverse
1393
1401
  ret.join("\n")
1394
1402
  end
@@ -1489,7 +1497,7 @@ module Squared
1489
1497
  else
1490
1498
  pat = /\A(\s*\d+\.)(.+)\z/
1491
1499
  unless grep.empty?
1492
- footer = "#{out.size} found"
1500
+ footer = "#{out.size} found "
1493
1501
  sub << { pat: /\A(\d+)( .+)\z/, styles: theme[:inline] }
1494
1502
  end
1495
1503
  end
@@ -1807,10 +1815,8 @@ module Squared
1807
1815
 
1808
1816
  def semcmp(val, other)
1809
1817
  return 0 if val == other
1810
-
1811
- a, b = [val, other].map! { |ver| ver.scan(SEM_VER) }
1812
- return -1 if b.empty?
1813
- return 1 if a.empty?
1818
+ return -1 if (b = other.scan(SEM_VER)).empty?
1819
+ return 1 if (a = val.scan(SEM_VER)).empty?
1814
1820
 
1815
1821
  a, b = [a.first, b.first].map! do |c|
1816
1822
  d = begin
@@ -2075,7 +2081,7 @@ module Squared
2075
2081
  if val.directory? && !val.empty?
2076
2082
  true
2077
2083
  else
2078
- log&.warn "directory \"#{val}\" (#{val.empty? ? 'empty' : 'not found'})"
2084
+ log&.warn "directory \"#{val}\" (#{val.directory? ? 'empty' : 'not found'})"
2079
2085
  false
2080
2086
  end
2081
2087
  end
@@ -13,7 +13,7 @@ module Squared
13
13
  buildx: {
14
14
  common: %w[builder=b D|debug],
15
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
16
+ cgroup-parent=b iidfile=p label=q a-file=p network=b no-cache-filter=b o|output=q platform=b
17
17
  q|quiet secret=qq shm-size=b ssh=qq t|tag=b target=b ulimit=q].freeze,
18
18
  bake: %w[print list=q set=q].freeze,
19
19
  shared: %w[check load no-cache pull push allow=q call=b? f|file=p metadata-file=p progress=b provenance=q
@@ -26,8 +26,8 @@ module Squared
26
26
  provenance=q sbom=q ssh=qq].freeze,
27
27
  exec: %w[d|detach privileged e|env=qq index=i T|no-TTY=b? user=e w|workdir=q].freeze,
28
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,
29
+ cap-add=b cap-drop=b entrypoint=q e|env=qq env-from-file=p i|interactive=b? l|label=q name=b
30
+ T|no-TTY=b? p|publish=q pull=b u|user=e v|volume=q w|workdir=q].freeze,
31
31
  up: %w[abort-on-container-exit abort-on-container-failure always-recreate-deps attach-dependencies build
32
32
  d|detach force-recreate menu no-build no-color no-deps no-log-prefix no-recreate no-start quiet-build
33
33
  quiet-pull remove-orphans V|renew-anon-volumes timestamps wait w|watch y|yes attach=b
@@ -36,25 +36,26 @@ module Squared
36
36
  }.freeze,
37
37
  container: {
38
38
  create: %w[init i|interactive no-healthcheck oom-kill-disable privileged P|publish-all q|quiet read-only
39
- rm runtime t|tty use-api-socket io-maxbandwidth=b io-maxiops=b add-host=q annotation=q 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
42
- device-write-iops=q disable-content-trust=b? dns=e dns-option=e dns-search=e domainname=b
43
- entrypoint=q e|env=qq env-file=p expose=e gpus=q group-add=b health-cmd=q health-interval=b 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,
50
- run: %w[d|detach detach-keys=q sig-proxy=b?].freeze,
39
+ rm t|tty use-api-socket add-host=q annotation=q a|attach=b blkio-weight=i blkio-weight-device=i
40
+ cap-add=b cap-drop=b cgroup-parent=b cgroupns=b cidfile=p device=q device-cgroup-rule=q
41
+ device-read-bps=q device-read-iops=q device-write-bps=q device-write-iops=q
42
+ disable-content-trust=b? dns=q dns-option=q dns-search=q domainname=b entrypoint=q e|env=qq
43
+ env-file=p expose=q gpus=q group-add=b health-cmd=q health-interval=b health-retries=i
44
+ health-start-interval=q health-start-period=q health-timeout=q io-maxbandwidth=b io-maxiops=b
45
+ ip=b ip6=q ipc=b isolation=b kernel-memory=b l|label=q label-file=q link=b link-local-ip=q
46
+ log-driver=b log-opt=q mac-address=q m|memory=b memory-reservation=b memory-swap=n
47
+ memory-swappiness=n mount=qq name=b network=b network-alias=b oom-score-adj=b pid=b pids-limit=n
48
+ platform=b p|publish=q pull=b restart=b runtime=b security-opt=q shm-size=b stop-signal=b
49
+ stop-timeout=i storage-opt=q sysctl=q tmpfs=q ulimit=q u|user=b userns=b uts=b v|volume=q
50
+ volume-driver=b volumes-from=b w|workdir=q].freeze,
51
+ run: %w[d|detach detach-keys=q hostname=q sig-proxy=b?].freeze,
51
52
  update: %w[blkio-weight=i cpu-period=i cpu-quota=i cpu-rt-period=i cpu-rt-runtime=i c|cpu-shares=i cpus=f
52
53
  cpuset-cpus=b cpuset-mems=b m|memory=b memory-reservation=b memory-swap=b pids-limit=n
53
54
  restart=q].freeze,
54
55
  exec: %w[d|detach i|interactive privileged t|tty detach-keys=q e|env=qq env-file=p user=e
55
56
  w|workdir=q].freeze,
56
57
  commit: %w[a|author=q c|change=q m|message=q pause=b?].freeze,
57
- inspect: %w[s|size f|format=q].freeze,
58
+ inspect: %w[s|size f|format=q type=b].freeze,
58
59
  start: %w[a|attach i|interactive detach-keys=q].freeze,
59
60
  stop: %w[s|signal=b t|time=i t|timeout=i].freeze,
60
61
  restart: %w[s|signal=b t|time=i t|timeout=i].freeze,
@@ -68,7 +69,7 @@ module Squared
68
69
  save: %w[o|output=p platform=b].freeze
69
70
  }.freeze,
70
71
  network: {
71
- connect: %w[alias=b driver-opt=q gw-priority=n ip=b ip6=b link=b link-local-ip=b].freeze,
72
+ connect: %w[alias=b driver-opt=q gw-priority=n ip=b ip6=q link=b link-local-ip=q].freeze,
72
73
  disconnect: %w[f|force].freeze
73
74
  }.freeze
74
75
  }.freeze
@@ -1559,7 +1559,7 @@ module Squared
1559
1559
  append_value list
1560
1560
  remote = nil
1561
1561
  when :move, :copy
1562
- s = "-#{flag.to_s[0]}"
1562
+ s = +"-#{flag.to_s[0]}"
1563
1563
  s.upcase! if option('force', 'f')
1564
1564
  cmd << s
1565
1565
  refs.compact.each { |val| cmd << shell_quote(val) }
@@ -1980,7 +1980,7 @@ module Squared
1980
1980
  when 'rebase'
1981
1981
  op << basic_option($1, $2) if VAL_GIT[:rebase][:value].include?($2)
1982
1982
  when 'shallow-since'
1983
- op.append?($1) { Date.parse($2)&.strftime('%F %T') }
1983
+ op.append?($1) { Date.parse($2).strftime('%F %T') }
1984
1984
  when 'recurse-submodules'
1985
1985
  op.append?($1, $2, type: :basic)
1986
1986
  when 'refspec'
@@ -130,10 +130,9 @@ module Squared
130
130
  when 'add'
131
131
  format_desc action, nil, 'save?=prod|dev|optional|peer,name+'
132
132
  task action, [:save] do |_, args|
133
- save = param_guard(action, 'save', args: args, key: :save)
134
- exact = true if save.delete_prefix!('=')
135
- packages = case save
136
- when 'prod', 'dev', 'optional', 'peer'
133
+ packages = if args.save =~ /\A(=)?(prod|dev|optional|peer)\z/
134
+ exact = !$1.nil?
135
+ save = $2
137
136
  args.extras
138
137
  else
139
138
  save = 'prod'
@@ -147,21 +146,21 @@ module Squared
147
146
 
148
147
  format_desc action, nil, "script,opts*|#{indexchar}index+|#,pattern*"
149
148
  task action, [:script] do |_, args|
149
+ list = scripts.to_a
150
150
  if args.script == '#'
151
- format_list(scripts.to_a, "run[#{indexchar}N]", 'scripts', grep: args.extras, from: dependfile)
151
+ format_list(list, "run[#{indexchar}N]", 'scripts', grep: args.extras, from: dependfile)
152
152
  else
153
153
  args = param_guard(action, 'script', args: args.to_a)
154
154
  opts = []
155
155
  args.each do |val|
156
156
  if (n, extra = indexitem(val))
157
157
  if (item = list[n - 1])
158
- val = extra ? "#{item.first} #{extra}" : item.first
158
+ run compose([item.first, extra].compact.join(' '), script: true)
159
159
  elsif exception
160
160
  indexerror n, list
161
161
  else
162
162
  next log.warn "run script #{n} of #{list.size} (out of range)"
163
163
  end
164
- run compose(val, script: true)
165
164
  else
166
165
  opts << val
167
166
  end
@@ -431,19 +430,7 @@ module Squared
431
430
  workspace.rev_clear(name, sync: sync)
432
431
  return update if !flag && env('NODE_UPDATE')
433
432
 
434
- pnpm = pnpm?
435
- yarn = pnpm ? 0 : dependtype(:yarn)
436
- if @pm[:__] && !pnpm && yarn == 0
437
- case @pm[:__]
438
- when 'pnpm'
439
- pnpm = true
440
- when 'yarn'
441
- yarn = 1
442
- when 'berry'
443
- yarn = 2
444
- end
445
- end
446
- if yarn > 0
433
+ if (yarn = dependtype(:yarn)) > 0
447
434
  cmd = session 'yarn'
448
435
  if flag == :add
449
436
  cmd << 'add'
@@ -453,7 +440,7 @@ module Squared
453
440
  cmd << 'install'
454
441
  cmd << '--ignore-engines' if yarn == 1 && !option('ignore-engines', equals: '0')
455
442
  end
456
- elsif pnpm
443
+ elsif pnpm?
457
444
  cmd = session 'pnpm'
458
445
  if flag == :add
459
446
  cmd << 'add' << "--save-#{save}"
@@ -642,7 +629,7 @@ module Squared
642
629
  else
643
630
  footer.call(0, found.size)
644
631
  end
645
- commit(:add, refs: ['package.json'], pass: true)
632
+ commit(:add, ['package.json'], pass: true)
646
633
  end
647
634
  elsif !avail.empty?
648
635
  col1 = size_col.call(avail, 0) + 4
@@ -888,45 +875,32 @@ module Squared
888
875
 
889
876
  def yarn?
890
877
  (@pm[:yarn] ||= if rootpath('yarn.lock', ascend: dependext).exist?
891
- if (rc = rootpath('.yarnrc.yml', ascend: dependext)).exist?
892
- begin
893
- require 'yaml'
894
- doc = YAML.load_file(rc)
895
- doc.nodeLinker == 'node-modules' ? 2 : 3
896
- rescue StandardError => e
897
- log.debug e
898
- 3
899
- end
878
+ yarntype
879
+ elsif (ver = read_packagemanager || read_install)
880
+ if ver =~ /^yarn(?:@(\d)|$)/
881
+ $1 && $1.to_i > 1 ? yarntype : 1
900
882
  else
901
- 1
883
+ 0
902
884
  end
903
- elsif (ver = read_packagemanager || read_install)&.start_with?('yarn')
904
- ver == 'yarn' || ver.include?('@1') ? 1 : 3
905
885
  else
906
- 0
886
+ case @pm[:__]
887
+ when 'yarn'
888
+ 1
889
+ when 'berry'
890
+ yarntype
891
+ else
892
+ 0
893
+ end
907
894
  end) > 0
908
895
  end
909
896
 
910
897
  def pnpm?
911
898
  (@pm[:pnpm] ||= if rootpath('pnpm-lock.yaml', ascend: dependext).exist?
912
- begin
913
- require 'yaml'
914
- doc = YAML.load_file(basepath('node_modules/.modules.yaml', ascend: dependext))
915
- @pm[:_] = doc['packageManager']
916
- case doc['nodeLinker']
917
- when 'hoisted'
918
- 1
919
- when 'pnp'
920
- 3
921
- else
922
- 4
923
- end
924
- rescue StandardError => e
925
- log.debug e
926
- 4
927
- end
899
+ pnpmtype
900
+ elsif (ver = read_packagemanager || read_install)
901
+ ver.start_with?('pnpm') ? pnpmtype : 0
928
902
  else
929
- (read_packagemanager || read_install)&.start_with?('pnpm') ? 4 : 0
903
+ @pm[:__] == 'pnpm' ? pnpmtype : 0
930
904
  end) > 0
931
905
  end
932
906
 
@@ -976,14 +950,17 @@ module Squared
976
950
  private
977
951
 
978
952
  def read_packagemanager(key = nil, version: nil, update: false)
979
- if @pm[:_].nil? || update
953
+ if (key ? !@pm.key?(key) : @pm[:_].nil?) || update
980
954
  doc = JSON.parse(dependfile.read)
981
- @pm[:_] = (val = doc['packageManager']) ? val[0, val.index('+') || val.size] : false
982
- @pm[:name] = doc['name']
983
- @pm[:scripts] = doc['scripts']
984
- @pm[:version] = doc['version']
985
- @pm[:private] = doc['private']
986
- @pm[:workspaces] = doc['workspaces']
955
+ if @pm[:_].nil?
956
+ @pm[:_] = (val = doc['packageManager']) ? val[0, val.index('+') || val.size] : false
957
+ @pm[:name] = doc['name']
958
+ @pm[:scripts] = doc['scripts']
959
+ @pm[:version] = doc['version']
960
+ @pm[:private] = doc['private']
961
+ @pm[:workspaces] = doc['workspaces']
962
+ end
963
+ @pm[key] = doc[key.to_s] if key
987
964
  end
988
965
  rescue StandardError => e
989
966
  log.debug e
@@ -1000,10 +977,67 @@ module Squared
1000
977
  def read_install
1001
978
  return unless (ret = env('NODE_INSTALL'))
1002
979
 
1003
- @pm[:_] ||= ret if ret.include?('@')
980
+ if ret.include?(',')
981
+ catch :found do
982
+ split_escape(ret).each do |val|
983
+ case val
984
+ when /^yarn/
985
+ next if yarntype(exist: true) == 0
986
+ when /^pnpm/
987
+ next if pnpmtype(exist: true) == 0
988
+ when /^npm/
989
+ nil
990
+ else
991
+ next
992
+ end
993
+ ret = val
994
+ throw :found
995
+ end
996
+ return
997
+ end
998
+ end
999
+ @pm[:_] ||= ret
1004
1000
  ret
1005
1001
  end
1006
1002
 
1003
+ def yarntype(exist: false)
1004
+ if (rc = rootpath('.yarnrc.yml', ascend: dependext)).exist?
1005
+ require 'yaml'
1006
+ doc = YAML.load_file(rc)
1007
+ doc.nodeLinker == 'node-modules' ? 2 : 3
1008
+ elsif exist && !basepath('yarn.lock').exist?
1009
+ 0
1010
+ else
1011
+ 1
1012
+ end
1013
+ rescue StandardError => e
1014
+ return 0 if exist
1015
+
1016
+ log.debug e
1017
+ 3
1018
+ end
1019
+
1020
+ def pnpmtype(exist: false)
1021
+ require 'yaml'
1022
+ doc = YAML.load_file(basepath('node_modules/.modules.yaml', ascend: dependext))
1023
+ @pm['packageManager'] = doc['packageManager']
1024
+ case doc['nodeLinker']
1025
+ when 'hoisted'
1026
+ 1
1027
+ when 'pnp'
1028
+ 3
1029
+ else
1030
+ 4
1031
+ end
1032
+ rescue StandardError => e
1033
+ if exist
1034
+ %w[pnpm-lock.yaml pnpm-workspace.yaml].any? { |val| basepath(val).exist? } ? 4 : 0
1035
+ else
1036
+ log.debug e
1037
+ 4
1038
+ end
1039
+ end
1040
+
1007
1041
  def append_loglevel(target: @session)
1008
1042
  level = env('NODE_LOGLEVEL')
1009
1043
  silent = !verbose || level == 'silent'
@@ -372,7 +372,7 @@ module Squared
372
372
  end
373
373
  end
374
374
 
375
- def outdated(flag = nil, opts = [], sync: invoked_sync?('outdated'))
375
+ def outdated(flag = nil, opts = [], sync: invoked_sync?('outdated', flag))
376
376
  cmd = pip_session 'list --outdated'
377
377
  append_global
378
378
  cmd = session_done cmd
@@ -279,7 +279,13 @@ module Squared
279
279
  elsif outdated?
280
280
  workspace.rev_clear(name, sync: sync)
281
281
  cmd = bundle_session 'install'
282
- cmd << '--without=development' if prod?
282
+ if prod? && !config_get('without')
283
+ if RUBY_VERSION > '3'
284
+ config_set 'without', 'development'
285
+ else
286
+ cmd << '--without=development'
287
+ end
288
+ end
283
289
  if (n = option('jobs')).to_i > 0
284
290
  cmd << "-j#{n}"
285
291
  end
@@ -918,7 +924,7 @@ module Squared
918
924
  pwd_set(pass: !opt.nil?) do
919
925
  out = `#{gem_output(opt, 'list --local -d', gemname)}`
920
926
  if out =~ /#{Regexp.escape(gemname)} \(([^)]+)\)/
921
- $1.split(/\s*,\s*/)
927
+ split_escape($1)
922
928
  .prepend(version)
923
929
  .uniq
924
930
  .each do |val|
@@ -1025,6 +1031,28 @@ module Squared
1025
1031
  session_output('rake', *cmd, **kwargs)
1026
1032
  end
1027
1033
 
1034
+ def config_get(key)
1035
+ ret = if pwd_set { `#{bundle_output('config get --parseable', key)}` } =~ /\A([^=]+)=(.*)\z/ && $1 == key
1036
+ $2.chomp
1037
+ end
1038
+ case ret
1039
+ when 'true'
1040
+ true
1041
+ when '', '[]'
1042
+ nil
1043
+ else
1044
+ if ret =~ /\A\[:(.+)\]\z/
1045
+ $1.split(', :').map! { |val| ((val.delete_prefix!('"') && val.delete_suffix!('"')) || val).to_sym }
1046
+ else
1047
+ ret || false
1048
+ end
1049
+ end
1050
+ end
1051
+
1052
+ def config_set(key, *val)
1053
+ run(bundle_output('config set', key, *val), banner: false, series: false)
1054
+ end
1055
+
1028
1056
  def preopts
1029
1057
  verbosetype > 1 && !session_arg?('quiet') ? ['--verbose'] : []
1030
1058
  end
@@ -135,7 +135,7 @@ module Squared
135
135
  next if (stage = env('REPO_STAGE')) == '1'
136
136
 
137
137
  @project.select do |_, proj|
138
- next unless proj.enabled?(proj.workspace.baseref)
138
+ next unless proj.enabled?(proj.workspace.baseref) && proj.global
139
139
 
140
140
  proj.depend(sync: true) if proj.depend?
141
141
  next if stage == '2'
@@ -12,17 +12,12 @@ module Squared
12
12
  Hash.new { |data, key| data[key] = [] }
13
13
  end
14
14
 
15
- def hashdup(data, pass: [])
15
+ def hashdup(data, pass: {})
16
16
  ret = {}
17
17
  data.each do |key, val|
18
18
  ret[key] = case val
19
19
  when Hash
20
- if pass.include?(val)
21
- val
22
- else
23
- pass << val
24
- hashdup(val, pass: pass)
25
- end
20
+ pass[val] ||= hashdup(val, pass: pass)
26
21
  when Proc, Method
27
22
  val
28
23
  else
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squared
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.11
4
+ version: 0.5.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-10-18 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rake
@@ -111,7 +110,6 @@ metadata:
111
110
  homepage_uri: https://github.com/anpham6/squared-ruby
112
111
  source_code_uri: https://github.com/anpham6/squared-ruby
113
112
  documentation_uri: https://squared.readthedocs.io
114
- post_install_message:
115
113
  rdoc_options: []
116
114
  require_paths:
117
115
  - lib
@@ -126,8 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
124
  - !ruby/object:Gem::Version
127
125
  version: '0'
128
126
  requirements: []
129
- rubygems_version: 3.2.33
130
- signing_key:
127
+ rubygems_version: 3.7.2
131
128
  specification_version: 4
132
129
  summary: Rake task generator for managing multi-language workspaces.
133
130
  test_files: []