squared 0.7.2 → 0.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9e8d3d41e090465c85e45088c984711f2a26f6ab2f38d56ed8b58658735f678
4
- data.tar.gz: 2ff93124747a950b6ac94424052268e4ab6b107e934a2fd16478ca03d74a5409
3
+ metadata.gz: cbb8baead0c85c247f6c587d2fce277c6e405d3426bcf64c081df7a5f00d4fc4
4
+ data.tar.gz: d9e1eb35ad8d447e3884f74a4a2baf42aee82a39bc729214f16b26a1dfbcb697
5
5
  SHA512:
6
- metadata.gz: 60b75a0d2d6c361ccf9341496b0b4e9e3a0599030ea6099f50a2819246111ff671a8f52cf583e91294593179949542f1e18814059c953007bbee528c1dbaa244
7
- data.tar.gz: c52d560aacea0d6279948db05d29c1a5b5c55a5d7fb2218f03d418122417a8ca3377a1b4af54238538d4d911c4827b6a2921b76001b161a6bfdd460e55dd13e5
6
+ metadata.gz: 6e4e0e6a5e48e0d8c7e1059df7ff4e38dac032b584a5c4468d05c11932c28a5e74dfb25b4a5c6384928d5e51c45dc09a8eadb8e9d0871eaf98e58cbd3cf58f71
7
+ data.tar.gz: 430bde498c8b0eeccf4eb546441cbb2afdc77b920dd7d0b00c4621b51eb612ece6f786622df624cfdf758d55898762db56e54e804f2af951b3584b8258f47650
data/CHANGELOG.md CHANGED
@@ -1,5 +1,80 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.4] - 2026-03-20
4
+
5
+ ### Added
6
+
7
+ - Ruby command bundle action check was implemented.
8
+ - Ruby command pry with stored command options was created.
9
+ - Node command tsc options were updated to 6.0.
10
+ - Ruby command rdbg with stored command options was created.
11
+
12
+ ### Changed
13
+
14
+ - Project base method dependindex replaces private instance variable.
15
+
16
+ ### Fixed
17
+
18
+ - Repo completely ignored group and ref method arguments since inception.
19
+ - Ruby command version did not abort asdf "Not installed" error.
20
+
21
+ ## [0.7.3] - 2026-03-11
22
+
23
+ ### Added
24
+
25
+ - Python command install action user for non-venv was implemented.
26
+ - Ruby command version can create .ruby-version in project directory.
27
+ - Ruby command reshim calls version manager to regenerate bin paths.
28
+ - Git command diff can be piped to an output file.
29
+
30
+ ### Changed
31
+
32
+ - Python command publish detects twine through the file system.
33
+ - Git revbuild can bypass checksum by project name using GIT_FORCE.
34
+ - Ruby method serve uses as default port 3000 due to Errno::EACCES.
35
+
36
+ ### Fixed
37
+
38
+ - Node command outdated using PNPM did not work in nested projects.
39
+
40
+ ## [0.6.11] - 2026-03-11
41
+
42
+ ### Changed
43
+
44
+ - Git internal data calls do not write to logs.
45
+
46
+ ## [0.5.22] - 2026-03-11
47
+
48
+ - Project base run command was not covered due to lack of type checking.
49
+
50
+ ## [0.4.36] - 2026-03-11
51
+
52
+ ### Added
53
+
54
+ - Python venv initialization installs setuptools when detected.
55
+ - Node task depend adds prod option flags when NODE_ENV=production.
56
+
57
+ ### Fixed
58
+
59
+ - OptionPartition methods with escape parameter were reordered.
60
+ - OptionPartition methods with quote parameter were revised.
61
+
62
+ ## [0.6.10] - 2026-02-23
63
+
64
+ ### Added
65
+
66
+ - Docker command image action [ls|rm|tag|save] can be filtered.
67
+ - Pip command options were updated to 26.1.
68
+
69
+ ### Changed
70
+
71
+ - Ruby property autodetect was converted into an accessor.
72
+ - Python property editable was converted into an accessor.
73
+
74
+ ### Fixed
75
+
76
+ - Gem command install did not respond to interactive prompt.
77
+
3
78
  ## [0.7.2] - 2026-02-09
