squared 0.4.6 → 0.4.7

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,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'date'
4
- require 'time'
5
- require 'digest'
6
-
7
3
  module Squared
8
4
  module Workspace
9
5
  module Git
@@ -141,7 +137,7 @@ module Squared
141
137
  private
142
138
 
143
139
  def rev_timenow
144
- DateTime.now.strftime('%Q').to_i + time_offset
140
+ Time.now.utc.strftime('%s%L').to_i
145
141
  end
146
142
  end
147
143
  Application.include Git
@@ -163,11 +159,12 @@ module Squared
163
159
  show: %w[s exit-code histogram].freeze
164
160
  }.freeze,
165
161
  fetch: {
166
- base: %w[multiple progress P|prune-tags refetch stdin u|update-head-ok recurse-submodules=b
162
+ base: %w[multiple progress P|prune-tags refetch stdin u|update-head-ok
167
163
  recurse-submodules-default=b].freeze,
168
164
  pull: %w[4 6 n t a|append atomic dry-run f|force k|keep n|negotiate-only prefetch p|prune q|quiet
169
165
  set-upstream unshallow update-shallow v|verbose deepen=i depth=i j|jobs=i negotiation-tip=q
170
- refmap=q o|server-option=q shallow-exclude=e shallow-since=b upload-pack=q].freeze
166
+ recurse-submodules=v refmap=q o|server-option=q shallow-exclude=e shallow-since=v
167
+ upload-pack=q].freeze
171
168
  }.freeze,
172
169
  log: {
173
170
  base: %w[all all-match alternate-refs author-date-order basic-regexp bisect boundary cherry cherry-mark
@@ -199,7 +196,7 @@ module Squared
199
196
  X|exclude-from=p exclude-per-directory=p format=q with-tree=q].freeze,
200
197
  ls_remote: %w[exit-code get-url q|quiet o|server-option=q symref sort=q upload-pack=q].freeze,
201
198
  mv: %w[k f|force n|dry-run v|verbose].freeze,
202
- pull: %w[e n allow-unrelated-histories ff-only S|gpg-sign=qq log=i r|rebase=b? s|strategy=b
199
+ pull: %w[e n allow-unrelated-histories ff-only S|gpg-sign=qq log=i r|rebase=v? s|strategy=b
203
200
  X|strategy-option=b].freeze,
204
201
  merge: %w[e n allow-unrelated-histories ff-only m=q q|quiet v|verbose cleanup=b F|file=p S|gpg-sign=qq
205
202
  into-name=e log=i s|strategy=b X|strategy-option=b].freeze,
@@ -328,7 +325,7 @@ module Squared
328
325
  'rev' => %i[commit branch output parseopt build].freeze,
329
326
  'show' => %i[format oneline textconv].freeze,
330
327
  'stash' => %i[push pop apply drop clear list].freeze,
331
- 'tag' => %i[add delete list].freeze
328
+ 'tag' => %i[add sign delete list].freeze
332
329
  })
333
330
 
334
331
  def initialize(*, **)
@@ -391,7 +388,7 @@ module Squared
391
388
  refs = param_guard(action, flag, args: args.to_a)
392
389
  tag(flag, refs: refs)
393
390
  end
394
- when :add
391
+ when :add, :sign
395
392
  format_desc action, flag, 'name,message?,commit?'
396
393
  task flag, [:name, :message, :commit] do |_, args|
397
394
  name = param_guard(action, flag, args: args, key: :name)
@@ -699,17 +696,18 @@ module Squared
699
696
  end
700
697
 
701
698
  def pull(flag = nil, opts = [], sync: invoked_sync?('pull', flag), remote: nil)
702
- cmd, opts = git_session('pull', flag && "--#{flag}", opts: opts)
699
+ cmd, opts = git_session('pull', opts: opts)
703
700
  if flag == :rebase
704
- cmd << '--autostash' if option('autostash')
701
+ cmd << '--rebase'
705
702
  elsif (val = option('rebase', ignore: false))
706
703
  cmd << case val
707
- when '0'
704
+ when '0', 'false'
708
705
  '--no-rebase'
709
706
  else
