squared 0.1.7 → 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
@@ -123,8 +152,8 @@ module Squared
123
152
  end
124
153
  end
125
154
 
126
- def copy(from: 'build', into: 'node_modules', workspace: false, scope: nil,
127
- also: nil, create: nil, override: false, **kwargs)
155
+ def copy(from: 'build', into: 'node_modules', workspace: false, include: nil, exclude: nil, scope: nil,
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,21 +162,21 @@ 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]
139
170
  also = @copy[:also]
140
171
  create = @copy[:create]
141
- else
142
- glob = kwargs[:include]
143
- exclude = kwargs[:exclude]
144
172
  end
145
173
  items = []
146
174
  items << @workspace.home if build? && path != @workspace.home && @workspace.home?
147
175
  items += as_a(also) if also
148
176
  return if items.empty?
149
177
 
150
- 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}|$)/)
151
180
  items.each do |dir|
152
181
  case dir
153
182
  when Pathname
@@ -163,6 +192,8 @@ module Squared
163
192
  from = dir[:from] if dir.key?(:from)
164
193
  into = dir[:into] if dir.key?(:into)
165
194
  scope = dir[:scope] if dir.key?(:scope)
195
+ link = dir[:link] if dir.key?(:link)
196
+ force = dir[:force] if dir.key?(:force)
166
197
  dest = dir[:target]
167
198
  create = dir[:create]
168
199
  workspace = dir[:workspace]
@@ -186,10 +217,11 @@ module Squared
186
217
  elsif (file = path.join('package.json')).exist?
187
218
  begin
188
219
  doc = JSON.parse(file.read)
189
- doc['name']
190
220
  rescue StandardError => e
191
221
  log.error e
192
222
  raise if exception
223
+ else
224
+ doc['name']
193
225
  end
194
226
  end
195
227
  if sub
@@ -203,18 +235,29 @@ module Squared
203
235
  end
204
236
  target.each do |src, to|
205
237
  glob.each { |val| log.info "cp #{from.join(val)} #{to}" }
206
- 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
207
245
  end
208
246
  end
247
+ on :last, :copy
209
248
  end
210
249
 
211
- def depend(flag = nil, sync: invoked_sync?('depend', flag))
250
+ def depend(flag = nil, sync: invoked_sync?('depend', flag), packages: [], save: nil, exact: nil)
212
251
  if @depend && !flag
213
252
  super
214
253
  elsif outdated?
215
254
  if (yarn = dependtype(:yarn)) > 0
216
255
  cmd = session 'yarn'
217
- 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
218
261
  if flag == :dedupe
219
262
  cmd << 'dedupe'
220
263
  else
@@ -235,7 +278,12 @@ module Squared
235
278
  end
236
279
  elsif pnpm?
237
280
  cmd = session 'pnpm'
238
- 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
239
287
  cmd << 'dedupe'
240
288
  else
241
289
  cmd << 'install' << if flag == :force
@@ -249,10 +297,15 @@ module Squared
249
297
  split_escape(val).each { |opt| cmd << shell_option('public-hoist-pattern', opt, quote: true) }
250
298
  end
251
299
  cmd << '--ignore-workspace' if env('NODE_WORKSPACES', equals: '0')
252
- append_nocolor option('no-color')
300
+ append_nocolor
253
301
  else
254
302
  cmd = session 'npm'
255
- 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
256
309
  cmd << 'dedupe'
257
310
  else
258
311
  cmd << 'install' << if flag == :force
@@ -261,34 +314,41 @@ module Squared
261
314
  '--package-lock-only'
262
315
  end
263
316
  end
264
- 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
265
322
  cmd << '--workspaces=false' if env('NODE_WORKSPACES', equals: '0')
266
323
  cmd << '--package-lock=false' if option('package-lock', equals: '0')
267
- append_nocolor option('no-color')
324
+ append_nocolor
268
325
  end
269
326
  append_loglevel
270
- run(sync: sync)
327
+ run(from: :depend, sync: sync)
271
328
  end
272
329
  end
273
330
 
