squared 0.5.0 → 0.5.2

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 = {}
6
+ GIT_REPO = Workspace.hashobj
7
7
  GIT_PROTO = %r{^(?:https?|ssh|git|file)://}i.freeze
8
8
  private_constant :GIT_REPO, :GIT_PROTO
9
9
 
@@ -27,7 +27,7 @@ module Squared
27
27
  base = name
28
28
  @project.each_value { |proj| repo << proj if !proj.parent && check.call(proj) }
29
29
  else
30
- warn log_message(Logger::WARN, name, subject: 'git', hint: 'invalid', pass: true) if warning
30
+ warn log_message(Logger::WARN, name, subject: 'git', hint: 'invalid') if warning
31
31
  return self
32
32
  end
33
33
  if base
@@ -58,8 +58,8 @@ module Squared
58
58
  end
59
59
  end
60
60
  key = task_name key
61
- (GIT_REPO[main] ||= {})[key] = [uri.to_s, opts]
62
- (@kind[key] ||= []) << Project::Git
61
+ GIT_REPO[main][key] = [uri.to_s, opts]
62
+ @kind[key] << Project::Git
63
63
  end
64
64
  if cache == true
65
65
  revbuild
@@ -343,7 +343,7 @@ module Squared
343
343
  'restore' => %i[source staged worktree].freeze,
344
344
  'rev' => %i[commit build output].freeze,
345
345
  'show' => %i[format oneline textconv].freeze,
346
- 'stash' => %i[push pop apply drop clear list].freeze,
346
+ 'stash' => %i[push pop apply branch drop clear list].freeze,
347
347
  'switch' => %i[create detach merge].freeze,
348
348
  'tag' => %i[add sign delete list].freeze
349
349
  })
@@ -370,13 +370,13 @@ module Squared
370
370
  case action
371
371
  when 'pull', 'fetch'
372
372
  if flag == :remote
373
- format_desc action, flag, 'remote,opts*'
373
+ format_desc action, flag, 'remote?,opts*'
374
374
  task flag, [:remote] do |_, args|
375
375
  if (remote = args.remote)
376
376
  args = args.extras
377
377
  else
378
378
  remote = choice_remote
379
- args = args.to_a.drop(1)
379
+ args = args.to_a
380
380
  end
381
381
  __send__(action, flag, args, remote: remote)
382
382
  end
@@ -399,12 +399,12 @@ module Squared
399
399
  if flag == :fixup
400
400
  ref, squash, pick = choice_commit(accept: [['Auto squash?', true]], reflog: false,
401
401
  values: ['Pick [amend|reword]'])
402
- pick = case pick&.downcase
403
- when 'a', 'amend'
404
- 'amend'
405
- when 'r', 'reword'
406
- 'reword'
407
- end
402
+ pick &&= case pick.downcase
403
+ when 'a', 'amend'
404
+ 'amend'
405
+ when 'r', 'reword'
406
+ 'reword'
407
+ end
408
408
  if squash
409
409
  found = false
410
410
  git_spawn(git_output('log --format=%h'), stdout: false).each do |val|
@@ -416,12 +416,14 @@ module Squared
416
416
  end
417
417
  end
418
418
  end
419
- refs = pick == 'reword' ? [] : param_guard(action, flag, args: args.to_a)
420
- if flag == :add
421
- opts = refs
422
- refs = []
423
- else
424
- opts = []
419
+ opts = []
420
+ refs = []
421
+ unless pick == 'reword'
422
+ if flag == :add
423
+ opts = param_guard(action, flag, args: args.to_a)
424
+ elsif (refs = args.to_a).empty?
425
+ refs = readline('Enter file patterns', force: true).shellsplit
426
+ end
425
427
  end
426
428
  commit(flag, opts, refs: refs, ref: ref, squash: squash, pick: pick)
427
429
  end
@@ -462,6 +464,7 @@ module Squared
462
464
  when 'stash'
463
465
  format_desc(action, flag, 'opts*', after: case flag
464
466
  when :push then 'pathspec*'
467
+ when :branch then 'name,stash?|:'
465
468
  when :clear, :list then nil
466
469
  else 'stash?|:' end)
