squared 0.1.4 → 0.2.0

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.
@@ -8,7 +8,7 @@ module Squared
8
8
  def populate(*); end
9
9
 
10
10
  def tasks
11
- %i[outdated].freeze
11
+ [:outdated].freeze
12
12
  end
13
13
 
14
14
  def batchargs
@@ -35,11 +35,12 @@ module Squared
35
35
  end
36
36
 
37
37
  @@tasks[ref] = {
38
- install: %i[force frozen dedupe].freeze,
39
- outdated: %i[major minor patch].freeze,
40
- bump: %i[major minor patch].freeze,
41
- update: nil,
42
- run: nil
38
+ 'install' => %i[force frozen dedupe].freeze,
39
+ 'outdated' => %i[major minor patch].freeze,
40
+ 'bump' => %i[version major minor patch].freeze,
41
+ 'add' => nil,
42
+ 'update' => nil,
43
+ 'run' => nil
43
44
  }.freeze
44
45
 
45
46
  def initialize(*, **kwargs)
@@ -59,25 +60,45 @@ module Squared
59
60
  Node.ref
60
61
  end
61
62
 
62
- def populate(*)
63
+ def populate(*, **)
63
64
  super
64
65
  return unless outdated? && ref?(Node.ref)
65
66
 
66
67
  namespace name do
67
68
  @@tasks[Node.ref].each do |action, flags|
69
+ next if @pass.include?(action)
70
+
68
71
  if flags.nil?
69
72
  case action
70
- when :run
71
- desc format_desc(action, nil, 'command+|^index|#,pattern*')
73
+ when 'add'
74
+ format_desc action, nil, 'save?=prod|dev|optional|peer,name+'
75
+ task action, [:save, :name] do |_, args|
76
+ save = param_guard(action, 'save', args: args, key: :save)
77
+ if save.start_with?('=')
78
+ exact = true
79
+ save = save[1..-1]
80
+ end
81
+ case save
82
+ when 'prod', 'dev', 'optional', 'peer'
83
+ name = param_guard(action, 'name', args: args.to_a.drop(1))
84
+ else
85
+ save = 'prod'
86
+ name = param_guard(action, 'name', args: args.to_a)
87
+ end
88
+ depend(:add, packages: name, save: save, exact: exact)
89
+ end
90
+ when 'run'
91
+ next if (list = read_scripts).empty?
92
+
93
+ format_desc action, nil, 'command+|^index|#,pattern*'
72
94
  task action, [:command] do |_, args|
73
95
  if args.command == '#'
74
- format_list(read_scripts, 'run[^N]', 'scripts', grep: args.extras, from: dependfile.to_s)
96
+ format_list(list, 'run[^N]', 'scripts', grep: args.extras, from: dependfile.to_s)
75
97
  else
76
- cmd = guard_params(action, 'command', args: args.to_a)
98
+ cmd = param_guard(action, 'command', args: args.to_a)
77
99
  cmd.each do |val|
78
100
  if (data = indexitem(val))
79
101
  n, opts = data
80
- list = read_scripts
81
102
  if (item = list[n - 1])
82
103
  val = opts ? "#{item.first} #{opts}" : item.first
83
104
  elsif exception
@@ -90,9 +111,9 @@ module Squared
90
111
  end
91
112
  end
92
113
  end
93
- when :update
94
- desc format_desc(action, nil, 'packages*')
95
- task action, [:packages] do |_, args|
114
+ when 'update'
115
+ format_desc action, nil, 'packages*'
116
+ task action do |_, args|
96
117
  update args.to_a
97
118
  end
98
119
  end
@@ -100,20 +121,28 @@ module Squared
100
121
  namespace action do
101
122
  flags.each do |flag|
102
123
  case action
103
- when :install
104
- desc format_desc(action, flag)
124
+ when 'install'
125
+ format_desc action, flag
105
126
  task flag do
106
127
  depend flag
107
128
  end
