squared 0.0.9 → 0.0.10

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.
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
-
5
3
  module Squared
6
4
  module Workspace
7
5
  module Project
@@ -34,28 +32,17 @@ module Squared
34
32
 
35
33
  attr_reader :package
36
34
 
37
- def initialize(*, script: nil, **kwargs)
35
+ def initialize(*, **kwargs)
38
36
  super
39
- initialize_script(Node.ref, **kwargs)
40
- @dev = kwargs[:dev]
41
- @prod = kwargs[:prod]
37
+ if @pass.include?(Node.ref)
38
+ initialize_ref(Node.ref)
39
+ initialize_logger(**kwargs)
40
+ else
41
+ initialize_build(Node.ref, prod: prod?, **kwargs)
42
+ initialize_env(**kwargs)
43
+ end
42
44
  @pm = {}
43
45
  @package = base_path('package.json')
44
- return if @output[0] == false
45
-
46
- if @output[0].nil?
47
- val, ext = @workspace.script(Node.ref, @group)
48
- script_set val
49
- unless ext
50
- if script
51
- script_set script
52
- elsif (val = @script && @script[:run])
53
- @output[0] = val
54
- @output[1] = nil
55
- end
56
- end
57
- end
58
- @output[@output[0] || val.include?(' ') ? 0 : 1] = val if (val = env('BUILD', strict: true))
59
46
  end
60
47
 
61
48
  def ref
@@ -75,7 +62,7 @@ module Squared
75
62
  task action, [:command] do |_, args|
76
63
  cmd = args.to_a
77
64
  guard_params(action, 'command', args: cmd)
78
- run_script cmd
65
+ cmd.each { |val| run_s compose(val) }
79
66
  end
80
67
  end
81
68
  else
@@ -100,9 +87,9 @@ module Squared
100
87
  end
101
88
  end
102
89
 
103
- def copy(from: 'build', glob: '**/*', subdir: 'node_modules', into: nil, also: [], override: false)
90
+ def copy(from: 'build', glob: '**/*', subdir: 'node_modules', into: nil, also: nil, override: false)
104
91
  if @copy && !override
105
- return super if @copy.is_a?(::String)
92
+ return super if runnable?(@copy)
106
93
 
107
94
  from = @copy[:from] if @copy.key?(:from)
108
95
  glob = @copy[:glob] if @copy.key?(:glob)
@@ -110,10 +97,11 @@ module Squared
110
97
  into = @copy[:into] if @copy.key?(:into)
111
98
  also = @copy[:also] if @copy.key?(:also)
112
99
  end
113
- items = [name == workspace.main ? nil : workspace.home].concat(as_a(also))
100
+ items = [path == workspace.home ? nil : workspace.home]
101
+ items += as_a(also) if also
114
102
  items.each_with_index do |dir, i|
115
103
  if i == 0
116
- next unless dev? & !doc?
104
+ next unless dev? && build?
117
105
 
118
106
  dest = dir
119
107
  else
@@ -123,10 +111,13 @@ module Squared
123
111
  when ::Symbol
124
112
  dest = Workspace.resolve(dir)&.path
125
113
  when ::Hash
114
+ glob = '**/*'
115
+ dest = nil
126
116
  into = nil
127
- glob = nil
128
117
  dir.each do |key, val|
129
118
  case key.to_sym
119
+ when :target
120
+ dest = val
130
121
  when :from
131
122
  from = val
132
123
  when :glob
@@ -147,7 +138,7 @@ module Squared
147
138
  from = base_path(from)
148
139
  dest = dest.join(subdir, into || project)
149
140
  log.warn "cp #{from.join(glob)} #{dest}"
150
- copy_d(from, dest, glob: glob, verbose: verbose?)
141
+ copy_d(from, dest, glob: glob, verbose: verbose)
151
142
  end
152
143
  end
153
144
 
@@ -173,7 +164,7 @@ module Squared
173
164
  elsif flag == :frozen
174
165
  '--frozen-lockfile'
175
166
  end
176
- cmd << '--production' if prod?
167
+ cmd << '--production' if flag && prod?
177
168
  cmd << '--ignore-engines' unless env('YARN_IGNORE_ENGINES', equals: '0')
178
169
  end
179
170
  elsif pnpm?
@@ -187,7 +178,10 @@ module Squared
187
178
  '--frozen-lockfile'
188
179
  end
189
180
  end