467
470
  task flag do |_, args|
@@ -930,7 +933,7 @@ module Squared
930
933
  source(sync: sync, sub: if verbose
931
934
  [
932
935
  { pat: /^(.+)(\|\s+\d+\s+)([^-]*)(-+)(.*)$/, styles: color(:red), index: 4 },
933
- { pat: /^(.+)(\|\s+\d+\s+)(\++)(-*)(.*)$/, styles: color(:green), index: 3 }
936
+ { pat: /^(.+)(\|\s+\d+\s+)(\++)(.*)$/, styles: color(:green), index: 3 }
934
937
  ]
935
938
  end, **threadargs)
936
939
  end
@@ -945,7 +948,7 @@ module Squared
945
948
  return unless upstream
946
949
 
947
950
  op = OptionPartition.new(opts, OPT_GIT[:rebase], cmd, project: self, no: OPT_GIT[:no][:rebase])
948
- cmd << shell_escape(upstream)
951
+ cmd << upstream
949
952
  append_head op.shift
950
953
  op.clear(pass: false)
951
954
  when :onto
@@ -953,7 +956,7 @@ module Squared
953
956
 
954
957
  cmd << '--interactive' if option('interactive', 'i')
955
958
  cmd << shell_option('onto', commit) if commit
956
- cmd << shell_escape(upstream)
959
+ cmd << upstream
957
960
  append_head branch
958
961
  else
959
962
  return unless VAL_GIT[:rebase][:send].include?(command)
@@ -1018,18 +1021,30 @@ module Squared
1018
1021
  case flag
1019
1022
  when :push
1020
1023
  append_pathspec op.extras
1021
- when :pop, :apply, :drop
1024
+ when :pop, :apply, :drop, :branch
1022
1025
  if op.extras.delete(':')
1023
- op << choice_index('Choose a stash', git_spawn('stash list', stdout: false),
1024
- column: /^[^@]+@\{(\d+)\}/, force: true)
1026
+ if flag == :branch
1027
+ if op.empty?
1028
+ values = [['Branch name', true]]
1029
+ else
1030
+ op << op.pop
1031
+ end
1032
+ end
1033
+ out = choice_index('Choose a stash', git_spawn('stash list', stdout: false),
1034
+ values: values, column: /^[^@]+@\{(\d+)\}/, force: true)
1035
+ if values
1036
+ op.merge(out.reverse)
1037
+ else
1038
+ op << out
1039
+ end
1025
1040
  elsif !op.empty?
1026
- op << shell_escape(op.pop)
1041
+ op << op.pop
1042
+ elsif flag == :branch
1043
+ raise_error 'no branch name'
1027
1044
  end
1028
1045
  op.clear
1029
1046
  when :clear
1030
- if confirm("Remove #{sub_style('all', styles: theme[:active])} stash entries? [y/N] ", 'N')
1031
- source(stdout: true)
1032
- end
1047
+ source(stdout: true) if confirm("Remove #{sub_style('all', styles: theme[:active])} stash entries?", 'N')
1033
1048
  return
1034
1049
  when :list
1035
1050
  op.clear
@@ -1085,8 +1100,8 @@ module Squared
1085
1100
  def revbuild(flag = nil, opts = [], sync: nil, **kwargs)
1086
1101
  statusargs = lambda do
1087
1102
  {
1088
- include: relativepath(as_a(kwargs[:include]), all: true),
1089
- exclude: relativepath(as_a(kwargs[:exclude]), all: true)
1103
+ include: relativepath(Array(kwargs[:include]), all: true),
1104
+ exclude: relativepath(Array(kwargs[:exclude]), all: true)
1090
1105
  }
1091
1106
  end
1092
1107
  unless workspace.closed
@@ -1195,13 +1210,14 @@ module Squared
1195
1210
  else
1196
1211
  op = OptionPartition.new(opts, OPT_GIT[:checkout], cmd, project: self, no: OPT_GIT[:no][:checkout],
1197
1212
  first: flag == :path ? matchpathspec : nil)
1198
- if flag == :commit
1199
- op.append(commit)
1200
- .clear(pass: false)
1201
- else
1213
+ if flag == :path
1202
1214
  append_head
