squared 0.4.12 → 0.4.14
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 +100 -0
- data/README.ruby.md +6 -2
- data/lib/squared/common/base.rb +5 -2
- data/lib/squared/common/format.rb +8 -2
- data/lib/squared/common/prompt.rb +1 -1
- data/lib/squared/common/shell.rb +14 -14
- data/lib/squared/common/system.rb +21 -14
- data/lib/squared/common/utils.rb +7 -3
- data/lib/squared/config.rb +6 -5
- data/lib/squared/version.rb +1 -1
- data/lib/squared/workspace/application.rb +21 -12
- data/lib/squared/workspace/project/base.rb +348 -137
- data/lib/squared/workspace/project/docker.rb +95 -52
- data/lib/squared/workspace/project/git.rb +86 -52
- data/lib/squared/workspace/project/node.rb +71 -44
- data/lib/squared/workspace/project/python.rb +360 -131
- data/lib/squared/workspace/project/ruby.rb +140 -103
- data/lib/squared/workspace/project/support/class.rb +39 -3
- data/lib/squared/workspace/repo.rb +2 -1
- data/lib/squared/workspace/support/data.rb +2 -2
- metadata +1 -1
@@ -21,7 +21,8 @@ module Squared
|
|
21
21
|
compose: {
|
22
22
|
common: %w[all-resources compatibility dry-run ansi|b env-file=p f|file=p parallel=b profile=b progress=b
|
23
23
|
project-directory=p p|project-name=e].freeze,
|
24
|
-
build: %w[no-cache pull push with-dependencies q|quiet build-arg=qq builder=b m|memory=b
|
24
|
+
build: %w[check no-cache pull push with-dependencies q|quiet build-arg=qq builder=b m|memory=b
|
25
|
+
ssh=qq].freeze,
|
25
26
|
exec: %w[dry-run privileged d|detach e|env=qq index=i T|no-TTY=b? user=e w|workdir=q].freeze,
|
26
27
|
run: %w[build dry-run no-deps quiet-pull remove-orphans rm P|service-ports use-aliases cap-add=b cap-drop=b
|
27
28
|
d|detach entrypoint=q e|env=qq i|interactive=b? l|label=q name=b T|no-TTY=b? p|publish=e pull=b
|
@@ -32,22 +33,24 @@ module Squared
|
|
32
33
|
no-attach=b pull=b scale=i t|timeout=i wait-timeout=i].freeze
|
33
34
|
}.freeze,
|
34
35
|
container: {
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
36
|
+
create: %w[init i|interactive no-healthcheck oom-kill-disable privileged P|publish-all q|quiet read-only
|
37
|
+
rm runtime t|tty use-api-socket io-maxbandwidth=b io-maxiops=b add-host=q annotation=q
|
38
|
+
a|attach=b blkio-weight=i blkio-weight-device=i cap-add=b cap-drop=b cgroup-parent=b cgroupns=b
|
39
|
+
cidfile=p device=q device-cgroup-rule=q device-read-bps=q device-read-iops=q device-write-bps=q
|
40
|
+
device-write-iops=q disable-content-trust=b? dns=e dns-option=e dns-search=e domainname=b
|
41
|
+
entrypoint=q e|env=qq env-file=p expose=e gpus=q group-add=b health-cmd=q health-interval=b
|
42
|
+
health-retries=i health-start-interval=b health-start-period=b health-timeout=b h|hostname=e ip=b
|
43
|
+
ip6=e ipc=b isolation=b kernel-memory=b l|label=q label-file=p link=b link-local-ip=b
|
44
|
+
log-driver=b log-opt=q mac-address=e m|memory=b memory-reservation=b memory-swap=n
|
45
|
+
memory-swappiness=n mount=qq name=b network=b network-alias=b oom-score-adj=b pid=b pids-limit=n
|
46
|
+
platform=b p|publish=e pull=b restart=b runtime=b security-opt=q shm-size=b stop-signal=b
|
47
|
+
stop-timeout=i storage-opt=q sysctl=q tmpfs=q ulimit=q u|user=b userns=b uts=b v|volume=q
|
48
|
+
volume-driver=b volumes-from=b w|workdir=q].freeze,
|
49
|
+
run: %w[d|detach detach-keys=q sig-proxy=b?].freeze,
|
47
50
|
exec: %w[d|detach i|interactive privileged t|tty detach-keys=q e|env=qq env-file=p user=e
|
48
51
|
w|workdir=q].freeze,
|
49
52
|
update: %w[blkio-weight=i cpu-period=i cpu-quota=i cpu-rt-period=i cpu-rt-runtime=i c|cpu-shares=i cpus=f
|
50
|
-
cpuset-cpus=b cpuset-mems=b m|memory=b memory-reservation=b memory-swap=b pids-limit=
|
53
|
+
cpuset-cpus=b cpuset-mems=b m|memory=b memory-reservation=b memory-swap=b pids-limit=n
|
51
54
|
restart=q].freeze,
|
52
55
|
commit: %w[a|author=q c|change=q m|message=q pause=b?].freeze,
|
53
56
|
inspect: %w[s|size f|format=q].freeze,
|
@@ -60,7 +63,8 @@ module Squared
|
|
60
63
|
image: {
|
61
64
|
list: %w[a|all digests no-trunc f|filter=q format=q].freeze,
|
62
65
|
push: %w[a|all-tags disable-content-trust=b? platform=b q|quiet].freeze,
|
63
|
-
rm: %w[f|force no-prune].freeze
|
66
|
+
rm: %w[f|force no-prune].freeze,
|
67
|
+
save: %w[o|output=p platform=b].freeze
|
64
68
|
}.freeze,
|
65
69
|
network: {
|
66
70
|
connect: %w[alias=b driver-opt=q gw-priority=n ip=b ip6=b link=b link-local-ip=b].freeze,
|
@@ -90,8 +94,8 @@ module Squared
|
|
90
94
|
subtasks({
|
91
95
|
'build' => %i[tag context bake].freeze,
|
92
96
|
'compose' => %i[build run exec up].freeze,
|
93
|
-
'image' => %i[list rm push].freeze,
|
94
|
-
'container' => %i[run exec update commit inspect diff start stop restart pause unpause top stats kill
|
97
|
+
'image' => %i[list rm push tag save].freeze,
|
98
|
+
'container' => %i[run create exec update commit inspect diff start stop restart pause unpause top stats kill
|
95
99
|
rm].freeze,
|
96
100
|
'network' => %i[connect disconnect].freeze
|
97
101
|
})
|
@@ -107,7 +111,7 @@ module Squared
|
|
107
111
|
@tag = tag || tagname("#{@project}:#{@version || 'latest'}")
|
108
112
|
@mounts = mounts
|
109
113
|
@secrets = secrets
|
110
|
-
@registry =
|
114
|
+
@registry = tagjoin registry, kwargs[:username]
|
111
115
|
initialize_ref Docker.ref
|
112
116
|
initialize_logger(**kwargs)
|
113
117
|
initialize_env(**kwargs)
|
@@ -156,7 +160,7 @@ module Squared
|
|
156
160
|
compose! flag, args.to_a
|
157
161
|
end
|
158
162
|
when :exec, :run
|
159
|
-
format_desc action, flag, "service,command#{flag == :exec ? '' : '?'}
|
163
|
+
format_desc action, flag, "service,command#{flag == :exec ? '' : '?'}|:,args*,opts*"
|
160
164
|
task flag, [:service] do |_, args|
|
161
165
|
service = param_guard(action, flag, args: args, key: :service)
|
162
166
|
compose!(flag, args.extras, service: service)
|
@@ -174,7 +178,7 @@ module Squared
|
|
174
178
|
container(flag, args.extras, id: id)
|
175
179
|
end
|
176
180
|
end
|
177
|
-
when :run
|
181
|
+
when :run, :create
|
178
182
|
format_desc action, flag, 'image,opts*,args*'
|
179
183
|
task flag, [:image] do |_, args|
|
180
184
|
if args.image
|
@@ -197,12 +201,15 @@ module Squared
|
|
197
201
|
tag = param_guard(action, flag, args: args, key: :tag)
|
198
202
|
image(flag, args.extras, id: tag)
|
199
203
|
end
|
200
|
-
|
201
|
-
format_desc(action, flag, flag
|
204
|
+
else
|
205
|
+
format_desc(action, flag, case flag
|
206
|
+
when :rm, :save then 'id*,opts*'
|
207
|
+
when :tag then 'version?'
|
208
|
+
else 'opts*,args*' end)
|
202
209
|
task flag do |_, args|
|
203
210
|
args = args.to_a
|
204
|
-
if flag
|
205
|
-
choice_command
|
211
|
+
if args.empty? && flag != :list
|
212
|
+
choice_command flag
|
206
213
|
else
|
207
214
|
image flag, args
|
208
215
|
end
|
@@ -273,12 +280,12 @@ module Squared
|
|
273
280
|
ret << quote_option('secret', @secrets, double: true)
|
274
281
|
when Hash
|
275
282
|
append = lambda do |type|
|
276
|
-
|
283
|
+
Array(@secrets[type]).each { |arg| ret << quote_option('secret', "type=#{type},#{arg}", double: true) }
|
277
284
|
end
|
278
285
|
append.call(:file)
|
279
286
|
append.call(:env)
|
280
287
|
else
|
281
|
-
|
288
|
+
Array(@secrets).each { |arg| ret << quote_option('secret', arg) }
|
282
289
|
end
|
283
290
|
if (val = option('tag', ignore: false))
|
284
291
|
append_tag val
|
@@ -306,7 +313,7 @@ module Squared
|
|
306
313
|
when :bake
|
307
314
|
unless op.empty?
|
308
315
|
args = op.dup
|
309
|
-
op.
|
316
|
+
op.reset
|
310
317
|
if Dir.exist?(args.last)
|
311
318
|
if projectpath?(val = args.pop)
|
312
319
|
context = val
|
@@ -340,18 +347,20 @@ module Squared
|
|
340
347
|
|
341
348
|
def container(flag, opts = [], id: nil)
|
342
349
|
cmd, opts = docker_session('container', flag, opts: opts)
|
350
|
+
rc = flag == :run || flag == :create
|
343
351
|
list = OPT_DOCKER[:container].fetch(flag, [])
|
344
|
-
list += OPT_DOCKER[:container][:
|
345
|
-
|
352
|
+
list += OPT_DOCKER[:container][:create] if flag == :run
|
353
|
+
list += OPT_DOCKER[:container][:update] if rc
|
354
|
+
op = OptionPartition.new(opts, list, cmd, project: self, args: rc || flag == :exec)
|
346
355
|
from = :"container:#{flag}"
|
347
356
|
case flag
|
348
|
-
when :run, :exec
|
349
|
-
if
|
357
|
+
when :run, :create, :exec
|
358
|
+
if rc && !op.arg?('mount')
|
350
359
|
run = VAL_DOCKER[:run]
|
351
360
|
both = run[:bind] + run[:tmpfs]
|
352
361
|
diff = run[:bind].reject { |val| run[:tmpfs].include?(val) }
|
353
362
|
delim = Regexp.new(",\\s*(?=#{both.join('|')})")
|
354
|
-
|
363
|
+
Array(@mounts).each do |val|
|
355
364
|
args = []
|
356
365
|
tmpfs = true
|
357
366
|
val.split(delim).each do |opt|
|
@@ -378,7 +387,7 @@ module Squared
|
|
378
387
|
cmd << "--mount type=#{tmpfs ? 'tmpfs' : 'bind'},#{args.join(',')}"
|
379
388
|
end
|
380
389
|
end
|
381
|
-
append_command(flag, id
|
390
|
+
append_command(flag, id || tagmain, op.extras, from: from)
|
382
391
|
when :update
|
383
392
|
raise_error('missing container', hint: from) if op.empty?
|
384
393
|
op.append(escape: true)
|
@@ -442,7 +451,7 @@ module Squared
|
|
442
451
|
|
443
452
|
def image(flag, opts = [], sync: true, id: nil, registry: nil)
|
444
453
|
cmd, opts = docker_session('image', flag, opts: opts)
|
445
|
-
op = OptionPartition.new(opts, OPT_DOCKER[:image][
|
454
|
+
op = OptionPartition.new(opts, OPT_DOCKER[:image].fetch(flag, []), cmd, project: self)
|
446
455
|
exception = @exception
|
447
456
|
banner = true
|
448
457
|
from = :"image:#{flag}"
|
@@ -473,7 +482,7 @@ module Squared
|
|
473
482
|
end
|
474
483
|
else
|
475
484
|
if op.empty?
|
476
|
-
list_image(
|
485
|
+
list_image(:rm, docker_output('image ls -a'), from: from) do |val|
|
477
486
|
image(:rm, opts, sync: sync, id: val)
|
478
487
|
end
|
479
488
|
else
|
@@ -481,6 +490,14 @@ module Squared
|
|
481
490
|
end
|
482
491
|
return
|
483
492
|
end
|
493
|
+
when :tag, :save
|
494
|
+
list_image(flag, docker_output('image ls -a'), from: from) do |val|
|
495
|
+
op << val
|
496
|
+
if flag == :tag
|
497
|
+
op << tagname("#{@project}:#{op.extras.first}")
|
498
|
+
break
|
499
|
+
end
|
500
|
+
end
|
484
501
|
when :push
|
485
502
|
id ||= option('tag', ignore: false) || tagmain
|
486
503
|
registry ||= op.shift || option('registry') || @registry
|
@@ -497,7 +514,8 @@ module Squared
|
|
497
514
|
exception = true
|
498
515
|
banner = false
|
499
516
|
end
|
500
|
-
run(cmd, sync: sync, exception: exception, banner: banner, from: from)
|
517
|
+
ret = run(cmd, sync: sync, exception: exception, banner: banner, from: from)
|
518
|
+
print_success if success?(ret) && (flag == :tag || flag == :save)
|
501
519
|
end
|
502
520
|
|
503
521
|
def network(flag, opts = [], target: nil)
|
@@ -548,7 +566,9 @@ module Squared
|
|
548
566
|
end
|
549
567
|
|
550
568
|
def append_command(flag, val, list, target: @session, from: nil)
|
551
|
-
if (
|
569
|
+
if list.delete(':')
|
570
|
+
list << readline('Enter command [args]', force: true)
|
571
|
+
elsif (args = env('DOCKER_ARGS'))
|
552
572
|
list << args
|
553
573
|
end
|
554
574
|
case flag
|
@@ -571,7 +591,7 @@ module Squared
|
|
571
591
|
def append_file(type, target: @session)
|
572
592
|
return unless type == 2 || type == 4 || @file.is_a?(Array)
|
573
593
|
|
574
|
-
files =
|
594
|
+
files = Array(@file).map { |val| quote_option('file', path + val) }
|
575
595
|
if target.is_a?(Set)
|
576
596
|
target.merge(files)
|
577
597
|
else
|
@@ -645,7 +665,7 @@ module Squared
|
|
645
665
|
cols.each do |key|
|
646
666
|
next if (key == 'Tag' && !dd) || (key == 'Size' && data[key] == '0B')
|
647
667
|
|
648
|
-
puts "#{g + f} #{key}: #{
|
668
|
+
puts "#{g + f} #{key}: #{Array(data[key]).join(', ')}" unless data[key].to_s.empty?
|
649
669
|
end
|
650
670
|
w = 9 + flag.to_s.size + 4 + ee.size
|
651
671
|
puts g + sub_style(ARG[:BORDER][6] + (ARG[:BORDER][1] * w), styles: theme[:inline])
|
@@ -685,14 +705,14 @@ module Squared
|
|
685
705
|
|
686
706
|
def choice_command(flag)
|
687
707
|
msg, cmd, index = case flag
|
688
|
-
when :run, :rm
|
689
|
-
['Choose an image', 'images -a', 2]
|
690
708
|
when :exec
|
691
709
|
['Choose a container', 'ps -a', 0]
|
692
710
|
when :bake
|
693
711
|
['Choose a target', 'buildx bake --list=type=targets', 0]
|
694
|
-
|
712
|
+
when :connect, :disconnect
|
695
713
|
['Choose a network', 'network ls', 0]
|
714
|
+
else
|
715
|
+
['Choose an image', 'images -a', 2]
|
696
716
|
end
|
697
717
|
lines = `#{docker_output(cmd)}`.lines
|
698
718
|
header = lines.shift
|
@@ -702,25 +722,43 @@ module Squared
|
|
702
722
|
puts " # #{header}"
|
703
723
|
multiple = false
|
704
724
|
parse = ->(val) { val.split(/\s+/)[index] }
|
725
|
+
ctx = flag.to_s
|
705
726
|
case flag
|
706
727
|
when :run, :exec
|
707
728
|
values = [['Options', flag == :run], ['Arguments', flag == :exec]]
|
708
|
-
cmd = flag.to_s
|
709
729
|
when :rm, :bake
|
710
730
|
values = ['Options']
|
711
731
|
multiple = true
|
712
|
-
|
713
|
-
|
732
|
+
ctx = flag == :rm ? 'image rm' : "buildx bake -f #{shell_quote(dockerfile)}"
|
733
|
+
when :save
|
734
|
+
values = [['Output', true], 'Platform']
|
735
|
+
multiple = true
|
736
|
+
when :connect, :disconnect
|
714
737
|
values = ['Options', ['Container', true]]
|
715
|
-
|
738
|
+
ctx = "network #{flag}"
|
716
739
|
end
|
717
740
|
out, opts, args = choice_index(msg, lines, multiple: multiple, values: values)
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
741
|
+
cmd = docker_output ctx
|
742
|
+
case flag
|
743
|
+
when :tag
|
744
|
+
args = tagjoin @registry, @tag
|
745
|
+
when :save
|
746
|
+
opts = "#{opts}.tar" unless opts.end_with?('.tar')
|
747
|
+
cmd << quote_option('output', File.expand_path(opts))
|
748
|
+
if args
|
749
|
+
cmd << basic_option('platform', args)
|
750
|
+
args = nil
|
751
|
+
end
|
752
|
+
else
|
753
|
+
cmd << opts << '--'
|
754
|
+
end
|
755
|
+
cmd.merge(if out.is_a?(Array)
|
756
|
+
out.map! { |val| parse.call(val) }
|
757
|
+
else
|
758
|
+
[parse.call(out)]
|
759
|
+
end)
|
760
|
+
cmd << args
|
761
|
+
print_success if success?(run(cmd)) && ctx.match?(/\A(?:network|tag|save)/)
|
724
762
|
end
|
725
763
|
end
|
726
764
|
|
@@ -743,6 +781,11 @@ module Squared
|
|
743
781
|
val && projectpath?(val) ? shell_quote(path + val) : '.'
|
744
782
|
end
|
745
783
|
|
784
|
+
def tagjoin(*args, char: '/')
|
785
|
+
args.compact!
|
786
|
+
args.join(char) unless args.empty?
|
787
|
+
end
|
788
|
+
|
746
789
|
def tagname(val)
|
747
790
|
val = val.split(':').map! { |s| charname(s.sub(/^\W+/, '')) }
|
748
791
|
ret = val.join(':')
|
@@ -27,7 +27,7 @@ module Squared
|
|
27
27
|
base = name
|
28
28
|
@project.each_value { |proj| repo << proj if !proj.parent && check.call(proj) }
|
29
29
|
else
|
30
|
-
warn log_message(Logger::WARN, name, subject: 'git', hint: 'invalid'
|
30
|
+
warn log_message(Logger::WARN, name, subject: 'git', hint: 'invalid') if warning
|
31
31
|
return self
|
32
32
|
end
|
33
33
|
if base
|
@@ -340,7 +340,7 @@ module Squared
|
|
340
340
|
'restore' => %i[source staged worktree].freeze,
|
341
341
|
'rev' => %i[commit build output].freeze,
|
342
342
|
'show' => %i[format oneline textconv].freeze,
|
343
|
-
'stash' => %i[push pop apply drop clear list].freeze,
|
343
|
+
'stash' => %i[push pop apply branch drop clear list].freeze,
|
344
344
|
'switch' => %i[create detach merge].freeze,
|
345
345
|
'tag' => %i[add sign delete list].freeze
|
346
346
|
})
|
@@ -367,13 +367,13 @@ module Squared
|
|
367
367
|
case action
|
368
368
|
when 'pull', 'fetch'
|
369
369
|
if flag == :remote
|
370
|
-
format_desc action, flag, 'remote
|
370
|
+
format_desc action, flag, 'remote?,opts*'
|
371
371
|
task flag, [:remote] do |_, args|
|
372
372
|
if (remote = args.remote)
|
373
373
|
args = args.extras
|
374
374
|
else
|
375
375
|
remote = choice_remote
|
376
|
-
args = args.to_a
|
376
|
+
args = args.to_a
|
377
377
|
end
|
378
378
|
__send__(action, flag, args, remote: remote)
|
379
379
|
end
|
@@ -459,6 +459,7 @@ module Squared
|
|
459
459
|
when 'stash'
|
460
460
|
format_desc(action, flag, 'opts*', after: case flag
|
461
461
|
when :push then 'pathspec*'
|
462
|
+
when :branch then 'name,stash?|:'
|
462
463
|
when :clear, :list then nil
|
463
464
|
else 'stash?|:' end)
|
464
465
|
task flag do |_, args|
|
@@ -927,7 +928,7 @@ module Squared
|
|
927
928
|
source(sync: sync, sub: if verbose
|
928
929
|
[
|
929
930
|
{ pat: /^(.+)(\|\s+\d+\s+)([^-]*)(-+)(.*)$/, styles: color(:red), index: 4 },
|
930
|
-
{ pat: /^(.+)(\|\s+\d+\s+)(\++)(
|
931
|
+
{ pat: /^(.+)(\|\s+\d+\s+)(\++)(.*)$/, styles: color(:green), index: 3 }
|
931
932
|
]
|
932
933
|
end, **threadargs)
|
933
934
|
end
|
@@ -942,7 +943,7 @@ module Squared
|
|
942
943
|
return unless upstream
|
943
944
|
|
944
945
|
op = OptionPartition.new(opts, OPT_GIT[:rebase], cmd, project: self, no: OPT_GIT[:no][:rebase])
|
945
|
-
cmd <<
|
946
|
+
cmd << upstream
|
946
947
|
append_head op.shift
|
947
948
|
op.clear(pass: false)
|
948
949
|
when :onto
|
@@ -950,7 +951,7 @@ module Squared
|
|
950
951
|
|
951
952
|
cmd << '--interactive' if option('interactive', 'i')
|
952
953
|
cmd << shell_option('onto', commit) if commit
|
953
|
-
cmd <<
|
954
|
+
cmd << upstream
|
954
955
|
append_head branch
|
955
956
|
else
|
956
957
|
return unless VAL_GIT[:rebase][:send].include?(command)
|
@@ -984,7 +985,14 @@ module Squared
|
|
984
985
|
end
|
985
986
|
end
|
986
987
|
opts[:origin] = val if (val = option('origin', ignore: false))
|
987
|
-
|
988
|
+
if (val = option('branch', strict: true))
|
989
|
+
opts[:branch] = val
|
990
|
+
opts.delete(:revision)
|
991
|
+
elsif (val = option('revision', strict: true))
|
992
|
+
opts[:revision] = val
|
993
|
+
opts.delete(:branch)
|
994
|
+
opts.delete(:mirror)
|
995
|
+
end
|
988
996
|
opts[:local] = val != '0' if (val = option('local', strict: true))
|
989
997
|
opts.delete(:'recurse-submodules') || opts.delete(:'no-recurse-submodules') if append_submodules(from: :clone)
|
990
998
|
append_hash opts
|
@@ -1005,12 +1013,26 @@ module Squared
|
|
1005
1013
|
case flag
|
1006
1014
|
when :push
|
1007
1015
|
append_pathspec op.extras
|
1008
|
-
when :pop, :apply, :drop
|
1016
|
+
when :pop, :apply, :drop, :branch
|
1009
1017
|
if op.extras.delete(':')
|
1010
|
-
|
1011
|
-
|
1018
|
+
if flag == :branch
|
1019
|
+
if op.empty?
|
1020
|
+
values = [['Branch name', true]]
|
1021
|
+
else
|
1022
|
+
op << op.pop
|
1023
|
+
end
|
1024
|
+
end
|
1025
|
+
out = choice_index('Choose a stash', git_spawn('stash list', stdout: false),
|
1026
|
+
values: values, column: /^[^@]+@\{(\d+)\}/, force: true)
|
1027
|
+
if values
|
1028
|
+
op.merge(out.reverse)
|
1029
|
+
else
|
1030
|
+
op << out
|
1031
|
+
end
|
1012
1032
|
elsif !op.empty?
|
1013
|
-
op <<
|
1033
|
+
op << op.pop
|
1034
|
+
elsif flag == :branch
|
1035
|
+
raise_error 'no branch name'
|
1014
1036
|
end
|
1015
1037
|
op.clear
|
1016
1038
|
when :clear
|
@@ -1072,8 +1094,8 @@ module Squared
|
|
1072
1094
|
def revbuild(flag = nil, opts = [], sync: nil, **kwargs)
|
1073
1095
|
statusargs = lambda do
|
1074
1096
|
{
|
1075
|
-
include: relativepath(
|
1076
|
-
exclude: relativepath(
|
1097
|
+
include: relativepath(Array(kwargs[:include]), all: true),
|
1098
|
+
exclude: relativepath(Array(kwargs[:exclude]), all: true)
|
1077
1099
|
}
|
1078
1100
|
end
|
1079
1101
|
unless workspace.closed
|
@@ -1182,13 +1204,14 @@ module Squared
|
|
1182
1204
|
else
|
1183
1205
|
op = OptionPartition.new(opts, OPT_GIT[:checkout], cmd, project: self, no: OPT_GIT[:no][:checkout],
|
1184
1206
|
first: flag == :path ? matchpathspec : nil)
|
1185
|
-
if flag == :
|
1186
|
-
op.append(commit)
|
1187
|
-
.clear(pass: false)
|
1188
|
-
else
|
1207
|
+
if flag == :path
|
1189
1208
|
append_head
|
1190
1209
|
append_pathspec(op.extras, pass: false)
|
1210
|
+
print_success if success?(source)
|
1211
|
+
return
|
1191
1212
|
end
|
1213
|
+
op.append(commit)
|
1214
|
+
.clear(pass: false)
|
1192
1215
|
end
|
1193
1216
|
source
|
1194
1217
|
end
|
@@ -1228,9 +1251,9 @@ module Squared
|
|
1228
1251
|
|
1229
1252
|
def log!(flag, opts = [], range: [], index: [])
|
1230
1253
|
cmd, opts = git_session('log', opts: opts)
|
1231
|
-
op = OptionPartition.new(opts, collect_hash(OPT_GIT[:log]), cmd,
|
1232
|
-
|
1233
|
-
|
1254
|
+
op = OptionPartition.new(opts, collect_hash(OPT_GIT[:log]), cmd, project: self,
|
1255
|
+
no: collect_hash(OPT_GIT[:no][:log]),
|
1256
|
+
first: matchpathspec)
|
1234
1257
|
case flag
|
1235
1258
|
when :between, :contain
|
1236
1259
|
op << shell_quote(range.join(flag == :between ? '..' : '...'))
|
@@ -1617,19 +1640,20 @@ module Squared
|
|
1617
1640
|
red = color(:red)
|
1618
1641
|
grep.map! { |val| Regexp.new(val[1..-2]) }
|
1619
1642
|
files = status_data.map! do |a, b|
|
1620
|
-
next
|
1643
|
+
next if b.strip.empty? || (!grep.empty? && grep.none? { |pat| pat.match?(a) })
|
1621
1644
|
|
1622
1645
|
"#{sub_style(b, styles: red)} #{a}"
|
1623
1646
|
end
|
1624
1647
|
.compact
|
1625
1648
|
unless files.empty?
|
1626
1649
|
files = choice_index('Select files', files, multiple: true, force: true, trim: /^\S+\s/,
|
1627
|
-
accept: 'Add?')
|
1650
|
+
accept: [['Add?', false, true]])
|
1628
1651
|
end
|
1629
1652
|
op.swap(list + files)
|
1630
1653
|
end
|
1631
1654
|
end
|
1632
|
-
append_pathspec(op.extras)
|
1655
|
+
return source(git_session('status', '-s'), banner: false) unless append_pathspec(op.extras)
|
1656
|
+
|
1633
1657
|
verbose = flag == :add && !op.arg?('verbose')
|
1634
1658
|
print_success if success?(source) && verbose
|
1635
1659
|
return
|
@@ -1658,30 +1682,36 @@ module Squared
|
|
1658
1682
|
private
|
1659
1683
|
|
1660
1684
|
def source(cmd = @session, exception: true, io: false, sync: true, stdout: false, stderr: false, banner: true,
|
1661
|
-
multiple: false, **kwargs)
|
1685
|
+
multiple: false, from: nil, **kwargs)
|
1662
1686
|
cmd = cmd.target if cmd.is_a?(OptionPartition)
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1687
|
+
if io && banner == false
|
1688
|
+
from = nil
|
1689
|
+
banner = nil
|
1690
|
+
else
|
1691
|
+
banner = nil if banner && (multiple || !banner?)
|
1692
|
+
if cmd.respond_to?(:done)
|
1693
|
+
if from.nil? && (from = cmd.drop(1).find { |val| val.match?(/\A[a-z]{1,2}[a-z\-]*\z/) })
|
1694
|
+
from = :"git:#{from}"
|
1695
|
+
end
|
1696
|
+
banner &&= cmd.temp { |val| val.start_with?('--work-tree') || val.start_with?('--git-dir') }
|
1669
1697
|
end
|
1670
|
-
|
1698
|
+
from = nil if from == false
|
1671
1699
|
end
|
1672
1700
|
cmd = session_done cmd
|
1673
1701
|
log&.info cmd
|
1674
|
-
on :first, from
|
1675
1702
|
banner = if banner
|
1676
1703
|
format_banner((banner.is_a?(String) ? banner : cmd).gsub(File.join(path, ''), ''), banner: true)
|
1677
1704
|
end
|
1705
|
+
on :first, from
|
1678
1706
|
begin
|
1679
1707
|
if io
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1708
|
+
ret = if stdout
|
1709
|
+
`#{cmd}`
|
1710
|
+
else
|
1711
|
+
banner ? [IO.popen(cmd), banner, from] : IO.popen(cmd)
|
1712
|
+
end
|
1713
|
+
return ret
|
1714
|
+
elsif stdin? ? sync : stdout
|
1685
1715
|
print_item banner unless multiple
|
1686
1716
|
ret = `#{cmd}`
|
1687
1717
|
if !ret.empty?
|
@@ -1689,7 +1719,7 @@ module Squared
|
|
1689
1719
|
elsif success?(!banner.nil?)
|
1690
1720
|
print_success
|
1691
1721
|
end
|
1692
|
-
elsif sync || (!exception && !stderr)
|
1722
|
+
elsif !kwargs[:sub] && (sync || (!exception && !stderr))
|
1693
1723
|
print_item banner unless multiple
|
1694
1724
|
ret = shell(cmd, exception: exception)
|
1695
1725
|
else
|
@@ -1760,15 +1790,13 @@ module Squared
|
|
1760
1790
|
end
|
1761
1791
|
|
1762
1792
|
def list_result(size, type, grep: [], action: 'found', from: nil)
|
1763
|
-
if
|
1764
|
-
|
1765
|
-
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1770
|
-
puts empty_status("No #{type} were #{action}", 'grep', grep.join(', '))
|
1771
|
-
end
|
1793
|
+
if size == 0
|
1794
|
+
puts empty_status("No #{type} were #{action}", 'grep', grep.join(', '))
|
1795
|
+
elsif verbose
|
1796
|
+
styles = theme.fetch(:banner, []).reject { |s| s.to_s.end_with?('!') }
|
1797
|
+
styles << :bold if styles.size <= 1
|
1798
|
+
puts print_footer("#{size} #{size == 1 ? type.sub(/(?:(?<!l)e)?s\z/, '') : type}",
|
1799
|
+
sub: [pat: /^(\d+)(.+)$/, styles: styles])
|
1772
1800
|
end
|
1773
1801
|
on :last, from
|
1774
1802
|
end
|
@@ -1884,6 +1912,7 @@ module Squared
|
|
1884
1912
|
def append_pathspec(files = [], target: @session, expect: false, parent: false, pass: true)
|
1885
1913
|
if session_arg?('pathspec-from-file', target: target)
|
1886
1914
|
option_clear files
|
1915
|
+
true
|
1887
1916
|
else
|
1888
1917
|
if files.empty? && (val = option('pathspec', target: target))
|
1889
1918
|
files = split_escape val
|
@@ -1891,8 +1920,11 @@ module Squared
|
|
1891
1920
|
files = projectmap(files, parent: parent, pass: pass)
|
1892
1921
|
if !files.empty?
|
1893
1922
|
target << '--' << files.join(' ')
|
1923
|
+
true
|
1894
1924
|
elsif expect
|
1895
1925
|
raise_error(parent ? 'pathspec not present' : 'pathspec not within worktree')
|
1926
|
+
else
|
1927
|
+
false
|
1896
1928
|
end
|
1897
1929
|
end
|
1898
1930
|
end
|
@@ -1935,8 +1967,10 @@ module Squared
|
|
1935
1967
|
end
|
1936
1968
|
|
1937
1969
|
def foreachref(path, *args, format: nil)
|
1938
|
-
path =
|
1939
|
-
|
1970
|
+
path = Array(path).map! { |val| "refs/#{val}" }
|
1971
|
+
format &&= quote_option('format', format)
|
1972
|
+
ret = git_spawn('for-each-ref', format, *args, *path, stdout: workspace.windows?)
|
1973
|
+
ret.is_a?(String) ? ret.lines : ret
|
1940
1974
|
end
|
1941
1975
|
|
1942
1976
|
def git_session(*cmd, opts: nil, worktree: true, **kwargs)
|
@@ -1974,8 +2008,8 @@ module Squared
|
|
1974
2008
|
|
1975
2009
|
def repotrack(origin, branch, quote: true)
|
1976
2010
|
i = origin.index('/')
|
1977
|
-
branch = "#{branch}:#{origin[i + 1..-1]}" unless origin.end_with?("/#{branch}")
|
1978
|
-
ret = [origin[0..i - 1], branch]
|
2011
|
+
branch = "#{branch}:#{origin[(i + 1)..-1]}" unless origin.end_with?("/#{branch}")
|
2012
|
+
ret = [origin[0..(i - 1)], branch]
|
1979
2013
|
quote ? ret.map! { |val| shell_quote(val) } : ret
|
1980
2014
|
end
|
1981
2015
|
|