squared 0.4.10 → 0.4.12
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +57 -0
- data/README.md +3 -3
- data/README.ruby.md +63 -10
- data/lib/squared/common/base.rb +1 -0
- data/lib/squared/common/format.rb +8 -5
- data/lib/squared/common/utils.rb +4 -8
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +154 -5
- data/lib/squared/workspace/project/base.rb +56 -62
- data/lib/squared/workspace/project/docker.rb +24 -16
- data/lib/squared/workspace/project/git.rb +60 -52
- data/lib/squared/workspace/project/node.rb +76 -55
- data/lib/squared/workspace/project/python.rb +21 -13
- data/lib/squared/workspace/project/ruby.rb +4 -3
- data/lib/squared/workspace/project/support/class.rb +4 -4
- data/lib/squared/workspace/project.rb +2 -7
- data/lib/squared/workspace/series.rb +34 -0
- data/lib/squared/workspace/support/data.rb +10 -0
- data/lib/squared/workspace/support.rb +3 -0
- data/lib/squared/workspace.rb +1 -0
- metadata +3 -1
@@ -212,16 +212,11 @@ module Squared
|
|
212
212
|
elsif (val = log[:file])
|
213
213
|
file = val.is_a?(String) ? Time.now.strftime(val) : "#{@name}-#{Date.today}.log"
|
214
214
|
end
|
215
|
-
|
216
|
-
file
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
raise if @exception
|
221
|
-
|
222
|
-
file = nil
|
223
|
-
warn log_message(Logger::WARN, e, pass: true) if warning?
|
224
|
-
end
|
215
|
+
begin
|
216
|
+
file &&= @workspace.home.join(env('LOG_DIR', ''), file).realdirpath
|
217
|
+
rescue StandardError => e
|
218
|
+
file = nil
|
219
|
+
warn log_message(Logger::WARN, e, pass: true) if warning?
|
225
220
|
end
|
226
221
|
log[:progname] ||= @name
|
227
222
|
if (val = env('LOG_LEVEL', ignore: false))
|
@@ -355,7 +350,7 @@ module Squared
|
|
355
350
|
false
|
356
351
|
end
|
357
352
|
end
|
358
|
-
if path.is_a?(String) && (seg = path[%r{
|
353
|
+
if path.is_a?(String) && (seg = path[%r{\A(.+)[\\/]\*+\z}, 1])
|
359
354
|
return self unless checkdir.call(path = basepath(seg))
|
360
355
|
|
361
356
|
path = path.children.select { |val| checkdir.call(val) }
|
@@ -366,10 +361,11 @@ module Squared
|
|
366
361
|
return self
|
367
362
|
elsif !projectpath?(path = basepath(path)) || !checkdir.call(path)
|
368
363
|
return self
|
369
|
-
|
370
|
-
name = name
|
371
|
-
|
372
|
-
|
364
|
+
else
|
365
|
+
name = case name
|
366
|
+
when String, Symbol
|
367
|
+
name.to_s
|
368
|
+
end
|
373
369
|
end
|
374
370
|
if @withargs
|
375
371
|
data = @withargs.dup
|
@@ -389,6 +385,11 @@ module Squared
|
|
389
385
|
self
|
390
386
|
end
|
391
387
|
|
388
|
+
def chain(*args, **kwargs)
|
389
|
+
workspace.chain(*args, project: self, **kwargs)
|
390
|
+
self
|
391
|
+
end
|
392
|
+
|
392
393
|
def inject(obj, *args, **kwargs, &blk)
|
393
394
|
return self unless enabled?
|
394
395
|
|
@@ -518,7 +519,7 @@ module Squared
|
|
518
519
|
if @clean.is_a?(Enumerable) && !series?(@clean)
|
519
520
|
@clean.each do |val|
|
520
521
|
entry = path + (val = val.to_s)
|
521
|
-
if entry.directory? && val.match?(%r{[\\/]
|
522
|
+
if entry.directory? && val.match?(%r{[\\/]\z})
|
522
523
|
log&.warn "rm -rf #{entry}"
|
523
524
|
rm_rf(entry, verbose: verbose)
|
524
525
|
else
|
@@ -572,8 +573,7 @@ module Squared
|
|
572
573
|
end
|
573
574
|
end
|
574
575
|
|
575
|
-
def unpack(target, uri:, sync: true, digest: nil, ext: nil, force: false, depth: 1, headers: {},
|
576
|
-
from: :unpack)
|
576
|
+
def unpack(target, uri:, sync: true, digest: nil, ext: nil, force: false, depth: 1, headers: {}, from: :unpack)
|
577
577
|
if !target.exist?
|
578
578
|
target.mkpath
|
579
579
|
elsif !target.directory?
|
@@ -581,18 +581,11 @@ module Squared
|
|
581
581
|
elsif !target.empty?
|
582
582
|
raise_error('directory not empty', hint: target) unless force || env('UNPACK_FORCE')
|
583
583
|
create = true
|
584
|
-
elsif !uri
|
585
|
-
raise_error('no download uri', hint: target)
|
586
584
|
end
|
587
585
|
if digest
|
588
586
|
require 'digest'
|
589
|
-
|
590
|
-
|
591
|
-
digest = digest[n + 1..-1]
|
592
|
-
else
|
593
|
-
size = digest.size
|
594
|
-
end
|
595
|
-
algo = case size
|
587
|
+
digest, type = digest.split(':', 2).reverse
|
588
|
+
algo = case type&.downcase || digest.size
|
596
589
|
when 32, 'md5'
|
597
590
|
Digest::MD5
|
598
591
|
when 'rmd160'
|
@@ -610,16 +603,15 @@ module Squared
|
|
610
603
|
end
|
611
604
|
end
|
612
605
|
if (val = env('HEADERS')) && (val = parse_json(val, hint: "HEADERS_#{@envname}"))
|
613
|
-
headers = val
|
606
|
+
headers = headers.is_a?(Hash) ? headers.merge(val) : val
|
614
607
|
end
|
615
608
|
data = nil
|
616
609
|
(uri = as_a(uri)).each_with_index do |url, index|
|
617
|
-
last = index == uri.size - 1
|
618
610
|
fetch_uri(url, headers) do |f|
|
619
611
|
data = f.read
|
620
612
|
if algo && algo.hexdigest(data) != digest
|
621
613
|
data = nil
|
622
|
-
raise_error("checksum failed: #{digest}", hint: url) if
|
614
|
+
raise_error("checksum failed: #{digest}", hint: url) if index == uri.size - 1
|
623
615
|
end
|
624
616
|
next if ext && index == 0
|
625
617
|
|
@@ -632,14 +624,11 @@ module Squared
|
|
632
624
|
ext = 'txz'
|
633
625
|
end
|
634
626
|
end
|
635
|
-
if data
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
raise_error('no content', hint: url)
|
640
|
-
end
|
627
|
+
break uri = url if data
|
628
|
+
end
|
629
|
+
unless data && (ext ||= URI.parse(uri).path[/\.(\w+)(?:\?|\z)/, 1])
|
630
|
+
raise_error("no content#{data ? ' type' : ''}", hint: uri)
|
641
631
|
end
|
642
|
-
raise_error('no content type', hint: uri) unless ext ||= URI.parse(uri).path[/\.(\w+)(\?|$)/i, 1]
|
643
632
|
ext = ext.downcase
|
644
633
|
if (val = env("#{%w[zip 7z gem].include?(ext) ? ext.upcase : 'TAR'}_DEPTH", ignore: false))
|
645
634
|
depth = val.to_i
|
@@ -698,8 +687,8 @@ module Squared
|
|
698
687
|
ensure
|
699
688
|
if dir
|
700
689
|
remove_entry dir
|
701
|
-
|
702
|
-
file
|
690
|
+
else
|
691
|
+
file&.unlink
|
703
692
|
end
|
704
693
|
end
|
705
694
|
end
|
@@ -916,6 +905,7 @@ module Squared
|
|
916
905
|
end
|
917
906
|
return
|
918
907
|
end
|
908
|
+
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
919
909
|
cmd = session_done cmd
|
920
910
|
log&.info cmd
|
921
911
|
on :first, from
|
@@ -1178,8 +1168,8 @@ module Squared
|
|
1178
1168
|
end
|
1179
1169
|
|
1180
1170
|
def print_item(*val)
|
1181
|
-
puts if
|
1182
|
-
|
1171
|
+
puts if !printfirst? && stdout?
|
1172
|
+
printsucc
|
1183
1173
|
puts val unless val.empty? || (val.size == 1 && val.first.nil?)
|
1184
1174
|
end
|
1185
1175
|
|
@@ -1209,10 +1199,9 @@ module Squared
|
|
1209
1199
|
|
1210
1200
|
def print_footer(*lines, sub: nil, reverse: false, right: false, **kwargs)
|
1211
1201
|
n = Project.max_width(lines)
|
1212
|
-
sub = as_a sub
|
1213
1202
|
lines.map! do |val|
|
1214
1203
|
s = right ? val.rjust(n) : val.ljust(n)
|
1215
|
-
sub
|
1204
|
+
sub&.each { |h| s = sub_style(s, **h) }
|
1216
1205
|
s
|
1217
1206
|
end
|
1218
1207
|
ret = [sub_style(ARG[:BORDER][1] * n, styles: kwargs.key?(:border) ? kwargs[:border] : borderstyle), *lines]
|
@@ -1243,7 +1232,7 @@ module Squared
|
|
1243
1232
|
if data[:command]
|
1244
1233
|
if cmd =~ /\A(?:"((?:[^"]|(?<=\\)")+)"|'((?:[^']|(?<=\\)')+)'|(\S+)) /
|
1245
1234
|
path = $3 || $2 || $1
|
1246
|
-
cmd = cmd.sub(path,
|
1235
|
+
cmd = cmd.sub(path, stripext(path).upcase)
|
1247
1236
|
end
|
1248
1237
|
out << cmd
|
1249
1238
|
end
|
@@ -1502,12 +1491,12 @@ module Squared
|
|
1502
1491
|
b = sub_style("#{pkg} #{ver}", styles: theme[:inline])
|
1503
1492
|
c, d = rev == 1 || lock ? ['y/N', 'N'] : ['Y/n', 'Y']
|
1504
1493
|
e = lock ? " #{sub_style('(locked)', styles: color(:red))}" : ''
|
1505
|
-
confirm
|
1494
|
+
confirm "Upgrade to #{a}? #{b + e} [#{c}] ", d
|
1506
1495
|
end
|
1507
1496
|
|
1508
1497
|
def choice_index(msg, list, values: nil, accept: nil, series: false, trim: nil, column: nil,
|
1509
1498
|
multiple: false, force: true, **kwargs)
|
1510
|
-
puts if !series &&
|
1499
|
+
puts if !series && !printfirst?
|
1511
1500
|
msg = "#{msg} (optional)" unless force
|
1512
1501
|
unless (ret = choice(msg, list, multiple: multiple, force: force, **kwargs)) || !force
|
1513
1502
|
raise_error 'user cancelled'
|
@@ -1519,7 +1508,7 @@ module Squared
|
|
1519
1508
|
end
|
1520
1509
|
ret = multiple ? ret.map! { |val| val.sub(trim, '') } : ret.sub(trim, '') if trim
|
1521
1510
|
if column
|
1522
|
-
a, b = as_a
|
1511
|
+
a, b = as_a column
|
1523
1512
|
ret = as_a(ret).map! { |val| val[a, b || 1] }
|
1524
1513
|
ret = ret.first unless multiple
|
1525
1514
|
end
|
@@ -1554,7 +1543,7 @@ module Squared
|
|
1554
1543
|
ret << (val.empty? ? nil : val)
|
1555
1544
|
end
|
1556
1545
|
end
|
1557
|
-
|
1546
|
+
printsucc unless series
|
1558
1547
|
ret
|
1559
1548
|
end
|
1560
1549
|
|
@@ -1608,15 +1597,17 @@ module Squared
|
|
1608
1597
|
end
|
1609
1598
|
|
1610
1599
|
def indexitem(val)
|
1611
|
-
|
1612
|
-
|
1613
|
-
[$1.to_i, $2 && $2[1..-1]]
|
1600
|
+
[$1.to_i, $2 && $2[1..-1]] if val =~ /\A\^(\d+)(:.+)?\z/
|
1614
1601
|
end
|
1615
1602
|
|
1616
1603
|
def indexerror(val, list = nil)
|
1617
1604
|
raise_error("requested index #{val}", hint: list && "of #{list.size}")
|
1618
1605
|
end
|
1619
1606
|
|
1607
|
+
def printsucc
|
1608
|
+
@@print_order += 1
|
1609
|
+
end
|
1610
|
+
|
1620
1611
|
def color(val)
|
1621
1612
|
ret = theme[val]
|
1622
1613
|
ret && !ret.empty? ? ret : [val]
|
@@ -1642,16 +1633,14 @@ module Squared
|
|
1642
1633
|
end
|
1643
1634
|
|
1644
1635
|
def on(event, from, *args, **kwargs)
|
1645
|
-
return unless from
|
1646
|
-
|
1647
|
-
|
1648
|
-
if obj.is_a?(Array) && obj[1].is_a?(Hash)
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
target = obj
|
1654
|
-
end
|
1636
|
+
return unless from && (data = @events[event])
|
1637
|
+
|
1638
|
+
data[from]&.each do |obj|
|
1639
|
+
target, opts = if obj.is_a?(Array) && obj[1].is_a?(Hash)
|
1640
|
+
[obj[0], kwargs.empty? ? obj[1] : obj[1].merge(kwargs)]
|
1641
|
+
else
|
1642
|
+
[obj, kwargs]
|
1643
|
+
end
|
1655
1644
|
as_a(target, flat: true).each do |cmd|
|
1656
1645
|
case cmd
|
1657
1646
|
when Proc, Method
|
@@ -1796,6 +1785,10 @@ module Squared
|
|
1796
1785
|
(cur[0] == '0' && want[0] == '0' ? cur[2] != want[2] : cur[0] != want[0]) && !want[5]
|
1797
1786
|
end
|
1798
1787
|
|
1788
|
+
def printfirst?
|
1789
|
+
@@print_order == 0
|
1790
|
+
end
|
1791
|
+
|
1799
1792
|
def runnable?(val)
|
1800
1793
|
case val
|
1801
1794
|
when String, Enumerable, Proc, Method
|
@@ -1825,8 +1818,9 @@ module Squared
|
|
1825
1818
|
return true if val || from_sync?(ac = workspace.task_name(action))
|
1826
1819
|
return val if group && !(val = from_sync?(ac, group)).nil?
|
1827
1820
|
return val if (base = workspace.find_base(self)) && !(val = from_sync?(ac, base.ref)).nil?
|
1821
|
+
return false if workspace.series.chain?(val = task_join(name, action))
|
1828
1822
|
|
1829
|
-
if task_invoked?(
|
1823
|
+
if task_invoked?(val) && (!task_invoked?(ac) || !workspace.task_defined?(ac, 'sync'))
|
1830
1824
|
true
|
1831
1825
|
else
|
1832
1826
|
val = workspace.series.name_get(action)
|
@@ -138,10 +138,14 @@ module Squared
|
|
138
138
|
buildx(:build, args.extras, "#{flag}": param)
|
139
139
|
end
|
140
140
|
when :bake
|
141
|
-
format_desc action, flag, 'opts*,target*,context?'
|
141
|
+
format_desc action, flag, ':?,opts*,target*,context?'
|
142
142
|
task flag do |_, args|
|
143
|
-
args =
|
144
|
-
|
143
|
+
args = args.to_a
|
144
|
+
if args.first == ':'
|
145
|
+
choice_command :bake
|
146
|
+
else
|
147
|
+
buildx flag, args
|
148
|
+
end
|
145
149
|
end
|
146
150
|
end
|
147
151
|
when 'compose'
|
@@ -226,11 +230,11 @@ module Squared
|
|
226
230
|
image(:rm, sync: sync)
|
227
231
|
end
|
228
232
|
|
229
|
-
def compose(opts, flags = nil, script: false, args: nil, from: :
|
233
|
+
def compose(opts, flags = nil, script: false, args: nil, from: :run, **)
|
230
234
|
return opts if script == false
|
231
235
|
|
232
236
|
ret = docker_session
|
233
|
-
if from == :
|
237
|
+
if from == :run
|
234
238
|
case (n = filetype)
|
235
239
|
when 1, 2
|
236
240
|
ret << 'buildx' << 'bake'
|
@@ -254,14 +258,16 @@ module Squared
|
|
254
258
|
when Enumerable
|
255
259
|
ret.merge(opts.to_a)
|
256
260
|
end
|
257
|
-
[args, flags].each_with_index do |target, index|
|
258
|
-
next unless target
|
259
261
|
|
260
|
-
|
261
|
-
|
262
|
+
[args, flags].each_with_index do |target, index|
|
263
|
+
if target.is_a?(String)
|
264
|
+
ret << target
|
265
|
+
elsif (target = append_any(target, target: []))
|
266
|
+
ret.merge(target.map { |arg| index == 0 ? fill_option(arg) : quote_option('build-arg', arg) })
|
267
|
+
end
|
262
268
|
end
|
263
269
|
case from
|
264
|
-
when :
|
270
|
+
when :run
|
265
271
|
case @secrets
|
266
272
|
when String
|
267
273
|
ret << quote_option('secret', @secrets, double: true)
|
@@ -647,11 +653,11 @@ module Squared
|
|
647
653
|
index += 1
|
648
654
|
next unless confirm("#{h + b}? [#{c}] ", d, timeout: 60)
|
649
655
|
|
650
|
-
puts if
|
656
|
+
puts if printfirst?
|
651
657
|
end
|
652
658
|
yield id
|
653
659
|
end
|
654
|
-
puts log_message(Logger::INFO, 'none detected', subject: "#{name}:#{from}", hint: hint)
|
660
|
+
puts log_message(Logger::INFO, 'none detected', subject: "#{name}:#{from}", hint: hint) if found || y
|
655
661
|
end
|
656
662
|
rescue StandardError => e
|
657
663
|
log.error e
|
@@ -664,13 +670,13 @@ module Squared
|
|
664
670
|
def confirm_command(*args, title: nil, target: nil, as: nil)
|
665
671
|
return false unless title && target
|
666
672
|
|
667
|
-
puts unless
|
673
|
+
puts unless printfirst?
|
668
674
|
t = title.to_s.split(':')
|
669
675
|
emphasize(args, title: message(t.first.upcase, *t.drop(1)), border: borderstyle, sub: [
|
670
676
|
{ pat: /\A(\w+(?: => \w+)+)(.*)\z/, styles: theme[:header] },
|
671
677
|
{ pat: /\A(.+)\z/, styles: theme[:caution] }
|
672
678
|
])
|
673
|
-
|
679
|
+
printsucc
|
674
680
|
a = t.last.capitalize
|
675
681
|
b = sub_style(target, styles: theme[:subject])
|
676
682
|
c = as && sub_style(as, styles: theme[:inline])
|
@@ -683,6 +689,8 @@ module Squared
|
|
683
689
|
['Choose an image', 'images -a', 2]
|
684
690
|
when :exec
|
685
691
|
['Choose a container', 'ps -a', 0]
|
692
|
+
when :bake
|
693
|
+
['Choose a target', 'buildx bake --list=type=targets', 0]
|
686
694
|
else
|
687
695
|
['Choose a network', 'network ls', 0]
|
688
696
|
end
|
@@ -698,10 +706,10 @@ module Squared
|
|
698
706
|
when :run, :exec
|
699
707
|
values = [['Options', flag == :run], ['Arguments', flag == :exec]]
|
700
708
|
cmd = flag.to_s
|
701
|
-
when :rm
|
709
|
+
when :rm, :bake
|
702
710
|
values = ['Options']
|
703
711
|
multiple = true
|
704
|
-
cmd =
|
712
|
+
cmd = flag == :rm ? 'image rm' : "buildx bake -f #{shell_quote(dockerfile)}"
|
705
713
|
else
|
706
714
|
values = ['Options', ['Container', true]]
|
707
715
|
cmd = "network #{flag}"
|
@@ -14,7 +14,11 @@ module Squared
|
|
14
14
|
check = ->(proj) { proj.is_a?(Project::Git) && !proj.exclude?(Project::Git.ref) && git_clone?(proj.path) }
|
15
15
|
if uri.is_a?(Array)
|
16
16
|
base = name
|
17
|
-
uri.each
|
17
|
+
uri.each do |val|
|
18
|
+
if (proj = @project[val.to_s]) && check.call(proj)
|
19
|
+
repo << proj
|
20
|
+
end
|
21
|
+
end
|
18
22
|
elsif uri
|
19
23
|
data[name.to_s] = uri
|
20
24
|
elsif name.is_a?(Enumerable)
|
@@ -121,20 +125,18 @@ module Squared
|
|
121
125
|
def rev_write(name = nil, data = nil, sync: true, utc: nil)
|
122
126
|
return unless @revfile
|
123
127
|
|
128
|
+
sleep 0 while !sync && @revlock
|
129
|
+
@revlock = true
|
124
130
|
if name
|
125
131
|
data&.each { |key, val| rev_entry(name, key, val: val) }
|
126
132
|
rev_timeutc(name, utc) if utc
|
127
133
|
end
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
warn log_message(Logger::WARN, e, pass: true) if warning?
|
135
|
-
ensure
|
136
|
-
@revlock = false
|
137
|
-
end
|
134
|
+
File.write(@revfile, JSON.pretty_generate(@revdoc))
|
135
|
+
rescue StandardError => e
|
136
|
+
log&.debug e
|
137
|
+
warn log_message(Logger::WARN, e, pass: true) if warning?
|
138
|
+
ensure
|
139
|
+
@revlock = false
|
138
140
|
end
|
139
141
|
|
140
142
|
def git_clone?(path, name = nil)
|
@@ -288,17 +290,20 @@ module Squared
|
|
288
290
|
namespace(name = ws.task_name('git')) do
|
289
291
|
all = ws.task_join(name, 'all')
|
290
292
|
|
291
|
-
ws.format_desc(all,
|
293
|
+
ws.format_desc(all, 'stash|rebase|autostash?,depend?')
|
292
294
|
task 'all' do |_, args|
|
293
|
-
|
294
|
-
cmd = if
|
295
|
-
[
|
296
|
-
elsif
|
297
|
-
[
|
295
|
+
args = args.to_a
|
296
|
+
cmd = if args.include?('stash')
|
297
|
+
['stash', 'pull']
|
298
|
+
elsif args.include?('rebase')
|
299
|
+
['rebase']
|
300
|
+
elsif args.include?('autostash')
|
301
|
+
['autostash']
|
298
302
|
else
|
299
|
-
[
|
303
|
+
['pull']
|
300
304
|
end
|
301
|
-
cmd
|
305
|
+
cmd.map! { |val| ws.task_sync(val) }
|
306
|
+
cmd << ws.task_sync('depend') if args.include?('depend') && !ws.series.exclude?(:depend, true)
|
302
307
|
cmd << ws.task_sync('build')
|
303
308
|
Common::Utils.task_invoke(*cmd, **ws.invokeargs)
|
304
309
|
end
|
@@ -454,8 +459,8 @@ module Squared
|
|
454
459
|
when 'stash'
|
455
460
|
format_desc(action, flag, 'opts*', after: case flag
|
456
461
|
when :push then 'pathspec*'
|
457
|
-
when :list then nil
|
458
|
-
else '
|
462
|
+
when :clear, :list then nil
|
463
|
+
else 'stash?|:' end)
|
459
464
|
task flag do |_, args|
|
460
465
|
stash flag, args.to_a
|
461
466
|
end
|
@@ -513,15 +518,7 @@ module Squared
|
|
513
518
|
index = choice_commit(multiple: true)
|
514
519
|
else
|
515
520
|
index = []
|
516
|
-
args.each
|
517
|
-
if matchhead(val)
|
518
|
-
index << commithead(val)
|
519
|
-
elsif (sha = commithash(val))
|
520
|
-
index << sha
|
521
|
-
else
|
522
|
-
break
|
523
|
-
end
|
524
|
-
end
|
521
|
+
args.each { |val| index << (commithead(val) || commithash(val) || break) }
|
525
522
|
args = args.drop(index.size)
|
526
523
|
end
|
527
524
|
diff(flag, args, index: index)
|
@@ -1009,10 +1006,13 @@ module Squared
|
|
1009
1006
|
when :push
|
1010
1007
|
append_pathspec op.extras
|
1011
1008
|
when :pop, :apply, :drop
|
1012
|
-
|
1009
|
+
if op.extras.delete(':')
|
1010
|
+
op << choice_index('Choose a stash', git_spawn('stash list', stdout: false),
|
1011
|
+
column: /^[^@]+@\{(\d+)\}/, force: true)
|
1012
|
+
elsif !op.empty?
|
1013
1013
|
op << shell_escape(op.pop)
|
1014
|
-
op.clear
|
1015
1014
|
end
|
1015
|
+
op.clear
|
1016
1016
|
when :clear
|
1017
1017
|
if confirm("Remove #{sub_style('all', styles: theme[:active])} stash entries? [y/N] ", 'N')
|
1018
1018
|
source(stdout: true)
|
@@ -1061,7 +1061,7 @@ module Squared
|
|
1061
1061
|
{ pat: /^(## )(.+?)(\.{3})(.+)$/, styles: [nil, g, nil, r], index: -1 }
|
1062
1062
|
]
|
1063
1063
|
else
|
1064
|
-
[
|
1064
|
+
[pat: /^(\t+)([a-z]+: +.+)$/, styles: r, index: 2]
|
1065
1065
|
end
|
1066
1066
|
end
|
1067
1067
|
out, banner, from = source(io: true)
|
@@ -1069,7 +1069,7 @@ module Squared
|
|
1069
1069
|
list_result(ret, 'files', from: from, action: 'modified')
|
1070
1070
|
end
|
1071
1071
|
|
1072
|
-
def revbuild(flag = nil, opts = [], sync:
|
1072
|
+
def revbuild(flag = nil, opts = [], sync: nil, **kwargs)
|
1073
1073
|
statusargs = lambda do
|
1074
1074
|
{
|
1075
1075
|
include: relativepath(as_a(kwargs[:include]), all: true),
|
@@ -1087,6 +1087,7 @@ module Squared
|
|
1087
1087
|
sha = git_spawn('rev-parse --verify HEAD').chomp
|
1088
1088
|
return if sha.empty?
|
1089
1089
|
|
1090
|
+
sync = invoked_sync?('revbuild', flag) if sync.nil?
|
1090
1091
|
kwargs = kwargs.key?(:include) || kwargs.key?(:exclude) ? statusargs.call : @revbuild || {}
|
1091
1092
|
case flag
|
1092
1093
|
when :build
|
@@ -1454,7 +1455,7 @@ module Squared
|
|
1454
1455
|
else
|
1455
1456
|
git_spawn 'fetch --all --prune --quiet' if option('sync')
|
1456
1457
|
out, banner, from = source(cmd << '-vv --no-abbrev --list', io: true)
|
1457
|
-
ret = write_lines(out, grep: /^\*\s+#{Regexp.escape(head)}\s
|
1458
|
+
ret = write_lines(out, grep: [/^\*\s+#{Regexp.escape(head)}\s/], banner: banner, first: true) do |line|
|
1458
1459
|
next line if stdin?
|
1459
1460
|
|
1460
1461
|
data = line.sub(/^\*\s+/, '').split(/\s+/)
|
@@ -1582,7 +1583,7 @@ module Squared
|
|
1582
1583
|
op << shell_quote(remote) if remote
|
1583
1584
|
out, banner, from = source(io: true)
|
1584
1585
|
print_item banner
|
1585
|
-
ret = write_lines(out, grep: op.extras)
|
1586
|
+
ret = write_lines(out, grep: op.extras, prefix: "refs/#{flag}/")
|
1586
1587
|
list_result(ret, flag.to_s, from: from, grep: op.extras)
|
1587
1588
|
end
|
1588
1589
|
|
@@ -1659,7 +1660,7 @@ module Squared
|
|
1659
1660
|
def source(cmd = @session, exception: true, io: false, sync: true, stdout: false, stderr: false, banner: true,
|
1660
1661
|
multiple: false, **kwargs)
|
1661
1662
|
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
1662
|
-
banner = nil if
|
1663
|
+
banner = nil if banner && (multiple || !banner?)
|
1663
1664
|
if cmd.respond_to?(:done)
|
1664
1665
|
if io && banner == false
|
1665
1666
|
from = nil
|
@@ -1720,15 +1721,27 @@ module Squared
|
|
1720
1721
|
end
|
1721
1722
|
end
|
1722
1723
|
|
1723
|
-
def write_lines(data,
|
1724
|
-
grep
|
1725
|
-
|
1724
|
+
def write_lines(data, grep: [], prefix: nil, sub: nil, banner: nil, loglevel: nil, pass: false, first: false)
|
1725
|
+
grep = unless grep.empty?
|
1726
|
+
grep.map do |val|
|
1727
|
+
if val.is_a?(Regexp)
|
1728
|
+
val
|
1729
|
+
else
|
1730
|
+
val = ".*#{val}" if prefix && !val.sub!(/\A(\^|\\A)/, '')
|
1731
|
+
Regexp.new("#{prefix}#{val == '*' ? '.+' : val}")
|
1732
|
+
end
|
1733
|
+
end
|
1734
|
+
end
|
1735
|
+
sub = nil if stdin?
|
1726
1736
|
ret = 0
|
1727
1737
|
out = []
|
1728
1738
|
data.each do |line|
|
1729
1739
|
next if grep&.none? { |pat| pat.match?(line) }
|
1730
1740
|
|
1731
|
-
|
1741
|
+
if block_given?
|
1742
|
+
line = yield line
|
1743
|
+
next unless line
|
1744
|
+
end
|
1732
1745
|
if loglevel
|
1733
1746
|
log&.add loglevel, line
|
1734
1747
|
else
|
@@ -1746,20 +1759,15 @@ module Squared
|
|
1746
1759
|
ret
|
1747
1760
|
end
|
1748
1761
|
|
1749
|
-
def list_result(size, type,
|
1762
|
+
def list_result(size, type, grep: [], action: 'found', from: nil)
|
1750
1763
|
if verbose
|
1751
1764
|
if size > 0
|
1752
1765
|
styles = theme.fetch(:banner, []).reject { |s| s.to_s.end_with?('!') }
|
1753
1766
|
styles << :bold if styles.size <= 1
|
1754
1767
|
puts print_footer("#{size} #{size == 1 ? type.sub(/(?:(?<!l)e)?s\z/, '') : type}",
|
1755
|
-
sub:
|
1768
|
+
sub: [pat: /^(\d+)(.+)$/, styles: styles])
|
1756
1769
|
else
|
1757
|
-
puts empty_status("No #{type} were #{action}", 'grep', grep.
|
1758
|
-
when 0
|
1759
|
-
nil
|
1760
|
-
else
|
1761
|
-
grep.join(', ')
|
1762
|
-
end : grep.to_s)
|
1770
|
+
puts empty_status("No #{type} were #{action}", 'grep', grep.join(', '))
|
1763
1771
|
end
|
1764
1772
|
end
|
1765
1773
|
on :last, from
|
@@ -1840,7 +1848,7 @@ module Squared
|
|
1840
1848
|
when 'refspec'
|
1841
1849
|
refspec << shell_escape($2, quote: true)
|
1842
1850
|
end
|
1843
|
-
elsif op.arg?('
|
1851
|
+
elsif op.arg?('multiple')
|
1844
1852
|
op.found << opt
|
1845
1853
|
else
|
1846
1854
|
op.errors << opt
|
@@ -1855,7 +1863,7 @@ module Squared
|
|
1855
1863
|
op.merge(refspec)
|
1856
1864
|
end
|
1857
1865
|
op.delete('--all')
|
1858
|
-
elsif op.arg?('
|
1866
|
+
elsif op.arg?('multiple')
|
1859
1867
|
op.swap.merge(op.map! { |opt| shell_escape(opt, quote: true) })
|
1860
1868
|
return
|
1861
1869
|
elsif option('all')
|
@@ -1972,7 +1980,7 @@ module Squared
|
|
1972
1980
|
end
|
1973
1981
|
|
1974
1982
|
def commithash(val)
|
1975
|
-
val[
|
1983
|
+
val[/\A:(\h{5,40})\z/, 1] || val[/\A#\{(\h{5,40})\}\z/, 1]
|
1976
1984
|
end
|
1977
1985
|
|
1978
1986
|
def commithead(val)
|