4
79
 
5
80
  ### Added
@@ -1668,7 +1743,7 @@
1668
1743
  - Rake did not set original rakefile when calling itself.
1669
1744
  - Extended tasks were not associated to their supporting class method.
1670
1745
 
1671
- ## [0.1.0] - 2024-12-7
1746
+ ## [0.1.0] - 2024-12-07
1672
1747
 
1673
1748
  ### Added
1674
1749
 
@@ -1689,15 +1764,19 @@
1689
1764
  - Git pull did not display colors for diff bar chart.
1690
1765
  - Git commit did not fetch latest refs before submitting.
1691
1766
 
1692
- ## [0.0.12] - 2024-12-1
1767
+ ## [0.0.12] - 2024-12-01
1693
1768
 
1694
1769
  ### Added
1695
1770
 
1696
1771
  - Changelog was created.
1697
1772
 
1773
+ [0.7.4]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.4
1774
+ [0.7.3]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.3
1698
1775
  [0.7.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.2
1699
1776
  [0.7.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.1
1700
1777
  [0.7.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.0
1778
+ [0.6.11]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.11
1779
+ [0.6.10]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.10
1701
1780
  [0.6.9]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.9
1702
1781
  [0.6.8]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.8
1703
1782
  [0.6.7]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.7
@@ -1708,6 +1787,7 @@
1708
1787
  [0.6.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.2
1709
1788
  [0.6.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.1
1710
1789
  [0.6.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.0
1790
+ [0.5.22]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.22
1711
1791
  [0.5.21]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.21
1712
1792
  [0.5.20]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.20
1713
1793
  [0.5.19]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.19
@@ -1730,6 +1810,7 @@
1730
1810
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
1731
1811
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
1732
1812
  [0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
1813
+ [0.4.36]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.36
1733
1814
  [0.4.35]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.35
1734
1815
  [0.4.34]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.34
1735
1816
  [0.4.33]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.33
data/README.md CHANGED
@@ -133,7 +133,7 @@ Node = Workspace::Project::Node # tsc
133
133
  Node.options("build:dev", "target=es2022", project: "tsconfig.json") # :node (ref)
134
134
  Node.options("build:dev", "outDir=tmp", :squared) # squared (project name)
135
135
 
136
- Ruby = Workspace::Project::Ruby # ruby | gem | rake | bundle | irb | rbs | rubocop
136
+ Ruby = Workspace::Project::Ruby # ruby | gem | rake | bundle | irb | rdbg | rbs | rubocop | pry
137
137
  Ruby.options("lint", "rubocop", opts: ["gemfile=Gemfile"]) # :ruby
138
138
  Ruby.options("lint", "--parallel", :squared)
139
139
 
@@ -641,7 +641,7 @@ BANNER_${NAME}=0 #
641
641
  VERBOSE=0 # console output level
642
642
  VERBOSE_${NAME}=0 # 0,1,2,n
643
643
 
644
- REVBUILD_FORCE=1 # Rebuild all targets
644
+ REVBUILD_FORCE=1 # Rebuild all targets (GIT_FORCE)
645
645
  REVBUILD_FORCE_${NAME}=1 # Rebuild project
646
646
 
647
647
  PREREQS_${NAME}=build,copy # Class method name to invoke
@@ -749,12 +749,13 @@ docker build --no-cache --label=v1 --build-arg="NODE_TAG=24" --build-arg="RUBY_V
749
749
  | compose | run | VERSION=s |
750
750
  | compose | publish | TAG=s REGISTRY=s |
751
751
  | container | commit | REGISTRY=s PLATFORM=s DISABLE_CONTENT_TRUST=0,1 |
752
- | container | -run -create -exec | ALL=1 |
752
+ | container | -run -create -exec | ALL=1 FILTER=s |
753
753
  | | -update -commit | |
754
754
  | image | rm | Y=1 |
755
755
  | image | push | TAG=s REGISTRY=s |
756
756
  | image | -push | ALL=1 |
757
- | network | * | ALL=1 |
757
+ | image | -push -pull | FILTER=s |
758
+ | network | * | ALL=1 FILTER=s |
758
759
 
759
760
  ### asdf
760
761
 
@@ -10,7 +10,9 @@ module Squared
10
10
  private_constant :QUOTE_VALUE
11
11
 
12
12
  String.define_method(:stripquote) { sub(QUOTE_VALUE, '\2') }
13
- Array.define_method(:quote!) { |**kwargs| map { |s| Shell.shell_quote(s, **kwargs) } }
13
+ Array.define_method(:quote!) do |escape: false, **kwargs|
14
+ map { |s| escape && !Rake::Win32.windows? ? Shellwords.escape(s) : Shell.shell_quote(s, **kwargs) }
15
+ end
14
16
 
15
17
  module_function
16
18
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.7.2'
4
+ VERSION = '0.7.4'
5
5
  end
@@ -466,7 +466,7 @@ module Squared
466
466
  args[0] = instance_eval(&blk) || f
467
467
  return unless args.first
468
468
  end
469
- if args.all? { |val| val.is_a?(Array) }
469
+ if args.all?(Array)
470
470
  var = {}
471
471
  cmd = args.each_with_object([]) do |val, out|
472
472
  case val.first
@@ -782,19 +782,18 @@ module Squared
782
782
  ensure
783
783
  if dir
784
784
  remove_entry dir
785
- elsif delete && file&.exist?
785
+ elsif delete && file.exist?
786
786
  file.unlink
787
787
  end
788
788
  end
789
789
  end
790
790
 
791
- def asdf(flag, opts = [], version: nil)
791
+ def asdf(flag, opts = [], name: nil, version: nil, banner: true)
792
792
  return unless @asdf
793
793
 
794
794
  cmd = flag == :update ? session('asdf', 'plugin update') : session('asdf', flag)
795
- name = @asdf.first
795
+ name ||= @asdf.first
796
796
  legacy = @@asdf.version == 15
797
- banner = true
798
797
  case flag
799
798
  when :set
800
799
  u = has_value?(opts, 'u', 'home')
@@ -817,7 +816,7 @@ module Squared
817
816
  cmd << name
818
817
  banner = false if flag == :latest || flag == :where
819
818
  end
820
- success?(run(banner: banner, from: symjoin('asdf', flag)), flag == :set || flag == :reshim)
819
+ success?(run(banner: banner, from: symjoin('asdf', flag)), banner, flag == :set || flag == :reshim)
821
820
  end
822
821
 
823
822
  def first(key, *args, **kwargs, &blk)
@@ -1006,7 +1005,7 @@ module Squared
1006
1005
  run_set(output[0], *args, **kwargs)
1007
1006
  when :dependfile
1008
1007
  @dependindex = nil
1009
- @dependfile = val.nil? ? nil : basepath(*args)
1008
+ @dependfile = (basepath(*args) if val)
1010
1009
  else
1011
1010
  instance_variable_set(:"@#{key}", val)
1012
1011
  end
@@ -1114,7 +1113,7 @@ module Squared
1114
1113
  end
1115
1114
 
1116
1115
  def dependtype(*)
1117
- @dependindex ? @dependindex.succ : 0
1116
+ dependindex&.succ || 0
1118
1117
  end
1119
1118
 
1120
1119
  def dependname
@@ -1281,7 +1280,7 @@ module Squared
1281
1280
  print_error e
1282
1281
  end
1283
1282
  log[:progname] ||= @name
1284
- env('LOG_LEVEL', ignore: false) { |val| log[:level] = val.start_with?(/\d/) ? log_sym(val.to_i) : val }
1283
+ env('LOG_LEVEL', ignore: false) { |s| log[:level] = s.start_with?(/\d/) ? log_sym(s.to_i) : s }
1285
1284
  log.delete(:file)
1286
1285
  @log = [file, log]
1287
1286
  end
@@ -1460,17 +1459,17 @@ module Squared
1460
1459
  s += "#{indent || (last && data[final].last == kwargs[:context]) ? ' ' : a} "
1461
1460
  k += 1
1462
1461
  end
1463
- s += "#{j ? d : c}#{b * 3} #{tag.call(proj)}"
1462
+ s + "#{j ? d : c}#{b * 3} #{tag.call(proj)}"
1464
1463
  end
1465
1464
  end
1466
1465
  if order
1467
1466
  n = order.size
1468
1467
  order[name] ||= if proj.parent
1469
- if order[s = proj.parent.name]
1470
- order[s] += 1
1468
+ if order[key = proj.parent.name]
1469
+ order[key] += 1
1471
1470
  n.pred
1472
1471
  else
1473
- order[s] = n.succ
1472
+ order[key] = n.succ
1474
1473
  n
1475
1474
  end
1476
1475
  else
@@ -2044,10 +2043,12 @@ module Squared
2044
2043
  [shell_bin(a), b].compact.join(' ')
2045
2044
  end
2046
2045
 
2047
- def parse_json(val, kind: Hash, hint: nil)
2046
+ def parse_json(val, kind: Hash, key: nil, hint: nil, &blk)
2048
2047
  ret = JSON.parse(val)
2049
2048
  raise_error 'invalid JSON'.subhint(kind.name), val, hint: hint if kind && !ret.is_a?(kind)
2050
- ret
2049
+ return ret unless key
2050
+
2051
+ block_given? ? ret.fetch(key, &blk) : ret[key]
2051
2052
  rescue => e
2052
2053
  print_error(kind ? Logger::ERROR : Logger::INFO, e, subject: name)
2053
2054
  end
@@ -2421,7 +2422,7 @@ module Squared
2421
2422
  ret = []
2422
2423
  if data[:command]
2423
2424
  ret[0] = data[:command]
2424
- ret[1] = data[:opts] unless diso
2425
+ ret[1] = data[:opts] unless noopt
2425
2426
  ret[3] = data[:args]
2426
2427
  elsif data[:script]
2427
2428
  ret[1] = data[:script]
@@ -2430,7 +2431,7 @@ module Squared
2430
2431
  else
2431
2432
  ret[0] = false
2432
2433
  end
2433
- ret[2] = data[:env] unless dise
2434
+ ret[2] = data[:env] unless noenv
2434
2435
  ret
2435
2436
  end
2436
2437
  case global
@@ -2445,7 +2446,7 @@ module Squared
2445
2446
  when Hash
2446
2447
  @output = parse.call(data)
2447
2448
  when Enumerable
2448
- @output = if cmd.all? { |data| data.is_a?(Hash) }
2449
+ @output = if cmd.all?(Hash)
2449
2450
  noopt = false
2450
2451
  noenv = false
2451
2452
  cmd.map { |data| parse.call(data) }
@@ -2564,13 +2565,19 @@ module Squared
2564
2565
  end
2565
2566
  end
2566
2567
 
2567
- def dependfile_set(list)
2568
+ def dependfile_set(list, default: 0)
2568
2569
  @dependindex = if @dependname
2569
2570
  @dependfile = basepath @dependname
2570
2571
  list.index(@dependname)
2571
2572
  else
2572
- list.index { |file| exist?(file) }.tap { |i: 0| @dependfile = basepath(list[i]) }
2573
- end
2573
+ list.index { |file| exist?(file) }.tap { |i| @dependfile = basepath(list[i || default]) }
2574
+ end || (list unless enabled?)
2575
+ end
2576
+
2577
+ def dependindex
2578
+ dependfile_set @dependindex if @dependindex.is_a?(Array)
2579
+
2580
+ @dependindex unless @dependindex.is_a?(Array)
2574
2581
  end
2575
2582
 
2576
2583
  def as_get(val, from, *type)
@@ -72,8 +72,8 @@ module Squared
72
72
  }.freeze,
73
73
  network: {
74
74
  connect: %w[alias=b driver-opt=q gw-priority=n ip=b ip6=q link=b link-local-ip=q].freeze,
75
- create: %w[attachable config-only gateway ingress internal ipv4 ipv6 aux-address=q config-from=b d|driver=b
76
- ip-range=q ipam-driver=b ipam-opt=q label=q o|opt=q scope=b subnet=q].freeze,
75
+ create: %w[attachable config-only gateway=q ingress internal ipv4 ipv6 aux-address=q config-from=b
76
+ d|driver=b ip-range=q ipam-driver=b ipam-opt=q label=q o|opt=q scope=b subnet=q].freeze,
77
77
  disconnect: %w[f|force].freeze
78
78
  }.freeze
79
79
  }.freeze
@@ -128,7 +128,7 @@ module Squared
128
128
  self.global = nil
129
129
  return unless dockerfile(kwargs[:file]).exist?
130
130
 
131
- self.tag = kwargs[:tag] || tagname("#{@project}:#{@version || 'latest'}")
131
+ @tag = kwargs[:tag] || tagname("#{@project}:#{@version || 'latest'}")
132
132
  @context = kwargs[:context]
133
133
  @mounts = mounts
134
134
  @secrets = kwargs[:secrets]
@@ -298,14 +298,18 @@ module Squared
298
298
  end
299
299
  else
300
300
  format_desc(action, flag, case flag
301
- when :rm, :save then 'id*,opts*'
302
- when :tag then 'version?'
301
+ when :rm, :save then 'id,opts*'
302
+ when :tag then 'version'
303
303
  else 'opts*,args*'
304
- end)
304
+ end, before: 'pattern?')
305
305
  task flag do |_, args|
306
306
  args = args.to_a
307
+ n = args.size
308
+ if (n > 1 || (flag == :ls && n > 0)) && OptionPartition.pattern?(args.first)
309
+ filter = args.shift
310
+ end
307
311
  if !args.empty? || flag == :ls
308
- image flag, args
312
+ image(flag, args, filter: filter)
309
313
  else
310
314
  choice_command flag
311
315
  end
@@ -531,7 +535,7 @@ module Squared
531
535
  return unless confirm_command(cmd.to_s, title: from, target: id, as: latest)
532
536
 
533
537
  registry = option('registry') || @registry
534
- run(from: from, exception: registry.nil? ? exception : true)
538
+ run(from: from, exception: registry.nil? ? exception? : true)
535
539
  return unless registry
536
540
 
537
541
  opts = []
@@ -556,7 +560,7 @@ module Squared
556
560
  run(from: from)
557
561
  end
558
562
 
559
- def image(flag, opts = [], sync: true, id: nil, registry: nil)
563
+ def image(flag, opts = [], sync: true, id: nil, registry: nil, filter: nil)
560
564
  cmd, opts = docker_session('image', flag, opts: opts)
561
565
  op = OptionPartition.new(opts, OPT_DOCKER[:image].fetch(flag, []), cmd, project: self)
562
566
  exception = exception?
@@ -574,7 +578,7 @@ module Squared
574
578
  opts.delete(val)
575
579
  break
576
580
  end
577
- list_image(:run, from: from) do |val|
581
+ list_image(:run, filter: filter, from: from) do |val|
578
582
  container(:run, if name
579
583
  opts.dup << "name=#{index == 0 ? name : "#{name}-#{index}"}"
580
584
  else
@@ -588,7 +592,7 @@ module Squared
588
592
  when :rm
589
593
  unless id
590
594
  if op.empty?
591
- list_image(:rm, from: from) { |val| image(:rm, opts, sync: sync, id: val) }
595
+ list_image(:rm, filter: filter, from: from) { |val| image(:rm, opts, sync: sync, id: val) }
592
596
  else
593
597
  op.each { |val| run(cmd.temp(val), sync: sync, from: from) }
594
598
  end
@@ -600,13 +604,16 @@ module Squared
600
604
  banner = false
601
605
  end
602
606
  when :tag, :save
603
- list_image(flag, from: from) do |val|
607
+ found = false
608
+ list_image(flag, filter: filter, from: from) do |val|
604
609
  op << val
605
- next unless flag == :tag
606
-
607
- op << tagname("#{project}:#{op.first}")
608
- break
610
+ found = true
611
+ if flag == :tag
612
+ op << tagname("#{project}:#{op.first}")
613
+ break
614
+ end
609
615
  end
616
+ raise_error ArgumentError, 'target not specified', hint: flag unless found
610
617
  when :pull
611
618
  if !id
612
619
  id = tagmain
@@ -795,12 +802,20 @@ module Squared
795
802
  [cmd, status, no]
796
803
  end
797
804
 
798
- def list_image(flag, cmd = docker_output('image ls -a'), hint: nil, no: true, from: nil)
805
+ def list_image(flag, cmd = docker_output('image ls -a'), filter: nil, hint: nil, no: true, from: nil)
799
806
  pwd_set(from: from) do
800
807
  index = 1
801
808
  all = option('all', prefix: 'docker')
802
809
  y = from == :'image:rm' && option('y', prefix: 'docker')
803
- pat = /\b(?:#{dnsname(name)}|#{tagname(project)}|#{tagmain.split(':', 2).first})\b/
810
+ filter = env('DOCKER_FILTER', filter).to_s
811
+ pat = if OptionPartition.pattern?(filter)
812
+ Regexp.new(filter)
813
+ elsif filter.match?(/[:_-]$/)
814
+ /\b#{Regexp.escape(filter)}/
815
+ else
816
+ filter = filter.empty? ? '(?:[:_-]|$)' : "[:_-]#{filter}"
817
+ /\b(?:#{dnsname(name)}|#{tagname(project)}|#{tagmain.split(':', 2).first})#{filter}/
818
+ end
804
819
  IO.popen(cmd.temp('--format=json')).each do |line|
805
820
  data = JSON.parse(line)
806
821
  id = data['ID']
@@ -436,7 +436,7 @@ module Squared
436
436
  end
437
437
  if squash
438
438
  found = false
439
- git_spawn(git_output('log --format=%h'), stdout: false).each do |val|
439
+ git_spawn('log --format=%h', stdout: false).each do |val|
440
440
  if found
441
441
  squash = val.chomp
442
442
  break
@@ -1320,7 +1320,12 @@ module Squared
1320
1320
  OptionPartition.uniq!(args)
1321
1321
  end
1322
1322
  run_p(*Array(kwargs[:before]), sync: sync, from: :revbuild) if kwargs[:before]
1323
- if (cur = workspace.rev_entry(name)) && cur['revision'] == sha && !env('REVBUILD_FORCE')
1323
+ force = if (force = env('REVBUILD_FORCE', strict: true))
1324
+ force != '0' && force != 'false'
1325
+ elsif (force = ENV['GIT_FORCE'] || ENV['REVBUILD_FORCE'])
1326
+ split_escape(force).any? { |val| val == '1' || val == 'true' || val == name }
1327
+ end
1328
+ if !force && (cur = workspace.rev_entry(name)) && cur['revision'] == sha
1324
1329
  files = status_digest(*args, **kwargs)
1325
1330
  if cur['files'].size == files.size && cur['files'].find { |key, val| files[key] != val }.nil?
1326
1331
  workspace.rev_timeutc(name, 'build') unless (since = workspace.rev_timesince(name, 'build'))
@@ -1475,14 +1480,6 @@ module Squared
1475
1480
  op << '--no-index'
1476
1481
  patch = refs.pop
1477
1482
  append_pathspec(refs, parent: true)
1478
- if patch
1479
- patch = basepath patch
1480
- exit 1 if patch.exist? && !confirm_basic('Overwrite?', patch)
1481
- op << '>' << shell_quote(patch)
1482
- source(banner: false)
1483
- puts patch.read if patch.exist? && (stdin? || verbose?)
1484
- return
1485
- end
1486
1483
  else
1487
1484
  op << '--merge-base' if option('merge-base')
1488
1485
  case flag
@@ -1504,9 +1501,22 @@ module Squared
1504
1501
  op << "HEAD~#{n}"
1505
1502
  end
1506
1503
  end
1504
+ if (n = op.index('>'))
1505
+ patch = op.slice!(n, 2)[1]
1506
+ elsif !op.exist?(op.last)
1507
+ patch ||= op.pop
1508
+ end
1507
1509
  append_pathspec op.extras
1508
1510
  end
1509
- source(exception: op.arg?('exit-code'))
1511
+ if patch
1512
+ patch = basepath patch.delete_prefix('>')
1513
+ exit 1 if patch.exist? && !confirm_basic('Overwrite?', patch)
1514
+ op << '>' << shell_quote(patch)
1515
+ source(banner: false)
1516
+ puts patch.read if patch.exist? && (stdin? || verbose?)
1517
+ else
1518
+ source(exception: op.arg?('exit-code'))
1519
+ end
1510
1520
  end
1511
1521
 
1512
1522
  def commit(flag, opts = [], refs: [], ref: nil, squash: nil, pick: nil, message: nil, pass: false)
@@ -1962,23 +1972,23 @@ module Squared
1962
1972
  if io && banner == false
1963
1973
  from = nil
1964
1974
  banner = nil
1975
+ args = false
1965
1976
  else
1966
- if banner
1967
- banner = nil unless banner? && !multiple
1968
- args = true
1969
- end
1970
1977
  if from == false
1971
1978
  from = nil
1972
1979
  elsif !from && cmd.respond_to?(:drop)
1973
1980
  from = cmd.drop(1).find { |val| val.match?(/\A[a-z]{1,2}[a-z-]*\z/) }
1974
1981
  from &&= symjoin 'git', from
1975
1982
  end
1976
- banner &&= cmd.temp { |val| val.start_with?(/--(work-tree|git-dir)/) } if cmd.respond_to?(:temp)
1983
+ if banner
1984
+ banner = cmd.temp { |val| val.start_with?(/--(work-tree|git-dir)/) } if cmd.respond_to?(:temp)
1985
+ args = true
1986
+ end
1977
1987
  end
1978
1988
  timeout = session_timeout cmd if timeout.nil?
1979
1989
  cmd = session_done cmd
1980
- log&.info cmd
1981
- banner = if banner
1990
+ log&.info cmd unless args == false
1991
+ banner = if banner && banner? && !multiple
1982
1992
  format_banner(banner.is_a?(String) ? banner : cmd, hint: hint, strip: true)
1983
1993
  end
1984
1994
  on :first, from
@@ -2164,9 +2174,7 @@ module Squared
2164
2174
 
2165
2175
  def append_message(val = nil, target: @session)
2166
2176
  val = messageopt if val.to_s.empty?
2167
- return unless val
2168
-
2169
- target << quote_option('message', val)
2177
+ target << quote_option('message', val) if val
2170
2178
  end
2171
2179
 
2172
2180
  def append_head(val = nil, target: @session)