274
- def outdated(rev = nil, opts: [], sync: invoked_sync?('outdated', rev))
331
+ def outdated(flag = nil, sync: invoked_sync?('outdated', flag), opts: [])
275
332
  dryrun = opts.include?('dry-run')
276
- if pnpm? && read_packagemanager(version: '7.15')
277
- cmd = 'pnpm outdated'
333
+ if pnpm? && read_packagemanager(version: '7.15', update: true)
334
+ cmd = session 'pnpm', 'outdated'
278
335
  dryrun ||= dryrun?('pnpm')
279
336
  else
280
- cmd = 'npm outdated'
337
+ cmd = session 'npm', 'outdated'
281
338
  dryrun ||= dryrun?('npm')
282
339
  end
283
- log.info cmd
284
- 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))
285
343
  print_item banner if sync
286
344
  begin
287
- data = pwd_set { `#{cmd} --json --loglevel=error` }
288
- json = JSON.parse(doc = dependfile.read)
345
+ data = pwd_set { `#{cmd.temp('--json', '--loglevel=error')}` }
346
+ doc = dependfile.read
347
+ json = JSON.parse(doc)
289
348
  rescue StandardError => e
290
349
  log.error e
291
- raise if exception
350
+ ret = on(:error, :outdated, e)
351
+ raise if exception && ret != true
292
352
 
293
353
  warn log_message(Logger::WARN, e) if warning?
294
354
  return
@@ -299,7 +359,7 @@ module Squared
299
359
  end
300
360
  found = []
301
361
  avail = []
302
- rev ||= (prod? ? :patch : :minor)
362
+ rev = flag || (prod? ? :patch : :minor)
303
363
  inter = opts.include?('interactive')
304
364
  unless data.empty?
305
365
  JSON.parse(data).each_pair do |key, val|
@@ -357,7 +417,7 @@ module Squared
357
417
  ret = val.succ.to_s
358
418
  ord.size > 9 ? ret.rjust(ord.size.to_s.size) : ret
359
419
  end
360
- footer = lambda do |val = 0|
420
+ footer = lambda do |val, size|
361
421
  next unless verbose
362
422
 
363
423
  msg, hint = if modified == -1
@@ -365,7 +425,8 @@ module Squared
365
425
  else
366
426
  ['No packages were updated', 'possible']
367
427
  end
368
- 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))
369
430
  end
370
431
  print_item banner unless sync
371
432
  if !found.empty?
@@ -389,6 +450,8 @@ module Squared
389
450
  end
390
451
  end
391
452
  a = a.ljust(col1)
453
+ b = b.ljust(col2)
454
+ b = sub_style(b, styles: theme[:current]) if theme[:current]
392
455
  c = if cur == -1
393
456
  'SKIP'
394
457
  elsif modified == cur
@@ -399,14 +462,14 @@ module Squared
399
462
  else
400
463
  sub_style(c, pat: SEM_VER, styles: color(:green), index: d)
401
464
  end
402
- puts "#{pad_ord.(i, found)}. #{a}#{b.ljust(col2)}#{c}"
465
+ puts "#{pad_ord.(i, found)}. #{a + b + c}"
403
466
  end
404
467
  pending = avail.reduce(pending) { |a, b| a + (b[3] ? 0 : 1) }
405
468
  if dryrun || (modified == 0 && pending > 0)
406
- footer.(modified)
469
+ footer.(modified, found.size)
407
470
  elsif modified > 0
408
471
  modified = -1
409
- footer.()
472
+ footer.(0, found.size)
410
473
  File.write(dependfile, doc)
411
474
  commit(:add, ['package.json'], pass: true)
412
475
  install if opts.include?('prune')
@@ -427,51 +490,58 @@ module Squared
427
490
  end
428
491
  puts "#{pad_ord.(i, avail)}. #{a + c + b} (#{d ? 'locked' : 'latest'})"
429
492
  end
430
- footer.()
493
+ footer.(0, avail.size)
431
494
  else
432
495
  puts 'No updates were found'
433
496
  end
497
+ on :last, :outdated unless dryrun
434
498
  end
435
499
 
