squared 0.4.24 → 0.4.26

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: c07babae909a985bae708b8a2bec453b223d9889af828da70d990609e9966142
4
- data.tar.gz: 5375a660bbcc0f49b5a3eaad5ab2740b103beeb3823a0d7b027b9005bf39faa9
3
+ metadata.gz: 31cca2889400b4e4b51df7249ac426d782a9905cc69e731d0766ef1012002651
4
+ data.tar.gz: 4353d4d765dc14916e6db6c9605cc0b02fe48b353adc0ed274c08f01e0cc6f25
5
5
  SHA512:
6
- metadata.gz: 23cd1e57c7d0039fed851d6d426eec51022dba2c26bbce9faafddd20ded4aad3d00d6db023c3a99e2aa485aace597567df4f603130746daa5dc5e2d661c658dd
7
- data.tar.gz: cb9556662d393d458413df3669f9859b4b3df9d9ca3e659b9098fac0d550349eaf8b414e6cb85b0828f522f3b78f1627c282350eb6b9b62218f76413ebcaabb8
6
+ metadata.gz: 6fda0932de949193edfc82bb533c3b21b39624b2d1d8fc3b1762b0c8e93ce47807e9a34c8b378896d6f4f92c18d06ae82b217dfd42539667cb0df3de5d98cd5c
7
+ data.tar.gz: 411bba4daeb35c641b67306bba13502a78cab65c09e94d3a5fcef0f7ad213f5a8a75886b641a32d4e1dce83b6c697784ca438d4c570a30dd3d331ae8b25541c0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.26] - 2025-10-31
4
+
5
+ ### Added
6
+
7
+ - Docker command options were updated to 28.5.
8
+
9
+ ### Changed
10
+
11
+ - Node package manager does not override package.json with NODE_INSTALL.
12
+ - Node workspaces can specify more than one package manager through NODE_INSTALL.
13
+
14
+ ### Fixed
15
+
16
+ - Node command add did not provide optional save argument.
17
+ - Python command outdated did not detect synchronous output.
18
+ - Node command outdated auto-commit was completely dysfunctional.
19
+ - Project workspaces caused a complete meltdown on TruffleRuby.
20
+ - Project build initialization global flag was always incoherent.
21
+ - Project base setters did not accept direct values.
22
+ - Project base global graph tasks are not definable by a sub-project.
23
+
24
+ ## [0.4.25] - 2025-10-18
25
+
26
+ ### Fixed
27
+
28
+ - Project groups did not have their own copy of base events.
29
+
3
30
  ## [0.4.24] - 2025-10-17
4
31
 
5
32
  ### Added
@@ -1037,6 +1064,8 @@
1037
1064
 
1038
1065
  - Changelog was created.
1039
1066
 
1067
+ [0.4.26]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.26
1068
+ [0.4.25]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.25
1040
1069
  [0.4.24]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.24
1041
1070
  [0.4.23]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.23
1042
1071
  [0.4.22]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.22
data/README.md CHANGED
@@ -686,7 +686,7 @@ GIT_AUTOSTASH_${NAME}=0 # rebase (project only)
686
686
 
687
687
  ### Docker
688
688
 