190
- cmd << '--prod' if prod?
181
+ cmd << '--prod' if flag && prod?
182
+ if (val = env('PNPM_PUBLIC_HOIST_PATTERN'))
183
+ split_escape(val).each { |opt| cmd << "--public-hoist-pattern=#{shell_escape(opt, quote: true)}" }
184
+ end
191
185
  cmd << '--ignore-workspace' if env('NODE_WORKSPACES', equals: '0')
192
186
  append_nocolor
193
187
  else
@@ -201,7 +195,7 @@ module Squared
201
195
  '--package-lock-only'
202
196
  end
203
197
  end
204
- cmd << '--omit=dev' if prod?
198
+ cmd << '--omit=dev' if flag && prod?
205
199
  cmd << '--workspaces=false' if env('NODE_WORKSPACES', equals: '0')
206
200
  cmd << '--package-lock=false' if env('NPM_PACKAGE_LOCK', equals: '0')
207
201
  append_nocolor
@@ -212,49 +206,56 @@ module Squared
212
206
  end
213
207
 
214
208
  def outdated(rev = nil, opts: [])
215
- equ = rev || (prod? ? :patch : :minor)
216
- cmd = pnpm? ? 'pnpm outdated' : 'npm outdated'
209
+ dryrun = opts.include?('dry-run') || !env('NODE_DRY_RUN').nil?
210
+ cmd = pnpm? && read_packagemanager(ver: '7.15') ? 'pnpm outdated' : 'npm outdated'
217
211
  log.info cmd
