squared 0.5.2 → 0.5.3

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
 
@@ -181,6 +181,9 @@ module Squared
181
181
  }.freeze,
182
182
  git: {
183
183
  add: %w[N|intent-to-add refresh].freeze,
184
+ 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
185
+ p|porcelain root score-debug f|show-name e|show-email n|show-number show-stats abbrev=i
186
+ contents=p date=q encoding=b ignore-rev=b ignore-revs-file=p reverse=q].freeze,
184
187
  clean: %w[d x X f|force n|dry-run i|interactive q|quiet e|exclude=q].freeze,
185
188
  mv: %w[k f|force n|dry-run v|verbose].freeze,
186
189
  revert: %w[e S=bm? abort continue n|no-commit quit reference skip cleanup=b gpg-sign=b? m|mainline=i
@@ -248,6 +251,7 @@ module Squared
248
251
  tag: %w[n=im cleanup=b create-reflog i|ignore-case omit-empty color=b? column=b contains=b? format=q merged=b?
249
252
  no-contains=b? no-merged=b? points-at=q sort=q trailer=q].freeze,
250
253
  no: {
254
+ blame: %w[progress].freeze,
251
255
  branch: %w[color color-moved column track].freeze,
252
256
  checkout: %w[overwrite-ignore guess overlay progress recurse-submodules track].freeze,
253
257
  fetch: {
@@ -333,7 +337,7 @@ module Squared
333
337
  'diff' => %i[head branch files view between contain].freeze,
334
338
  'fetch' => %i[origin remote].freeze,
335
339
  'files' => %i[cached modified deleted others].freeze,
336
- 'git' => %i[add clean mv revert rm].freeze,
340
+ 'git' => %i[add blame clean mv revert rm].freeze,
337
341
  'log' => %i[view between contain].freeze,
338
342
  'merge' => %i[commit no-commit send].freeze,
339
343
  'pull' => %i[origin remote].freeze,
@@ -363,7 +367,7 @@ module Squared
363
367
 
364
368
  namespace name do
365
369
  Git.subtasks do |action, flags|
366
- next if @pass.include?(action)
370
+ next if task_pass?(action)
367
371
 
368
372
  namespace action do
369
373
  flags.each do |flag|
@@ -862,19 +866,14 @@ module Squared
862
866
  args = args.to_a
863
867
  if args.empty? || args.last == ':'
864
868
  files = []
865
- status_data.each do |line|
866
- case (flag == :staged ? line[2] : line[1])
867
- when /[AMDRTC]/
868
- files << line[0]
869
- end
870
- end
869
+ status_data.each { |row| files << row[0] if row[flag == :staged ? 2 : 1].match?(/[AMDRTC]/) }
871
870
  unless files.empty?
872
871
  files = choice_index('Select a file', files, multiple: true, force: false,
873
872
  accept: 'Restore?')
874
873
  end
875
874
  args.pop
876
875
  args, glob = args.partition { |val| val.match?(/^(?:[a-z-]+=|[^*]+$)/) }
877
- (files ||= []).concat(glob)
876
+ files.concat(glob)
878
877
  next if args.empty? && files.empty?
879
878
  end
880
879
  restore(flag, args, files: files)
@@ -882,10 +881,11 @@ module Squared
882
881
  end
883
882
  when 'git'
884
883
  before = case flag
884
+ when :blame then 'file'
885
885
  when :mv then 'source+,destination'
886
886
  when :revert then 'commit+' end
887
887
  format_desc(action, flag, 'opts*', before: before, after: case flag
888
- when :add then 'pathspec*|:pattern:*'
888
+ when :add then 'pathspec*,:pattern:*'
889
889
  when :clean, :rm then 'pathspec*' end)
890
890
  task flag do |_, args|
891
891
  git flag, args.to_a
@@ -1146,10 +1146,7 @@ module Squared
1146
1146
  rescue StandardError => e
1147
1147
  warn log_message(Logger::WARN, e, pass: true) if warning?
1148
1148
  else
1149
- if verbose
1150
- msg = sub_style('completed', styles: theme[:active])
1151
- puts log_message(Logger::INFO, name, msg, subject: 'revbuild', hint: time_format(epochtime - start))
1152
- end
1149
+ print_status(name, subject: 'revbuild', start: start, from: :completed)
1153
1150
  workspace.rev_write(name, { 'revision' => sha, 'files' => status_digest(*args, **kwargs) },
1154
1151
  sync: sync, utc: 'build')
1155
1152
  end
@@ -1627,10 +1624,16 @@ module Squared
1627
1624
 
1628
1625
  def git(flag, opts = [])
1629
1626
  cmd, opts = git_session(flag, opts: opts)
1630
- list = OPT_GIT[:git].fetch(flag, []) + OPT_GIT.fetch(flag, [])
1631
- op = OptionPartition.new(opts, list, cmd, project: self, no: OPT_GIT[:no][flag],
1632
- first: flag == :revert ? nil : matchpathspec)
1627
+ op = OptionPartition.new(opts, OPT_GIT[:git].fetch(flag, []) + OPT_GIT.fetch(flag, []), cmd,
1628
+ project: self, no: OPT_GIT[:no][flag], first: case flag
1629
+ when :blame, :revert
1630
+ nil
1631
+ else matchpathspec end)
1633
1632
  case flag
1633
+ when :blame
1634
+ raise_error 'no file found' unless (n = op.index { |s| (path + s).file? })
1635
+ op << '--' << shell_quote(path + op.delete_at(n))
1636
+ op.clear
1634
1637
  when :revert
1635
1638
  if VAL_GIT[:rebase][:send].any? { |val| op.arg?(val) }
1636
1639
  op.clear
@@ -1641,14 +1644,13 @@ module Squared
1641
1644
  end
1642
1645
  when :add, :clean
1643
1646
  if flag == :add && !op.arg?('pathspec-from-file')
1644
- grep, list = op.extras.partition { |val| val.start_with?(':') && val.end_with?(':') }
1645
- if list.empty? || !grep.empty?
1646
- red = color(:red)
1647
+ grep, list = op.partition { |val| val.start_with?(':') && val.end_with?(':') }
1648
+ unless grep.empty? && !list.empty?
1647
1649
  grep.map! { |val| Regexp.new(val[1..-2]) }
1648
1650
  files = status_data.map! do |a, b|
1649
1651
  next if b.strip.empty? || (!grep.empty? && grep.none? { |pat| pat.match?(a) })
1650
1652
 
1651
- "#{sub_style(b, styles: red)} #{a}"
1653
+ "#{sub_style(b, styles: color(:red))} #{a}"
1652
1654
  end
1653
1655
  .compact
1654
1656
  unless files.empty?
@@ -1745,11 +1747,7 @@ module Squared
1745
1747
  end
1746
1748
  end
1747
1749
  rescue StandardError => e
1748
- log&.error e
1749
- ret = on :error, from, e
1750
- raise if exception && ret != true
1751
-
1752
- warn log_message(Logger::WARN, e, pass: true) if warning?
1750
+ on_error(e, from, pass: true)
1753
1751
  nil
1754
1752
  else
1755
1753
  on :last, from
@@ -121,7 +121,7 @@ module Squared
121
121
 
122
122
  namespace name do
123
123
  Node.subtasks do |action, flags|
124
- next if @pass.include?(action)
124
+ next if task_pass?(action)
125
125
 
126
126
  if flags.nil?
127
127
  case action
@@ -269,6 +269,11 @@ module Squared
269
269
  otp = args.first
270
270
  else
271
271
  tag, otp = param_guard(action, flag, args: args)
272
+ unless SEM_VER.match?(tag)
273
+ a = sub_style(project, styles: theme[:active])
274
+ b = sub_style(tag, styles: theme[:inline])
275
+ exit 1 unless confirm("Publish #{a}@#{b}?", 'N')
276
+ end
272
277
  end
273
278
  publish(flag, otp: otp, tag: tag, dryrun: dryrun, access: access)
274
279
  end
@@ -280,7 +285,7 @@ module Squared
280
285
  end
281
286
  end
282
287
 
283
- def copy(from: 'build', into: 'node_modules', scope: nil, also: nil, create: nil, workspace: false,
288
+ def copy(from: 'build', into: 'node_modules', scope: nil, also: nil, create: nil, files: nil, workspace: false,
284
289
  link: false, force: false, override: false, sync: invoked_sync?('copy'), **kwargs)
285
290
  glob = kwargs[:include]
286
291
  pass = kwargs[:exclude]
@@ -289,6 +294,7 @@ module Squared
289
294
 
290
295
  from = @copy[:from] if @copy.key?(:from)
291
296
  into = @copy[:into] if @copy.key?(:into)
297
+ files = @copy[:files] if @copy.key?(:files)
292
298
  workspace = @copy[:workspace] if @copy.key?(:workspace)
293
299
  link = @copy[:link] if @copy.key?(:link)
294
300
  force = @copy[:force] if @copy.key?(:force)
@@ -310,6 +316,7 @@ module Squared
310
316
 
311
317
  on :first, :copy
312
318
  print_item unless @output[0] || !verbose || task_invoked?(/^copy(?::#{Node.ref}|$)/)
319
+ packed = false
313
320
  items.each do |dir|
314
321
  case dir
315
322
  when Pathname
@@ -347,9 +354,49 @@ module Squared
347
354
  end
348
355
  next unless from && dest&.directory?
349
356
 
350
- from = path + from
357
+ if from == :npm
358
+ begin
359
+ unless packed
360
+ require 'open3'
361
+ files = pwd_set do
362
+ Open3.capture2e(session_output('npm', 'pack --dry-run --no-color', npmname).to_s)
363
+ .first
364
+ .scan(/^npm notice \d+(?:\.\d+)?[a-z]+ (.+)$/i)
365
+ .map { |item| Pathname.new(item.first) }
366
+ .select(&:exist?)
367
+ end
368
+ .concat(Array(files))
369
+ packed = true
370
+ end
371
+ to = dest.join(into, npmname)
372
+ to.mkpath
373
+ log.info "cp npm:#{npmname} #{to}"
374
+ subdir = []
375
+ errors = 0
376
+ files.each do |file|
377
+ s, d = file.is_a?(Array) ? file : [file, file]
378
+ dest = to + d
379
+ unless subdir.include?((target = dest.dirname).to_s)
380
+ target.mkpath
381
+ subdir << target.to_s
382
+ end
383
+ begin
384
+ FileUtils.cp(path + s, dest, verbose: verbose.is_a?(Numeric) && verbose > 0)
385
+ rescue StandardError => e
386
+ print_error e
387
+ errors += 1
388
+ end
389
+ end
390
+ rescue StandardError => e
391
+ on_error e, :copy
392
+ else
393
+ puts message(to, subdir.size, files.size - errors) if verbose
394
+ end
395
+ next
396
+ end
351
397
  glob = Array(glob || '**/*')
352
398
  target = []
399
+ from = path + from
353
400
  if workspace
354
401
  from.glob('*').each do |entry|
355
402
  next unless entry.directory?
@@ -373,16 +420,14 @@ module Squared
373
420
  end
374
421
  end
375
422
  else
376
- target << [from, dest.join(into, scope || project)]
423
+ target << [from, dest.join(into, scope || npmname)]
377
424
  end
378
425
  target.each do |src, to|
379
426
  glob.each { |val| log.info "cp #{from + val} #{to}" }
380
427
  begin
381
428
  copy_dir(src, to, glob, create: create, link: link, force: force, pass: pass, verbose: verbose)
382
429
  rescue StandardError => e
383
- log.error e
384
- ret = on :error, :copy, e
385
- raise if exception && ret != true
430
+ on_error e, :copy
386
431
  end
387
432
  end
388
433
  end
@@ -448,19 +493,14 @@ module Squared
448
493
  log.info cmd.to_s
449
494
  on :first, :outdated
450
495
  end
451
- banner = format_banner(cmd.temp(dryrun ? ' --dry-run' : nil))
496
+ banner = format_banner(cmd.temp(dryrun ? '--dry-run' : nil))
452
497
  print_item banner if sync
453
498
  begin
454
499
  data = pwd_set { `#{cmd.temp('--json', '--loglevel=error')}` }
455
500
  doc = dependfile.read
456
501
  json = JSON.parse(doc)
457
502
  rescue StandardError => e
458
- log.error e
459
- unless dryrun
460
- ret = on :error, :outdated, e
461
- raise if exception && ret != true
462
- end
463
- warn log_message(Logger::WARN, e) if warning?
503
+ on_error(e, :outdated, dryrun: dryrun)
464
504
  return
465
505
  else
466
506
  dep1 = json['dependencies'] || {}
@@ -611,7 +651,7 @@ module Squared
611
651
  package('update', from: :update)
612
652
  end
613
653
 
614
- def publish(flag = nil, *, sync: invoked_sync?('publish', flag), otp: nil, tag: nil, dryrun: nil, access: nil)
654
+ def publish(flag = nil, *, sync: invoked_sync?('publish', flag), otp: nil, tag: nil, access: nil, dryrun: nil)
615
655
  if !version || read_packagemanager(:private)
616
656
  warn log_message(Logger::WARN, 'invalid task "publish"', subject: name, hint: version ? 'private' : nil)
617
657
  return
@@ -628,7 +668,7 @@ module Squared
628
668
  log.info cmd.to_s
629
669
  end
630
670
  if sync
631
- run(from: from, sync: sync, interactive: !dryrun && "Publish #{sub_style(project, styles: theme[:active])}")
671
+ run(from: from, sync: sync, interactive: !dryrun && "Publish #{sub_style(npmname, styles: theme[:active])}")
632
672
  else
633
673
  on :first, from
634
674
  pwd_set(from: from) do
@@ -746,9 +786,7 @@ module Squared
746
786
  raise_error('version not found', hint: dependfile)
747
787
  end
748
788
  rescue StandardError => e
749
- log.debug e
750
- ret = on :error, :bump, e
751
- raise if exception && ret != true
789
+ on_error e, :bump
752
790
  end
753
791
  end
754
792
 
@@ -887,7 +925,7 @@ module Squared
887
925
  end
888
926
 
889
927
  def version
890
- super || (@version = read_packagemanager(:version))
928
+ @version ||= read_packagemanager(:version)
891
929
  end
892
930
 
893
931
  def packagename
@@ -913,7 +951,7 @@ module Squared
913
951
  else
914
952
  if key
915
953
  @pm[key]
916
- elsif (ret = @pm[:_]) && !(version && ret[(ret.index('@') + 1)..-1] < version)
954
+ elsif (ret = @pm[:_]) && !(version && semcmp(ret[(ret.index('@') + 1)..-1], version) == 1)
917
955
  ret
918
956
  end
919
957
  end
@@ -978,6 +1016,10 @@ module Squared
978
1016
  'package.json' if parent&.has?('outdated', Node.ref)
979
1017
  end
980
1018
 
1019
+ def npmname
1020
+ packagename || project
1021
+ end
1022
+
981
1023
  def npmnotice
982
1024
  [
983
1025
  { 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
@@ -655,7 +659,7 @@ module Squared
655
659
  if edit
656
660
  edit = path + edit unless %r{^[a-z]+(?:\+[a-z]+)?://}i.match?(edit)
657
661
  if flag == :editable
658
- op.extras << edit
662
+ op.push(edit)
659
663
  else
660
664
  target << quote_option('e', edit)
661
665
  end
@@ -851,17 +855,17 @@ module Squared
851
855
  return if !venv || (venvbin.directory? && !venvbin.empty?)
852
856
 
853
857
  puts log_message(Logger::INFO, venv, subject: 'venv', hint: 'init')
854
- @venvopts &&= @venvopts.map { |val| OptionPartition.strip(val) }.flatten
855
- venv_create(venv, @venvopts || ["prompt=#{name}", 'upgrade-deps'], env: false, banner: false)
858
+ opts = @venvopts&.map { |val| OptionPartition.strip(val) }&.flatten
859
+ venv_create(venv, opts || ["prompt=#{name}", 'upgrade-deps'], env: false, banner: false)
856
860
  puts log_message(Logger::INFO, venv, subject: 'venv', hint: 'created')
857
861
  end
858
862
 
859
863
  def venv_create(dir, opts = [], env: nil, banner: true)
860
864
  cmd, opts = python_session('-m venv', opts: opts)
861
865
  op = OptionPartition.new(opts, OPT_PYTHON[:venv], cmd, project: self)
862
- op.append(dir, delim: true)
863
- .clear(pass: false)
864
- status = op.arg?(/\A-v+\z/, 'verbose')
866
+ status = op.append(dir, delim: true)
867
+ .clear(pass: false)
868
+ .arg?(/\A-v+\z/, 'verbose')
865
869
  run(op, env, exception: true, banner: banner)
866
870
  puts(dir.directory? ? "Success: #{dir}" : 'Failed') if banner && !status
867
871
  end