squared 0.1.3 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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