436
- def bump(flag = nil)
437
- return unless (ver = version)
500
+ def bump(flag, val = nil)
501
+ return unless (cur = version)
438
502
 
439
- seg = semscan(ver, fill: false)
440
- case flag
441
- when :major
442
- if seg[0] != '0' || seg[2].nil?
443
- seg[0] = seg[0].succ
444
- else
445
- seg[2] = seg[2].succ
446
- end
447
- when :minor
448
- 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
449
521
  seg[4] &&= seg[4].succ
450
- else
451
- seg[2] = seg[2].succ
452
522
  end
453
- else
454
- seg[4] &&= seg[4].succ
523
+ return if (val = seg.join) == cur
455
524
  end
456
- return if (out = seg.join) == ver
457
525
 
458
526
  begin
459
527
  doc = dependfile.read
460
- if doc.sub!(/"version"\s*:\s*"#{ver}"/, "\"version\": \"#{out}\"")
528
+ if doc.sub!(/"version"\s*:\s*"#{cur}"/, "\"version\": \"#{val}\"")
461
529
  unless dryrun?
462
530
  dependfile.write(doc)
463
- log.info "bump version #{ver} to #{out} (#{flag})"
531
+ log.info "bump version #{cur} to #{val} (#{flag})"
532
+ on :first, :bump
464
533
  end
465
534
  if verbose
466
535
  major = flag == :major