710
707
  VAL_GIT[:rebase][:value].include?(val) ? basic_option('rebase', val) : '--rebase'
711
708
  end
712
709
  end
710
+ cmd << '--autostash' if option('autostash')
713
711
  append_pull(opts, OPT_GIT[:pull] + OPT_GIT[:fetch][:pull],
714
712
  no: OPT_GIT[:no][:pull] + OPT_GIT[:no][:fetch][:pull], remote: remote, flag: flag)
715
713
  source(sync: sync, sub: if verbose
@@ -727,15 +725,15 @@ module Squared
727
725
  cmd, opts = git_session('rebase', opts: opts)
728
726
  case flag
729
727
  when :branch
730
- branch = option_sanitize(opts, OPT_GIT[:rebase], no: OPT_GIT[:no][:rebase]).first
731
- case branch.size
728
+ op = OptionPartition.new(opts, OPT_GIT[:rebase], cmd, project: self, no: OPT_GIT[:no][:rebase])
729
+ case op.size
732
730
  when 0
733
731
  append_head
734
732
  when 1, 2
735
- append_value(branch, delim: true)
733
+ op.append(delim: true)
736
734
  else
737
- append_value([branch.pop, branch.pop].reverse, delim: true)
738
- option_clear(branch, pass: false)
735
+ op.append(op.pop(2), delim: true)
736
+ .clear(pass: false)
739
737
  end
740
738
  when :onto
741
739
  return unless upstream
@@ -754,10 +752,10 @@ module Squared
754
752
 
755
753
  def fetch(flag = nil, opts = [], sync: invoked_sync?('fetch', flag), remote: nil)
756
754
  cmd, opts = git_session('fetch', opts: opts)
757
- append_pull(opts, collect_hash(OPT_GIT[:fetch]), no: collect_hash(OPT_GIT[:no][:fetch]),
758
- remote: remote, flag: flag)
755
+ append_pull(opts, collect_hash(OPT_GIT[:fetch]), no: collect_hash(OPT_GIT[:no][:fetch]), remote: remote,
756
+ flag: flag)
759
757
  cmd << '--all' if !remote && !session_arg?('multiple') && option('all')
760
- cmd << '--verbose' if verbose && !session_arg('quiet')
758
+ cmd << '--verbose' if verbose && !session_arg?('quiet')
761
759
  source(sync: sync, **threadargs)
762
760
  end
763
761
 
@@ -786,25 +784,25 @@ module Squared
786
784
  def stash(flag = nil, opts = [], sync: invoked_sync?('stash', flag))
787
785
  if flag
788
786
  cmd, opts = git_session('stash', flag, opts: opts)
789
- refs = option_sanitize(opts, OPT_GIT[:stash][:common] + OPT_GIT[:stash].fetch(flag, [])).first
787
+ op = OptionPartition.new(opts, OPT_GIT[:stash][:common] + OPT_GIT[:stash].fetch(flag, []), cmd,
788
+ project: self)
790
789
  case flag
791
790
  when :push
792
- append_pathspec refs
791
+ append_pathspec op.extras
793
792
  when :pop, :apply, :drop
794
- unless refs.empty?
795
- cmd << shell_escape(refs.pop)
796
- option_clear refs
793
+ unless op.empty?
794
+ op << shell_escape(op.pop)
795
+ op.clear
797
796
  end
798
797
  when :clear
799
- if confirm("Remove #{sub_style('all', styles: theme[:active])} the stash entries? [y/N] ", 'N')
798
+ if confirm("Remove #{sub_style('all', styles: theme[:active])} stash entries? [y/N] ", 'N')
800
799
  source(stdout: true)
801
800
  end
802
801
  return
803
802
  when :list
804
803
  out, banner, from = source(io: true)
805
804
  print_item banner
806
- ret = write_lines(out)
807
- list_result(ret, 'objects', from: from)
805
+ list_result(write_lines(out), 'objects', from: from)
808
806
  return
809
807
  end
810
808
  else
@@ -864,13 +862,14 @@ module Squared
864
862
  sha = git_spawn('rev-parse --verify HEAD').first.to_s.chomp
865
863
  return if sha.empty?
866
864
 
867
- args = []
868
865
  kwargs = kwargs.key?(:include) || kwargs.key?(:exclude) ? statusargs.() : @revbuild || {}
869
866
  case flag
870
867
  when :build
871
- opts = option_sanitize(opts, OPT_GIT[:status], target: args).first
872
- option_clear(opts, append: true)
868
+ op = OptionPartition.new(opts, OPT_GIT[:status], project: self)
869
+ op.clear(append: true)
870
+ args = op.to_a
873
871
  else
872
+ args = []
874
873
  args << basic_option('untracked-files', flag) if (flag = option('untracked-files', prefix: 'git'))
875
874
  args << basic_option('ignore-submodules', flag) if (flag = option('ignore-submodules', prefix: 'git'))
876
875
  args << basic_option('ignored', flag) if (flag = option('ignored', prefix: 'git'))
@@ -904,13 +903,14 @@ module Squared
904
903
  cmd, opts = git_session('reset', opts: opts)
905
904
  case flag
906
905
  when :commit, :index
907
- files = option_sanitize(opts, OPT_GIT[:reset] + VAL_GIT[:reset], no: OPT_GIT[:no][:reset]).first
906
+ op = OptionPartition.new(opts, OPT_GIT[:reset] + VAL_GIT[:reset], cmd,
907
+ project: self, no: OPT_GIT[:no][:reset])
908
908
  if flag == :commit
909
- append_value(commit, delim: true)
910
- option_clear(files, pass: false)
909
+ op.append(commit, delim: true)
910
+ .clear(pass: false)
911
911
  ref = false
912
912
  else
913
- (refs ||= []).concat(files)
913
+ (refs ||= []).concat(op.extras)
914
914
  end
915
915
  when :mode
916
916
  return unless VAL_GIT[:reset].include?(mode)
@@ -922,8 +922,6 @@ module Squared
922
922
  end
923
923
  when :patch
924
924
  cmd << '--patch'
925
- else
926
- return
927
925
  end
928
926
  unless ref == false
929
927
  append_commit(ref, head: true)
@@ -952,13 +950,13 @@ module Squared
952
950
  when :detach
953
951
  cmd << '--detach' << commit
954
952
  else
955
- refs = option_sanitize(opts, OPT_GIT[:checkout], no: OPT_GIT[:no][:checkout]).first
953
+ op = OptionPartition.new(opts, OPT_GIT[:checkout], cmd, project: self, no: OPT_GIT[:no][:checkout])
956
954
  if flag == :commit
957
- append_value(commit, delim: true)
958
- option_clear(refs, pass: false)
955
+ op.append(commit, delim: true)
956
+ .clear(pass: false)
959
957
  else
960
958
  append_head
961
- append_pathspec refs
959
+ append_pathspec op.extras
962
960
  end
963
961
  end
964
962
  source
@@ -967,12 +965,13 @@ module Squared
967
965
  def tag(flag, opts = [], refs: [], message: nil, commit: nil)
968
966
  cmd, opts = git_session('tag', opts: opts)
969
967
  case flag
970
- when :add
971
- if option('sign')
968
+ when :add, :sign
969
+ if flag == :sign || option('sign')
972
970
  cmd << '--sign'
973
971
  elsif !session_arg?('s', 'sign', 'u', 'local-user')
974
972
  cmd << '--annotate'
975
973
  end
974
+ cmd << '--force' if option('force')
976
975
  if !commit && message && (sha = commithash(message))
977
976
  commit = sha
978
977
  else
@@ -981,12 +980,11 @@ module Squared
981
980
  append_value refs
982
981
  append_head commit
983
982
  when :list
984
- cmd << '--list'
985
- grep = option_sanitize(opts, OPT_GIT[:tag], no: OPT_GIT[:no][:tag]).first
983
+ op = OptionPartition.new(opts, OPT_GIT[:tag], cmd << '--list', project: self, no: OPT_GIT[:no][:tag])
986
984
  out, banner, from = source(io: true)
987
985
  print_item banner
988
- ret = write_lines(out, grep: grep)
989
- list_result(ret, 'tags', from: from, grep: grep)
986
+ ret = write_lines(out, grep: op.extras)
987
+ list_result(ret, 'tags', from: from, grep: op.extras)
990
988
  return
991
989
  when :delete
992
990
  cmd << '--delete'
@@ -999,55 +997,56 @@ module Squared
999
997
 
1000
998
  def logx(flag, opts = [], range: [], index: [])
1001
999
  cmd, opts = git_session('log', opts: opts)
1002
- refs = option_sanitize(opts, collect_hash(OPT_GIT[:log]), no: collect_hash(OPT_GIT[:no][:log])).first
1000
+ op = OptionPartition.new(opts, collect_hash(OPT_GIT[:log]), cmd,
1001
+ project: self, no: collect_hash(OPT_GIT[:no][:log]))
1003
1002
  case flag
1004
1003
  when :between, :contain
1005
- cmd << shell_quote(range.join(flag == :between ? '..' : '...'))
1004
+ op << shell_quote(range.join(flag == :between ? '..' : '...'))
1006
1005
  else
1007
- cmd.merge(index)
1006
+ op.merge(index)
1008
1007
  end
1009
1008
  append_nocolor
1010
- append_pathspec refs
1009
+ append_pathspec op.extras
1011
1010
  source(exception: false)
1012
1011
  end
1013
1012
 
1014
1013
  def diff(flag, opts = [], refs: [], branch: nil, range: [], index: [])
1015
1014
  cmd, opts = git_session('diff', opts: opts)
1016
- files = option_sanitize(opts, collect_hash(OPT_GIT[:diff]) + OPT_GIT[:log][:diff],
1017
- no: OPT_GIT[:no][:log][:diff]).first
1015
+ op = OptionPartition.new(opts, collect_hash(OPT_GIT[:diff]) + OPT_GIT[:log][:diff], cmd,
1016
+ project: self, no: OPT_GIT[:no][:log][:diff])
1018
1017
  case flag
1019
1018
  when :files, :view, :between, :contain
1020
- cmd.delete('--cached')
1019
+ op.delete('--cached')
1021
1020
  end
1022
1021
  append_nocolor
1023
1022
  if flag == :files
1024
- cmd << '--no-index'
1023
+ op << '--no-index'
1025
1024
  append_pathspec(refs, parent: true)
1026
1025
  else
1027
1026
  case flag
1028
1027
  when :view
1029
- cmd << '--merge-base' if option('merge-base')
1030
- cmd << shell_quote(range.first, quote: true) << shell_quote(range.last, quote: true)
1028
+ op << '--merge-base' if option('merge-base')
1029
+ op << shell_quote(range.first, quote: true) << shell_quote(range.last, quote: true)
1031
1030
  when :between, :contain
1032
- cmd.delete('--merge-base')
1033
- cmd << shell_quote(range.join(flag == :between ? '..' : '...'))
1031
+ op.delete('--merge-base')
1032
+ op << shell_quote(range.join(flag == :between ? '..' : '...'))
1034
1033
  else
1035
- cmd << '--merge-base' if option('merge-base')
1036
- cmd << shell_quote(branch) if branch
1034
+ op << '--merge-base' if option('merge-base')
1035
+ op << shell_quote(branch) if branch
1037
1036
  if !index.empty?
1038
- if session_arg?('cached')
1037
+ if op.arg?('cached')
1039
1038
  raise_error("one commit only: #{index.join(', ')}", hint: '--cached') if index.size > 1
1040
- cmd << index.first
1039
+ op << index.first
1041
1040
  else
1042
- cmd.merge(index)
1041
+ op.merge(index)
1043
1042
  end
1044
1043
  elsif (n = option('index', ignore: false))
1045
- cmd << "HEAD~#{n}"
1044
+ op << "HEAD~#{n}"
1046
1045
  end
1047
1046
  end
1048
- append_pathspec files
1047
+ append_pathspec op.extras
1049
1048
  end
1050
- source(exception: session_arg?('exit-code'))
1049
+ source(exception: op.arg?('exit-code'))
1051
1050
  end
1052
1051
 
1053
1052
  def commit(flag, *, refs: [], message: nil, pass: false)
@@ -1122,10 +1121,10 @@ module Squared
1122
1121
  cmd, opts = git_session('merge', opts: opts)
1123
1122
  case flag
1124
1123
  when :commit, :'no-commit'
1125
- refs = option_sanitize(opts, OPT_GIT[:merge], no: OPT_GIT[:no][:merge]).first
1126
- raise_error 'no branch/commit' if refs.empty?
1127
- cmd << "--#{flag}" << '--'
1128
- append_commit(*refs)
1124
+ op = OptionPartition.new(opts, OPT_GIT[:merge], cmd, project: self, no: OPT_GIT[:no][:merge])
1125
+ raise_error 'no branch/commit' if op.empty?
1126
+ op << "--#{flag}" << '--'
1127
+ append_commit(*op.extras)
1129
1128
  else
1130
1129
  return unless VAL_GIT[:merge][:send].include?(command)
1131
1130
 
@@ -1141,7 +1140,7 @@ module Squared
1141
1140
  when :create
1142
1141
  if (arg = option('track', ignore: false))
1143
1142
  cmd << case arg
1144
- when '0'
1143
+ when '0', 'false'
1145
1144
  '--no-track'
1146
1145
  when 'direct', 'inherit'
1147
1146
  basic_option('track', arg)
@@ -1182,14 +1181,16 @@ module Squared
1182
1181
  cmd << '--edit-description'
1183
1182
  when :current
1184
1183
  cmd << '--show-current'
1184
+ source(banner: verbosetype > 1, stdout: true)
1185
+ return
1185
1186
  when :list
1186
- opts = option_sanitize(opts, OPT_GIT[:branch], no: OPT_GIT[:no][:branch], single: /^v+$/).first
1187
- cmd << '--list'
1188
- opts.each { |val| cmd << shell_quote(val) }
1187
+ op = OptionPartition.new(opts, OPT_GIT[:branch], cmd << '--list',
1188
+ project: self, no: OPT_GIT[:no][:branch], single: /^v+$/)
1189
+ op.each { |val| op << shell_quote(val) }
1189
1190
  out, banner, from = source(io: true)
1190
1191
  print_item banner
1191
1192
  ret = write_lines(out, sub: [
1192
- { pat: /^(\*\s+)(\S+)(\s*)$/, styles: color(:green), index: 2 },
1193
+ { pat: /^(\*\s+)(\S+)(.*)$/, styles: color(:green), index: 2 },
1193
1194
  { pat: %r{^(\s*)(remotes/\S+)(.*)$}, styles: color(:red), index: 2 }
1194
1195
  ])
1195
1196
  list_result(ret, 'branches', from: from)
@@ -1232,9 +1233,9 @@ module Squared
1232
1233
  end
1233
1234
 
1234
1235
  def restore(flag, opts = [])
1235
- opts = git_session('restore', "--#{flag}", opts: opts).last
1236
- refs = option_sanitize(opts, OPT_GIT[:restore], no: OPT_GIT[:no][:restore]).first
1237
- append_pathspec(refs, pass: false)
1236
+ cmd, opts = git_session('restore', "--#{flag}", opts: opts)
1237
+ op = OptionPartition.new(opts, OPT_GIT[:restore], cmd, project: self, no: OPT_GIT[:no][:restore])
1238
+ append_pathspec(op.extras, pass: false)
1238
1239
  source(sync: false, stderr: true)
1239
1240
  end
1240
1241
 
@@ -1264,13 +1265,14 @@ module Squared
1264
1265
  end
1265
1266
  end
1266
1267
  end
1267
- refs = option_sanitize(opts, OPT_GIT[:show] + OPT_GIT[:diff][:show] + OPT_GIT[:log][:diff],
1268
- no: OPT_GIT[:no][:show] + collect_hash(OPT_GIT[:no][:log], pass: [:base])).first
1269
- unless val == 'oneline' && session_arg?('abbrev-commit')
1270
- cmd << basic_option('abbrev', val) if (val = option('abbrev')) && val.to_i > 0
1268
+ op = OptionPartition.new(opts, OPT_GIT[:show] + OPT_GIT[:diff][:show] + OPT_GIT[:log][:diff], cmd,
1269
+ project: self,
1270
+ no: OPT_GIT[:no][:show] + collect_hash(OPT_GIT[:no][:log], pass: [:base]))
1271
+ unless val == 'oneline' && op.arg?('abbrev-commit')
1272
+ op << basic_option('abbrev', val) if (val = option('abbrev')) && val.to_i > 0
1271
1273
  banner = true
1272
1274
  end
1273
- append_value(refs, delim: true)
1275
+ op.append(delim: true)
1274
1276
  source(exception: false, banner: banner)
1275
1277
  end
1276
1278
 
@@ -1289,60 +1291,60 @@ module Squared
1289
1291
  cmd << '--abbrev-ref'
1290
1292
  append_commit(ref, head: true)
1291
1293
  else
1292
- args = option_sanitize(opts, OPT_GIT[:rev_parse][flag]).first
1293
- append_value(args, escape: session_arg?('sq-quote'))
1294
+ op = OptionPartition.new(opts, OPT_GIT[:rev_parse][flag], cmd, project: self)
1295
+ op.append(escape: op.arg?('sq-quote'))
1294
1296
  end
1295
- source(banner: verbosity > 0)
1297
+ source(banner: verbosetype > 1)
1296
1298
  end
1297
1299
 
1298
1300
  def ls_remote(flag, opts = [], remote: nil)
1299
1301
  cmd, opts = git_session('ls-remote', '--refs', opts: opts)
1300
1302
  cmd << "--#{flag}" unless flag == :remote
1301
- grep = option_sanitize(opts, OPT_GIT[:ls_remote]).first
1302
- cmd << shell_quote(remote) if remote
1303
+ op = OptionPartition.new(opts, OPT_GIT[:ls_remote], cmd, project: self)
1304
+ op << shell_quote(remote) if remote
1303
1305
  out, banner, from = source(io: true)
1304
1306
  print_item banner
1305
- ret = write_lines(out, grep: grep)
1306
- list_result(ret, flag.to_s, from: from, grep: grep)
1307
+ ret = write_lines(out, grep: op.extras)
1308
+ list_result(ret, flag.to_s, from: from, grep: op.extras)
1307
1309
  end
1308
1310
 
1309
1311
  def ls_files(flag, opts = [])
1310
- opts = git_session('ls-files', "--#{flag}", opts: opts).last
1311
- grep = option_sanitize(opts, OPT_GIT[:ls_files]).first
1312
+ cmd, opts = git_session('ls-files', "--#{flag}", opts: opts)
1313
+ op = OptionPartition.new(opts, OPT_GIT[:ls_files], cmd, project: self)
1312
1314
  out, banner, from = source(io: true)
1313
1315
  print_item banner
1314
- ret = write_lines(out, grep: grep)
1315
- list_result(ret, 'files', from: from, grep: grep)
1316
+ ret = write_lines(out, grep: op.extras)
1317
+ list_result(ret, 'files', from: from, grep: op.extras)
1316
1318
  end
1317
1319
 
1318
1320
  def git(flag, opts = [])
1319
1321
  cmd, opts = git_session(flag, opts: opts)
1320
- refs = option_sanitize(opts, OPT_GIT[flag], no: OPT_GIT[:no][flag]).first
1322
+ op = OptionPartition.new(opts, OPT_GIT[flag], cmd, project: self, no: OPT_GIT[:no][flag])
1321
1323
  sync = false
1322
1324
  stderr = true
1323
1325
  case flag
1324
1326
  when :clean
1325
- refs = projectmap(refs)
1327
+ refs = projectmap(op.extras)
1326
1328
  unless refs.empty?
1327
- cmd << '--'
1328
- cmd.merge(refs)
1329
+ op << '--'
1330
+ op.merge(refs)
1329
1331
  end
1330
1332
  sync = true
1331
1333
  stderr = false
1332
1334
  when :revert
1333
- if VAL_GIT[:rebase][:send].any? { |val| session_arg?(val) }
1334
- option_clear refs
1335
- elsif refs.empty?
1335
+ if VAL_GIT[:rebase][:send].any? { |val| op.arg?(val) }
1336
+ op.clear
1337
+ elsif op.empty?
1336
1338
  raise_error 'no commit given'
1337
1339
  else
1338
- append_commit(*refs)
1340
+ append_commit(*op.extras)
1339
1341
  end
1340
1342
  when :mv
1341
- refs = projectmap(refs)
1343
+ refs = projectmap(op.extras)
1342
1344
  raise_error 'no source/destination' unless refs.size > 1
1343
- cmd.merge(refs)
1345
+ op.merge(refs)
1344
1346
  when :rm
1345
- append_pathspec(refs, expect: true)
1347
+ append_pathspec(op.extras, expect: true)
1346
1348
  end
1347
1349
  source(sync: sync, stderr: stderr)
1348
1350
  end
@@ -1473,15 +1475,13 @@ module Squared
1473
1475
  glob = kwargs.fetch(:include, [])
1474
1476
  pass = kwargs.fetch(:exclude, [])
1475
1477
  ret = {}
1476
- git_spawn('status -s --porcelain', *args, stdout: false)
1477
- .first
1478
- .each do |line|
1479
- next unless (file = line[/^[A-Z ?!]{3}"?(.+?)"?$/, 1])
1480
- next if !glob.empty? && glob.none? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
1481
- next if !pass.empty? && pass.any? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
1482
-
1483
- ret[file] = algorithm.hexdigest(File.read(basepath(file)))
1484
- end
1478
+ git_spawn('status -s --porcelain', *args, stdout: false).first.each do |line|
1479
+ next unless (file = line[/^[A-Z ?!]{3}"?(.+?)"?$/, 1])
1480
+ next if !glob.empty? && glob.none? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
1481
+ next if !pass.empty? && pass.any? { |val| File.fnmatch?(val, file, File::FNM_DOTMATCH) }
1482
+
1483
+ ret[file] = algorithm.hexdigest(File.read(basepath(file)))
1484
+ end
1485
1485
  ret
1486
1486
  end
1487
1487
 
@@ -1489,43 +1489,44 @@ module Squared
1489
1489
  source(git_output(*cmd), io: true, banner: false, stdout: stdout)
1490
1490
  end
1491
1491
 
1492
- def append_pull(opts, list, target: @session, no: nil, flag: nil, remote: nil)
1493
- cmd << '--force' if option('force')
1494
- rsm = append_submodules(target: target)
1495
- out = []
1492
+ def append_pull(opts, list, target: @session, flag: nil, no: nil, remote: nil)
1493
+ target << '--force' if option('force', target: target)
1494
+ append_submodules(target: target)
1496
1495
  refspec = []
1497
- opts, pat = option_sanitize(opts, remote ? list + ['refspec=b'] : list, target: target, no: no)
1498
- opts.each do |opt|
1499
- if opt =~ pat
1496
+ op = OptionPartition.new(opts, remote ? list + ['refspec=v'] : list, target, project: self, no: no)
1497
+ op.each do |opt|
1498
+ if opt =~ op.values
1500
1499
  case $1
1501
1500
  when 'rebase'
1502
- target << basic_option($1, $2) if VAL_GIT[:rebase][:value].include?($2)
1501
+ op << basic_option($1, $2) if VAL_GIT[:rebase][:value].include?($2)
1503
1502
  when 'shallow-since'
1504
1503
  next unless (val = Date.parse($2))
1505
1504
 
1506
- target << quote_option($1, val.strftime('%F %T'))
1505
+ op << quote_option($1, val.strftime('%F %T'))
1507
1506
  when 'recurse-submodules'
1508
- target << basic_option($1, $2) unless rsm
1507
+ op << basic_option($1, $2) unless op.arg?('recurse-submodules')
1509
1508
  when 'refspec'
1510
1509
  refspec << shell_escape($2, quote: true)
1511
1510
  end
1511
+ elsif op.arg?('--multiple')
1512
+ op.found << opt
1512
1513
  else
1513
- out << opt
1514
+ op.errors << opt
1514
1515
  end
1515
1516
  end
1516
1517
  if remote
1517
- append_value(remote, target: target, delim: true)
1518
- if (val = option('refspec', strict: true))
1519
- append_value(split_escape(val), target: target)
1518
+ op.append(remote, delim: true)
1519
+ if (val = option('refspec', target: target, strict: true))
1520
+ op.append(*split_escape(val))
1520
1521
  else
1521
- target.merge(refspec)
1522
+ op.merge(refspec)
1522
1523
  end
1523
- target.delete('--all')
1524
- elsif target.include?('--multiple')
1525
- target.merge(out.map! { |opt| shell_escape(opt, quote: true) })
1524
+ op.delete('--all')
1525
+ elsif op.arg?('--multiple')
1526
+ op.swap.merge(op.map! { |opt| shell_escape(opt, quote: true) })
1526
1527
  return
1527
1528
  end
1528
- option_clear(out, target: target, subject: flag.to_s) if flag
1529
+ op.clear(errors: true, subject: flag.to_s) if flag
1529
1530
  end
1530
1531
 
1531
1532
  def append_commit(*val, target: @session, head: false)
@@ -1538,10 +1539,10 @@ module Squared
1538
1539
  end
1539
1540
 
1540
1541
  def append_pathspec(files = [], target: @session, expect: false, parent: false, pass: true)
1541
- if session_arg?('pathspec-from-file')
1542
+ if session_arg?('pathspec-from-file', target: target)
1542
1543
  option_clear files
1543
1544
  else
1544
- if files.empty? && (val = option('pathspec'))
1545
+ if files.empty? && (val = option('pathspec', target: target))
1545
1546
  files = split_escape(val)
1546
1547
  end
1547
1548
  files = projectmap(files, parent: parent, pass: pass)
@@ -1564,7 +1565,7 @@ module Squared
1564
1565
  end
1565
1566
 
1566
1567
  def append_submodules(from = nil, target: @session)
1567
- return unless (val = option('recurse-submodules', ignore: false))
1568
+ return unless (val = option('recurse-submodules', target: target, ignore: false))
1568
1569
 
1569
1570
  if from == :clone
1570
1571
  projectmap(split_escape(val)).each do |path|
@@ -1573,7 +1574,7 @@ module Squared
1573
1574
  target
1574
1575
  else
1575
1576
  target << case val
1576
- when 'no', '0'
1577
+ when 'no', '0', 'false'
1577
1578
  '--no-recurse-submodules'
1578
1579
  when 'yes', 'on-demand'
1579
1580
  "--recurse-submodules#{from == :reset ? '' : "=#{val}"}"
@@ -1587,9 +1588,9 @@ module Squared
1587
1588
  dir = worktree ? ["--work-tree=#{shell_quote(path)}", "--git-dir=#{shell_quote(gitpath)}"] : []
1588
1589
  return session('git', *dir, *cmd, **kwargs) unless opts
1589
1590
 
1590
- opts = option_sanitize(opts, OPT_GIT[:common], target: dir).first
1591
- ret = session('git', *dir, *cmd, **kwargs)
1592
- [ret, opts]
1591
+ op = OptionPartition.new(opts, OPT_GIT[:common], dir, project: self)
1592
+ ret = session('git', *op.to_a, *cmd, **kwargs)
1593
+ [ret, op.extras]
1593
1594
  end
1594
1595
 
1595
1596
  def git_output(*cmd, **kwargs)
@@ -1597,24 +1598,15 @@ module Squared
1597
1598
  end
1598
1599
 
1599
1600
  def dryrun?(*, target: @session, **)
1600
- !!target&.include?('--dry-run')
1601
+ return false unless target
1602
+
1603
+ target.include?('--dry-run')
1601
1604
  end
1602
1605
 
1603
1606
  def quiet?(target: @session)
1604
1607
  return false unless target
1605
1608
 
1606
- target.include?('--quiet') || (target.include?('-q') && target.first == 'git')
1607
- end
1608
-
1609
- def verbosity
1610
- case verbose
1611
- when true
1612
- 0
1613
- when Numeric
1614
- verbose
1615
- else
1616
- -1
1617
- end
1609
+ target.include?('--quiet') || (target.include?('-q') && stripext(target.first) == 'git')
1618
1610
  end
1619
1611
 
1620
1612
  def gitpath