1203
1215
  append_pathspec(op.extras, pass: false)
1216
+ print_success if success?(source)
1217
+ return
1204
1218
  end
1219
+ op.append(commit)
1220
+ .clear(pass: false)
1205
1221
  end
1206
1222
  source
1207
1223
  end
@@ -1241,9 +1257,9 @@ module Squared
1241
1257
 
1242
1258
  def log!(flag, opts = [], range: [], index: [])
1243
1259
  cmd, opts = git_session('log', opts: opts)
1244
- op = OptionPartition.new(opts, collect_hash(OPT_GIT[:log]), cmd,
1245
- project: self, no: collect_hash(OPT_GIT[:no][:log]),
1246
- first: matchpathspec)
1260
+ op = OptionPartition.new(opts, collect_hash(OPT_GIT[:log]), cmd, project: self,
1261
+ no: collect_hash(OPT_GIT[:no][:log]),
1262
+ first: matchpathspec)
1247
1263
  case flag
1248
1264
  when :between, :contain
1249
1265
  op << shell_quote(range.join(flag == :between ? '..' : '...'))
@@ -1630,19 +1646,20 @@ module Squared
1630
1646
  red = color(:red)
1631
1647
  grep.map! { |val| Regexp.new(val[1..-2]) }
1632
1648
  files = status_data.map! do |a, b|
1633
- next unless grep.empty? || grep.any? { |pat| pat.match?(a) }
1649
+ next if b.strip.empty? || (!grep.empty? && grep.none? { |pat| pat.match?(a) })
1634
1650
 
1635
1651
  "#{sub_style(b, styles: red)} #{a}"
1636
1652
  end
1637
1653
  .compact
1638
1654
  unless files.empty?
1639
1655
  files = choice_index('Select files', files, multiple: true, force: true, trim: /^\S+\s/,
1640
- accept: 'Add?')
1656
+ accept: [['Add?', false, true]])
1641
1657
  end
1642
1658
  op.swap(list + files)
1643
1659
  end
1644
1660
  end
1645
- append_pathspec op.extras
1661
+ return source(git_session('status', '-s'), banner: false) unless append_pathspec(op.extras)
1662
+
1646
1663
  verbose = flag == :add && !op.arg?('verbose')
1647
1664
  print_success if success?(source) && verbose
1648
1665
  return
@@ -1671,30 +1688,36 @@ module Squared
1671
1688
  private
1672
1689
 
1673
1690
  def source(cmd = @session, exception: true, io: false, sync: true, stdout: false, stderr: false, banner: true,
1674
- multiple: false, **kwargs)
1691
+ multiple: false, from: nil, **kwargs)
1675
1692
  cmd = cmd.target if cmd.is_a?(OptionPartition)
1676
- banner = nil if banner && (multiple || !banner?)
1677
- if cmd.respond_to?(:done)
1678
- if io && banner == false
1679
- from = nil
1680
- elsif !from && (from = cmd.drop(1).find { |val| val.match?(/\A[a-z]{1,2}[a-z\-]*\z/) })
1681
- from = :"git:#{from}"
1693
+ if io && banner == false
1694
+ from = nil
1695
+ banner = nil
1696
+ else
1697
+ banner = nil if banner && (multiple || !banner?)
1698
+ if cmd.respond_to?(:done)
1699
+ if from.nil? && (from = cmd.drop(1).find { |val| val.match?(/\A[a-z]{1,2}[a-z\-]*\z/) })
1700
+ from = :"git:#{from}"
1701
+ end
1702
+ banner &&= cmd.temp { |val| val.start_with?('--work-tree') || val.start_with?('--git-dir') }
1682
1703
  end
1683
- banner &&= cmd.temp { |val| val.start_with?('--work-tree') || val.start_with?('--git-dir') }
1704
+ from = nil if from == false
1684
1705
  end
1685
1706
  cmd = session_done cmd
1686
1707
  log&.info cmd
1687
- on :first, from
1688
1708
  banner = if banner
1689
1709
  format_banner((banner.is_a?(String) ? banner : cmd).gsub(File.join(path, ''), ''), banner: true)
