squared 0.6.2 → 0.6.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.
@@ -154,14 +154,15 @@ module Squared
154
154
  task action, [:command] do |_, args|
155
155
  command = param_guard(action, 'command', args: args, key: :command)
156
156
  args = args.extras
157
- ls = case command
158
- when 'image', 'container', 'network'
159
- 'ls'
160
- when 'compose'
161
- 'ps'
162
- else
163
- raise_error ArgumentError, 'unrecognized command', hint: command
164
- end
157
+ cmd = docker_output(command, case command
158
+ when 'image', 'container', 'network'
159
+ 'ls'
160
+ when 'compose'
161
+ 'ps'
162
+ else
163
+ raise_error ArgumentError, 'unrecognized command', hint: command
164
+ end)
165
+ cmd << '-a' if has_value!(args, 'a', 'all') && command != 'network'
165
166
  data = VAL_DOCKER[:ls][command.to_sym]
166
167
  if has_value!(args, 's', 'standard')
167
168
  cols = data.first(data.index('CreatedAt'))
@@ -180,8 +181,6 @@ module Squared
180
181
  cols = choice_index('Select a column', data, multiple: true, force: true, attempts: 1)
181
182
  end
182
183
  end
183
- cmd = docker_output command, ls
184
- cmd << '-a' unless command == 'network' || !has_value!(args, 'a', 'all')
185
184
  cmd << quote_option('format', "table #{cols.map! { |val| "{{.#{val}}}" }.join("\t")}")
186
185
  run(cmd, banner: false, from: :ls)
187
186
  end
@@ -201,7 +200,7 @@ module Squared
201
200
 
202
201
  case flag
203
202
  when :build
204
- format_desc action, flag, 'opts*,target*,context?|:'
203
+ format_desc action, flag, 'opts*,target*,context/:'
205
204
  task flag do |_, args|
206
205
  args = args.to_a
207
206
  if args.first == ':'
@@ -222,7 +221,7 @@ module Squared
222
221
 
223
222
  case flag
224
223
  when :exec, :run
225
- format_desc action, flag, "service|:,command#{flag == :exec ? '' : '?'}|::,args*,opts*"
224
+ format_desc action, flag, "service|:,command#{'?' unless flag == :exec}|::,args*,opts*"
226
225
  task flag, [:service] do |_, args|
227
226
  service = param_guard(action, flag, args: args, key: :service)
228
227
  compose!(flag, args.extras, service: service)
@@ -374,9 +373,7 @@ module Squared
374
373
  end
375
374
  append_context
376
375
  when :bake, :compose
377
- option(from == :bake ? 'target' : 'service', ignore: false) do |val|
378
- ret.merge(split_escape(val).map! { |s| shell_quote(s) })
379
- end
376
+ option(from == :bake ? 'target' : 'service', ignore: false) { |val| ret.merge(split_escape(val).quote!) }
380
377
  end
381
378
  ret
382
379
  end
@@ -477,8 +474,8 @@ module Squared
477
474
  end
478
475
  elsif all.include?(k)
479
476
  unless type
480
- VAL_DOCKER[:run].each_pair do |key, val|
481
- next unless val.include?(k)
477
+ VAL_DOCKER[:run].each_pair do |key, a|
478
+ next unless a.include?(k)
482
479
 
483
480
  type = key.to_s unless key == :common
484
481
  break
@@ -493,8 +490,8 @@ module Squared
493
490
  v = shell_quote(v, option: false, force: false) if q == ''
494
491
  end
495
492
  args << "#{k}=#{q + v + q}"
496
- elsif verbose
497
- log_message(Logger::INFO, 'unrecognized option', subject: from, hint: k)
493
+ elsif !silent?
494
+ log_message('unrecognized option', subject: from, hint: k)
498
495
  end
499
496
  end
500
497
  raise_error TypeError, 'none specified', hint: flag unless type
@@ -523,7 +520,7 @@ module Squared
523
520
  else
524
521
  '--disable-content-trust'
525
522
  end
526
- opts << '--quiet' unless verbose
523
+ opts << '--quiet' if silent?
527
524
  return image(:push, opts, id: latest, registry: registry)
528
525
  else
529
526
  if op.empty?
@@ -804,14 +801,14 @@ module Squared
804
801
  unless y
805
802
  bb = index.to_s
806
803
  cc = bb.size.succ
807
- a = sub_style(ee, styles: theme[:inline])
808
- b = "Execute #{sub_style(flag, styles: theme[:active])} on #{a.subhint(ee == id ? nil : id)}"
804
+ a = sub_style ee, theme[:inline]
805
+ b = "Execute #{sub_style(flag, theme[:active])} on #{a.subhint(ee == id ? nil : id)}"
809
806
  e = time_format(time_since(data['CreatedAt']), pass: ['ms'])
810
- f = sub_style(ARG[:BORDER][0], styles: theme[:inline])
807
+ f = sub_style ARG[:BORDER][0], theme[:inline]
811
808
  g = ' ' * cc.succ
812
- h = "#{sub_style(bb.rjust(cc), styles: theme[:current])} #{f} "
809
+ h = "#{sub_style(bb.rjust(cc), theme[:current])} #{f} "
813
810
  puts unless index == 1
814
- puts (h + sub_style(aa, styles: theme[:subject])).subhint("created #{e} ago")
811
+ puts (h + sub_style(aa, theme[:subject])).subhint("created #{e} ago")
815
812
  cols = %w[Tag Status Ports]
816
813
  cols << case flag
817
814
  when :connect, :disconnect
@@ -825,7 +822,7 @@ module Squared
825
822
  puts "#{g + f} #{key}: #{Array(data[key]).join(', ')}" unless data[key].to_s.empty?
826
823
  end
827
824
  w = 9 + flag.to_s.size + 4 + ee.size
828
- puts g + sub_style(ARG[:BORDER][6] + (ARG[:BORDER][1] * w), styles: theme[:inline])
825
+ puts g + sub_style(ARG[:BORDER][6] + (ARG[:BORDER][1] * w), theme[:inline])
829
826
  index += 1
830
827
  next unless confirm("#{h + b}?", no ? 'N' : 'Y')
831
828
 
@@ -841,7 +838,7 @@ module Squared
841
838
 
842
839
  def list_empty(subject: name, hint: nil, **kwargs)
843
840
  hint = "status: #{hint.join(', ')}" if hint.is_a?(Array)
844
- puts log_message(Logger::INFO, 'none detected', subject: subject, hint: hint, **kwargs)
841
+ puts log_message('none detected', subject: subject, hint: hint, **kwargs)
845
842
  end
846
843
 
847
844
  def confirm_command(*args, title: nil, target: nil, as: nil)
@@ -854,10 +851,8 @@ module Squared
854
851
  opt_style(theme[:caution], /\A(.+)\z/)
855
852
  ])
856
853
  printsucc
857
- a = t.last.capitalize
858
- b = sub_style(target, styles: theme[:subject])
859
- c = as && sub_style(as, styles: theme[:inline])
860
- confirm "#{a} #{b}#{c ? " as #{c}" : ''}?", 'N'
854
+ s = t.last.capitalize
855
+ confirm "#{s} #{sub_style(target, theme[:subject])}#{" as #{sub_style(as, theme[:inline])}" if as}?", 'N'
861
856
  end
862
857
 
863
858
  def choice_command(flag, *action)
@@ -880,8 +875,7 @@ module Squared
880
875
  lines = `#{docker_output(cmd)}`.lines
881
876
  header = lines.shift
882
877
  if lines.empty?
883
- puts log_message(Logger::INFO, 'none found', subject: name,
884
- hint: "docker #{cmd.split(' ', 3)[0...2].join(' ')}")
878
+ puts log_message('none found', subject: name, hint: "docker #{cmd.split(' ', 3)[0...2].join(' ')}")
885
879
  return
886
880
  end
887
881
  puts " # #{header}"
@@ -923,7 +917,7 @@ module Squared
923
917
  end
924
918
  cmd.merge(Array(out).map! { |val| parse.call(val) })
925
919
  cmd << args
926
- success?(run(cmd), ctx.start_with?(/(?:network|tag|save)/))
920
+ success?(run(cmd), ctx.start_with?(/network|tag|save/))
927
921
  end
928
922
 
929
923
  def filetype(val = dockerfile)
@@ -21,14 +21,17 @@ module Squared
21
21
  end
22
22
  elsif uri
23
23
  data[name.to_s] = uri
24
- elsif name.is_a?(Enumerable)
25
- data = name.to_h
26
- elsif name.is_a?(String) && name.match?(GIT_PROTO)
27
- base = name
28
- @project.each_value { |proj| repo << proj if !proj.parent && check.call(proj) }
29
24
  else
30
- warn log_message(Logger::WARN, name, subject: 'git', hint: 'invalid') if warning
31
- return self
25
+ case name
26
+ when Enumerable
27
+ data = name.to_h
28
+ when GIT_PROTO
29
+ base = name.to_s
30
+ each { |proj| repo << proj if !proj.parent && check.call(proj) }
31
+ else
32
+ warn log_message(Logger::WARN, name, subject: 'git', hint: 'invalid') if warning
33
+ return self
34
+ end
32
35
  end
33
36
  if base
34
37
  base = base.match?(GIT_PROTO) ? "#{base.chomp('/')}/" : rootpath(base)
@@ -144,6 +147,7 @@ module Squared
144
147
  @revlock = false
145
148
  end
146
149
  end
150
+
147
151
  Application.include Git
148
152
 
149
153
  module Project
@@ -323,7 +327,7 @@ module Squared
323
327
  'fetch' => %i[origin remote all].freeze,
324
328
  'files' => %i[cached modified deleted others].freeze,
325
329
  'git' => %i[add blame clean grep mv revert rm status].freeze,
326
- 'log' => %i[view between contain].freeze,
330
+ 'log' => %i[view grep between contain].freeze,
327
331
  'merge' => %i[commit no-commit send].freeze,
328
332
  'pull' => %i[origin remote all].freeze,
329
333
  'rebase' => %i[branch onto send].freeze,
@@ -483,9 +487,9 @@ module Squared
483
487
  when 'stash'
484
488
  format_desc(action, flag, 'opts*', after: case flag
485
489
  when :push then 'pathspec*,:'
486
- when :branch then 'name,stash?|:'
490
+ when :branch then 'name,stash/:'
487
491
  when :clear, :list, :all then nil
488
- else 'stash?|:'
492
+ else 'stash/:'
489
493
  end)
490
494
  task flag do |_, args|
491
495
  stash flag, args.to_a
@@ -566,6 +570,37 @@ module Squared
566
570
  path2 = param_guard(action, flag, args: args, key: :path2)
567
571
  diff(flag, refs: [path1, path2, args.patch])
568
572
  end
573
+ when :grep
574
+ format_desc action, flag, 'pattern+,a/ll-match?,in/vert-grep?,i/E/F/P?,max-count?=i,f/ormat?=s'
575
+ task flag do |_, args|
576
+ grep = args.to_a
577
+ opts = ['oneline']
578
+ while (last = grep.pop)
579
+ case last
580
+ when '--'
581
+ grep << '--' if grep.empty?
582
+ break
583
+ when 'a', 'all-match'
584
+ opts << 'all-match'
585
+ when 'in', 'invert-grep'
586
+ opts << 'invert-grep'
587
+ when 'i', 'E', 'F', 'P'
588
+ opts << last
589
+ else
590
+ if last =~ /^(?:f(?:-ormat)?)=(.+)$/
591
+ opts.shift
592
+ opts << "format=#{$1}"
593
+ elsif last =~ /^(?:max(?:-count)?)=(\d+)$/
594
+ opts << "max-count=#{$1}"
595
+ else
596
+ grep << last
597
+ break
598
+ end
599
+ end
600
+ end
601
+ param_guard(action, flag, args: grep)
602
+ log!(flag, opts, grep: grep)
603
+ end
569
604
  end
570
605
  when 'checkout'
571
606
  case flag
@@ -637,7 +672,7 @@ module Squared
637
672
  when 'branch'
638
673
  case flag
639
674
  when :create
640
- format_desc action, flag, 'name,ref?|:'
675
+ format_desc action, flag, 'name,ref/:'
641
676
  task flag, [:name, :ref] do |_, args|
642
677
  target = param_guard(action, flag, args: args, key: :name)
643
678
  ref = commithead args.ref
@@ -659,7 +694,7 @@ module Squared
659
694
  branch(flag, target: target, ref: ref, remote: remote)
660
695
  end
661
696
  when :delete
662
- format_desc action, flag, '(^~)name*,:?'
697
+ format_desc action, flag, '[^~]name*,:?'
663
698
  task flag do |_, args|
664
699
  refs = args.to_a
665
700
  if refs.empty? || (r = refs.last == ':')
@@ -702,7 +737,7 @@ module Squared
702
737
  when 'switch'
703
738
  case flag
704
739
  when :create
705
- format_desc action, flag, '(^)name,ref?|:'
740
+ format_desc action, flag, '(^)name,ref/:'
706
741
  task flag, [:name, :commit] do |_, args|
707
742
  branch = param_guard(action, flag, args: args, key: :name)
708
743
  commit = commithead args.commit
@@ -752,7 +787,7 @@ module Squared
752
787
  reset(flag, flag == :index ? args.to_a : [])
753
788
  end
754
789
  when :mode
755
- format_desc action, flag, 'mode,ref?|:'
790
+ format_desc action, flag, 'mode,ref/:'
756
791
  task flag, [:mode, :ref] do |_, args|
757
792
  mode = param_guard(action, flag, args: args, key: :mode)
758
793
  ref = commithead args.ref
@@ -760,7 +795,7 @@ module Squared
760
795
  reset(flag, mode: mode, ref: ref)
761
796
  end
762
797
  when :patch
763
- format_desc action, flag, 'ref?|:,pathspec*'
798
+ format_desc action, flag, 'ref/:,pathspec*'
764
799
  task flag, [:ref] do |_, args|
765
800
  ref = commithead args.ref
766
801
  ref = choice_commit(reflog: false) unless ref && ref != ':'
@@ -1031,7 +1066,7 @@ module Squared
1031
1066
  append_head branch
1032
1067
  else
1033
1068
  unless gitpath('REBASE_HEAD').exist?
1034
- puts log_message(Logger::INFO, name, 'no rebase in progress', hint: command) if stdout?
1069
+ puts log_message('no rebase in progress', subject: name, hint: command) if stdout?
1035
1070
  exit 1
1036
1071
  end
1037
1072
  return unless VAL_GIT[:rebase][:send].include?(command)
@@ -1078,9 +1113,18 @@ module Squared
1078
1113
  end
1079
1114
  option('local', strict: true) { |val| opts[:local] = val != '0' }
1080
1115
  option('bare') { |val| opts[:bare] = val }
1116
+ option('single-branch', ignore: false) do |val|
1117
+ opts[:'single-branch'] = val != '0' && val != 'false'
1118
+ opts.delete(:'no-single-branch')
1119
+ end
1120
+ option('no-checkout') do
1121
+ opts[:'no-checkout'] = true
1122
+ opts.delete(:n)
1123
+ end
1124
+ option('no-tags') { opts[:'no-tags'] = true }
1081
1125
  opts.delete(:'recurse-submodules') || opts.delete(:'no-recurse-submodules') if append_submodules(from: :clone)
1082
1126
  append_hash opts
1083
- cmd << '--quiet' unless verbose
1127
+ cmd << '--quiet' if option('quiet') || !verbose
1084
1128
  append_value(data[0], path, delim: true)
1085
1129
  source(banner: sync && !quiet?, multiple: !sync || quiet?)
1086
1130
  end
@@ -1099,7 +1143,7 @@ module Squared
1099
1143
  flag = :push
1100
1144
  end
1101
1145
  unless (file = gitpath('logs/refs/stash')).exist? || flag == :push
1102
- puts log_message(Logger::INFO, name, 'no stashes were found', hint: flag) if stdout?
1146
+ puts log_message('no stashes were found', subject: name, hint: flag) if stdout?
1103
1147
  exit 1
1104
1148
  end
1105
1149
  cmd, opts = git_session('stash', flag, opts: opts)
@@ -1136,8 +1180,8 @@ module Squared
1136
1180
  end
1137
1181
  op.clear
1138
1182
  when :clear
1139
- n = sub_style(file.read.lines.size, styles: theme[:inline])
1140
- s = sub_style(name, styles: theme[:active])
1183
+ n = sub_style file.read.lines.size, theme[:inline]
1184
+ s = sub_style name, theme[:active]
1141
1185
  source(stdout: true) if confirm("Remove #{n} stash entries from #{s}?", 'N')
1142
1186
  return
1143
1187
  when :list
@@ -1193,11 +1237,11 @@ module Squared
1193
1237
  end
1194
1238
  out, banner, from = source(io: true)
1195
1239
  ret = write_lines(out, banner: banner, sub: sub)
1196
- list_result(ret, 'files', from: from, action: 'modified')
1240
+ list_result(ret, 'files', action: 'modified', from: from)
1197
1241
  end
1198
1242
 
1199
1243
  def revbuild(flag = nil, opts = [], sync: nil, **kwargs)
1200
- statusargs = lambda do
1244
+ kw = lambda do
1201
1245
  {
1202
1246
  include: relativepath(Array(kwargs[:include]), all: true),
1203
1247
  exclude: relativepath(Array(kwargs[:exclude]), all: true)
@@ -1205,9 +1249,9 @@ module Squared
1205
1249
  end
1206
1250
  unless workspace.closed
1207
1251
  if @revbuild
1208
- statusargs.call.each { |key, val| @revbuild[key] += val }
1252
+ kw.call.each { |key, val| @revbuild[key] += val }
1209
1253
  else
1210
- @revbuild = statusargs.call
1254
+ @revbuild = kw.call
1211
1255
  end
1212
1256
  return
1213
1257
  end
@@ -1215,7 +1259,7 @@ module Squared
1215
1259
  return if sha.empty?
1216
1260
 
1217
1261
  sync = invoked_sync?('revbuild', flag) if sync.nil?
1218
- kwargs = kwargs.key?(:include) || kwargs.key?(:exclude) ? statusargs.call : @revbuild || {}
1262
+ kwargs = kwargs.key?(:include) || kwargs.key?(:exclude) ? kw.call : @revbuild || {}
1219
1263
  case flag
1220
1264
  when :build
1221
1265
  op = OptionPartition.new(opts, VAL_GIT[:revbuild].map { |key| "#{key}=b?" }, project: self)
@@ -1233,17 +1277,17 @@ module Squared
1233
1277
  if cur['files'].size == files.size && cur['files'].find { |key, val| files[key] != val }.nil?
1234
1278
  workspace.rev_timeutc(name, 'build') unless (since = workspace.rev_timesince(name, 'build'))
1235
1279
  if stdout?
1236
- puts log_message(Logger::INFO, name, 'no changes', subject: 'revbuild', hint: ("#{since} ago" if since))
1280
+ puts log_message(['revbuild', 'no changes'], subject: name, hint: ("#{since} ago" if since))
1237
1281
  end
1238
1282
  return
1239
1283
  end
1240
1284
  end
1241
1285
  start = time_epoch
1242
- build(@output, sync: sync, from: :'git:revbuild')
1286
+ build(*@output, sync: sync, from: :'git:revbuild')
1243
1287
  rescue StandardError => e
1244
1288
  print_error(e, pass: true)
1245
1289
  else
1246
- print_status(name, subject: 'revbuild', start: start, from: :completed)
1290
+ print_status('revbuild', subject: name, start: start, from: :completed)
1247
1291
  workspace.rev_write(name, { 'revision' => sha, 'files' => status_digest(*args, **kwargs) },
1248
1292
  sync: sync, utc: 'build')
1249
1293
  end
@@ -1336,18 +1380,14 @@ module Squared
1336
1380
  out, banner, from = source(io: true)
1337
1381
  print_item banner
1338
1382
  ret = write_lines(out, grep: op.extras)
1339
- list_result(ret, 'tags', from: from, grep: op.extras)
1383
+ list_result(ret, 'tags', grep: op.extras, from: from)
1340
1384
  return
1341
1385
  end
1342
1386
  remote ||= option('remote')
1343
- source.tap do |ret|
1344
- next unless ret && remote
1345
-
1346
- git_spawn('push', ('-d' if flag == :delete), remote, *refs.map! { |val| shell_quote(val) })
1347
- end
1387
+ source.tap { |ret| git_spawn('push', ('-d' if flag == :delete), remote, *refs.quote!) if ret && remote }
1348
1388
  end
1349
1389
 
1350
- def log!(flag, opts = [], range: [], index: [])
1390
+ def log!(flag, opts = [], range: [], index: [], grep: [])
1351
1391
  cmd, opts = git_session('log', opts: opts)
1352
1392
  op = OptionPartition.new(opts, collect_hash(OPT_GIT[:log]), cmd, project: self,
1353
1393
  no: collect_hash(OPT_GIT[:no][:log]),
@@ -1355,6 +1395,8 @@ module Squared
1355
1395
  case flag
1356
1396
  when :between, :contain
1357
1397
  op.add_quote(range.join(flag == :between ? '..' : '...'))
1398
+ when :grep
1399
+ op.merge(grep.map { |val| quote_option('grep', val) })
1358
1400
  else
1359
1401
  op.merge(index)
1360
1402
  end
@@ -1442,7 +1484,7 @@ module Squared
1442
1484
  cmd, opts = git_session('add', opts: opts)
1443
1485
  op = OptionPartition.new(opts, OPT_GIT[:add] + OPT_GIT[:log][:diff_context], cmd,
1444
1486
  project: self, no: OPT_GIT[:no][:add], first: matchpathspec)
1445
- op << '--verbose' if verbose
1487
+ op << '--verbose' unless silent?
1446
1488
  format = '%(if)%(HEAD)%(then)%(refname:short)...%(upstream:short)...%(upstream:track)%(end)'
1447
1489
  git_spawn 'fetch --no-tags --quiet'
1448
1490
  foreachref('heads', format: format).each do |line|
@@ -1461,7 +1503,6 @@ module Squared
1461
1503
  end
1462
1504
  origin = readline('Enter an upstream', force: true)
1463
1505
  end
1464
- raise_error ArgumentError, 'missing remote name', hint: origin unless origin.include?('/')
1465
1506
  upstream = true
1466
1507
  end
1467
1508
  break
@@ -1500,7 +1541,7 @@ module Squared
1500
1541
  if banner?
1501
1542
  puts 'Nothing to commit'
1502
1543
  elsif stdout?
1503
- puts log_message(Logger::INFO, name, 'nothing to commit', hint: flag)
1544
+ puts log_message('nothing to commit', subject: name, hint: flag)
1504
1545
  end
1505
1546
  exit 1
1506
1547
  end
@@ -1522,7 +1563,7 @@ module Squared
1522
1563
  end
1523
1564
  else
1524
1565
  unless gitpath('MERGE_HEAD').exist?
1525
- puts log_message(Logger::INFO, name, 'no merge in progress', hint: command) if stdout?
1566
+ puts log_message('no merge in progress', subject: name, hint: command) if stdout?
1526
1567
  exit 1
1527
1568
  end
1528
1569
  return unless VAL_GIT[:merge][:send].include?(command)
@@ -1562,9 +1603,7 @@ module Squared
1562
1603
  cmd << shell_quote(target) if target
1563
1604
  end
1564
1605
  when :delete
1565
- remote&.each do |val|
1566
- source git_output('push --delete', *val.split('/', 2).map! { |s| shell_quote(s) })
1567
- end
1606
+ remote&.each { |val| source git_output('push --delete', *val.split('/', 2).quote!) }
1568
1607
  force, list = refs.partition { |val| val.start_with?(/[~^]/) }
1569
1608
  force.each do |val|
1570
1609
  r = '-r' if val.delete!('~')
@@ -1579,7 +1618,7 @@ module Squared
1579
1618
  s = +"-#{flag.to_s[0]}"
1580
1619
  s.upcase! if option('f', 'force')
1581
1620
  cmd << s
1582
- refs.compact.each { |val| cmd << shell_quote(val) }
1621
+ cmd.merge(refs.compact.quote!)
1583
1622
  stdout = true
1584
1623
  when :current
1585
1624
  cmd << '--show-current'
@@ -1608,11 +1647,11 @@ module Squared
1608
1647
  next line if stdin?
1609
1648
 
1610
1649
  data = line.sub(/^\*\s+/, '').split(/\s+/)
1611
- a = sub_style(data[0], styles: theme[:inline])
1612
- b = sub_style(data[1], styles: theme[:extra])
1650
+ a = sub_style data[0], theme[:inline]
1651
+ b = sub_style data[1], theme[:extra]
1613
1652
  r = /\A(?:\[((?~\]\s))\]\s)?(.+)\z/m.match(data[2..-1].join(' '))
1614
1653
  if (r1 = r[1]) && r1 =~ /^(.+):(?: ([a-z]+) (\d+),)? ([a-z]+) (\d+)$/
1615
- write = ->(s1, s2) { "#{s1.capitalize.rjust(7)}: #{sub_style(s2, styles: theme[:warn])}" }
1654
+ write = ->(s1, s2) { "#{s1.capitalize.rjust(7)}: #{sub_style(s2, theme[:warn])}" }
1616
1655
  r1 = $1
1617
1656
  r2 = $2 && write.call($2, $3)
1618
1657
  r3 = write.call($4, $5)
@@ -1739,7 +1778,7 @@ module Squared
1739
1778
  out, banner, from = source(io: true)
1740
1779
  print_item banner
1741
1780
  ret = write_lines(out, grep: op.extras, prefix: "refs/#{flag}/")
1742
- list_result(ret, flag.to_s, from: from, grep: op.extras)
1781
+ list_result(ret, flag.to_s, grep: op.extras, from: from)
1743
1782
  end
1744
1783
 
1745
1784
  def ls_files(flag, opts = [])
@@ -1749,7 +1788,7 @@ module Squared
1749
1788
  out, banner, from = source(io: true)
1750
1789
  print_item banner
1751
1790
  ret = write_lines(out, grep: op.extras)
1752
- list_result(ret, 'files', from: from, grep: op.extras)
1791
+ list_result(ret, 'files', grep: op.extras, from: from)
1753
1792
  end
1754
1793
 
1755
1794
  def git(flag, opts = [])
@@ -1788,7 +1827,7 @@ module Squared
1788
1827
  status_data.each do |a, b|
1789
1828
  next if b.strip.empty? || (!grep.empty? && grep.none? { |pat| pat.match?(a) })
1790
1829
 
1791
- out << "#{sub_style(b, styles: color(:red))} #{a}"
1830
+ out << "#{sub_style(b, color(:red))} #{a}"
1792
1831
  end
1793
1832
  end
1794
1833
  unless files.empty?
@@ -1917,7 +1956,7 @@ module Squared
1917
1956
  if loglevel
1918
1957
  log&.add loglevel, line
1919
1958
  else
1920
- sub&.each { |h| line = sub_style(line, **h) }
1959
+ sub&.each { |h| sub_style!(line, **h) }
1921
1960
  if banner
1922
1961
  out << line
1923
1962
  else
@@ -1931,7 +1970,7 @@ module Squared
1931
1970
  ret
1932
1971
  end
1933
1972
 
1934
- def list_result(size, type, grep: [], action: 'found', from: nil)
1973
+ def list_result(size, type, action: 'found', grep: [], from: nil)
1935
1974
  if size == 0
1936
1975
  puts empty_status("No #{type} were #{action}", 'grep', grep.join(', '))
1937
1976
  elsif stdout?
@@ -1946,7 +1985,7 @@ module Squared
1946
1985
  def choice_refs(msg, *type, format: nil, sort: '-creatordate', count: true, short: true, **kwargs)
1947
1986
  type << 'heads' if type.empty?
1948
1987
  unless format
1949
- format = +"%(refname#{short ? ':short' : ''})"
1988
+ format = +"%(refname#{':short' if short})"
1950
1989
  if type.include?('heads') || type.include?('tags')
1951
1990
  format += '%(if)%(HEAD)%(then) *%(end)'
1952
1991
  trim = /\s+\*\z/
@@ -2149,9 +2188,11 @@ module Squared
2149
2188
  end
2150
2189
 
2151
2190
  def repotrack(origin, branch, quote: true)
2152
- i = origin.index('/')
2191
+ unless origin && branch && (i = origin.index('/'))
2192
+ raise_error(ArgumentError, "missing #{origin ? 'branch' : 'remote'} name", hint: origin)
2193
+ end
2153
2194
  branch = "#{branch}:#{origin[i.succ..-1]}" unless origin.end_with?("/#{branch}")
2154
- [origin[0..i.pred], branch].tap { |ret| ret.map! { |val| shell_quote(val) } if quote }
2195
+ [origin[0..i.pred], branch].tap { |ret| ret.quote! if quote }
2155
2196
  end
2156
2197
 
2157
2198
  def commithash(val)