467
- emphasize("version: #{out}", title: name, border: borderstyle, sub: [
536
+ emphasize("version: #{val}", title: name, border: borderstyle, sub: [
468
537
  headerstyle,
469
538
  { pat: /\A(version:)( )(\S+)(.*)\z/, styles: color(major ? :green : :yellow), index: 3 },
470
539
  { pat: /\A(version:)(.*)\z/, styles: theme[major ? :major : :active] }
471
540
  ])
472
541
  elsif stdin?
473
- puts out
542
+ puts val
474
543
  end
544
+ on :last, :bump unless dryrun?
475
545
  else
476
546
  raise_error('not found', hint: 'version')
477
547
  end
@@ -493,19 +563,19 @@ module Squared
493
563
  elsif pnpm?
494
564
  cmd = session 'pnpm', 'update'
495
565
  cmd << '--prod' if prod?
496
- append_nocolor option('no-color')
566
+ append_nocolor
497
567
  else
498
568
  cmd = session 'npm', 'update'
499
569
  cmd << '--omit=dev' if prod?
500
- append_nocolor option('no-color')
570
+ append_nocolor
501
571
  end
502
572
  append_loglevel
503
573
  append_value pkgs
504
574
  run
505
575
  end
506
576
 
507
- def compose(opts, flags = nil, script: false)
508
- return unless opts && script
577
+ def compose(opts, flags = nil, script: false, from: :build)
578
+ return unless opts && script && from == :build
509
579
 
510
580
  ret = session dependbin, 'run', flags
511
581
  append_loglevel
@@ -515,7 +585,7 @@ module Squared
515
585
  when String
516
586
  ret << opts
517
587
  else
518
- raise_error("#{ret.first} script name", hint: opts.nil? ? 'missing' : 'invalid')
588
+ raise_error("#{dependbin} script name", hint: opts.nil? ? 'missing' : 'invalid')
519
589
  end
520
590
  ret
521
591
  end
@@ -539,13 +609,14 @@ module Squared
539
609
  require 'yaml'
540
610
  doc = YAML.load_file(rc)
541
611
  doc.nodeLinker == 'node-modules' ? 2 : 3
542
- rescue StandardError
612
+ rescue StandardError => e
613
+ log.debug e
543
614
  3
544
615
  end
545
616
  else
546
617
  1
547
618
  end
548
- elsif (ver = read_packagemanager || read_install) && ver.start_with?('yarn')
619
+ elsif (ver = read_packagemanager || read_install)&.start_with?('yarn')
549
620
  ver == 'yarn' || ver.include?('@1') ? 1 : 3
550
621
  else
551
622
  0
@@ -566,7 +637,8 @@ module Squared
566
637
  else
567
638
  4
568
639
  end
569
- rescue StandardError
640
+ rescue StandardError => e
641
+ log.debug e
570
642
  4
571
643
  end
572
644
  else
@@ -578,8 +650,7 @@ module Squared
578
650
  if pnpm?
579
651
  basepath('pnpm-workspace.yaml').exist?
580
652
  else
581
- read_packagemanager
582
- @pm[:workspaces].is_a?(Array)
653
+ read_packagemanager(:workspaces).is_a?(Array)
583
654
  end
584
655
  end
585
656
 
@@ -599,19 +670,17 @@ module Squared
599
670
  end
600
671
 
601
672
  def version
602
- read_packagemanager
603
- @pm[:version]
673
+ super || (@version = read_packagemanager(:version))
604
674
  end
605
675
 
606
676
  def packagename
607
- read_packagemanager
608
- @pm[:name]
677
+ read_packagemanager :name
609
678
  end
610
679
 
611
680
  private
612
681
 
613
- def read_packagemanager(version: nil)
614
- if @pm[:_].nil?
682
+ def read_packagemanager(key = nil, version: nil, update: false)
683
+ if @pm[:_].nil? || update
615
684
  doc = JSON.parse(dependfile.read)
616
685
  @pm[:_] = (val = doc['packageManager']) ? val[0..(val.index('+') || 0) - 1] : false
617
686
  @pm[:name] = doc['name']
@@ -620,10 +689,12 @@ module Squared
620
689
  @pm[:workspaces] = doc['workspaces']
621
690
  end
622
691
  rescue StandardError => e
623
- log.debug e if dependfile.exist?
692
+ log.debug e
624
693
  @pm[:_] = false
625
694
  nil
626
695
  else
696
+ return @pm[key] if key
697
+
627
698
  !(ret = @pm[:_]) || (version && ret[ret.index('@') + 1..-1] < version) ? nil : ret
628
699
  end
629
700
 
@@ -635,11 +706,11 @@ module Squared
635
706
  end
636
707
 
637
708
  def read_scripts
638
- read_packagemanager
639
- @pm[:scripts].is_a?(Hash) ? @pm[:scripts].to_a : []
709
+ ret = read_packagemanager(:scripts)
710
+ ret.is_a?(Hash) ? ret.to_a : []
640
711
  end
641
712
 
642
- def append_loglevel
713
+ def append_loglevel(target: @session)
643
714
  level = env('NODE_LOGLEVEL')
644
715
  silent = !verbose || level == 'silent'
645
716
  return unless silent || level
@@ -647,26 +718,26 @@ module Squared
647
718
  if yarn?
648
719
  if dependtype(:yarn) == 1
649
720
  if silent
650
- @session << '--silent'
721
+ target << '--silent'
651
722
  elsif level == 'verbose'
652
- @session << '--verbose'
723
+ target << '--verbose'
653
724
  end
654
725
  end
655
726
  elsif pnpm?
656
727
  if silent
657
- @session << shell_option('reporter', 'silent', escape: false)
728
+ target << '--reporter=silent'
658
729
  level ||= 'error'
659
730
  end
660
731
  case level
661
732
  when 'debug', 'info', 'warn', 'error'
662
- @session << shell_option('loglevel', level, escape: false)
733
+ target << basic_option('loglevel', level)
663
734
  end
664
735
  elsif silent
665
- @session << shell_option('loglevel', 'silent', escape: false)
736
+ target << '--loglevel=silent'
666
737
  else
667
738
  case level
668
739
  when 'error', 'warn', 'notice', 'http', 'info', 'verbose', 'silly'
669
- @session << shell_option('loglevel', level, escape: false)
740
+ target << basic_option('loglevel', level)
670
741
  end
671
742
  end
672
743
  end
@@ -687,7 +758,7 @@ module Squared
687
758
  end
688
759
 
689
760
  def dryrun?(prefix = dependbin)
690
- !option('dry-run', prefix: prefix).nil?
761
+ super || !option('dry-run', prefix: prefix).nil?
691
762
  end
692
763
 
693
764
  def dependbin