1690
1710
  end
1711
+ on :first, from
1691
1712
  begin
1692
1713
  if io
1693
- return `#{cmd}` if stdout
1694
-
1695
- return banner ? [IO.popen(cmd), banner, from] : IO.popen(cmd)
1696
- end
1697
- if stdin? ? sync : stdout
1714
+ ret = if stdout
1715
+ `#{cmd}`
1716
+ else
1717
+ banner ? [IO.popen(cmd), banner, from] : IO.popen(cmd)
1718
+ end
1719
+ return ret
1720
+ elsif stdin? ? sync : stdout
1698
1721
  print_item banner unless multiple
1699
1722
  ret = `#{cmd}`
1700
1723
  if !ret.empty?
@@ -1702,7 +1725,7 @@ module Squared
1702
1725
  elsif success?(!banner.nil?)
1703
1726
  print_success
1704
1727
  end
1705
- elsif sync || (!exception && !stderr)
1728
+ elsif !kwargs[:sub] && (sync || (!exception && !stderr))
1706
1729
  print_item banner unless multiple
1707
1730
  ret = shell(cmd, exception: exception)
1708
1731
  else
@@ -1723,7 +1746,7 @@ module Squared
1723
1746
  end
1724
1747
  rescue StandardError => e
1725
1748
  log&.error e
1726
- ret = on(:error, from, e)
1749
+ ret = on :error, from, e
1727
1750
  raise if exception && ret != true
1728
1751
 
1729
1752
  warn log_message(Logger::WARN, e, pass: true) if warning?
@@ -1895,13 +1918,17 @@ module Squared
1895
1918
  def append_pathspec(files = [], target: @session, expect: false, parent: false, pass: true)
1896
1919
  if session_arg?('pathspec-from-file', target: target)
1897
1920
  option_clear files
1921
+ true
1898
1922
  else
1899
1923
  option('pathspec', target: target) { |val| files = split_escape val } if files.empty?
1900
1924
  files = projectmap(files, parent: parent, pass: pass)
1901
1925
  if !files.empty?
1902
1926
  target << '--' << files.join(' ')
1927
+ true
1903
1928
  elsif expect
1904
1929
  raise_error(parent ? 'pathspec not present' : 'pathspec not within worktree')
1930
+ else
1931
+ false
1905
1932
  end
1906
1933
  end
1907
1934
  end
@@ -1944,8 +1971,10 @@ module Squared
1944
1971
  end
1945
1972
 
1946
1973
  def foreachref(path, *args, format: nil)
1947
- path = as_a(path).map! { |val| "refs/#{val}" }
1948
- git_spawn('for-each-ref', format && quote_option('format', format), *args, *path, stdout: false)
1974
+ path = Array(path).map! { |val| "refs/#{val}" }
1975
+ format &&= quote_option('format', format)
1976
+ ret = git_spawn('for-each-ref', format, *args, *path, stdout: workspace.windows?)
1977
+ ret.is_a?(String) ? ret.lines : ret
1949
1978
  end
1950
1979
 
1951
1980
  def git_session(*cmd, opts: nil, worktree: true, **kwargs)
@@ -1983,8 +2012,8 @@ module Squared
1983
2012
 
1984
2013
  def repotrack(origin, branch, quote: true)
1985
2014
  i = origin.index('/')
1986
- branch = "#{branch}:#{origin[i + 1..-1]}" unless origin.end_with?("/#{branch}")
1987
- [origin[0..i - 1], branch].tap { |ret| ret.map! { |val| shell_quote(val) } if quote }
2015
+ branch = "#{branch}:#{origin[(i + 1)..-1]}" unless origin.end_with?("/#{branch}")
2016
+ [origin[0..(i - 1)], branch].tap { |ret| ret.map! { |val| shell_quote(val) } if quote }
1988
2017
  end
1989
2018
 
1990
2019
  def commithash(val)
@@ -135,7 +135,7 @@ module Squared
135
135
  end
136
136
  case save
137
137
  when 'prod', 'dev', 'optional', 'peer'