689
- * Version: 28.3
689
+ * Version: [28.5](https://docs.docker.com/engine/release-notes/28)
690
690
 
691
691
  ```sh
692
692
  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
 
@@ -179,7 +179,7 @@ module Squared
179
179
  if level.is_a?(::Numeric)
180
180
  if append && respond_to?(:log)
181
181
  (log rescue nil).tap do |ref|
182
- ref.add(level, message(subject, *args, hint: hint, space: ', ')) if ref.is_a?(Logger)
182
+ ref.add(level, message(subject, *args, hint: hint, space: ', ')) if ref.is_a?(::Logger)
183
183
  end
184
184
  end
185
185
  return false if !pass && level < ARG[:LEVEL]
@@ -199,7 +199,7 @@ module Squared
199
199
  def log_console(*args, pipe: 1)
200
200
  return if args.first == false && args.size == 1
201
201
 
202
- if pipe.is_a?(Pathname)
202
+ if pipe.is_a?(::Pathname)
203
203
  begin
204
204
  File.open(pipe, 'a') do |f|
205
205
  br = File::SEPARATOR == '\\' ? "\r\n" : "\n"
@@ -233,7 +233,7 @@ module Squared
233
233
  lines = val.map(&:to_s)
234
234
  else
235
235
  lines = val.to_s.lines(chomp: true)
236
- lines[0] = "#{val.class}: #{lines.first}" if (err = val.is_a?(StandardError))
236
+ lines[0] = "#{val.class}: #{lines.first}" if (err = val.is_a?(::StandardError))
237
237
  end
238
238
  n = cols || max.call(lines)
239
239
  if $stdout.tty?
@@ -47,11 +47,11 @@ module Squared
47
47
  end
48
48
  max = items.size
49
49
  raise_error 'empty selection list' if max == 0
50
- min = [min, max].min
50
+ min = grep ? 1 : [min, max].min
51
51
  if auto
52
- msg = "#{msg}: [1-#{max}#{if multiple
53
- "|,#{multiple.is_a?(Numeric) ? "{#{multiple}}" : ''}"
54
- end}] "
52
+ msg = "#{msg + (force ? ':' : '?')} [#{min}-#{max}#{if (n = multiple)
53
+ "|,#{n.is_a?(::Numeric) ? "{#{n}}" : ''}"
54
+ end}] "
55
55
  end
56
56
  end
57
57
  valid = ->(s) { s.match?(/^-?\d+$/) && s.to_i.between?(min, max) }
@@ -63,10 +63,7 @@ module Squared
63
63
  a = ch.split(/\s*,\s*/)
64
64
  b = a.select { |s| valid.call(s) }.map!(&:to_i).sort
65
65
  next unless a.size == b.size
66
- return b unless items
67
- next if multiple.is_a?(::Numeric) && multiple != b.size
68
-
69
- return b.map! { |i| items[i - 1] }
66
+ return items ? b.map! { |i| items[i - 1] } : b unless multiple.is_a?(::Numeric) && multiple != b.size
70
67
  elsif valid.call(ch)
71
68
  return items ? items[ch.to_i - 1] : ch.to_i
72
69
  end
@@ -97,18 +94,18 @@ module Squared
97
94
  elsif block_given?
98
95
  Readline.readmultiline(msg, history, &blk)
99
96
  else
100
- Readline.readmultiline(msg, history) { |line| multiline.any? { |val| line.split.last.end_with?(val) } }
97
+ Readline.readmultiline(msg, history) { |line| multiline.any? { |val| line.split.last.end_with?(val.to_s) } }
101
98
  end
102
99
  end
103
100
  case force
104
101
  when ::TrueClass, ::FalseClass
105
102
  msg = "#{msg} %s " % if multiline
106
- multiline.is_a?(::Enumerable) ? "{#{multiline.join('|')}}" : multiline
103
+ multiline.is_a?(::Enumerable) ? "{#{multiline.to_a.join('|')}}" : multiline
107
104
  else
108
105
  "(#{force ? 'required' : 'optional'}):"
109
106
  end
110
107
  ret = (prompt.call || '').strip
111
- multiline.each { |val| break if ret.delete_suffix!(val) } if multiline.is_a?(::Enumerable)
108
+ multiline.each { |val| break if ret.delete_suffix!(val.to_s) } if multiline.is_a?(::Enumerable)
112
109
  exit 1 if force && ret.empty?
113
110
  ret
114
111
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.4.24'
4
+ VERSION = '0.4.26'
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?
@@ -322,21 +321,9 @@ module Squared
322
321
  end
323
322
 
324
323
  def add(path, project = nil, **kwargs, &blk)
325
- if @withargs
326
- data = @withargs.dup
327
- data.merge!(kwargs)
328
- kwargs = data
329
- end
330
- ref = if kwargs.key?(:ref)
331
- kwargs = kwargs.dup unless @withargs
332
- kwargs.delete(:ref)
333
- elsif @ref.is_a?(Symbol)
334
- @ref
335
- end
336
- if @group.is_a?(String) && !kwargs.key?(:group)
337
- kwargs = kwargs.dup unless @withargs
338
- kwargs[:group] = @group
339
- end
324
+ kwargs = Support.hashdup(@withargs).update(kwargs) if @withargs
325
+ ref = kwargs.key?(:ref) ? kwargs.delete(:ref) : @ref
326
+ kwargs[:group] = @group if @group && !kwargs.key?(:group)
340
327
  path = root + path
341
328
  project = (project || path.basename).to_s
342
329
  name = task_name project
@@ -629,9 +616,7 @@ module Squared
629
616
  end
630
617
 
631
618
  def home?
632
- return false unless (proj = find(home))
633
-
634
- proj.enabled?
619
+ !!find(home)&.enabled?
635
620
  end
636
621
 
637
622
  def windows?
@@ -74,6 +74,7 @@ module Squared
74
74
 
75
75
  attr_reader :name, :project, :workspace, :path, :theme, :group, :parent, :dependfile,
76
76
  :exception, :pipe, :verbose
77
+ attr_accessor :global
77
78
 
78
79
  def initialize(workspace, path, name, *, group: nil, first: {}, last: {}, error: {}, common: ARG[:COMMON],
79
80
  **kwargs)
@@ -91,9 +92,14 @@ module Squared
91
92
  @clean = kwargs[:clean]
92
93
  @release = kwargs[:release]
93
94
  self.version = kwargs[:version]
94
- self.exception = kwargs[:exception]
95
- self.pipe = kwargs[:pipe]
96
- self.verbose = kwargs[:verbose]
95
+ self.exception = env_bool(kwargs[:exception], workspace.exception, strict: true)
96
+ self.pipe = env_pipe(kwargs[:pipe], workspace.pipe, strict: true)
97
+ self.verbose = case (val = env('VERBOSE', kwargs[:verbose]))
98
+ when String
99
+ env_bool(val, workspace.verbose, strict: true, index: true)
100
+ else
101
+ val.nil? ? workspace.verbose : val
102
+ end
97
103
  @output = []
98
104
  @ref = []
99
105
  @children = []
@@ -138,8 +144,10 @@ module Squared
138
144
  data = @workspace.script_find(*@ref, @group)
139
145
  if @output[0].nil?
140
146
  if (scr = data[:script])
141
- @global = true
142
- script_set(scr, args: data.fetch(:args, kwargs[:args]), prod: kwargs[:prod])
147
+ unless kwargs[:script] == false
148
+ @global = true
149
+ script_set(scr, args: data.fetch(:args, kwargs[:args]), prod: kwargs[:prod])
150
+ end
143
151
  elsif (run = data[:run])
144
152
  @global = true
145
153
  run_set run
@@ -162,7 +170,6 @@ module Squared
162
170
  @global = true
163
171
  run_set data[:run]
164
172
  end
165
- @global = true
166
173
  end
167
174
 
168
175
  def initialize_events(ref, **)
@@ -279,21 +286,29 @@ module Squared
279
286
  end
280
287
 
281
288
  def exception=(val)
282
- @exception = env_bool(val, workspace.exception, strict: true)
289
+ @exception = case val
290
+ when Numeric, TrueClass, FalseClass
291
+ val
292
+ else
293
+ workspace.exception
294
+ end
283
295
  end
284
296
 
285
297
  def pipe=(val)
286
- @pipe = env_pipe(val, workspace.pipe, strict: true)
298
+ @pipe = case val
299
+ when Numeric, Pathname
300
+ val
301
+ else
302
+ workspace.pipe
303
+ end
287
304
  end
288
305
 
289
306
  def verbose=(val)
290
- @verbose = case (val = env('VERBOSE', val))
291
- when NilClass
292
- workspace.verbose
293
- when String
294
- env_bool(val, workspace.verbose, strict: true, index: true)
295
- else
307
+ @verbose = case val
308
+ when Numeric, TrueClass, FalseClass
296
309
  val
310
+ else
311
+ workspace.verbose
297
312
  end
298
313
  end
299
314
 
@@ -323,13 +338,8 @@ module Squared
323
338
  else
324
339
  out, done = graph(args, out: [])
325
340
  out.map! do |val|
326
- done.each_with_index do |proj, i|
327
- next unless val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/)
328
-
329
- val += " (#{i.succ})"
330
- break
331
- end
332
- val
341
+ n = done.index { |proj| val.match?(/ #{Regexp.escape(proj.name)}(?:@\d|\z)/) }
342
+ n ? "#{val} (#{n.succ})" : val
333
343
  end
334
344
  emphasize(out, title: path, right: true, border: borderstyle, sub: [
335
345
  { pat: /\A(#{Regexp.escape(path.to_s)})(.*)\z/, styles: theme[:header] },
@@ -385,44 +395,33 @@ module Squared
385
395
  end
386
396
 
387
397
  def add(path, name = nil, **kwargs, &blk)
388
- if path.is_a?(String) && (seg = path[%r{\A(.+)[\\/]\*+\z}, 1])
389
- return self unless checkdir?(path = basepath(seg))
398
+ if path.is_a?(String) && path =~ %r{\A(.+)[\\/]\*+\z}
399
+ return self unless checkdir?(path = basepath($1))
390
400
 
391
401
  path = path.children.select { |val| checkdir?(val) }
392
402
  end
393
403
  if path.is_a?(Array)
394
- name = @name if name == true
404
+ name = self.name if name == true
395
405
  path.each { |val| add(val, name && task_join(name, File.basename(val)), **kwargs, &blk) }
396
- return self
397
- elsif !projectpath?(path = basepath(path)) || !checkdir?(path)
398
- return self
399
- else
406
+ elsif projectpath?(path = basepath(path)) && checkdir?(path)
407
+ kwargs = hashdup(@withargs).update(kwargs) if @withargs
408
+ kwargs[:group] = group if group && !kwargs.key?(:group)
409
+ kwargs[:ref] = ref unless kwargs.key?(:ref)
410
+ parent = self
411
+ proj = nil
400
412
  name = case name
401
413
  when String, Symbol
402
414
  name.to_s
415
+ else
416
+ path.basename
403
417
  end
418
+ workspace.add(path, name, **kwargs) do
419
+ __send__ :parent_set, parent
420
+ proj = self
421
+ instance_eval(&blk) if block_given?
422
+ end
423
+ @children << proj
404
424
  end
405
- if @withargs
406
- data = @withargs.dup
407
- data.merge!(kwargs)
408
- kwargs = data
409
- end
410
- kwargs[:group] = group unless kwargs.key?(:group)
411
- kwargs[:ref] = ref unless kwargs.key?(:ref)
412
- parent = self
413
- proj = nil
414
- name = case name
415
- when String, Symbol
416
- name.to_s
417
- else
418
- path.basename
419
- end
420
- workspace.add(path, name, **kwargs) do
421
- __send__ :parent_set, parent
422
- proj = self
423
- instance_eval(&blk) if block_given?
424
- end
425
- @children << proj
426
425
  self
427
426
  end
428
427
 
@@ -432,13 +431,13 @@ module Squared
432
431
  end
433
432
 
434
433
  def inject(obj, *args, **kwargs, &blk)
435
- return self unless enabled?
436
-
437
- out = obj.link(self, *args, **kwargs, &blk) if obj.respond_to?(:link)
438
- if !out
439
- print_error('link not compatible', subject: obj, hint: name)
440
- elsif out.respond_to?(:build)
441
- out.build
434
+ if enabled?
435
+ out = obj.link(self, *args, **kwargs, &blk) if obj.respond_to?(:link)
436
+ if !out
437
+ print_error('link not compatible', subject: obj, hint: name)
438
+ elsif out.respond_to?(:build)
439
+ out.build
440
+ end
442
441
  end
443
442
  self
444
443
  end
@@ -522,7 +521,7 @@ module Squared
522
521
  next if @@graph[:_].include?(proj)
523
522
 
524
523
  if (val = ENV["PREREQS_#{proj.instance_variable_get(:@envname)}"] || ENV["PREREQS_#{proj.ref.upcase}"])
525
- val.split(/\s*,\s*/).each do |meth|
524
+ split_escape(val).each do |meth|
526
525
  if proj.respond_to?(meth.to_sym)
527
526
  begin
528
527
  proj.__send__(meth, sync: sync)
@@ -581,7 +580,7 @@ module Squared
581
580
  begin
582
581
  @clean.each { |cmd, opts| build(cmd.to_s, opts, sync: sync) }
583
582
  rescue StandardError => e
584
- on_error e, from
583
+ on_error e, :clean
585
584
  end
586
585
  else
587
586
  if @clean.is_a?(Enumerable) && !series?(@clean)
@@ -692,6 +691,8 @@ module Squared
692
691
  ext = 'tgz'
693
692
  when 'application/x-xz'
694
693
  ext = 'txz'
694
+ when 'application/x-7z-compressed'
695
+ ext = '7z'
695
696
  end
696
697
  end
697
698
  break uri = url if data
@@ -726,7 +727,7 @@ module Squared
726
727
  case ext
727
728
  when 'zip', 'aar'
728
729
  session 'unzip', shell_quote(file), quote_option('d', target)
729
- when 'tar', 'tgz', 'tar.gz', 'tar.xz', 'gz', 'xz'
730
+ when 'tar', 'tgz', 'txz', 'tar.gz', 'tar.xz', 'gz', 'xz'
730
731
  flags = +(verbose ? 'v' : '')
731
732
  if ext.end_with?('gz')
732
733
  flags += 'z'
@@ -1081,6 +1082,7 @@ module Squared
1081
1082
  def graph_branch(target, data, tasks = nil, out = nil, sync: true, pass: [], done: [], depth: 0,
1082
1083
  single: false, last: false, context: nil)
1083
1084
  tag = ->(proj) { "#{proj.name}#{SEM_VER.match?(proj.version) ? "@#{proj.version}" : ''}" }
1085
+ script = ->(proj) { workspace.script_get(:graph, group: proj.group, ref: proj.allref)&.fetch(:graph, nil) }
1084
1086
  check = ->(deps) { deps.reject { |val| done.include?(val) } }
1085
1087
  dedupe = lambda do |name|
1086
1088
  next [] unless (ret = data[name])
@@ -1131,10 +1133,7 @@ module Squared
1131
1133
  single: single, last: j == true, context: target)
1132
1134
  end
1133
1135
  if !out
1134
- if !tasks && (script = workspace.script_get(:graph, group: proj.group, ref: proj.allref))
1135
- tasks = script[:graph]
1136
- end
1137
- (tasks || (dev? ? ['build', 'copy'] : ['depend', 'build'])).each do |meth|
1136
+ (tasks || (subtasks = script.call(proj)) || (dev? ? %w[build copy] : %w[depend build])).each do |meth|
1138
1137
  next if pass.include?(meth)
1139
1138
 
1140
1139
  if workspace.task_defined?(cmd = task_join(proj.name, meth))
@@ -1145,7 +1144,7 @@ module Squared
1145
1144
  end
1146
1145
  run(cmd, sync: false, banner: false)
1147
1146
  ENV.delete(key) if key
1148
- elsif proj.has?(meth, tasks ? nil : workspace.baseref)
1147
+ elsif proj.has?(meth, tasks || subtasks ? nil : workspace.baseref)
1149
1148
  proj.__send__(meth.to_sym, sync: sync)
1150
1149
  end
1151
1150
  end
@@ -1331,7 +1330,7 @@ module Squared
1331
1330
  sub&.each { |h| s = sub_style(s, **h) }
1332
1331
  s
1333
1332
  end
1334
- ret = [sub_style(ARG[:BORDER][1] * n, styles: border), *lines]
1333
+ ret = [sub_style(ARG[:BORDER][1] * n, styles: border)].concat(lines)
1335
1334
  ret.reverse! if reverse
1336
1335
  ret.join("\n")
1337
1336
  end
@@ -1433,7 +1432,7 @@ module Squared
1433
1432
  else
1434
1433
  pat = /\A(\s*\d+\.)(.+)\z/
1435
1434
  unless grep.empty?
1436
- footer = "#{out.size} found"
1435
+ footer = "#{out.size} found "
1437
1436
  sub << { pat: /\A(\d+)( .+)\z/, styles: theme[:inline] }
1438
1437
  end
1439
1438
  end
@@ -1760,10 +1759,8 @@ module Squared
1760
1759
 
1761
1760
  def semcmp(val, other)
1762
1761
  return 0 if val == other
1763
-
1764
- a, b = [val, other].map! { |ver| ver.scan(SEM_VER) }
1765
- return -1 if b.empty?
1766
- return 1 if a.empty?
1762
+ return -1 if (b = other.scan(SEM_VER)).empty?
1763
+ return 1 if (a = val.scan(SEM_VER)).empty?
1767
1764
 
1768
1765
  a, b = [a.first, b.first].map! do |c|
1769
1766
  begin
@@ -2039,7 +2036,7 @@ module Squared
2039
2036
  if val.directory? && !val.empty?
2040
2037
  true
2041
2038
  else
2042
- log&.warn "directory \"#{val}\" (#{val.empty? ? 'empty' : 'not found'})"
2039
+ log&.warn "directory \"#{val}\" (#{val.directory? ? 'empty' : 'not found'})"
2043
2040
  false
2044
2041
  end
2045
2042
  end
@@ -2139,6 +2136,10 @@ module Squared
2139
2136
  Workspace::Support.hashlist
2140
2137
  end
2141
2138
 
2139
+ def hashdup
2140
+ Workspace::Support.hashdup
2141
+ end
2142
+
2142
2143
  def borderstyle
2143
2144
  ((data = workspace.banner_get(*@ref, group: group)) && data[:border]) || theme[:border]
2144
2145
  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
@@ -630,13 +631,14 @@ module Squared
630
631
  when 2, 4
631
632
  return
632
633
  when 3
633
- return unless COMPOSEFILE.map { |val| basepath(val) }.select(&:exist?).size > 1
634
+ return unless COMPOSEFILE.select { |val| basepath(val).exist? }.size > 1
634
635
  end
635
636
  end
636
637
  files = Array(@file).map { |val| quote_option('file', basepath(val)) }
637
638
  if target.is_a?(Set)
638
639
  opts = target.to_a.insert(index, *files)
639
- target.clear.merge(opts)
640
+ target.clear
641
+ .merge(opts)
640
642
  else
641
643
  target.insert(index, *files)
642
644
  end
@@ -1549,7 +1549,7 @@ module Squared
1549
1549
  append_value list
1550
1550
  remote = nil
1551
1551
  when :move, :copy
1552
- s = "-#{flag.to_s[0]}"
1552
+ s = +"-#{flag.to_s[0]}"
1553
1553
  s.upcase! if option('force', 'f')
1554
1554
  cmd << s
1555
1555
  refs.compact.each { |val| cmd << shell_quote(val) }
@@ -1977,7 +1977,7 @@ module Squared
1977
1977
  when 'rebase'
1978
1978
  op << basic_option($1, $2) if VAL_GIT[:rebase][:value].include?($2)
1979
1979
  when 'shallow-since'
1980
- op.append?($1) { Date.parse($2)&.strftime('%F %T') }
1980
+ op.append?($1) { Date.parse($2).strftime('%F %T') }
1981
1981
  when 'recurse-submodules'
1982
1982
  op.append?($1, $2, type: :basic)
1983
1983
  when 'refspec'
@@ -129,13 +129,9 @@ module Squared
129
129
  when 'add'
130
130
  format_desc action, nil, 'save?=prod|dev|optional|peer,name+'
131
131
  task action, [:save] do |_, args|
132
- save = param_guard(action, 'save', args: args, key: :save)
133
- if save.start_with?('=')
134
- exact = true
135
- save = save[1..-1]
136
- end
137
- packages = case save
138
- when 'prod', 'dev', 'optional', 'peer'
132
+ packages = if args.save =~ /\A(=)?(prod|dev|optional|peer)\z/
133
+ exact = !$1.nil?
134
+ save = $2
139
135
  args.extras
140
136
  else
141
137
  save = 'prod'
@@ -426,19 +422,7 @@ module Squared
426
422
  workspace.rev_clear(name, sync: sync)
427
423
  return update if !flag && env('NODE_UPDATE')
428
424
 
429
- pnpm = pnpm?
430
- yarn = pnpm ? 0 : dependtype(:yarn)
431
- if @pm[:__] && !pnpm && yarn == 0
432
- case @pm[:__]
433
- when 'pnpm'
434
- pnpm = true
435
- when 'yarn'
436
- yarn = 1
437
- when 'berry'
438
- yarn = 2
439
- end
440
- end
441
- if yarn > 0
425
+ if (yarn = dependtype(:yarn)) > 0
442
426
  cmd = session 'yarn'
443
427
  if flag == :add
444
428
  cmd << 'add'
@@ -448,7 +432,7 @@ module Squared
448
432
  cmd << 'install'
449
433
  cmd << '--ignore-engines' if yarn == 1 && !option('ignore-engines', equals: '0')
450
434
  end
451
- elsif pnpm
435
+ elsif pnpm?
452
436
  cmd = session 'pnpm'
453
437
  if flag == :add
454
438
  cmd << 'add' << "--save-#{save}"
@@ -637,7 +621,7 @@ module Squared
637
621
  else
638
622
  footer.call(0, found.size)
639
623
  end
640
- commit(:add, refs: ['package.json'], pass: true)
624
+ commit(:add, ['package.json'], pass: true)
641
625
  end
642
626
  elsif !avail.empty?
643
627
  col1 = size_col.call(avail, 0) + 4
@@ -884,45 +868,32 @@ module Squared
884
868
 
885
869
  def yarn?
886
870
  (@pm[:yarn] ||= if rootpath('yarn.lock', ascend: dependext).exist?
887
- if (rc = rootpath('.yarnrc.yml', ascend: dependext)).exist?
888
- begin
889
- require 'yaml'
890
- doc = YAML.load_file(rc)
891
- doc.nodeLinker == 'node-modules' ? 2 : 3
892
- rescue StandardError => e
893
- log.debug e
894
- 3
895
- end
871
+ yarntype
872
+ elsif (ver = read_packagemanager || read_install)
873
+ if ver =~ /^yarn(?:@(\d)|$)/
874
+ $1 && $1.to_i > 1 ? yarntype : 1
896
875
  else
897
- 1
876
+ 0
898
877
  end
899
- elsif (ver = read_packagemanager || read_install)&.start_with?('yarn')
900
- ver == 'yarn' || ver.include?('@1') ? 1 : 3
901
878
  else
902
- 0
879
+ case @pm[:__]
880
+ when 'yarn'
881
+ 1
882
+ when 'berry'
883
+ yarntype
884
+ else
885
+ 0
886
+ end
903
887
  end) > 0
904
888
  end
905
889
 
906
890
  def pnpm?
907
891
  (@pm[:pnpm] ||= if rootpath('pnpm-lock.yaml', ascend: dependext).exist?
908
- begin
909
- require 'yaml'
910
- doc = YAML.load_file(basepath('node_modules/.modules.yaml', ascend: dependext))
911
- @pm[:_] = doc['packageManager']
912
- case doc['nodeLinker']
913
- when 'hoisted'
914
- 1
915
- when 'pnp'
916
- 3
917
- else
918
- 4
919
- end
920
- rescue StandardError => e
921
- log.debug e
922
- 4
923
- end
892
+ pnpmtype
893
+ elsif (ver = read_packagemanager || read_install)
894
+ ver.start_with?('pnpm') ? pnpmtype : 0
924
895
  else
925
- (read_packagemanager || read_install)&.start_with?('pnpm') ? 4 : 0
896
+ @pm[:__] == 'pnpm' ? pnpmtype : 0
926
897
  end) > 0
927
898
  end
928
899
 
@@ -972,14 +943,17 @@ module Squared
972
943
  private
973
944
 
974
945
  def read_packagemanager(key = nil, version: nil, update: false)
975
- if @pm[:_].nil? || update
946
+ if (key ? !@pm.key?(key) : @pm[:_].nil?) || update
976
947
  doc = JSON.parse(dependfile.read)
977
- @pm[:_] = (val = doc['packageManager']) ? val[0, val.index('+') || val.size] : false
978
- @pm[:name] = doc['name']
979
- @pm[:scripts] = doc['scripts']
980
- @pm[:version] = doc['version']
981
- @pm[:private] = doc['private']
982
- @pm[:workspaces] = doc['workspaces']
948
+ if @pm[:_].nil?
949
+ @pm[:_] = (val = doc['packageManager']) ? val[0, val.index('+') || val.size] : false
950
+ @pm[:name] = doc['name']
951
+ @pm[:scripts] = doc['scripts']
952
+ @pm[:version] = doc['version']
953
+ @pm[:private] = doc['private']
954
+ @pm[:workspaces] = doc['workspaces']
955
+ end
956
+ @pm[key] = doc[key.to_s] if key
983
957
  end
984
958
  rescue StandardError => e
985
959
  log.debug e
@@ -996,10 +970,67 @@ module Squared
996
970
  def read_install
997
971
  return unless (ret = env('NODE_INSTALL'))
998
972
 
999
- @pm[:_] ||= ret if ret.include?('@')
973
+ if ret.include?(',')
974
+ catch :found do
975
+ split_escape(ret).each do |val|
976
+ case val
977
+ when /^yarn/
978
+ next if yarntype(exist: true) == 0
979
+ when /^pnpm/
980
+ next if pnpmtype(exist: true) == 0
981
+ when /^npm/
982
+ nil
983
+ else
984
+ next
985
+ end
986
+ ret = val
987
+ throw :found
988
+ end
989
+ return
990
+ end
991
+ end
992
+ @pm[:_] ||= ret
1000
993
  ret
1001
994
  end
1002
995
 
996
+ def yarntype(exist: false)
997
+ if (rc = rootpath('.yarnrc.yml', ascend: dependext)).exist?
998
+ require 'yaml'
999
+ doc = YAML.load_file(rc)
1000
+ doc.nodeLinker == 'node-modules' ? 2 : 3
1001
+ elsif exist && !basepath('yarn.lock').exist?
1002
+ 0
1003
+ else
1004
+ 1
1005
+ end
1006
+ rescue StandardError => e
1007
+ return 0 if exist
1008
+
1009
+ log.debug e
1010
+ 3
1011
+ end
1012
+
1013
+ def pnpmtype(exist: false)
1014
+ require 'yaml'
1015
+ doc = YAML.load_file(basepath('node_modules/.modules.yaml', ascend: dependext))
1016
+ @pm['packageManager'] = doc['packageManager']
1017
+ case doc['nodeLinker']
1018
+ when 'hoisted'
1019
+ 1
1020
+ when 'pnp'
1021
+ 3
1022
+ else
1023
+ 4
1024
+ end
1025
+ rescue StandardError => e
1026
+ if exist
1027
+ %w[pnpm-lock.yaml pnpm-workspace.yaml].any? { |val| basepath(val).exist? } ? 4 : 0
1028
+ else
1029
+ log.debug e
1030
+ 4
1031
+ end
1032
+ end
1033
+
1003
1034
  def read_scripts
1004
1035
  ret = read_packagemanager(:scripts)
1005
1036
  ret.is_a?(Hash) ? ret.to_a : []
@@ -363,7 +363,7 @@ module Squared
363
363
  end
364
364
  end
365
365
 
366
- def outdated(flag = nil, opts = [], sync: invoked_sync?('outdated'))
366
+ def outdated(flag = nil, opts = [], sync: invoked_sync?('outdated', flag))
367
367
  cmd = pip_session 'list --outdated'
368
368
  append_global
369
369
  cmd = session_done cmd
@@ -886,7 +886,7 @@ module Squared
886
886
  pwd_set(pass: !opt.nil?) do
887
887
  out = `#{gem_output(opt, 'list --local -d', gemname)}`
888
888
  if out =~ /#{Regexp.escape(gemname)} \(([^)]+)\)/
889
- $1.split(/\s*,\s*/)
889
+ split_escape($1)
890
890
  .unshift(@version)
891
891
  .uniq
892
892
  .each do |val|
@@ -247,9 +247,9 @@ module Squared
247
247
  add quote_option(key, val, double: qq.include?(key), merge: merge)
248
248
  elsif p.include?(key)
249
249
  if val.match?(/\A(["']).+\1\z/)
250
- add shell_option(key, val, escape: false, merge: merge, sep: sep)
250
+ add shell_option(key, val, escape: false, merge: merge)
251
251
  elsif path
252
- add quote_option(key, path + val, merge: merge, sep: sep)
252
+ add quote_option(key, path + val, merge: merge)
253
253
  else
254
254
  push opt
255
255
  end
@@ -7,7 +7,7 @@ module Squared
7
7
  attr_accessor :line_width
8
8
 
9
9
  def max_width(lines)
10
- n = [lines.max_by(&:size).size, 80].max
10
+ n = [lines.empty? ? 0 : lines.max_by(&:size).size, 80].max
11
11
  [n, Rake.application.terminal_width].min
12
12
  end
13
13
  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'
@@ -11,6 +11,21 @@ module Squared
11
11
  def hashlist
12
12
  Hash.new { |data, key| data[key] = [] }
13
13
  end
14
+
15
+ def hashdup(data, pass: {})
16
+ ret = {}
17
+ data.each do |key, val|
18
+ ret[key] = case val
19
+ when Hash
20
+ pass[val] ||= hashdup(val, pass: pass)
21
+ when Proc, Method
22
+ val
23
+ else
24
+ val.dup
25
+ end
26
+ end
27
+ ret
28
+ end
14
29
  end
15
30
  end
16
31
  end
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.24
4
+ version: 0.4.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham
@@ -125,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  - !ruby/object:Gem::Version
126
126
  version: '0'
127
127
  requirements: []
128
- rubygems_version: 3.6.9
128
+ rubygems_version: 3.7.2
129
129
  specification_version: 4
130
130
  summary: Rake task generator for managing multi-language workspaces.
131
131
  test_files: []