108
- when :outdated
109
- desc format_desc(action, flag, %w[prune interactive dry-run].freeze, arg: 'opts?')
110
- task flag, [:opts] do |_, args|
129
+ when 'outdated'
130
+ format_desc(action, flag, %w[prune interactive dry-run].freeze, arg: 'opts?')
131
+ task flag do |_, args|
111
132
  outdated(flag, opts: args.to_a)
112
133
  end
113
- else
114
- desc format_desc(action, flag)
115
- task flag do
116
- __send__(action, flag)
134
+ when 'bump'
135
+ if flag == :version
136
+ format_desc action, flag, 'version'
137
+ task flag, [:version] do |_, args|
138
+ version = param_guard(action, flag, args: args, key: :version)
139
+ bump flag, version
140
+ end
141
+ else
142
+ format_desc action, flag
143
+ task flag do
144
+ bump flag
145
+ end
117
146
  end
118
147
  end
119
148
  end
@@ -124,7 +153,7 @@ module Squared
124
153
  end
125
154
 
126
155
  def copy(from: 'build', into: 'node_modules', workspace: false, include: nil, exclude: nil, scope: nil,
127
- also: nil, create: nil, override: false)
156
+ also: nil, create: nil, link: false, force: false, override: false)
128
157
  return if @copy == false
129
158
 
130
159
  if @copy && !override
@@ -133,6 +162,8 @@ module Squared
133
162
  from = @copy[:from] if @copy.key?(:from)
134
163
  into = @copy[:into] if @copy.key?(:into)
135
164
  workspace = @copy[:workspace] if @copy.key?(:workspace)
165
+ link = @copy[:link] if @copy.key?(:link)
166
+ force = @copy[:force] if @copy.key?(:link)
136
167
  glob = @copy[:include]
137
168
  exclude = @copy[:exclude]
138
169
  scope = @copy[:scope]
@@ -144,7 +175,8 @@ module Squared
144
175
  items += as_a(also) if also
145
176
  return if items.empty?
146
177
 