218
- if store_pwd || invoked_sync?("outdated#{rev && ":#{rev}"}")
219
- print_item format_banner("#{cmd}#{opts.include?('dry-run') ? ' --dry-run' : ''}", multiple: true)
212
+ banner = format_banner("#{cmd}#{dryrun ? ' --dry-run' : ''}", multiple: true)
213
+ if invoked_sync?('outdated', rev)
214
+ print_item banner
215
+ banner = nil
220
216
  end
221
- data = `#{cmd} --json --loglevel=error`
222
- store_pwd true
217
+ data = nil
218
+ pwd_set { data = `#{cmd} --json --loglevel=error` }
223
219
  json = JSON.parse(doc = package.read)
224
220
  dep1 = json['dependencies'] || {}
225
221
  dep2 = json['devDependencies'] || {}
226
222
  found = []
227
223
  avail = []
228
- if !data.empty?
224
+ rev ||= (prod? ? :patch : :minor)
225
+ inter = opts.include?('interactive')
226
+ unless data.empty?
229
227
  JSON.parse(data).each_pair do |key, val|
230
- val = val.find { |item| item['dependent'] == json['name'] } if val.is_a?(Array)
228
+ val = val.find { |obj| obj['dependent'] == json['name'] } if val.is_a?(::Array)
231
229
  next unless val && (file = dep1[key] || dep2[key])
232
230
 
231
+ latest = val['latest']
233
232
  ch = file[0]
234
- unless ch =~ /[~^]/
235
- avail << [key, file, val['latest'], true]
233
+ if ch =~ /[~^]/
234
+ file = file[1..-1]
235
+ elsif inter && rev == :major
236
+ major = true
237
+ else
238
+ avail << [key, file, latest, true]
236
239
  next
237
240
  end
238
- file = file[1..-1]
239
- cur = val['current']
240
- want = if equ == :major && val['latest'] =~ SEM_VER
241
- [val['latest'], val['wanted']].max { |a, b| a <=> b }
242
- else
243
- val['wanted']
244
- end
245
- next unless (cur != want || file != want) && (want.match?(SEM_VER) || !file.match?(SEM_VER))
246
-
247
- a, b = file.split('.')
248
- c, d, e = want.split('.')
249
- case equ
241
+ want = rev == :major && latest.match(SEM_VER) && !Regexp.last_match(6) ? latest : val['wanted']
242
+ next unless (val['current'] != want || file != want) && (want.match?(SEM_VER) || !file.match?(SEM_VER))
243
+
244
+ f = semver(file.scan(SEM_VER)).first
245
+ w = semver(want.scan(SEM_VER)).first
246
+ a = f[0]
247
+ b = f[2]
248
+ c = w[0]
249
+ d = w[2]
250
+ case rev
250
251
  when :major
251
252
  upgrade = a == '0' ? c == '0' : true
252
253
  when :minor
253
254
  upgrade = ch == '^' && (a == '0' ? c == '0' && b == d : a == c)
254
255
  when :patch
255
- upgrade = a == c && b == d && !e.nil?
256
+ upgrade = a == c && b == d && f[4] != w[4]
256
257
  end
257
- if upgrade
258
+ if upgrade && !w[5]
258
259
  next if file == want
259
260
 
260
261
  index = if a != c
@@ -264,9 +265,9 @@ module Squared
264
265
  else
265
266
  5
266
267
  end
267
- found << [key, file, want, index]
268
- else
269
- avail << [key, file, val['latest'], false]
268
+ found << [key, file, want, index, major, f, w]
269
+ elsif !major
270
+ avail << [key, file, latest, false]
270
271
  end
271
272
  end
272
273
  end
@@ -278,7 +279,7 @@ module Squared
278
279
  ord.size > 9 ? ret.rjust(ord.size.to_s.size) : ret
279
280
  end
280
281
  footer = lambda do |val = 0|
281
- next unless verbose?
282
+ next unless verbose
282
283
 
283
284
  msg, hint = if modified == -1
284
285
  ['Packages were updated', 'more possible']
@@ -287,25 +288,24 @@ module Squared
287
288
  end
288
289
  puts print_footer(empty_status(msg, hint, pending + val))
289
290
  end
291
+ print_item banner if banner
290
292
  if !found.empty?
291
293
  col1 = size_col.(found, 0) + 4
292
294
  col2 = size_col.(found, 1) + 4
293
- inter = opts.include?('interactive')
294
295
  found.each_with_index do |item, i|
295
- a, b, c, d = item
296
- prompt = inter && (equ != :major || semmajor(semver(b.scan(SEM_VER)[0]), semver(c.scan(SEM_VER)[0])))
297
- if prompt && !confirm_outdated(equ.upcase, a, c)
296
+ a, b, c, d, e = item
297
+ if inter && (rev != :major || e || semmajor(item[5], item[6])) && !confirm_outdated(a, c, d)
298
298
  cur = -1
299
299
  else
300
300
  cur = modified
301
- doc.sub!(/("#{Regexp.escape(a)}"\s*:\s*)"([~^])#{Regexp.escape(b)}"/) do |capture|
302
- if $2 == '~' && equ != :patch
301
+ doc.sub!(/("#{Regexp.escape(a)}"\s*:\s*)"([~^])#{e ? '?' : ''}#{Regexp.escape(b)}"/) do |capture|
302
+ if $2 == '~' && rev != :patch
303
303
  cur = -1
304
304
  pending += 1
305
305
  capture
306
306
  else
307
307
  modified += 1
308
- "#{$1}\"#{$2 || ''}#{c}\""
308
+ "#{$1}\"#{$2 || (d == 1 && e ? '^' : '')}#{c}\""
309
309
  end
310
310
  end
311
311
  end
@@ -316,14 +316,14 @@ module Squared
316
316
  'FAIL'
317
317
  elsif d == 1
318
318
  a = sub_style(a, styles: theme[:major])
319
- sub_style(c, :green, :bold)
319
+ sub_style(c, :bold, styles: color(:green))
320
320
  else
321
- sub_style(c, :green, pat: SEM_VER, index: d)
321
+ sub_style(c, pat: SEM_VER, styles: color(:green), index: d)
322
322
  end
323
323
  puts "#{pad_ord.(i, found)}. #{a}#{b.ljust(col2)}#{c}"
324
324
  end
325
325
  pending = avail.reduce(pending) { |a, b| a + (b[3] ? 0 : 1) }
326
- if opts.include?('dry-run') || (modified == 0 && pending > 0)
326
+ if dryrun || (modified == 0 && pending > 0)
327
327
  footer.(modified)
328
328
  elsif modified > 0
329
329
  File.write(package, doc)
@@ -339,11 +339,11 @@ module Squared
339
339
  avail.each_with_index do |item, i|
340
340
  a, b, c, d = item
341
341
  a = a.ljust(col1)
342
- b = sub_style(b.ljust(col2), d ? :red : :yellow)
342
+ b = sub_style(b.ljust(col2), styles: color(d ? :red : :yellow))
343
343
  c = c.ljust(col3)
344
344
  unless d
345
345
  a = sub_style(a, styles: theme[:active])
346
- c = sub_style(c, :green)
346
+ c = sub_style(c, styles: color(:green))
347
347
  pending += 1
348
348
  end
349
349
  puts "#{pad_ord.(i, avail)}. #{a + c + b} (#{d ? 'locked' : 'latest'})"
@@ -354,23 +354,22 @@ module Squared
354
354
  end
355
355
  end
356
356
 
357
- def compose(args)
358
- args ||= @output[1]
359
- cmd = [if yarn?
360
- 'yarn'
361
- else
362
- pnpm? ? 'pnpm' : 'npm'
363
- end]
364
- cmd << 'run'
365
- append_loglevel cmd
366
- if args.is_a?(::Array)
367
- cmd += args
368
- elsif args.is_a?(::String)
369
- cmd << args
357
+ def compose(opts)
358
+ ret = session (if yarn?
359
+ 'yarn'
360
+ else
361
+ pnpm? ? 'pnpm' : 'npm'
362
+ end), 'run'
363
+ append_loglevel
364
+ case opts
365
+ when ::Enumerable
366
+ ret += opts.to_a
367
+ when ::String
368
+ ret << opts
370
369
  else
371
- raise_error("#{cmd.first} script name", hint: args.nil? ? 'missing' : 'invalid')
370
+ raise_error("#{ret.first} script name", hint: opts.nil? ? 'missing' : 'invalid')
372
371
  end
373
- cmd.join(' ')
372
+ ret
374
373
  end
375
374
 
376
375
  def install_type(prog = nil)
@@ -380,12 +379,8 @@ module Squared
380
379
  @pm[prog] || 0
381
380
  end
382
381
 
383
- def build?
384
- @output[0] != false && (!@output[0].nil? || !@output[1].nil?)
385
- end
386
-
387
382
  def copy?
388
- !!@copy
383
+ super || @copy.is_a?(::Hash)
389
384
  end
390
385
 
391
386
  def outdated?
@@ -393,8 +388,8 @@ module Squared
393
388
  end
394
389
 
395
390
  def yarn?
396
- (@pm[:yarn] ||= if File.exist?(base_path('yarn.lock'))
397
- if File.exist?(rc = base_path('.yarnrc.yml'))
391
+ (@pm[:yarn] ||= if base_path('yarn.lock').exist?
392
+ if (rc = base_path('.yarnrc.yml')).exist?
398
393
  begin
399
394
  require 'yaml'
400
395
  doc = YAML.load_file(rc)
@@ -405,7 +400,7 @@ module Squared
405
400
  else
406
401
  1
407
402
  end
408
- elsif (ver = read_packagemanager || env('NODE_INSTALL')) && ver.start_with?('yarn')
403
+ elsif (ver = read_packagemanager || read_install) && ver.start_with?('yarn')
409
404
  ver == 'yarn' || ver.include?('@1') ? 1 : 3
410
405
  else
411
406
  0
@@ -413,10 +408,11 @@ module Squared
413
408
  end
414
409
 
415
410
  def pnpm?
416
- (@pm[:pnpm] ||= if File.exist?(base_path('pnpm-lock.yaml'))
411
+ (@pm[:pnpm] ||= if base_path('pnpm-lock.yaml').exist?
417
412
  begin
418
413
  require 'yaml'
419
414
  doc = YAML.load_file(base_path('node_modules/.modules.yaml'))
415
+ @pm[:_] = doc['packageManager']
420
416
  case doc['nodeLinker']
421
417
  when 'hoisted'
422
418
  1
@@ -429,62 +425,68 @@ module Squared
429
425
  4
430
426
  end
431
427
  else
432
- (read_packagemanager || env('NODE_INSTALL'))&.start_with?('pnpm') ? 4 : 0
428
+ (read_packagemanager || read_install)&.start_with?('pnpm') ? 4 : 0
433
429
  end) > 0
434
430
  end
435
431
 
436
432
  def dev?
437
- !Node.prod? && workspace.dev?(pat: @dev, **runargs)
433
+ !Node.prod? && super
438
434
  end
439
435
 
440
436
  def prod?
441
- Node.prod? || workspace.prod?(pat: @prod, **runargs)
437
+ @prod != false && (Node.prod? || super)
442
438
  end
443
439
 
444
440
  private
445
441
 
446
- def run_script(cmd)
447
- cmd.each { |val| run_s compose(val) }
448
- end
449
-
450
- def append_loglevel(cmd = @session)
451
- return unless (level = env('NODE_LOGLEVEL'))
442
+ def append_loglevel
443
+ level = env('NODE_LOGLEVEL')
444
+ silent = !verbose || level == 'silent'
445
+ return unless silent || level
452
446
 
453
- silent = !workspace.verbose || level == 'silent'
454
447
  if yarn?
455
448
  if install_type(:yarn) == 1
456
449
  if silent
457
- cmd << '--silent'
450
+ @session << '--silent'
458
451
  elsif level == 'verbose'
459
- cmd << '--verbose'
452
+ @session << '--verbose'
460
453
  end
461
454
  end
462
455
  elsif pnpm?
463
456
  if silent
464
- cmd << '--reporter=silent'
457
+ @session << '--reporter=silent'
465
458
  level ||= 'error'
466
459
  end
467
460
  case level
468
461
  when 'debug', 'info', 'warn', 'error'
469
- cmd << "--loglevel=#{level}"
462
+ @session << "--loglevel=#{level}"
470
463
  end
471
464
  elsif silent
472
- cmd << '--loglevel=silent'
465
+ @session << '--loglevel=silent'
473
466
  else
474
467
  case level
475
468
  when 'error', 'warn', 'notice', 'http', 'info', 'verbose', 'silly'
476
- cmd << "--loglevel=#{level}"
469
+ @session << "--loglevel=#{level}"
477
470
  end
478
471
  end
479
472
  end
480
473
 
481
- def confirm_outdated(rev, pkg, ver)
482
- m = ver == :major
483
- confirm("Upgrade to #{rev}? #{sub_style("#{pkg} #{ver}", styles: theme[:inline])} [#{m ? 'y/N' : 'Y/n'}] ",
484
- default: m ? 'N' : 'Y', timeout: 60)
474
+ def confirm_outdated(pkg, ver, rev)
475
+ rev = case rev
476
+ when 1
477
+ 'MAJOR'
478
+ when 3
479
+ 'MINOR'
480
+ else
481
+ 'PATCH'
482
+ end
483
+ a = sub_style(rev, styles: theme[:header])
484
+ b = sub_style("#{pkg} #{ver}", styles: theme[:inline])
485
+ c, d = rev == 'MAJOR' ? ['y/N', 'N'] : ['Y/n', 'Y']
486
+ confirm("Upgrade to #{a}? #{b} [#{c}] ", d, timeout: 60)
485
487
  end
486
488
 
487
- def read_packagemanager
489
+ def read_packagemanager(ver: nil)
488
490
  if @pm[:_].nil?
489
491
  doc = JSON.parse(package.read)
490
492
  @pm[:_] = (val = doc['packageManager']) ? val[0..(val.index('+') || 0) - 1] : false
@@ -494,19 +496,16 @@ module Squared
494
496
  @pm[:_] = false
495
497
  nil
496
498
  else
497
- @pm[:_] || nil
498
- end
499
+ return unless @pm[:_]
499
500
 
500
- def script_set(val)
501
- @output[1] = if val.is_a?(::Array)
502
- val[Node.prod? ? 1 : 0]
503
- else
504
- val
505
- end
501
+ ver ? @pm[:_][@pm[:_].index('@') + 1..-1] >= ver : @pm[:_]
506
502
  end
507
503
 
508
- def runargs
509
- { script: @output[1], ref: Node.ref, group: group, global: @output[0].nil? && !(@script && @script[:run]) }
504
+ def read_install
505
+ return unless (ret = env('NODE_INSTALL'))
506
+
507
+ @pm[:_] ||= ret if ret.include?('@')
508
+ ret
510
509
  end
511
510
  end
512
511
  end
@@ -18,8 +18,7 @@ module Squared
18
18
  end
19
19
 
20
20
  def venv?
21
- val = ENV['VIRTUAL_ENV']
22
- !val.nil? && Dir.exist?(val)
21
+ Dir.exist?(ENV.fetch('VIRTUAL_ENV', ''))
23
22
  end
24
23
 
25
24
  def is_a?(val)
@@ -35,9 +34,15 @@ module Squared
35
34
 
36
35
  def initialize(*, **kwargs)
37
36
  super
37
+ if @pass.include?(Python.ref)
38
+ initialize_ref(Python.ref)
39
+ initialize_logger(**kwargs)
40
+ else
41
+ initialize_build(Python.ref, **kwargs)
42
+ initialize_env(**kwargs)
43
+ end
38
44
  @reqindex = REQUIREMENTS.index { |file| base_path(file).exist? } || 0
39
45
  @requirements = base_path(REQUIREMENTS[@reqindex])
40
- initialize_build(Python.ref, **kwargs)
41
46
  end
42
47
 
43
48
  @@tasks[ref] = {
@@ -128,6 +133,21 @@ module Squared
128
133
  requirements.exist? ? @reqindex + 1 : 0
129
134
  end
130
135
 
136
+ def variable_set(key, *val, **)
137
+ case key
138
+ when :requirements
139
+ req = base_path(val.first)
140
+ if (index = REQUIREMENTS.index(req.basename.to_s))
141
+ @reqindex = index
142
+ @requirements = req
143
+ else
144
+ log.warn "variable_set: @#{key}=#{req} (not supported)"
145
+ end
146
+ else
147
+ super
148
+ end
149
+ end
150
+
131
151
  def outdated?
132
152
  install_type > 0
133
153
  end