squared 0.6.2 → 0.6.4

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.
@@ -6,20 +6,22 @@ module Squared
6
6
  class Node < Git
7
7
  OPT_NPM = {
8
8
  common: %w[dry-run=!? loglevel=b include-workspace-root=!? workspaces=!? w|workspace=v].freeze,
9
- install: %w[package-lock-only=!? prefer-dedupe=!? cpu=b libc=b os=b].freeze,
10
- install_a: %w[audit=! bin-links=! fund=! ignore-scripts=!? install-links=!? package-lock=! strict-peer-deps=!?
11
- include=b install-strategy=b omit=b].freeze,
12
- install_b: %w[no-save save-bundle save-dev save-optional save-peer save-prod before=q foreground-scripts=!?
13
- g|global=!? S|save=!? E|save-exact=!?].freeze,
9
+ install: %w[package-lock-only=!? prefer-dedupe=!? E|save-exact=!? before=q cpu=b libc=b os=b].freeze,
10
+ install_a: %w[audit=! bin-links=! foreground-scripts=!? fund=! ignore-scripts=!? install-links=!?
11
+ package-lock=! strict-peer-deps=!? include=b install-strategy=b omit=b].freeze,
12
+ install_b: %w[no-save B|save-bundle D|save-dev O|save-optional save-peer P|save-prod g|global=!?
13
+ S|save=!?].freeze,
14
14
  run: %w[foreground-scripts=!? if-present=!? ignore-scripts=!? script-shell=p].freeze,
15
15
  exec: %w[c|call=q package=b].freeze,
16
16
  pack: %w[ignore-scripts=!? json=!? pack-destination=p].freeze,
17
+ rebuild: %w[bin-links=! foreground-scripts=!? global=!? ignore-scripts=!? install-links=!?].freeze,
17
18
  no: {
18
19
  install: %w[audit bin-links fund package-lock].freeze
19
20
  }.freeze
20
21
  }.freeze
21
22
  OPT_PNPM = {
22
- common: %w[aggregate-output color no-color stream use-stderr C|dir=p loglevel=b w|workspace-root].freeze,
23
+ common: %w[aggregate-output color ignore-workspace-root-check no-color stream use-stderr C|dir=p loglevel=b
24
+ r|recursive w|workspace-root].freeze,
23
25
  common_cpu: %w[cpu=b libc=b os=b].freeze,
24
26
  common_filter: %w[fail-if-no-match changed-files-ignore-pattern=q filter=q filter-prod=q
25
27
  test-pattern=q].freeze,
@@ -30,15 +32,18 @@ module Squared
30
32
  modules-dir=p network-concurrency=i package-import-method=b public-hoist-pattern=q
31
33
  reporter=b].freeze,
32
34
  install_a: %w[global-dir ignore-scripts offline prefer-offline store-dir=p virtual-store-dir=p].freeze,
33
- install_b: %w[D|dev global-dir no-optional P|prod r|recursive].freeze,
35
+ install_b: %w[D|dev no-optional P|prod].freeze,
36
+ add: %w[allow-build config g|global save-catalog D|save-dev O|save-optional save-peer P|save-prod
37
+ save-catalog-name=b].freeze,
34
38
  update: %w[g|global i|interactive L|latest depth=i].freeze,
35
39
  dedupe: %w[check].freeze,
36
- run: %w[if-present no-bail parallel r|recursive report-summary reporter-hide-prefix resume-from
37
- sequential].freeze,
38
- exec: %w[no-reporter-hide-prefix parallel r|recursive report-summary resume-from c|shell-mode].freeze,
39
- pack: %w[json r|recursive pack-destination=p pack-gzip-level=i out=p workspace-concurrency=i].freeze,
40
+ run: %w[if-present no-bail parallel report-summary reporter-hide-prefix resume-from sequential].freeze,
41
+ exec: %w[no-reporter-hide-prefix parallel report-summary resume-from c|shell-mode].freeze,
42
+ pack: %w[json pack-destination=p pack-gzip-level=i out=p workspace-concurrency=i].freeze,
43
+ rebuild: %w[filter=q].freeze,
40
44
  no: {
41
- install: %w[frozen-lockfile verify-store-integrity].freeze
45
+ install: %w[frozen-lockfile verify-store-integrity].freeze,
46
+ add: %w[save-exact save-workspace-protocol].freeze
42
47
  }.freeze