138
- packages = args.to_a.drop(1)
138
+ packages = args.extras
139
139
  else
140
140
  save = 'prod'
141
141
  packages = args.to_a
@@ -146,10 +146,10 @@ module Squared
146
146
  when 'run'
147
147
  next if (list = read_scripts).empty?
148
148
 
149
- format_desc action, nil, 'script,opts*|^index+|#,pattern*'
149
+ format_desc action, nil, "script,opts*|#{indexchar}index+|#,pattern*"
150
150
  task action, [:script] do |_, args|
151
151
  if args.script == '#'
152
- format_list(list, 'run[^N]', 'scripts', grep: args.extras, from: dependfile.to_s)
152
+ format_list(list, "run[#{indexchar}N]", 'scripts', grep: args.extras, from: dependfile)
153
153
  else
154
154
  args = param_guard(action, 'script', args: args.to_a)
155
155
  opts = []
@@ -186,7 +186,7 @@ module Squared
186
186
  format_desc action, nil, 'pkg/cmd,opts*,args*'
187
187
  task action, [:package] do |_, args|
188
188
  if (package = args.package)
189
- args = args.to_a.drop(1)
189
+ args = args.extras
190
190
  if pnpm?
191
191
  pre = ->(ch) { "-#{ch}" if (ch = args.delete(ch)) }
192
192
  cmd = session 'pnpm', pre.call('r'), pre.call('c'), 'exec'
@@ -217,7 +217,7 @@ module Squared
217
217
  format_desc action, nil, 'version,args*'
218
218
  task action, [:version] do |_, args|
219
219
  version = param_guard(action, 'version', args: args, key: :version)
220
- args = args.to_a.drop(1)
220
+ args = args.extras
221
221
  args << readline('Enter command', force: true) if args.empty?
222
222
  args.prepend(File.join(ENV['NVM_DIR'], 'nvm-exec'))
223
223
  run(args.join(' '), { 'NODE_VERSION' => version }, banner: false, from: :nvm)
@@ -238,7 +238,7 @@ module Squared
238
238
  outdated flag, args.to_a
239
239
  end
240
240
  when 'package'
241
- format_desc(action, flag, 'opts*', after: flag == :dedupe ? nil : 'names*')
241
+ format_desc(action, flag, 'opts*', after: flag == :dedupe ? nil : 'name*')
242
242
  task flag do |_, args|
243
243
  package flag, args.to_a
244
244
  end
@@ -348,7 +348,7 @@ module Squared
348
348
  next unless from && dest&.directory?
349
349
 
350
350
  from = path + from
351
- glob = as_a(glob || '**/*')
351
+ glob = Array(glob || '**/*')
352
352
  target = []
353
353
  if workspace
354
354
  from.glob('*').each do |entry|
@@ -381,7 +381,7 @@ module Squared
381
381
  copy_dir(src, to, glob, create: create, link: link, force: force, pass: pass, verbose: verbose)
382
382
  rescue StandardError => e
383
383
  log.error e
384
- ret = on(:error, :copy, e)
384
+ ret = on :error, :copy, e
385
385
  raise if exception && ret != true
386
386
  end
387
387
  end
@@ -457,10 +457,10 @@ module Squared
457
457
  rescue StandardError => e
458
458
  log.error e
459
459
  unless dryrun
460
- ret = on(:error, :outdated, e)
460
+ ret = on :error, :outdated, e
461
461
  raise if exception && ret != true
462
462
  end
463
- warn log_message(Logger::WARN, e, pass: true) if warning?
463
+ warn log_message(Logger::WARN, e) if warning?
464
464
  return
465
465
  else
466
466
  dep1 = json['dependencies'] || {}
@@ -608,49 +608,42 @@ module Squared
608
608
  end
609
609
 
610
610
  def update(*)
611
- package 'update'
611
+ package('update', from: :update)
612
612
  end
613
613
 
614
614
  def publish(flag = nil, *, sync: invoked_sync?('publish', flag), otp: nil, tag: nil, dryrun: nil, access: nil)
