squared 0.4.15 → 0.4.16

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.
@@ -3,7 +3,7 @@
3
3
  module Squared
4
4
  module Workspace
5
5
  module Git
6
- GIT_REPO = Workspace.hashobj
6
+ GIT_REPO = Support.hashobj
7
7
  GIT_PROTO = %r{^(?:https?|ssh|git|file)://}i.freeze
8
8
  private_constant :GIT_REPO, :GIT_PROTO
9
9
 
@@ -179,6 +179,9 @@ module Squared
179
179
  }.freeze,
180
180
  git: {
181
181
  add: %w[N|intent-to-add refresh].freeze,
182
+ blame: %w[b c l s t w C=im? L=q M=im? S=p color-by-age color-lines first-parent incremental line-porcelain
183
+ p|porcelain root score-debug f|show-name e|show-email n|show-number show-stats abbrev=i
184
+ contents=p date=q encoding=b ignore-rev=b ignore-revs-file=p reverse=q].freeze,
182
185
  clean: %w[d x X f|force n|dry-run i|interactive q|quiet e|exclude=q].freeze,
183
186
  mv: %w[k f|force n|dry-run v|verbose].freeze,
184
187
  revert: %w[e S=bm? abort continue n|no-commit quit reference skip cleanup=b gpg-sign=b? m|mainline=i
@@ -245,6 +248,7 @@ module Squared
245
248
  tag: %w[n=im cleanup=b create-reflog i|ignore-case color=b? column=b contains=b? format=q merged=b?
246
249
  no-contains=b? no-merged=b? points-at=q sort=q].freeze,
247
250
  no: {
251
+ blame: %w[progress].freeze,
248
252
  branch: %w[color color-moved column track].freeze,
249
253
  checkout: %w[overwrite-ignore guess overlay progress recurse-submodules track].freeze,
250
254
  fetch: {
@@ -330,7 +334,7 @@ module Squared
330
334
  'diff' => %i[head branch files view between contain].freeze,
331
335
  'fetch' => %i[origin remote].freeze,
332
336
  'files' => %i[cached modified deleted others].freeze,
333
- 'git' => %i[add clean mv revert rm].freeze,
337
+ 'git' => %i[add blame clean mv revert rm].freeze,
334
338
  'log' => %i[view between contain].freeze,
335
339
  'merge' => %i[commit no-commit send].freeze,
336
340
  'pull' => %i[origin remote].freeze,
@@ -360,7 +364,7 @@ module Squared
360
364
 
361
365
  namespace name do
362
366
  Git.subtasks do |action, flags|
363
- next if @pass.include?(action)
367
+ next if task_pass?(action)
364
368
 
365
369
  namespace action do
366
370
  flags.each do |flag|
@@ -859,19 +863,14 @@ module Squared
859
863
  args = args.to_a
860
864
  if args.empty? || args.last == ':'
861
865
  files = []
862
- status_data.each do |line|
863
- case (flag == :staged ? line[2] : line[1])
864
- when /[AMDRTC]/
865
- files << line[0]
866
- end
867
- end
866
+ status_data.each { |row| files << row[0] if row[flag == :staged ? 2 : 1].match?(/[AMDRTC]/) }
868
867
  unless files.empty?
869
868
  files = choice_index('Select a file', files, multiple: true, force: false,
870
869
  accept: 'Restore?')
871
870
  end
872
871
  args.pop
873
872
  args, glob = args.partition { |val| val.match?(/^(?:[a-z-]+=|[^*]+$)/) }
874
- (files ||= []).concat(glob)
873
+ files.concat(glob)
875
874
  next if args.empty? && files.empty?
876
875
  end
877
876
  restore(flag, args, files: files)
@@ -879,10 +878,11 @@ module Squared
879
878
  end
880
879
  when 'git'
881
880
  before = case flag
881
+ when :blame then 'file'
882
882
  when :mv then 'source+,destination'
883
883
  when :revert then 'commit+' end
884
884
  format_desc(action, flag, 'opts*', before: before, after: case flag
885
- when :add then 'pathspec*|:pattern:*'
885
+ when :add then 'pathspec*,:pattern:*'
886
886
  when :clean, :rm then 'pathspec*' end)
887
887
  task flag do |_, args|
888
888
  git flag, args.to_a
@@ -1142,10 +1142,7 @@ module Squared
1142
1142
  rescue StandardError => e
1143
1143
  warn log_message(Logger::WARN, e, pass: true) if warning?
1144
1144
  else
1145
- if verbose
1146
- msg = sub_style('completed', styles: theme[:active])
1147
- puts log_message(Logger::INFO, name, msg, subject: 'revbuild', hint: time_format(epochtime - start))
1148
- end
1145
+ print_status(name, subject: 'revbuild', start: start, from: :completed)
1149
1146
  workspace.rev_write(name, { 'revision' => sha, 'files' => status_digest(*args, **kwargs) },
1150
1147
  sync: sync, utc: 'build')
1151
1148
  end
@@ -1623,10 +1620,16 @@ module Squared
1623
1620
 
1624
1621
  def git(flag, opts = [])
1625
1622
  cmd, opts = git_session(flag, opts: opts)
1626
- list = OPT_GIT[:git].fetch(flag, []) + OPT_GIT.fetch(flag, [])
1627
- op = OptionPartition.new(opts, list, cmd, project: self, no: OPT_GIT[:no][flag],
1628
- first: flag == :revert ? nil : matchpathspec)
1623
+ op = OptionPartition.new(opts, OPT_GIT[:git].fetch(flag, []) + OPT_GIT.fetch(flag, []), cmd,
1624
+ project: self, no: OPT_GIT[:no][flag], first: case flag
1625
+ when :blame, :revert
1626
+ nil
1627
+ else matchpathspec end)
1629
1628
  case flag
1629
+ when :blame
1630
+ raise_error 'no file found' unless (n = op.index { |s| (path + s).file? })
1631
+ op << '--' << shell_quote(path + op.delete_at(n))
1632
+ op.clear
1630
1633
  when :revert
1631
1634
  if VAL_GIT[:rebase][:send].any? { |val| op.arg?(val) }
1632
1635
  op.clear
@@ -1637,14 +1640,13 @@ module Squared
1637
1640
  end
1638
1641
  when :add, :clean
1639
1642
  if flag == :add && !op.arg?('pathspec-from-file')
1640
- grep, list = op.extras.partition { |val| val.start_with?(':') && val.end_with?(':') }
1641
- if list.empty? || !grep.empty?
1642
- red = color(:red)
1643
+ grep, list = op.partition { |val| val.start_with?(':') && val.end_with?(':') }
1644
+ unless grep.empty? && !list.empty?
1643
1645
  grep.map! { |val| Regexp.new(val[1..-2]) }
1644
1646
  files = status_data.map! do |a, b|
1645
1647
  next if b.strip.empty? || (!grep.empty? && grep.none? { |pat| pat.match?(a) })
1646
1648
 
1647
- "#{sub_style(b, styles: red)} #{a}"
1649
+ "#{sub_style(b, styles: color(:red))} #{a}"
1648
1650
  end
1649
1651
  .compact
1650
1652
  unless files.empty?
@@ -1741,11 +1743,7 @@ module Squared
1741
1743
  end
1742
1744
  end
1743
1745
  rescue StandardError => e
1744
- log&.error e
1745
- ret = on(:error, from, e)
1746
- raise if exception && ret != true
1747
-
1748
- warn log_message(Logger::WARN, e, pass: true) if warning?
1746
+ on_error(e, from, pass: true)
1749
1747
  nil
1750
1748
  else
1751
1749
  on :last, from
@@ -120,7 +120,7 @@ module Squared
120
120
 
121
121
  namespace name do
122
122
  Node.subtasks do |action, flags|
123
- next if @pass.include?(action)
123
+ next if task_pass?(action)
124
124
 
125
125
  if flags.nil?
126
126
  case action
@@ -257,6 +257,11 @@ module Squared
257
257
  otp = args.first
258
258
  else
259
259
  tag, otp = param_guard(action, flag, args: args)
260
+ unless SEM_VER.match?(tag)
261
+ a = sub_style(project, styles: theme[:active])
262
+ b = sub_style(tag, styles: theme[:inline])
263
+ exit 1 unless confirm("Publish #{a}@#{b}? [y/N] ", 'N')
264
+ end
260
265
  end
261
266
  publish(flag, otp: otp, tag: tag, dryrun: dryrun, access: access)
262
267
  end
@@ -268,7 +273,7 @@ module Squared
268
273
  end
269
274
  end
270
275
 
271
- def copy(from: 'build', into: 'node_modules', scope: nil, also: nil, create: nil, workspace: false,
276
+ def copy(from: 'build', into: 'node_modules', scope: nil, also: nil, create: nil, files: nil, workspace: false,
272
277
  link: false, force: false, override: false, sync: invoked_sync?('copy'), **kwargs)
273
278
  glob = kwargs[:include]
274
279
  pass = kwargs[:exclude]
@@ -277,6 +282,7 @@ module Squared
277
282
 
278
283
  from = @copy[:from] if @copy.key?(:from)
279
284
  into = @copy[:into] if @copy.key?(:into)
285
+ files = @copy[:files] if @copy.key?(:files)
280
286
  workspace = @copy[:workspace] if @copy.key?(:workspace)
281
287
  link = @copy[:link] if @copy.key?(:link)
282
288
  force = @copy[:force] if @copy.key?(:force)
@@ -298,6 +304,7 @@ module Squared
298
304
 
299
305
  on :first, :copy
300
306
  print_item unless @output[0] || !verbose || task_invoked?(/^copy(?::#{Node.ref}|$)/)
307
+ packed = false
301
308
  items.each do |dir|
302
309
  case dir
303
310
  when Pathname
@@ -335,9 +342,49 @@ module Squared
335
342
  end
336
343
  next unless from && dest&.directory?
337
344
 
338
- from = path + from
345
+ if from == :npm
346
+ begin
347
+ unless packed
348
+ require 'open3'
349
+ files = pwd_set do
350
+ Open3.capture2e(session_output('npm', 'pack --dry-run --no-color', npmname).to_s)
351
+ .first
352
+ .scan(/^npm notice \d+(?:\.\d+)?[a-z]+ (.+)$/i)
353
+ .map { |item| Pathname.new(item.first) }
354
+ .select(&:exist?)
355
+ end
356
+ .concat(Array(files))
357
+ packed = true
358
+ end
359
+ to = dest.join(into, npmname)
360
+ to.mkpath
361
+ log.info "cp npm:#{npmname} #{to}"
362
+ subdir = []
363
+ errors = 0
364
+ files.each do |file|
365
+ s, d = file.is_a?(Array) ? file : [file, file]
366
+ dest = to + d
367
+ unless subdir.include?((target = dest.dirname).to_s)
368
+ target.mkpath
369
+ subdir << target.to_s
370
+ end
371
+ begin
372
+ FileUtils.cp(path + s, dest, verbose: verbose.is_a?(Numeric) && verbose > 0)
373
+ rescue StandardError => e
374
+ print_error e
375
+ errors += 1
376
+ end
377
+ end
378
+ rescue StandardError => e
379
+ on_error e, :copy
380
+ else
381
+ puts message(to, subdir.size, files.size - errors) if verbose
382
+ end
383
+ next
384
+ end
339
385
  glob = Array(glob || '**/*')
340
386
  target = []
387
+ from = path + from
341
388
  if workspace
342
389
  Dir.glob(from + '*').each do |path|
343
390
  next unless (path = Pathname.new(path)).directory?
@@ -361,16 +408,14 @@ module Squared
361
408
  end
362
409
  end
363
410
  else
364
- target << [from, dest.join(into, scope || project)]
411
+ target << [from, dest.join(into, scope || npmname)]
365
412
  end
366
413
  target.each do |src, to|
367
414
  glob.each { |val| log.info "cp #{from + val} #{to}" }
368
415
  begin
369
416
  copy_dir(src, to, glob, create: create, link: link, force: force, pass: pass, verbose: verbose)
370
417
  rescue StandardError => e
371
- log.error e
372
- ret = on(:error, :copy, e)
373
- raise if exception && ret != true
418
+ on_error e, :copy
374
419
  end
375
420
  end
376
421
  end
@@ -436,19 +481,14 @@ module Squared
436
481
  log.info cmd.to_s
437
482
  on :first, :outdated
438
483
  end
439
- banner = format_banner(cmd.temp(dryrun ? ' --dry-run' : nil))
484
+ banner = format_banner(cmd.temp(dryrun ? '--dry-run' : nil))
440
485
  print_item banner if sync
441
486
  begin
442
487
  data = pwd_set { `#{cmd.temp('--json', '--loglevel=error')}` }
443
488
  doc = dependfile.read
444
489
  json = JSON.parse(doc)
445
490
  rescue StandardError => e
446
- log.error e
447
- unless dryrun
448
- ret = on(:error, :outdated, e)
449
- raise if exception && ret != true
450
- end
451
- warn log_message(Logger::WARN, e) if warning?
491
+ on_error(e, :outdated, dryrun: dryrun)
452
492
  return
453
493
  else
454
494
  dep1 = json['dependencies'] || {}
@@ -599,16 +639,16 @@ module Squared
599
639
  package('update', from: :update)
600
640
  end
601
641
 
602
- def publish(flag = nil, *, sync: invoked_sync?('publish', flag), otp: nil, tag: nil, dryrun: nil, access: nil)
642
+ def publish(flag = nil, *, sync: invoked_sync?('publish', flag), otp: nil, tag: nil, access: nil, dryrun: nil)
603
643
  if !version || read_packagemanager(:private)
604
644
  warn log_message(Logger::WARN, 'invalid task "publish"', subject: name, hint: version ? 'private' : nil)
605
645
  return
606
646
  end
607
647
  cmd = session 'npm', 'publish'
608
- cmd << basic_option('otp', otp) if otp ||= option('otp')
609
- cmd << basic_option('tag', tag) if tag ||= option('tag')
610
- cmd << basic_option('access', access) if access ||= option('access')
611
- dryrun = dryrun?('npm') if dryrun.nil?
648
+ cmd << basic_option('otp', otp) if otp &&= option('otp')
649
+ cmd << basic_option('tag', tag) if tag &&= option('tag')
650
+ cmd << basic_option('access', access) if access &&= option('access')
651
+ dryrun &&= dryrun?('npm')
612
652
  if dryrun
613
653
  cmd << '--dry-run'
614
654
  else
@@ -616,7 +656,7 @@ module Squared
616
656
  log.info cmd.to_s
617
657
  end
618
658
  if sync
619
- run(from: from, sync: sync, interactive: !dryrun && "Publish #{sub_style(project, styles: theme[:active])}")
659
+ run(from: from, sync: sync, interactive: !dryrun && "Publish #{sub_style(npmname, styles: theme[:active])}")
620
660
  else
621
661
  on :first, from
622
662
  pwd_set(from: :publish, dryrun: dryrun) do
@@ -735,9 +775,7 @@ module Squared
735
775
  raise_error('version not found', hint: dependfile)
736
776
  end
737
777
  rescue StandardError => e
738
- log.debug e
739
- ret = on(:error, :bump, e)
740
- raise if exception && ret != true
778
+ on_error e, :bump
741
779
  end
742
780
  end
743
781
 
@@ -876,7 +914,7 @@ module Squared
876
914
  end
877
915
 
878
916
  def version
879
- super || (@version = read_packagemanager(:version))
917
+ @version ||= read_packagemanager(:version)
880
918
  end
881
919
 
882
920
  def packagename
@@ -902,7 +940,7 @@ module Squared
902
940
  else
903
941
  if key
904
942
  @pm[key]
905
- elsif (ret = @pm[:_]) && !(version && ret[(ret.index('@') + 1)..-1] < version)
943
+ elsif (ret = @pm[:_]) && !(version && semcmp(ret[(ret.index('@') + 1)..-1], version) == 1)
906
944
  ret
907
945
  end
908
946
  end
@@ -967,6 +1005,10 @@ module Squared
967
1005
  'package.json' if parent&.has?('outdated', Node.ref)
968
1006
  end
969
1007
 
1008
+ def npmname
1009
+ packagename || project
1010
+ end
1011
+
970
1012
  def npmnotice
971
1013
  [
972
1014
  { pat: /^(npm error )(code|\d+)(.+)$/, styles: color(:cyan), index: 2 },
@@ -114,7 +114,7 @@ module Squared
114
114
 
115
115
  namespace name do
116
116
  Python.subtasks do |action, flags|
117
- next if @pass.include?(action)
117
+ next if task_pass?(action)
118
118
 
119
119
  if flags.nil?
120
120
  case action
@@ -183,7 +183,7 @@ module Squared
183
183
  elsif i || args.empty?
184
184
  readline('Enter command', force: true)
185
185
  else
186
- if (val = command_args(args, prefix: 'python'))
186
+ if (val = command_args(args, min: 1, prefix: 'python'))
187
187
  args << val
188
188
  end
189
189
  args.join(' ')
@@ -366,7 +366,11 @@ module Squared
366
366
  pwd_set(from: :outdated) do
367
367
  buffer = []
368
368
  out = ->(val) { sync ? puts(val) : buffer << val }
369
- IO.popen(runenv || {}, cmd).each do |line|
369
+ if workspace.windows?
370
+ (venv ? command(runenv, cmd) : `#{cmd}`).lines
371
+ else
372
+ IO.popen(runenv || {}, cmd)
373
+ end.each do |line|
370
374
  next if line.match?(/^[ -]+$/)
371
375
 
372
376
  if start > 0
@@ -488,7 +492,7 @@ module Squared
488
492
  if srcdir
489
493
  args = flag == :pdm ? ['d', 'dest'] : ['o', 'output']
490
494
  if op.arg?(*args)
491
- op.extras << srcdir
495
+ op.push(srcdir)
492
496
  else
493
497
  op << quote_option(args.last, path + srcdir)
494
498
  end
@@ -531,7 +535,7 @@ module Squared
531
535
  case flag
532
536
  when :hatch, :twine
533
537
  if op.empty?
534
- op.extras << "#{dist.call}/*"
538
+ op.push("#{dist.call}/*")
535
539
  else
536
540
  op.map! { |val| path + val }
537
541
  end
@@ -651,7 +655,7 @@ module Squared
651
655
  if edit
652
656
  edit = path + edit unless %r{^[a-z]+(?:\+[a-z]+)?://}i.match?(edit)
653
657
  if flag == :editable
654
- op.extras << edit
658
+ op.push(edit)
655
659
  else
656
660
  target << quote_option('e', edit)
657
661
  end
@@ -847,8 +851,8 @@ module Squared
847
851
  return if !venv || (venvbin.directory? && !venvbin.empty?)
848
852
 
849
853
  puts log_message(Logger::INFO, venv, subject: 'venv', hint: 'init')
850
- @venvopts &&= @venvopts.map { |val| OptionPartition.strip(val) }.flatten
851
- venv_create(venv, @venvopts || ["prompt=#{name}", 'upgrade-deps'], env: false, banner: false)
854
+ opts = @venvopts&.map { |val| OptionPartition.strip(val) }&.flatten
855
+ venv_create(venv, opts || ["prompt=#{name}", 'upgrade-deps'], env: false, banner: false)
852
856
  puts log_message(Logger::INFO, venv, subject: 'venv', hint: 'created')
853
857
  end
854
858