43
48
  }.freeze
44
49
  OPT_YARN = {
@@ -50,13 +55,16 @@ module Squared
50
55
  network-timeout=i preferred-cache-folder=p production=b? proxy=q otp=b registry=q update-checksums
51
56
  use-yarnrc=p].freeze,
52
57
  install: %w[A|audit g|global S|save D|save-dev E|save-exact P|save-peer O|save-optional T|save-tilde].freeze,
58
+ add: %w[A|audit D|dev E|exact O|optional P|peer T|tilde ignore-workspace-root-check].freeze,
53
59
  update: %w[A|audit C|caret E|exact L|latest T|tilde P|pattern=q S|scope=b].freeze,
54
60
  run: %w[scripts-prepend-node-path=b?].freeze
55
61
  }.freeze
56
62
  OPT_BERRY = {
57
63
  install: %w[check-cache check-resolutions immutable immutable-cache inline-builds json refresh-lockfile
58
64
  mode=b].freeze,
59
- update: %w[C|caret E|exact F|fixed interactive T|tilde R|recursive mode=b].freeze,
65
+ add: %w[cached D|dev json O|optional P|peer prefer-dev].freeze,
66
+ add_a: %w[C|caret E|exact F|fixed interactive T|tilde mode=b].freeze,
67
+ update: %w[R|recursive].freeze,
60
68
  dedupe: %w[check json mode=b strategy=b].freeze,
61
69
  run: %w[B|binaries-only inspect inspect-brk T|top-level require=q].freeze,
62
70
  pack: %w[n|dry-run install-if-needed json o|out=p].freeze
@@ -128,7 +136,7 @@ module Squared
128
136
  end
129
137
 
130
138
  subtasks({
131
- 'package' => %i[install reinstall dedupe update].freeze,
139
+ 'package' => %i[install add update dedupe rebuild reinstall].freeze,
132
140
  'outdated' => %i[major minor patch].freeze,
133
141
  'bump' => %i[version major minor patch].freeze,
134
142
  'publish' => %i[latest tag].freeze,
@@ -170,18 +178,17 @@ module Squared
170
178
  if flags.nil?
171
179
  case action
172
180
  when 'add'
173
- format_desc action, nil, 'save?=prod|dev|optional|peer,name+'
181
+ format_desc action, nil, 'save?=[=-]prod|dev|optional|peer|bundle,(-)name+'
174
182
  task action, [:save] do |_, args|
175
- packages = if args.save =~ /\A(=)?(prod|dev|optional|peer)\z/
176
- exact = !$1.nil?
177
- save = $2
183
+ packages = if args.save =~ /\A([=-]*)?(prod|dev|optional|peer|bundle)\z/
184
+ save = [$2, $1.include?('='), $1.include?('-')]
178
185
  args.extras
179
186
  else
180
187
  save = 'prod'
181
188
  args.to_a
182
189
  end
183
190
  param_guard(action, 'name', args: packages)
184
- depend(:add, packages: packages, save: save, exact: exact)
191
+ depend(:add, packages: packages, save: save)
185
192
  end
186
193
  when 'run'
187
194
  next if scripts.empty?
@@ -273,13 +280,13 @@ module Squared
273
280
  flags.each do |flag|
274
281
  case action
275
282
  when 'outdated'
276
- format_desc action, flag, %w[u/pdate s/elect i/nteractive d/ry-run diff]
283
+ format_desc action, flag, "#{shortname('i', 's', 'u', 'd')},diff"
277
284
  task flag do |_, args|
278
285
  outdated flag, args.to_a
279
286
  end
280
287
  when 'package'
281
288
  format_desc(action, flag, 'opts*', before: case flag
282
- when :dedupe then nil
289
+ when :dedupe, :rebuild then nil
283
290
  when :reinstall then 'force?'
284
291
  else 'name*'
285
292
  end)
@@ -324,11 +331,15 @@ module Squared
324
331
  format_desc(action, flag, 'opts*', "#{flag == :project ? 'before' : 'after'}": 'config?')
325
332
  task flag do |_, args|
326
333
  args = args.to_a
327
- tsc(*args, banner: true, "#{flag}": if flag == :build
328
- true
329
- else
330
- exist?(args.first) ? args.shift : @tsfile
331
- end, watch: has_value!(args, 'w', 'watch'))
334
+ if flag == :project
335
+ project = if exist?(args.first)
336
+ args.shift
337
+ else
338
+ @tsfile
339
+ end
340
+ end
341
+ watch = has_value!(args, 'w', 'watch')
342
+ tsc(*args, banner: true, project: project, build: flag == :build, watch: !watch.nil?)
332
343
  end
333
344
  end
334
345
  end
@@ -368,7 +379,7 @@ module Squared
368
379
  return if items.empty?
369
380
 
370
381
  on :first, :copy
371
- print_item unless @output[0] || !verbose || task_invoked?(/^copy(?::#{Node.ref}|$)/)
382
+ print_item unless @output[0] || silent? || task_invoked?(/^copy(?::#{Node.ref}|$)/)
372
383
  packed = false
373
384
  items.each do |dir|
374
385
  case dir
@@ -417,8 +428,7 @@ module Squared
417
428
  .scan(/^npm notice \d+(?:\.\d+)?[a-z]+ (.+)$/i)
418
429
  .map { |item| Pathname.new(item.first) }
419
430
  .select(&:exist?)
420
- end
421
- .concat(Array(files))
431
+ end.concat(Array(files))
422
432
  packed = true
423
433
  end
424
434
  base = dest.join(into, npmname)
@@ -433,7 +443,7 @@ module Squared
433
443
  target.mkpath
434
444
  subdir << target.to_s
435
445
  end
436
- FileUtils.cp(basepath(s), dest, verbose: verbosetype > 0)
446
+ FileUtils.cp(basepath(s), dest, verbose: !silent?)
437
447
  rescue StandardError => e
438
448
  print_error e
439
449
  errors += 1
@@ -441,7 +451,7 @@ module Squared
441
451
  rescue StandardError => e
442
452
  on_error e, :copy
443
453
  else
444
- puts message(base, subdir.size, files.size - errors) if verbose
454
+ puts message(base, subdir.size, files.size - errors) unless silent?
445
455
  end
446
456
  next
447
457
  end
@@ -474,7 +484,7 @@ module Squared
474
484
  end
475
485
  target.each do |src, to|
476
486
  glob.each { |val| log.info "cp #{from + val} #{to}" }
477
- copy_dir(src, to, glob, create: create, link: link, force: force, pass: pass, verbose: verbosetype > 0)
487
+ copy_dir(src, to, glob, create: create, link: link, force: force, pass: pass, verbose: !silent?)
478
488
  rescue StandardError => e
479
489
  on_error e, :copy
480
490
  end
@@ -482,45 +492,81 @@ module Squared
482
492
  on :last, :copy
483
493
  end
484
494
 
485
- def depend(flag = nil, *, sync: invoked_sync?('depend', flag), packages: [], save: nil, exact: nil, **)
495
+ def depend(flag = nil, *, sync: invoked_sync?('depend', flag), packages: [], save: nil, exact: nil,
496
+ omit: env('NPM_OMIT'), **)
486
497
  if @depend && !flag
487
498
  super
488
499
  elsif outdated?
489
500
  workspace.rev_clear(name, sync: sync)
490
501
  return update if !flag && env('NODE_UPDATE')
491
502
 
503
+ add = flag == :add
504
+ if add
505
+ remove, packages = packages.partition { |val| val.delete_prefix!('-') }
506
+ remove.quote!
507
+ end
508
+ save, exact, omit = save if save.is_a?(Array)
492
509
  ws = env('NODE_WORKSPACES', equals: '0')
493
- ci = option('ci')
510
+ ci = -> { option('ci') }
511
+ is = -> { option('ignore-scripts') }
512
+ om = lambda do
513
+ next unless omit
514
+
515
+ save = case save
516
+ when 'peer'
517
+ 'optional'
518
+ when 'optional'
519
+ 'dev'
520
+ when 'dev'
521
+ 'prod'
522
+ end
523
+ end
524
+ rm = lambda do |target|
525
+ next if remove.empty?
526
+
527
+ run(target.temp(*remove).sub!(/ (?:add|install) /, ' remove '), from: :remove, sync: sync)
528
+ end
494
529
  if (yarn = dependtype(:yarn)) > 0
495
- cmd = session 'yarn'
496
- if flag == :add
497
- cmd << 'add'
498
- cmd << "--#{save}" unless save == 'prod'
499
- cmd << '--exact' if exact
530
+ cmd = session('yarn', flag || 'install')
531
+ append_loglevel
532
+ if yarn == 1
533
+ cmd << '--ignore-engines' unless option('ignore-engines', equals: '0')
534
+ cmd << '--ignore-scripts' if is.call
535
+ cmd << '--force' if option('force')
500
536
  else
501
- cmd << 'install'
502
- cmd << '--ignore-engines' if yarn == 1 && !option('ignore-engines', equals: '0')
503
- cmd << (yarn == 1 ? '--force' : '--check-cache') if option('force')
537
+ cmd << '--mode=skip-build' if is.call
538
+ cmd << '--check-cache' if !flag && option('force')
504
539
  end
505
540
  if nolockfile?('yarn')
506
541
  cmd << '--no-lockfile'
507
- elsif ci
542
+ elsif ci.call
508
543
  if yarn == 1
509
544
  cmd << '--frozen-lockfile'
510
- else
545
+ elsif !flag
511
546
  cmd << '--immutable' << '--refresh-lockfile'
512
547
  end
513
548
  end
549
+ if add
550
+ cmd << '-W' if yarn == 1 && !option('w', 'ignore-workspace-root-check', equals: '0')
551
+ rm.call(cmd)
552
+ om.call
553
+ cmd << "--#{save}" if save && save != 'bundle'
554
+ cmd << '--exact' if exact
555
+ end
514
556
  elsif pnpm?
515
- cmd = session 'pnpm'
516
- if flag == :add
517
- cmd << 'add' << "--save-#{save}"
557
+ cmd = session('pnpm', flag || 'install')
558
+ append_nocolor
559
+ append_loglevel
560
+ if add
561
+ om.call
562
+ cmd << "--save-#{save}" if save && save != 'bundle'
563
+ rm.call(cmd)
518
564
  cmd << '--save-exact' if exact
565
+ option('allow-build') { |val| cmd << quote_option('allow-build', val) }
519
566
  else
520
- cmd << 'install'
521
567
  append_platform
522
568
  end
523
- option('public-hoist-pattern', ignore: false) do |val|
569
+ option('public-hoist-pattern') do |val|
524
570
  split_escape(val) { |opt| cmd << shell_option('public-hoist-pattern', opt) }
525
571
  end
526
572
  cmd << '--ignore-workspace' if ws
@@ -528,30 +574,37 @@ module Squared
528
574
  '--force'
529
575
  elsif nolockfile?('pnpm')
530
576
  '--no-lockfile'
531
- elsif ci
577
+ elsif ci.call
532
578
  '--frozen-lockfile'
533
579
  end
534
- append_nocolor
580
+ cmd << '--ignore-scripts' if is.call
535
581
  else
536
- cmd = session 'npm'
537
- if ci
538
- cmd << 'ci'
539
- else
540
- cmd << 'install'
541
- if flag == :add
542
- cmd << "--save-#{save}"
582
+ cmd = session('npm', (ci = ci.call) ? 'ci' : 'install')
583
+ cmd << '--workspaces=false' if ws
584
+ append_nocolor
585
+ append_loglevel
586
+ if omit
587
+ cmd << "--omit=#{save}"
588
+ save = nil
589
+ end
590
+ unless ci
591
+ if add
592
+ cmd << "--save-#{save}" if save
593
+ rm.call(cmd)
543
594
  cmd << '--save-exact' if exact
544
- cmd.merge(packages.map { |pkg| shell_quote(pkg) })
545
595
  else
546
596
  append_platform
547
597
  end
548
598
  end
549
- cmd << '--workspaces=false' if ws
550
599
  cmd << '--package-lock=false' << 'save=false' if nolockfile?('npm')
551
- append_nocolor
600
+ cmd << '--ignore-scripts' if is.call
552
601
  end
553
- append_loglevel
554
- run(from: :depend, sync: sync)
602
+ if add
603
+ return if packages.empty?
604
+
605
+ cmd.merge(packages.quote!)
606
+ end
607
+ run(from: flag || :depend, sync: sync)
555
608
  end
556
609
  end
557
610
 
@@ -647,11 +700,8 @@ module Squared
647
700
  end
648
701
  pending = 0
649
702
  modified = 0
650
- size_col = ->(a, i) { a.map { |aa| aa[i] }.max_by(&:size).size }
651
- pad_ord = lambda do |val, ord|
652
- ret = val.succ.to_s
653
- ord.size > 9 ? ret.rjust(ord.size.to_s.size) : ret
654
- end
703
+ width = ->(a, i) { a.map { |aa| aa[i] }.max_by(&:size).size }
704
+ pad = ->(val, ord) { val.succ.to_s.rjust([ord.size.to_s.size, 2].max) }
655
705
  footer = lambda do |val, size|
656
706
  next unless verbose
657
707
 
@@ -665,19 +715,21 @@ module Squared
665
715
  end
666
716
  print_item banner unless sync
667
717
  if !found.empty?
668
- col1 = size_col.call(found, 0) + 4
669
- col2 = size_col.call(found, 1) + 4
718
+ col1 = width.call(found, 0) + 4
719
+ col2 = width.call(found, 1) + 4
670
720
  packages = []
671
- pat = ->(a) { /("#{Regexp.escape(a[0])}"\s*:\s*)"([~^])#{a[4] ? '?' : ''}#{Regexp.escape(a[1])}"/ }
721
+ pat = ->(a) { /("#{Regexp.escape(a[0])}"\s*:\s*)"([~^])#{'?' if a[4]}#{Regexp.escape(a[1])}"/ }
672
722
  edit = lambda do |a, pkg, mod|
673
723
  packages << a[0]
674
724
  modified += 1
675
725
  "#{pkg}\"#{mod || (a[3] == 1 && a[4] ? '^' : '')}#{a[2]}\""
676
726
  end
727
+ kwargs = { col1: col1, col2: col2, col3: width.call(found, 2), timeout: 0 }
677
728
  found.each_with_index do |item, i|
678
729
  a, b, c, d, e = item
679
730
  f = ia && (rev != :major || e || semmajor?(item[5], item[6]))
680
- if f && !confirm_outdated(a, c, (d / 2.0).ceil, b, lock: e, col1: col1, timeout: 0)
731
+ col0 = "#{pad.call(i, found)}. "
732
+ if f && !confirm_outdated(a, c, (d / 2.0).ceil, b, lock: e, col0: col0, **kwargs)
681
733
  cur = -1
682
734
  else
683
735
  cur = modified
@@ -691,9 +743,14 @@ module Squared
691
743
  end
692
744
  end
693
745
  end
694
- a = a.ljust(col1)
695
- b = b.ljust(col2)
696
- b = sub_style(b, styles: theme[:current]) if theme[:current] && !stdin?
746
+ if f
747
+ a = ' ' * col1
748
+ b = ' ' * col2
749
+ else
750
+ a = a.ljust(col1)
751
+ b = b.ljust(col2)
752
+ sub_style! b, theme[:current] if theme[:current] && !stdin?
753
+ end
697
754
  c = if cur == -1
698
755
  'SKIP'
699
756
  elsif modified == cur
@@ -703,15 +760,15 @@ module Squared
703
760
  else
704
761
  g = item
705
762
  if d == 1
706
- a = sub_style(a, styles: theme[:major])
707
- sub_style(c, :bold, styles: color(:green))
763
+ sub_style! a, theme[:major]
764
+ sub_style c, :bold, color(:green)
708
765
  else
709
766
  sub_style(c, **opt_style(color(d == 3 ? :green : :yellow), SEM_VER, d))
710
767
  end
711
768
  end
712
769
  s = a + b + c
713
770
  if !items
714
- puts "#{pad_ord.call(i, found)}. #{s}"
771
+ puts "#{f ? ' ' * col0.size : col0}#{s}"
715
772
  elsif g
716
773
  items << [s, g]
717
774
  end
@@ -749,20 +806,20 @@ module Squared
749
806
  end
750
807
  end
751
808
  elsif !avail.empty?
752
- col1 = size_col.call(avail, 0) + 4
753
- col2 = size_col.call(avail, 1)
754
- col3 = size_col.call(avail, 2) + 4
809
+ col1 = width.call(avail, 0) + 4
810
+ col2 = width.call(avail, 1)
811
+ col3 = width.call(avail, 2) + 4
755
812
  avail.each_with_index do |item, i|
756
813
  a, b, c, d = item
757
814
  a = a.ljust(col1)
758
- b = sub_style(b.ljust(col2), styles: color(d ? :red : :yellow))
815
+ b = sub_style b.ljust(col2), color(d ? :red : :yellow)
759
816
  c = c.ljust(col3)
760
817
  unless d
761
- a = sub_style(a, styles: theme[:active])
762
- c = sub_style(c, styles: color(:green))
818
+ sub_style! a, theme[:active]
819
+ sub_style! c, color(:green)
763
820
  pending += 1
764
821
  end
765
- puts "#{pad_ord.call(i, avail)}. #{(a + c + b).subhint(d ? 'locked' : 'latest')}"
822
+ puts "#{pad.call(i, avail)}. #{(a + c + b).subhint(d ? 'locked' : 'latest')}"
766
823
  end
767
824
  footer.call(0, avail.size)
768
825
  else
@@ -777,7 +834,7 @@ module Squared
777
834
 
778
835
  def publish(flag = nil, *, sync: invoked_sync?('publish', flag), otp: nil, tag: nil, access: nil, dryrun: nil)
779
836
  if read_package('private')
780
- ws = @children.select { |proj| proj.ref?(Node.ref) }
837
+ ws = children.select { |proj| proj.ref?(Node.ref) }
781
838
  if ws.empty?
782
839
  print_error('nothing to publish', subject: name, hint: 'private')
783
840
  elsif confirm_basic('Publish workspace?', ws.map(&:name).join(', '), 'N')
@@ -820,10 +877,16 @@ module Squared
820
877
 
821
878
  def package(flag, opts = [], packages: [], from: nil)
822
879
  workspace.rev_clear(name)
823
- if (yarn = dependtype(:yarn)) > 0
880
+ yarn = dependtype(:yarn)
881
+ if yarn > 0 && !(yarn == 1 && ((flag == :update && !packages.empty?) || flag == :rebuild))
824
882
  cmd = session 'yarn', case flag
825
883
  when :update
826
- yarn == 1 ? 'upgrade' : 'up'
884
+ if yarn == 1
885
+ 'upgrade'
886
+ else
887
+ spec = 0
888
+ 'up'
889
+ end
827
890
  when :reinstall
828
891
  if yarn == 1
829
892
  remove_modules 'yarn' if opts.include?('force')
@@ -832,35 +895,51 @@ module Squared
832
895
  end
833
896
  opts << 'no-lockfile' if lockfile(true)
834
897
  'install'
898
+ when :add
899
+ spec = 1
900
+ 'add'
835
901
  else
836
902
  yarn == 1 && flag == :dedupe ? 'install' : flag
837
903
  end
838
904
  op = OptionPartition.new(opts, if yarn == 1
839
905
  OPT_YARN.fetch(flag == :dedupe ? :install : flag, []) + OPT_YARN[:common]
840
906
  else
841
- OPT_BERRY.fetch(flag, [])
907
+ OPT_BERRY.fetch(flag, []) + case flag
908
+ when :add, :update then OPT_BERRY[:add_a]
909
+ else []
910
+ end
842
911
  end, cmd, project: self)
843
912
  if yarn == 1 && flag != :reinstall
844
913
  op << '--no-lockfile' if nolockfile?('yarn')
845
914
  op << '--ignore-engines' unless option('ignore-engines', equals: '0')
846
915
  end
847
- op.clear
848
- append_loglevel
849
916
  else
850
917
  args = if pnpm?
851
918
  case flag
852
919
  when :install, :update
853
920
  opts << 'no-lockfile' if nolockfile?('pnpm')
921
+ spec = 0 if flag == :update
922
+ when :add
923
+ spec = 1
854
924
  when :reinstall
855
925
  opts << 'force'
856
926
  flag = :install
857
927
  end
858
- no = OPT_PNPM[:no][flag]
928
+ flags = [flag]
929
+ unless flag == :rebuild
930
+ flags << :install_a
931
+ no = OPT_PNPM[:no][flag]
932
+ end
859
933
  [
860
934
  opts,
861
- [flag, :install_a].yield_self do |out|
862
- out.push(:install_b, :common_filter) unless flag == :dedupe
863
- out << :common_cpu unless flag == :update
935
+ flags.yield_self do |out|
936
+ unless flag == :dedupe
937
+ out << :common_filter
938
+ unless flag == :add
939
+ out << :install_b
940
+ out << :common_cpu unless flag == :update
941
+ end
942
+ end
864
943
  pnpmopts(*out)
865
944
  end,
866
945
  session('pnpm', flag)
@@ -869,27 +948,51 @@ module Squared
869
948
  case flag
870
949
  when :install, :update
871
950
  opts.unshift('package-lock=false', 'save=false') if nolockfile?('npm')
951
+ spec = 0
952
+ when :add
953
+ spec = 1
954
+ flag = :install
872
955
  when :reinstall
873
956
  remove_modules 'npm' if opts.delete('force')
874
957
  opts.unshift('package-lock=false') if lockfile(true)
875
958
  flag = :install
876
959
  end
877
- no = OPT_NPM[:no][:install]
960
+ flags = [flag]
961
+ unless flag == :rebuild
962
+ flags << :install_a
963
+ unless flag == :dedupe
964
+ %w[save ignore-scripts strict-peer-deps].each do |key|
965
+ option(key, prefix: 'npm', ignore: false) do |val|
966
+ opts << case val
967
+ when '0', 'false'
968
+ "#{key}=false"
969
+ else
970
+ "#{key}=true"
971
+ end
972
+ end
973
+ end
974
+ flags << :install_b
975
+ end
976
+ no = OPT_NPM[:no][:install]
977
+ end
878
978
  [
879
979
  opts,
880
- [flag, :install_a].yield_self do |out|
881
- out << :install_b unless flag == :dedupe
882
- npmopts(*out)
883
- end,
980
+ npmopts(*flags),
884
981
  session('npm', flag)
885
982
  ]
886
983
  end
887
984
  op = OptionPartition.new(*args, no: no, project: self)
985
+ append_platform if flag == :install
986
+ append_nocolor
987
+ end
988
+ append_loglevel
989
+ case spec
990
+ when 0, 1
888
991
  op.each do |opt|
889
992
  if opt =~ op.values
890
993
  case $1
891
994
  when 'w', 'workspace'
892
- op << ($2.match?(%r{[\\/]}) ? quote_option($1, basepath($2)) : shell_option($1, $2))
995
+ op << quotepath($1, $2)
893
996
  end
894
997
  elsif opt.include?('=') || opt.start_with?('-')
895
998
  op.errors << opt
@@ -899,22 +1002,17 @@ module Squared
899
1002
  end
900
1003
  op.swap
901
1004
  .concat(packages)
902
- append_platform if flag == :install
903
- append_nocolor
904
- append_loglevel
905
- if flag == :dedupe
906
- op.clear
907
- else
908
- op.append(quote: true)
909
- end
910
- op.clear(errors: true)
1005
+ raise_error ArgumentError, 'no packages to add' if op.empty? && spec == 1
1006
+ op.append(quote: true)
1007
+ .clear(errors: true)
1008
+ else
1009
+ op.clear
911
1010
  end
912
1011
  run(from: from || :"package:#{flag}")
913
1012
  end
914
1013
 
915
1014
  def bump(flag, val = nil)
916
- val = sembump version, flag unless flag == :version
917
- return unless val
1015
+ return unless val ||= sembump(version, flag)
918
1016
 
919
1017
  doc = dependfile.read
920
1018
  if doc.sub!(/"version"\s*:\s*"#{version}"/, "\"version\": \"#{val}\"")
@@ -925,7 +1023,7 @@ module Squared
925
1023
  end
926
1024
  if stdin?
927
1025
  puts val
928
- elsif verbose
1026
+ elsif !silent?
929
1027
  major = flag == :major
930
1028
  emphasize("version: #{val}", title: name, border: borderstyle, sub: [
931
1029
  headerstyle,
@@ -959,7 +1057,7 @@ module Squared
959
1057
 
960
1058
  case $1
961
1059
  when 'w', 'workspace'
962
- op << ($2.match?(%r{[\\/]}) ? quote_option($1, basepath($2)) : shell_option($1, $2))
1060
+ op << quotepath($1, $2)
963
1061
  op.found << opt
964
1062
  end
965
1063
  end
@@ -1037,7 +1135,7 @@ module Squared
1037
1135
  end
1038
1136
 
1039
1137
  def outdated?
1040
- dependfile.exist?
1138
+ dependfile.exist? && !task_pass?('outdated')
1041
1139
  end
1042
1140
 
1043
1141
  def update?
@@ -1231,7 +1329,7 @@ module Squared
1231
1329
 
1232
1330
  def append_loglevel(target: @session)
1233
1331
  level = env('NODE_LOGLEVEL')
1234
- silent = !verbose || level == 'silent'
1332
+ silent = silent? || level == 'silent'
1235
1333
  return unless silent || level
1236
1334
 
1237
1335
  if yarn?
@@ -1265,6 +1363,14 @@ module Squared
1265
1363
  %w[cpu os libc].each { |name| option(name) { |val| target << basic_option(name, val) } }
1266
1364
  end
1267
1365
 
1366
+ def quotepath(name, val)
1367
+ if $2.include?(File::SEPARATOR) || (workspace.windows? && val.match?(%r{[\\/]}))
1368
+ quote_option name, basepath(val)
1369
+ else
1370
+ shell_option name, val
1371
+ end
1372
+ end
1373
+
1268
1374
  def dependroot
1269
1375
  dependname if parent&.has?('outdated', Node.ref)
1270
1376
  end