615
- if read_packagemanager(:private)
616
- if warning?
617
- warn log_message(Logger::WARN, 'invalid task "publish"', subject: name, hint: 'private', pass: true)
618
- end
615
+ if !version || read_packagemanager(:private)
616
+ warn log_message(Logger::WARN, 'invalid task "publish"', subject: name, hint: version ? 'private' : nil)
619
617
  return
620
618
  end
621
- return unless version
622
-
623
619
  cmd = session 'npm', 'publish'
624
- dryrun = dryrun?('npm') if dryrun.nil?
625
620
  cmd << basic_option('otp', otp) if otp ||= option('otp')
626
621
  cmd << basic_option('tag', tag) if tag ||= option('tag')
627
622
  cmd << basic_option('access', access) if access ||= option('access')
628
- if verbose
629
- if dryrun
630
- cmd << '--dry-run'
631
- else
632
- log.info cmd.to_s
633
- end
634
- unless sync
635
- on :first, :publish unless dryrun
636
- pwd_set(from: :publish) do
637
- require 'open3'
638
- banner = format_banner cmd.to_s
639
- Open3.popen2e(cmd.done) do |_, out|
640
- write_lines(out, sub: npmnotice + [pat: /^(.+)(Tarball .+)$/, styles: color(:blue), index: 2],
641
- banner: banner)
642
- end
623
+ dryrun = dryrun?('npm') if dryrun.nil?
624
+ if dryrun
625
+ cmd << '--dry-run'
626
+ else
627
+ from = :publish
628
+ log.info cmd.to_s
629
+ end
630
+ if sync
631
+ run(from: from, sync: sync, interactive: !dryrun && "Publish #{sub_style(project, styles: theme[:active])}")
632
+ else
633
+ on :first, from
634
+ pwd_set(from: from) do
635
+ require 'open3'
636
+ banner = format_banner cmd.to_s
637
+ Open3.popen2e(cmd.done) do |_, out|
638
+ write_lines(out, sub: npmnotice + [pat: /^(.+)(Tarball .+)$/, styles: color(:blue), index: 2],
639
+ banner: banner)
643
640
  end
644
- on :last, :publish unless dryrun
645
- return
646
641
  end
647
- elsif dryrun
648
- return
642
+ on :last, from
649
643
  end
650
- run(from: :publish, sync: sync)
651
644
  end
652
645
 
653
- def package(flag, opts = [])
646
+ def package(flag, opts = [], from: nil)
654
647
  workspace.rev_clear(name)
655
648
  if (yarn = dependtype(:yarn)) > 0
656
649
  cmd = session 'yarn', if flag == :update
@@ -676,6 +669,7 @@ module Squared
676
669
  list = OPT_NPM[:install_base] + OPT_NPM.fetch(flag, []) + OPT_NPM[:common]
677
670
  list.concat(OPT_NPM[:install_as]) unless flag == :dedupe
678
671
  no = OPT_NPM[:install_no]
672
+ cmd << '--save=true' if option('save')
679
673
  end
680
674
  op = OptionPartition.new(opts, list, cmd, no: no, project: self)
681
675
  op.each do |opt|
@@ -700,7 +694,7 @@ module Squared
700
694
  end
701
695
  op.clear(errors: true)
702
696
  end
703
- run(from: :"package:#{flag}")
697
+ run(from: from || :"package:#{flag}")
704
698
  end
705
699
 
706
700
  def bump(flag, val = nil)
@@ -753,7 +747,7 @@ module Squared
753
747
  end
754
748
  rescue StandardError => e
755
749
  log.debug e
756
- ret = on(:error, :bump, e)
750
+ ret = on :error, :bump, e
757
751
  raise if exception && ret != true
758
752
  end
759
753
  end
@@ -917,9 +911,11 @@ module Squared
917
911
  @pm[:_] = false
918
912
  nil
919
913
  else
920
- return @pm[key] if key
921
-
922
- !(ret = @pm[:_]) || (version && ret[ret.index('@') + 1..-1] < version) ? nil : ret
914
+ if key
915
+ @pm[key]
916
+ elsif (ret = @pm[:_]) && !(version && ret[(ret.index('@') + 1)..-1] < version)
917
+ ret
918
+ end
923
919
  end
924
920
 
925
921
  def read_install