squared 0.4.2 → 0.4.4

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.
@@ -145,16 +145,14 @@ module Squared
145
145
 
146
146
  module Project
147
147
  class Git < Base
148
- include Prompt
149
-
150
148
  OPT_GIT = {
151
- common: %w[bare p|paginate P|no-pager glob-pathspecs icase-pathspecs literal-pathspecs no-optional-locks
149
+ common: %w[bare paginate no-pager glob-pathspecs icase-pathspecs literal-pathspecs no-optional-locks
152
150
  no-replace-objects noglob-pathspecs c=q config-env=q exec-path=p namespace=p].freeze,
153
151
  branch: %w[a|all create-reflog i|ignore-case q|quiet r|remotes v|verbose abbrev=i color=b column=b
154
152
  contains=b format=q merged=b no-contains=b no-merged=b points-at=e u|set-upstream-to=e sort=q
155
153
  t|track=b].freeze,
156
154
  checkout: %w[l d|detach f|force ignore-other-worktrees ignore-skip-worktree-bits m|merge p|patch
157
- pathspec-file-nul q quiet orphan=e ours theirs conflict=b pathspec-from-file=p
155
+ pathspec-file-nul q|quiet orphan=e ours theirs conflict=b pathspec-from-file=p
158
156
  t|track=b].freeze,
159
157
  clean: %w[d x X f|force i|interactive n|dry-run q|quiet e|exlcude=q].freeze,
160
158
  diff: {
@@ -309,25 +307,26 @@ module Squared
309
307
  end
310
308
  end
311
309
 
312
- @@tasks[ref] = {
310
+ subtasks({
313
311
  'branch' => %i[create set delete move copy list edit current].freeze,
314
312
  'checkout' => %i[commit branch track detach path].freeze,
315
313
  'commit' => %i[add all amend amend-orig].freeze,
316
314
  'diff' => %i[head branch files view between contain].freeze,
317
315
  'fetch' => %i[origin remote].freeze,
318
316
  'files' => %i[cached modified deleted others ignored].freeze,
319
- 'git' => %i[clean mv restore revert rm].freeze,
317
+ 'git' => %i[clean mv revert rm].freeze,
320
318
  'log' => %i[view between contain].freeze,
321
319
  'merge' => %i[commit no-commit send].freeze,
322
320
  'pull' => %i[origin remote].freeze,
323
321
  'rebase' => %i[branch onto send].freeze,
324
322
  'refs' => %i[heads tags remote].freeze,
325
323
  'reset' => %i[commit index patch mode].freeze,
324
+ 'restore' => %i[staged worktree].freeze,
326
325
  'rev' => %i[commit branch output parseopt build].freeze,
327
326
  'show' => %i[format oneline textconv].freeze,
328
327
  'stash' => %i[push pop apply drop clear list].freeze,
329
328
  'tag' => %i[add delete list].freeze
330
- }.freeze
329
+ })
331
330
 
332
331
  def initialize(*, **)
333
332
  super
@@ -654,7 +653,7 @@ module Squared
654
653
  format_desc action, flag, 'remote,opts*,pattern*'
655
654
  task flag, [:remote] do |_, args|
656
655
  remote = param_guard(action, flag, args: args, key: :remote)
657
- ls_remote(flag, args.to_a.drop(1), remote: remote)
656
+ ls_remote(flag, args.extras, remote: remote)
658
657
  end
659
658
  else
660
659
  format_desc action, flag, 'opts*,pattern*'
@@ -662,7 +661,7 @@ module Squared
662
661
  __send__(action == 'refs' ? :ls_remote : :ls_files, flag, args.to_a)
663
662
  end
664
663
  end
665
- when 'git'
664
+ when 'restore', 'git'
666
665
  format_desc(action, flag, 'opts*', before: case flag
667
666
  when :rm
668
667
  'source+,destination'
@@ -672,7 +671,7 @@ module Squared
672
671
  'pathspec*'
673
672
  end)
674
673
  task flag do |_, args|
675
- git(flag, args.to_a)
674
+ __send__(action, flag, args.to_a)
676
675
  end
677
676
  end
678
677
  end
@@ -698,7 +697,9 @@ module Squared
698
697
 
699
698
  def pull(flag = nil, opts = [], sync: invoked_sync?('pull', flag), remote: nil)
700
699
  cmd, opts = git_session('pull', flag && "--#{flag}", opts: opts)
701
- if (val = option('rebase', ignore: false))
700
+ if flag == :rebase
701
+ cmd << '--autostash' if option('autostash')
702
+ elsif (val = option('rebase', ignore: false))
702
703
  cmd << case val
703
704
  when '0'
704
705
  '--no-rebase'
@@ -731,7 +732,7 @@ module Squared
731
732
  append_value(branch, delim: true)
732
733
  else
733
734
  append_value([branch.pop, branch.pop].reverse, delim: true)
734
- option_clear branch
735
+ option_clear(branch, pass: false)
735
736
  end
736
737
  when :onto
737
738
  return unless upstream
@@ -857,7 +858,7 @@ module Squared
857
858
  end
858
859
  return
859
860
  end
860
- sha = source(git_output('rev-parse --verify HEAD'), io: true, banner: false, stdout: true).first.to_s.chomp
861
+ sha = git_spawn('rev-parse --verify HEAD').first.to_s.chomp
861
862
  return if sha.empty?
862
863
 
863
864
  args = []
@@ -865,7 +866,7 @@ module Squared
865
866
  case flag
866
867
  when :build
867
868
  opts = option_sanitize(opts, OPT_GIT[:status], target: args).first
868
- option_clear opts
869
+ option_clear(opts, append: true)
869
870
  else
870
871
  args << basic_option('untracked-files', flag) if (flag = option('untracked-files', prefix: 'git'))
871
872
  args << basic_option('ignore-submodules', flag) if (flag = option('ignore-submodules', prefix: 'git'))
@@ -900,13 +901,13 @@ module Squared
900
901
  cmd, opts = git_session('reset', opts: opts)
901
902
  case flag
902
903
  when :commit, :index
903
- out = option_sanitize(opts, OPT_GIT[:reset] + VAL_GIT[:reset], no: OPT_GIT[:no][:reset]).first
904
+ files = option_sanitize(opts, OPT_GIT[:reset] + VAL_GIT[:reset], no: OPT_GIT[:no][:reset]).first
904
905
  if flag == :commit
905
906
  append_value(commit, delim: true)
906
- option_clear out
907
+ option_clear(files, pass: false)
907
908
  ref = false
908
909
  else
909
- (refs ||= []).concat(out)
910
+ (refs ||= []).concat(files)
910
911
  end
911
912
  when :mode
912
913
  return unless VAL_GIT[:reset].include?(mode)
@@ -923,7 +924,7 @@ module Squared
923
924
  end
924
925
  unless ref == false
925
926
  append_commit(ref, head: true)
926
- append_pathspec refs if refs
927
+ append_pathspec(refs, pass: false) if refs
927
928
  end
928
929
  source
929
930
  end
@@ -935,12 +936,7 @@ module Squared
935
936
  when :branch
936
937
  cmd << '--detach' if detach == 'd' || option('detach')
937
938
  append_option('track', equals: true)
938
- cmd << if create
939
- shell_option(create, branch)
940
- else
941
- branch
942
- end
943
- cmd << commit
939
+ cmd << (create ? shell_option(create, branch) : branch) << commit
944
940
  when :track
945
941
  if branch
946
942
  if branch.start_with?('^')
@@ -953,13 +949,13 @@ module Squared
953
949
  when :detach
954
950
  cmd << '--detach' << commit
955
951
  else
956
- out = option_sanitize(opts, OPT_GIT[:checkout], no: OPT_GIT[:no][:checkout]).first
952
+ refs = option_sanitize(opts, OPT_GIT[:checkout], no: OPT_GIT[:no][:checkout]).first
957
953
  if flag == :commit
958
954
  append_value(commit, delim: true)
959
- option_clear out
955
+ option_clear(refs, pass: false)
960
956
  else
961
957
  append_head
962
- append_pathspec out
958
+ append_pathspec refs
963
959
  end
964
960
  end
965
961
  source
@@ -1042,7 +1038,7 @@ module Squared
1042
1038
  else
1043
1039
  cmd.merge(index)
1044
1040
  end
1045
- elsif (n = option('index'))
1041
+ elsif (n = option('index', ignore: false))
1046
1042
  cmd << "HEAD~#{n}"
1047
1043
  end
1048
1044
  end
@@ -1069,8 +1065,8 @@ module Squared
1069
1065
  origin = nil
1070
1066
  branch = nil
1071
1067
  upstream = nil
1072
- source(git_output('fetch --no-tags --quiet'), io: true, banner: false)
1073
- source(git_output('branch -vv --list'), io: true, banner: false).first.each do |val|
1068
+ git_spawn 'fetch --no-tags --quiet'
1069
+ git_spawn('branch -vv --list', stdout: false).first.each do |val|
1074
1070
  next unless (r = /^\*\s(\S+)\s+(\h+)(?:\s\[(.+?)(?=\]\s)\])?\s/.match(val))
1075
1071
 
1076
1072
  branch = r[1]
@@ -1078,7 +1074,7 @@ module Squared
1078
1074
  origin = r[3][%r{^(.+)/#{Regexp.escape(branch)}$}, 1]
1079
1075
  else
1080
1076
  unless (origin = option('repository', prefix: 'git', ignore: false))
1081
- out = source(git_output('log -n1 --format=%h%d'), io: true, banner: false, stdout: true).first
1077
+ out = git_spawn('log -n1 --format=%h%d').first
1082
1078
  if out =~ /^#{r[2]} \(HEAD -> #{Regexp.escape(branch)}, (.+?)\)$/
1083
1079
  split_escape($1).each do |s|
1084
1080
  next unless s.end_with?("/#{branch}")
@@ -1101,7 +1097,7 @@ module Squared
1101
1097
  end
1102
1098
  if message
1103
1099
  append_message message
1104
- elsif flag == :'amend-orig' || option('no-edit')
1100
+ elsif flag == :'amend-orig' || option('edit', equals: '0')
1105
1101
  cmd << '--no-edit'
1106
1102
  end
1107
1103
  a = git_output 'add', '--verbose'
@@ -1111,7 +1107,7 @@ module Squared
1111
1107
  b << '--dry-run'
1112
1108
  end
1113
1109
  a << pathspec
1114
- b << '--force' if amend
1110
+ b << '--force-with-lease' if amend
1115
1111
  b << origin << branch
1116
1112
  puts if pass
1117
1113
  source a
@@ -1184,16 +1180,9 @@ module Squared
1184
1180
  when :current
1185
1181
  cmd << '--show-current'
1186
1182
  when :list
1187
- grep = []
1188
- option_sanitize(opts, OPT_GIT[:branch], no: OPT_GIT[:no][:branch]).first.each do |opt|
1189
- if opt =~ /^(v+)$/
1190
- cmd << "-#{$1}"
1191
- else
1192
- grep << opt
1193
- end
1194
- end
1183
+ opts = option_sanitize(opts, OPT_GIT[:branch], no: OPT_GIT[:no][:branch], single: /^v+$/).first
1195
1184
  cmd << '--list'
1196
- grep.each { |val| cmd << shell_quote(val) }
1185
+ opts.each { |val| cmd << shell_quote(val) }
1197
1186
  out, banner, from = source(io: true)
1198
1187
  print_item banner
1199
1188
  ret = write_lines(out, sub: [
@@ -1203,10 +1192,11 @@ module Squared
1203
1192
  list_result(ret, 'branches', from: from)
1204
1193
  return
1205
1194
  else
1206
- head = source(git_output('rev-parse --abbrev-ref HEAD'), io: true, banner: false, stdout: true).first.chomp
1195
+ head = git_spawn('rev-parse --abbrev-ref HEAD').first.chomp
1207
1196
  if head.empty?
1208
1197
  ret = 0
1209
1198
  else
1199
+ git_spawn 'fetch --all --prune --quiet' if option('sync')
1210
1200
  out, banner, from = source(cmd << '-vv --no-abbrev --list', io: true)
1211
1201
  ret = write_lines(out, grep: /^\*\s+#{Regexp.escape(head)}\s/, banner: banner, first: true) do |line|
1212
1202
  next line if stdin?
@@ -1215,7 +1205,16 @@ module Squared
1215
1205
  a = sub_style(data[0], styles: theme[:inline])
1216
1206
  b = sub_style(data[1], styles: theme[:extra])
1217
1207
  r = /\A(?:\[(.+?)(?=\]\s)\]\s)?(.+)\z/m.match(data[2..-1].join(' '))
1218
- [" Branch: #{a + (r[1] ? " (#{r[1]})" : '')}", " Commit: #{b}", "Message: #{r[2]}"].compact.join("\n")
1208
+ if (r1 = r[1]) && r1 =~ /^(.+):(?: ([a-z]+) (\d+),)? ([a-z]+) (\d+)$/
1209
+ write = ->(s1, s2) { "#{s1.capitalize.rjust(7)}: #{sub_style(s2, styles: theme[:warn])}" }
1210
+ r1 = $1
1211
+ r2 = $2 && write.($2, $3)
1212
+ r3 = write.($4, $5)
1213
+ end
1214
+ r1 = nil if r1 == "origin/#{data[0]}"
1215
+ [" Branch: #{a + (r1 ? " (#{r1})" : '')}", r2, r3, " Commit: #{b}", "Message: #{r[2]}"]
1216
+ .compact
1217
+ .join("\n")
1219
1218
  end
1220
1219
  on :last, from
1221
1220
  end
@@ -1229,6 +1228,13 @@ module Squared
1229
1228
  source(stdout: stdout)
1230
1229
  end
1231
1230
 
1231
+ def restore(flag, opts = [])
1232
+ opts = git_session('restore', "--#{flag}", opts: opts).last
1233
+ refs = option_sanitize(opts, OPT_GIT[:restore], no: OPT_GIT[:no][:restore]).first
1234
+ append_pathspec(refs, pass: false)
1235
+ source(sync: false, stderr: true)
1236
+ end
1237
+
1232
1238
  def show(flag, opts = [], format: nil, files: [])
1233
1239
  cmd, opts = git_session('show', opts: opts)
1234
1240
  case flag
@@ -1310,23 +1316,17 @@ module Squared
1310
1316
  def git(flag, opts = [])
1311
1317
  cmd, opts = git_session(flag, opts: opts)
1312
1318
  refs = option_sanitize(opts, OPT_GIT[flag], no: OPT_GIT[:no][flag]).first
1313
- refs = projectmap(refs) unless flag == :revert
1314
1319
  sync = false
1315
1320
  stderr = true
1316
1321
  case flag
1317
1322
  when :clean
1323
+ refs = projectmap(refs)
1318
1324
  unless refs.empty?
1319
1325
  cmd << '--'
1320
1326
  cmd.merge(refs)
1321
1327
  end
1322
1328
  sync = true
1323
1329
  stderr = false
1324
- when :restore
1325
- if session_arg?('p', 'patch')
1326
- option_clear refs
1327
- else
1328
- append_pathspec(refs, expect: true)
1329
- end
1330
1330
  when :revert
1331
1331
  if VAL_GIT[:rebase][:send].any? { |val| session_arg?(val) }
1332
1332
  option_clear refs
@@ -1336,6 +1336,7 @@ module Squared
1336
1336
  append_commit(*refs)
1337
1337
  end
1338
1338
  when :mv
1339
+ refs = projectmap(refs)
1339
1340
  raise_error 'no source/destination' unless refs.size > 1
1340
1341
  cmd.merge(refs)
1341
1342
  when :rm
@@ -1452,7 +1453,7 @@ module Squared
1452
1453
  if size > 0
1453
1454
  styles = theme.fetch(:banner, []).reject { |s| s.to_s.end_with?('!') }
1454
1455
  styles << :bold if styles.size <= 1
1455
- puts print_footer("#{size} #{size == 1 ? type.sub(/e?s\z/, '') : type}",
1456
+ puts print_footer("#{size} #{size == 1 ? type.sub(/(?:(?<!l)e)?s\z/, '') : type}",
1456
1457
  sub: { pat: /\A(\d+)(.+)\z/, styles: styles })
1457
1458
  else
1458
1459
  puts empty_status("No #{type} were #{action}", 'grep', grep.is_a?(Array) ? case grep.size
@@ -1470,17 +1471,22 @@ module Squared
1470
1471
  glob = kwargs.fetch(:include, [])
1471
1472
  pass = kwargs.fetch(:exclude, [])
1472
1473
  ret = {}
1473
- out = source(git_output('status -s --porcelain', *args), io: true, banner: false).first
1474
- out.each do |line|
1475
- next unless (file = line[/^[A-Z ?!]{3}"?(.+?)"?$/, 1])
1476
- next if !glob.empty? && glob.none? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
1477
- next if !pass.empty? && pass.any? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
1478
-
1479
- ret[file] = algorithm.hexdigest(File.read(basepath(file)))
1480
- end
1474
+ git_spawn('status -s --porcelain', *args, stdout: false)
1475
+ .first
1476
+ .each do |line|
1477
+ next unless (file = line[/^[A-Z ?!]{3}"?(.+?)"?$/, 1])
1478
+ next if !glob.empty? && glob.none? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
1479
+ next if !pass.empty? && pass.any? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
1480
+
1481
+ ret[file] = algorithm.hexdigest(File.read(basepath(file)))
1482
+ end
1481
1483
  ret
1482
1484
  end
1483
1485
 
1486
+ def git_spawn(*cmd, stdout: true)
1487
+ source(git_output(*cmd), io: true, banner: false, stdout: stdout)
1488
+ end
1489
+
1484
1490
  def append_pull(opts, list, target: @session, no: nil, flag: nil, remote: nil)
1485
1491
  cmd << '--force' if option('force')
1486
1492
  rsm = append_submodules(target: target)
@@ -1529,14 +1535,14 @@ module Squared
1529
1535
  end
1530
1536
  end
1531
1537
 
1532
- def append_pathspec(files = [], target: @session, expect: false, parent: false)
1538
+ def append_pathspec(files = [], target: @session, expect: false, parent: false, pass: true)
1533
1539
  if session_arg?('pathspec-from-file')
1534
1540
  option_clear files
1535
1541
  else
1536
1542
  if files.empty? && (val = option('pathspec'))
1537
1543
  files = split_escape(val)
1538
1544
  end
1539
- files = projectmap(files, parent: parent)
1545
+ files = projectmap(files, parent: parent, pass: pass)
1540
1546
  if !files.empty?
1541
1547
  target << '--' << files.join(' ')
1542
1548
  elsif expect
@@ -1577,11 +1583,11 @@ module Squared
1577
1583
 
1578
1584
  def git_session(*cmd, opts: nil, worktree: true, **kwargs)
1579
1585
  dir = worktree ? ["--work-tree=#{shell_quote(path)}", "--git-dir=#{shell_quote(gitpath)}"] : []
1580
- ret = session('git', *dir, **kwargs)
1581
- return ret.merge(cmd) unless opts
1586
+ return session('git', *dir, *cmd, **kwargs) unless opts
1582
1587
 
1583
- opts = option_sanitize(opts, OPT_GIT[:common]).first
1584
- [ret.merge(cmd), opts]
1588
+ opts = option_sanitize(opts, OPT_GIT[:common], target: dir).first
1589
+ ret = session('git', *dir, *cmd, **kwargs)
1590
+ [ret, opts]
1585
1591
  end
1586
1592
 
1587
1593
  def git_output(*cmd, **kwargs)
@@ -79,7 +79,7 @@ module Squared
79
79
  end
80
80
  end
81
81
 
82
- @@tasks[ref] = {
82
+ subtasks({
83
83
  'package' => %i[install dedupe update].freeze,
84
84
  'outdated' => %i[major minor patch].freeze,
85
85
  'bump' => %i[version major minor patch].freeze,
@@ -87,7 +87,7 @@ module Squared
87
87
  'add' => nil,
88
88
  'run' => nil,
89
89
  'pack' => nil
90
- }.freeze
90
+ })
91
91
 
92
92
  def initialize(*, **kwargs)
93
93
  super
@@ -145,8 +145,7 @@ module Squared
145
145
  else
146
146
  cmd = param_guard(action, 'command', args: args.to_a)
147
147
  cmd.each do |val|
148
- if (data = indexitem(val))
149
- n, opts = data
148
+ if (n, opts = indexitem(val))
150
149
  if (item = list[n - 1])
151
150
  val = opts ? "#{item.first} #{opts}" : item.first
152
151
  elsif exception
@@ -593,42 +592,41 @@ module Squared
593
592
  end).first
594
593
  append_loglevel
595
594
  option_clear out
595
+ run(from: :"package:#{flag}")
596
+ return
596
597
  elsif pnpm?
597
598
  cmd = session 'pnpm', flag
598
599
  list = OPT_PNPM[:install_base] + OPT_PNPM.fetch(flag, []) + OPT_PNPM[:common]
599
600
  list += OPT_PNPM[:install_as] unless flag == :dedupe
600
- out = option_sanitize(opts, list, no: OPT_PNPM[:"#{flag}_no"]).first
601
- append_nocolor
602
- append_loglevel
603
- option_clear out
601
+ opts = option_sanitize(opts, list, no: OPT_PNPM[:"#{flag}_no"]).first
604
602
  else
605
603
  cmd = session 'npm', flag
606
604
  list = OPT_NPM[:install_base] + OPT_NPM.fetch(flag, []) + OPT_NPM[:common]
607
605
  list += OPT_NPM[:install_as] unless flag == :dedupe
608
606
  opts, pat = option_sanitize(opts, list, no: OPT_NPM[:install_no])
609
- out = []
610
- err = []
611
- opts.each do |opt|
612
- if opt =~ pat
613
- case $1
614
- when 'w', 'workspace'
615
- cmd << (%r{[\\/]}.match?($2) ? quote_option($1, basepath($2)) : shell_option($1, $2))
616
- end
617
- elsif opt.include?('=')
618
- err << opt
619
- else
620
- out << opt
607
+ end
608
+ out = []
609
+ err = []
610
+ opts.each do |opt|
611
+ if pat && opt =~ pat
612
+ case $1
613
+ when 'w', 'workspace'
614
+ cmd << (%r{[\\/]}.match?($2) ? quote_option($1, basepath($2)) : shell_option($1, $2))
621
615
  end
622
- end
623
- append_nocolor
624
- append_loglevel
625
- if flag == :dedupe
626
- option_clear out
616
+ elsif opt.include?('=')
617
+ err << opt
627
618
  else
628
- append_value(out, escape: true)
619
+ out << opt
629
620
  end
630
- option_clear err
631
621
  end
622
+ append_nocolor
623
+ append_loglevel
624
+ if flag == :dedupe
625
+ option_clear out
626
+ else
627
+ append_value(out, escape: true)
628
+ end
629
+ option_clear err
632
630
  run(from: :"package:#{flag}")
633
631
  end
634
632