147
- print_item unless @output[0] || !verbose || task_invoked?(/\Acopy(?::#{Node.ref}|$)/)
178
+ on :first, :copy
179
+ print_item unless @output[0] || !verbose || task_invoked?(/^copy(?::#{Node.ref}|$)/)
148
180
  items.each do |dir|
149
181
  case dir
150
182
  when Pathname
@@ -160,6 +192,8 @@ module Squared
160
192
  from = dir[:from] if dir.key?(:from)
161
193
  into = dir[:into] if dir.key?(:into)
162
194
  scope = dir[:scope] if dir.key?(:scope)
195
+ link = dir[:link] if dir.key?(:link)
196
+ force = dir[:force] if dir.key?(:force)
163
197
  dest = dir[:target]
164
198
  create = dir[:create]
165
199
  workspace = dir[:workspace]
@@ -183,10 +217,11 @@ module Squared
183
217
  elsif (file = path.join('package.json')).exist?
184
218
  begin
185
219
  doc = JSON.parse(file.read)
186
- doc['name']
187
220
  rescue StandardError => e
188
221
  log.error e
189
222
  raise if exception
223
+ else
224
+ doc['name']
190
225
  end
191
226
  end
192
227
  if sub
@@ -200,18 +235,29 @@ module Squared
200
235
  end
201
236
  target.each do |src, to|
202
237
  glob.each { |val| log.info "cp #{from.join(val)} #{to}" }
203
- copy_d(src, to, glob: glob, create: create, pass: exclude, verbose: verbose)
238
+ begin
239
+ copy_dir(src, to, glob, create: create, link: link, force: force, pass: exclude, verbose: verbose)
240
+ rescue StandardError => e
241
+ log.error e
242
+ ret = on(:error, :copy, e)
243
+ raise if exception && ret != true
244
+ end
204
245
  end
205
246
  end
247
+ on :last, :copy
206
248
  end
207
249
 
208
- def depend(flag = nil, sync: invoked_sync?('depend', flag))
250
+ def depend(flag = nil, sync: invoked_sync?('depend', flag), packages: [], save: nil, exact: nil)
209
251
  if @depend && !flag
210
252
  super
211
253
  elsif outdated?
212
254
  if (yarn = dependtype(:yarn)) > 0
213
255
  cmd = session 'yarn'
214
- if yarn > 1
256
+ if flag == :add
257
+ cmd << 'add'
258
+ cmd << "--#{save}" unless save == 'prod'
259
+ cmd << '--exact' if exact
260
+ elsif yarn > 1
215
261
  if flag == :dedupe
216
262
  cmd << 'dedupe'
217
263
  else
@@ -232,7 +278,12 @@ module Squared
232
278
  end
233
279
  elsif pnpm?
234
280
  cmd = session 'pnpm'
235
- if flag == :dedupe
281
+ case flag
282
+ when :add
283
+ cmd << 'add'
284
+ cmd << "--save-#{save}"
285
+ cmd << '--save-exact' if exact
286
+ when :dedupe
236
287
  cmd << 'dedupe'
237
288
  else
238
289
  cmd << 'install' << if flag == :force
@@ -246,10 +297,15 @@ module Squared
246
297
  split_escape(val).each { |opt| cmd << shell_option('public-hoist-pattern', opt, quote: true) }
247
298
  end
248
299
  cmd << '--ignore-workspace' if env('NODE_WORKSPACES', equals: '0')
249
- append_nocolor option('no-color')
300
+ append_nocolor
250
301
  else
251
302
  cmd = session 'npm'
252
- if flag == :dedupe
303
+ case flag
304
+ when :add
305
+ cmd << 'install'
306
+ cmd << "--save-#{save}"
307
+ cmd << '--save-exact' if exact
308
+ when :dedupe
253
309
  cmd << 'dedupe'
254
310
  else
255
311
  cmd << 'install' << if flag == :force
@@ -258,34 +314,41 @@ module Squared
258
314
  '--package-lock-only'
259
315
  end
260
316
  end
261
- cmd << '--omit=dev' if flag && prod?
317
+ if flag == :add
318
+ cmd.merge(packages.map { |pkg| shell_escape(pkg) })
319
+ elsif flag && prod?
320
+ cmd << '--omit=dev'
321
+ end
262
322
  cmd << '--workspaces=false' if env('NODE_WORKSPACES', equals: '0')
263
323
  cmd << '--package-lock=false' if option('package-lock', equals: '0')
264
- append_nocolor option('no-color')
324
+ append_nocolor
265
325
  end
266
326
  append_loglevel
267
- run(sync: sync)
327
+ run(from: :depend, sync: sync)
268
328
  end
269
329
  end
270
330
 
271
- def outdated(rev = nil, opts: [], sync: invoked_sync?('outdated', rev))
331
+ def outdated(flag = nil, sync: invoked_sync?('outdated', flag), opts: [])
272
332
  dryrun = opts.include?('dry-run')
273
- if pnpm? && read_packagemanager(version: '7.15')
274
- cmd = 'pnpm outdated'
333
+ if pnpm? && read_packagemanager(version: '7.15', update: true)
334
+ cmd = session 'pnpm', 'outdated'
275
335
  dryrun ||= dryrun?('pnpm')
276
336
  else
277
- cmd = 'npm outdated'
337
+ cmd = session 'npm', 'outdated'
278
338
  dryrun ||= dryrun?('npm')
279
339
  end
280
- log.info cmd
281
- banner = format_banner("#{cmd}#{dryrun ? ' --dry-run' : ''}")
340
+ log.info cmd.to_s
341
+ on :first, :outdated unless dryrun
342
+ banner = format_banner(cmd.temp(dryrun ? ' --dry-run' : nil))
282
343
  print_item banner if sync
283
344
  begin
284
- data = pwd_set { `#{cmd} --json --loglevel=error` }
285
- json = JSON.parse(doc = dependfile.read)
345
+ data = pwd_set { `#{cmd.temp('--json', '--loglevel=error')}` }
346
+ doc = dependfile.read
347
+ json = JSON.parse(doc)
286
348
  rescue StandardError => e
287
349
  log.error e
288
- raise if exception
350
+ ret = on(:error, :outdated, e)
351
+ raise if exception && ret != true
289
352
 
290
353
  warn log_message(Logger::WARN, e) if warning?
291
354
  return
@@ -296,7 +359,7 @@ module Squared
296
359
  end
297
360
  found = []
298
361
  avail = []
299
- rev ||= (prod? ? :patch : :minor)
362
+ rev = flag || (prod? ? :patch : :minor)
300
363
  inter = opts.include?('interactive')
301
364
  unless data.empty?
302
365
  JSON.parse(data).each_pair do |key, val|
@@ -354,7 +417,7 @@ module Squared
354
417
  ret = val.succ.to_s
355
418
  ord.size > 9 ? ret.rjust(ord.size.to_s.size) : ret
356
419
  end
357
- footer = lambda do |val = 0|
420
+ footer = lambda do |val, size|
358
421
  next unless verbose
359
422
 
360
423
  msg, hint = if modified == -1
@@ -362,7 +425,8 @@ module Squared
362
425
  else
363
426
  ['No packages were updated', 'possible']
364
427
  end
365
- puts print_footer(empty_status(msg, hint, pending + val))
428
+ possible = pending + val
429
+ puts print_footer(empty_status(msg, hint, possible == size ? 0 : possible))
366
430
  end
367
431
  print_item banner unless sync
368
432
  if !found.empty?
@@ -386,6 +450,8 @@ module Squared
386
450
  end
387
451
  end
388
452
  a = a.ljust(col1)
453
+ b = b.ljust(col2)
454
+ b = sub_style(b, styles: theme[:current]) if theme[:current]
389
455
  c = if cur == -1
390
456
  'SKIP'
391
457
  elsif modified == cur
@@ -396,14 +462,14 @@ module Squared
396
462
  else
397
463
  sub_style(c, pat: SEM_VER, styles: color(:green), index: d)
398
464
  end
399
- puts "#{pad_ord.(i, found)}. #{a}#{b.ljust(col2)}#{c}"
465
+ puts "#{pad_ord.(i, found)}. #{a + b + c}"
400
466
  end
401
467
  pending = avail.reduce(pending) { |a, b| a + (b[3] ? 0 : 1) }
402
468
  if dryrun || (modified == 0 && pending > 0)
403
- footer.(modified)
469
+ footer.(modified, found.size)
404
470
  elsif modified > 0
405
471
  modified = -1
406
- footer.()
472
+ footer.(0, found.size)
407
473
  File.write(dependfile, doc)
408
474
  commit(:add, ['package.json'], pass: true)
409
475
  install if opts.include?('prune')
@@ -424,51 +490,58 @@ module Squared
424
490
  end
425
491
  puts "#{pad_ord.(i, avail)}. #{a + c + b} (#{d ? 'locked' : 'latest'})"
426
492
  end
427
- footer.()
493
+ footer.(0, avail.size)
428
494
  else
429
495
  puts 'No updates were found'
430
496
  end
497
+ on :last, :outdated unless dryrun
431
498
  end
432
499
 
433
- def bump(flag = nil)
434
- return unless (ver = version)
500
+ def bump(flag, val = nil)
501
+ return unless (cur = version)
435
502
 
436
- seg = semscan(ver, fill: false)
437
- case flag
438
- when :major
439
- if seg[0] != '0' || seg[2].nil?
440
- seg[0] = seg[0].succ
441
- else
442
- seg[2] = seg[2].succ
443
- end
444
- when :minor
445
- if seg[0] == '0'
503
+ if flag == :version
504
+ return unless val
505
+ else
506
+ seg = semscan(cur, fill: false)
507
+ case flag
508
+ when :major
509
+ if seg[0] != '0' || seg[2].nil?
510
+ seg[0] = seg[0].succ
511
+ else
512
+ seg[2] = seg[2].succ
513
+ end
514
+ when :minor
515
+ if seg[0] == '0'
516
+ seg[4] &&= seg[4].succ
517
+ else
518
+ seg[2] = seg[2].succ
519
+ end
520
+ when :patch
446
521
  seg[4] &&= seg[4].succ
447
- else
448
- seg[2] = seg[2].succ
449
522
  end
450
- else
451
- seg[4] &&= seg[4].succ
523
+ return if (val = seg.join) == cur
452
524
  end
453
- return if (out = seg.join) == ver
454
525
 
455
526
  begin
456
527
  doc = dependfile.read
457
- if doc.sub!(/"version"\s*:\s*"#{ver}"/, "\"version\": \"#{out}\"")
528
+ if doc.sub!(/"version"\s*:\s*"#{cur}"/, "\"version\": \"#{val}\"")
458
529
  unless dryrun?
459
530
  dependfile.write(doc)
460
- log.info "bump version #{ver} to #{out} (#{flag})"
531
+ log.info "bump version #{cur} to #{val} (#{flag})"
532
+ on :first, :bump
461
533
  end
462
534
  if verbose
463
535
  major = flag == :major
464
- emphasize("version: #{out}", title: name, border: borderstyle, sub: [
536
+ emphasize("version: #{val}", title: name, border: borderstyle, sub: [
465
537
  headerstyle,
466
538
  { pat: /\A(version:)( )(\S+)(.*)\z/, styles: color(major ? :green : :yellow), index: 3 },
467
539
  { pat: /\A(version:)(.*)\z/, styles: theme[major ? :major : :active] }
468
540
  ])
469
541
  elsif stdin?
470
- puts out
542
+ puts val
471
543
  end
544
+ on :last, :bump unless dryrun?
472
545
  else
473
546
  raise_error('not found', hint: 'version')
474
547
  end
@@ -490,19 +563,19 @@ module Squared
490
563
  elsif pnpm?
491
564
  cmd = session 'pnpm', 'update'
492
565
  cmd << '--prod' if prod?
493
- append_nocolor option('no-color')
566
+ append_nocolor
494
567
  else
495
568
  cmd = session 'npm', 'update'
496
569
  cmd << '--omit=dev' if prod?
497
- append_nocolor option('no-color')
570
+ append_nocolor
498
571
  end
499
572
  append_loglevel
500
573
  append_value pkgs
501
574
  run
502
575
  end
503
576
 
504
- def compose(opts, flags = nil, script: false)
505
- return unless opts && script
577
+ def compose(opts, flags = nil, script: false, from: :build)
578
+ return unless opts && script && from == :build
506
579
 
507
580
  ret = session dependbin, 'run', flags
508
581
  append_loglevel
@@ -512,7 +585,7 @@ module Squared
512
585
  when String
513
586
  ret << opts
514
587
  else
515
- raise_error("#{ret.first} script name", hint: opts.nil? ? 'missing' : 'invalid')
588
+ raise_error("#{dependbin} script name", hint: opts.nil? ? 'missing' : 'invalid')
516
589
  end
517
590
  ret
518
591
  end
@@ -536,13 +609,14 @@ module Squared
536
609
  require 'yaml'
537
610
  doc = YAML.load_file(rc)
538
611
  doc.nodeLinker == 'node-modules' ? 2 : 3
539
- rescue StandardError
612
+ rescue StandardError => e
613
+ log.debug e
540
614
  3
541
615
  end
542
616
  else
543
617
  1
544
618
  end
545
- elsif (ver = read_packagemanager || read_install) && ver.start_with?('yarn')
619
+ elsif (ver = read_packagemanager || read_install)&.start_with?('yarn')
546
620
  ver == 'yarn' || ver.include?('@1') ? 1 : 3
547
621
  else
548
622
  0
@@ -563,7 +637,8 @@ module Squared
563
637
  else
564
638
  4
565
639
  end
566
- rescue StandardError
640
+ rescue StandardError => e
641
+ log.debug e
567
642
  4
568
643
  end
569
644
  else
@@ -575,8 +650,7 @@ module Squared
575
650
  if pnpm?
576
651
  basepath('pnpm-workspace.yaml').exist?
577
652
  else
578
- read_packagemanager
579
- @pm[:workspaces].is_a?(Array)
653
+ read_packagemanager(:workspaces).is_a?(Array)
580
654
  end
581
655
  end
582
656
 
@@ -596,19 +670,17 @@ module Squared
596
670
  end
597
671
 
598
672
  def version
599
- read_packagemanager
600
- @pm[:version]
673
+ super || (@version = read_packagemanager(:version))
601
674
  end
602
675
 
603
676
  def packagename
604
- read_packagemanager
605
- @pm[:name]
677
+ read_packagemanager :name
606
678
  end
607
679
 
608
680
  private
609
681
 
610
- def read_packagemanager(version: nil)
611
- if @pm[:_].nil?
682
+ def read_packagemanager(key = nil, version: nil, update: false)
683
+ if @pm[:_].nil? || update
612
684
  doc = JSON.parse(dependfile.read)
613
685
  @pm[:_] = (val = doc['packageManager']) ? val[0..(val.index('+') || 0) - 1] : false
614
686
  @pm[:name] = doc['name']
@@ -617,10 +689,12 @@ module Squared
617
689
  @pm[:workspaces] = doc['workspaces']
618
690
  end
619
691
  rescue StandardError => e
620
- log.debug e if dependfile.exist?
692
+ log.debug e
621
693
  @pm[:_] = false
622
694
  nil
623
695
  else
696
+ return @pm[key] if key
697
+
624
698
  !(ret = @pm[:_]) || (version && ret[ret.index('@') + 1..-1] < version) ? nil : ret
625
699
  end
626
700
 
@@ -632,11 +706,11 @@ module Squared
632
706
  end
633
707
 
634
708
  def read_scripts
635
- read_packagemanager
636
- @pm[:scripts].is_a?(Hash) ? @pm[:scripts].to_a : []
709
+ ret = read_packagemanager(:scripts)
710
+ ret.is_a?(Hash) ? ret.to_a : []
637
711
  end
638
712
 
639
- def append_loglevel
713
+ def append_loglevel(target: @session)
640
714
  level = env('NODE_LOGLEVEL')
641
715
  silent = !verbose || level == 'silent'
642
716
  return unless silent || level
@@ -644,26 +718,26 @@ module Squared
644
718
  if yarn?
645
719
  if dependtype(:yarn) == 1
646
720
  if silent
647
- @session << '--silent'
721
+ target << '--silent'
648
722
  elsif level == 'verbose'
649
- @session << '--verbose'
723
+ target << '--verbose'
650
724
  end
651
725
  end
652
726
  elsif pnpm?
653
727
  if silent
654
- @session << shell_option('reporter', 'silent', escape: false)
728
+ target << '--reporter=silent'
655
729
  level ||= 'error'
656
730
  end
657
731
  case level
658
732
  when 'debug', 'info', 'warn', 'error'
659
- @session << shell_option('loglevel', level, escape: false)
733
+ target << basic_option('loglevel', level)
660
734
  end
661
735
  elsif silent
662
- @session << shell_option('loglevel', 'silent', escape: false)
736
+ target << '--loglevel=silent'
663
737
  else
664
738
  case level
665
739
  when 'error', 'warn', 'notice', 'http', 'info', 'verbose', 'silly'
666
- @session << shell_option('loglevel', level, escape: false)
740
+ target << basic_option('loglevel', level)
667
741
  end
668
742
  end
669
743
  end
@@ -684,7 +758,7 @@ module Squared
684
758
  end
685
759
 
686
760
  def dryrun?(prefix = dependbin)
687
- !option('dry-run', prefix: prefix).nil?
761
+ super || !option('dry-run', prefix: prefix).nil?
688
762
  end
689
763
 
690
764
  def dependbin