squared 0.7.3 → 0.7.5

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: 82923f41d47824239a45fb31f694e85d30c1cf0f73c099df00d2d7a210f6b156
4
- data.tar.gz: e80edb54f73431248fb26d11ff53c5424ae791ef28b5a5ddcc3bb3f0da20622b
3
+ metadata.gz: b3a64a3f90d6dfc5e68c78112d2c52d159be020666fb157947fbdc7d09082017
4
+ data.tar.gz: e24e2116bea994017beba440d32e3f9fcf3c4245f2fc152a8c9ab2d6331c34ed
5
5
  SHA512:
6
- metadata.gz: cbb9aaa755322f262c820b8f0cabb8e9bf6596e440e4d660311b5804b5c4f347c478c3bc2fddafdeddf4ff9643642da8c74445c118028e6ea904f59909232360
7
- data.tar.gz: d0457af211645c310de59ae11cb693fbdb1c0fddd49989f805317dffb9db251693da9268fa2ad25b1739e94216b243521044502051ac8dbd111a65efdc31b1c0
6
+ metadata.gz: '0792cc244db8ec647b9ca5eb30a2fbf8b5b2cd215613c619d96c52bc78abffd9b3231fb31f62cb1eec6227277c0fdd09dcea1a71e4624cb0f378b4fc1868f02d'
7
+ data.tar.gz: 42efaeed57cae1baa4b9b8ef8cbbde7d0e049713e6f246a0b3ce19175354ce35b633eb22e2e55f192763059451c7a421113b19f9b760b70de59115adf2a767d5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,63 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.5] - 2026-04-29
4
+
5
+ ### Added
6
+
7
+ - OptionPartition can exit on any unrecognized flags in strict mode.
8
+ - OptionPartition supports option flags as namespaced enum.
9
+ - Git commands [merge|rebase] action [no-]commit are interactive.
10
+ - Ruby command version did not detect any installed VM application.
11
+ - Python command pip action freeze option uninstall was implemented.
12
+ - Git command range-diff was implemented.
13
+ - Docker command bake action build can use a URL as the context.
14
+ - Git command options were updated to version 2.54.
15
+
16
+ ## [0.6.12] - 2026-04-29
17
+
18
+ ### Fixed
19
+
20
+ - Application dynamic Project loader assumed class would be found.
21
+ - Git command grep did not add patterns with "--" pathspec separator.
22
+
23
+ ## [0.5.23] - 2026-04-29
24
+
25
+ ### Fixed
26
+
27
+ - See `0.4.37`.
28
+
29
+ ## [0.4.37] - 2026-04-29
30
+
31
+ ### Changed
32
+
33
+ - Project base method dependindex replaces private instance variable.
34
+
35
+ ### Fixed
36
+
37
+ - Ruby command version did not abort asdf "Not installed" error.
38
+ - Git command pull action all did not pass option flags to branches.
39
+ - Python command exec did not activate virtual environment.
40
+ - Docker command bake did not reinsert failed check for context directory.
41
+ - Common method shell_quote argument preserve did not bypass requoting.
42
+
43
+ ## [0.7.4] - 2026-03-20
44
+
45
+ ### Added
46
+
47
+ - Ruby command bundle action check was implemented.
48
+ - Ruby command pry with stored command options was created.
49
+ - Node command tsc options were updated to 6.0.
50
+ - Ruby command rdbg with stored command options was created.
51
+
52
+ ### Changed
53
+
54
+ - Project base method dependindex replaces private instance variable.
55
+
56
+ ### Fixed
57
+
58
+ - Repo completely ignored group and ref method arguments since inception.
59
+ - Ruby command version did not abort asdf "Not installed" error.
60
+
3
61
  ## [0.7.3] - 2026-03-11
4
62
 
5
63
  ### Added
@@ -13,7 +71,6 @@
13
71
 
14
72
  - Python command publish detects twine through the file system.
15
73
  - Git revbuild can bypass checksum by project name using GIT_FORCE.
16
- - Git internal data calls do not write to logs.
17
74
  - Ruby method serve uses as default port 3000 due to Errno::EACCES.
18
75
 
19
76
  ### Fixed
@@ -28,6 +85,8 @@
28
85
 
29
86
  ## [0.5.22] - 2026-03-11
30
87
 
88
+ ### Fixed
89
+
31
90
  - Project base run command was not covered due to lack of type checking.
32
91
 
33
92
  ## [0.4.36] - 2026-03-11
@@ -42,7 +101,7 @@
42
101
  - OptionPartition methods with escape parameter were reordered.
43
102
  - OptionPartition methods with quote parameter were revised.
44
103
 
45
- ## [0.6.10] - 2025-02-23
104
+ ## [0.6.10] - 2026-02-23
46
105
 
47
106
  ### Added
48
107
 
@@ -1753,10 +1812,13 @@
1753
1812
 
1754
1813
  - Changelog was created.
1755
1814
 
1815
+ [0.7.5]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.5
1816
+ [0.7.4]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.4
1756
1817
  [0.7.3]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.3
1757
1818
  [0.7.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.2
1758
1819
  [0.7.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.1
1759
1820
  [0.7.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.7.0
1821
+ [0.6.12]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.12
1760
1822
  [0.6.11]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.11
1761
1823
  [0.6.10]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.10
1762
1824
  [0.6.9]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.9
@@ -1769,6 +1831,7 @@
1769
1831
  [0.6.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.2
1770
1832
  [0.6.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.1
1771
1833
  [0.6.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.0
1834
+ [0.5.23]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.23
1772
1835
  [0.5.22]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.22
1773
1836
  [0.5.21]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.21
1774
1837
  [0.5.20]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.20
@@ -1792,6 +1855,7 @@
1792
1855
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
1793
1856
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
1794
1857
  [0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
1858
+ [0.4.37]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.37
1795
1859
  [0.4.36]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.36
1796
1860
  [0.4.35]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.35
1797
1861
  [0.4.34]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.34
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
 
@@ -546,6 +546,7 @@ Most project classes will inherit from `Git` which enables these tasks:
546
546
  | log | log | view between contain |
547
547
  | merge | merge | commit no-commit send |
548
548
  | pull | pull | origin remote all |
549
+ | range-diff | range-diff | view between contain |
549
550
  | rebase | rebase | branch onto send |
550
551
  | refs | ls-remote --refs | heads tags remote |
551
552
  | reset | reset | commit index patch mode undo |
@@ -638,6 +639,9 @@ BUILD_${NAME}_VERSION=0.1.0 # publish + detection
638
639
  BANNER=0 # hide banner
639
640
  BANNER_${NAME}=0 #
640
641
 
642
+ STRICT=0 # bypass error checking CLI commands
643
+ STRICT_${NAME}=0 #
644
+
641
645
  VERBOSE=0 # console output level
642
646
  VERBOSE_${NAME}=0 # 0,1,2,n
643
647
 
@@ -670,13 +674,15 @@ LOG_LEVEL # See gem "logger"
670
674
 
671
675
  ### Git
672
676
 
673
- * Version: [2.51](https://github.com/git/git/blob/v2.51.0/Documentation/RelNotes/2.51.0.adoc)
677
+ * Version: [2.54](https://github.com/git/git/blob/v2.54.0/Documentation/RelNotes/2.54.0.adoc)
674
678
 
675
679
  ```sh
676
680
  GIT_OPTIONS=q,strategy=ort # all
677
681
  GIT_OPTIONS_${NAME}=v,ff # project only
678
682
  GIT_AUTOSTASH=1 # rebase (all)
679
683
  GIT_AUTOSTASH_${NAME}=0 # rebase (project only)
684
+ GIT_REFLOG=1 # list all commits
685
+ GIT_COUNT=50 # list display limit
680
686
  ```
681
687
 
682
688
  | Command | Flag | ENV |
@@ -693,7 +699,6 @@ GIT_AUTOSTASH_${NAME}=0 # rebase (project only)
693
699
  | clone | * | DEPTH=n ORIGIN=s BRANCH=s REVISION=s BARE=1 LOCAL=0,1 |
694
700
  | | | SINGLE_BRANCH=0,1 NO_CHECKOUT=1 NO_TAGS=1 QUIET=1 |
695
701
  | commit | * | UPSTREAM=s DRY_RUN EDIT=0 M|MESSAGE=s |
696
- | diff | -between -contain | MERGE_BASE |
697
702
  | diff | head branch | INDEX=n |
698
703
  | diff | * | PATHSPEC=s |
699
704
  | fetch | -remote | ALL |
@@ -705,6 +710,7 @@ GIT_AUTOSTASH_${NAME}=0 # rebase (project only)
705
710
  | pull | -remote | REBASE=0,1 ALL |
706
711
  | pull | all | FF_ONLY=0 |
707
712
  | pull | * | AUTOSTASH F|FORCE RECURSE_SUBMODULES=0,1,s |
713
+ | range-diff | * | PATHSPEC=s |
708
714
  | rebase | branch | HEAD=s |
709
715
  | rebase | onto | INTERACTIVE I HEAD=s |
710
716
  | reset | mode (mixed) | N REFRESH=0 |
@@ -720,8 +726,8 @@ GIT_AUTOSTASH_${NAME}=0 # rebase (project only)
720
726
  | switch | detach | REFLOG=1 |
721
727
  | switch | -detach | HEAD=s |
722
728
  | switch | * | F|FORCE |
723
- | tag | add | SIGN FORCE HEAD=s M|MESSAGE=s |
724
- | tag | sign | F|FORCE HEAD=s M|MESSAGE=s |
729
+ | tag | add | SIGN FORCE HEAD=s M|MESSAGE=s TRAILER=s |
730
+ | tag | sign | F|FORCE HEAD=s M|MESSAGE=s TRAILER=s |
725
731
  | tag | delete | COUNT=n |
726
732
  | rev | commit branch | HEAD=s |
727
733
 
@@ -885,6 +891,7 @@ Features can be enabled through ENV when calling global tasks such as through *C
885
891
  | pnpm | depend | PUBLIC_HOIST_PATTERN=s APPROVE_BUILDS |
886
892
  | pnpm | depend:add | ALLOW_BUILD=s |
887
893
  | yarn | depend package | IGNORE_ENGINES |
894
+ | yarn | depend:add | W|IGNORE_WORKSPACE_ROOT_CHECK=0 |
888
895
 
889
896
  #### Python
890
897
 
@@ -10,6 +10,7 @@ module Squared
10
10
  HOME: nil,
11
11
  COMMON: true,
12
12
  VERBOSE: nil,
13
+ STRICT: false,
13
14
  BANNER: true,
14
15
  CHOICE: 25,
15
16
  QUOTE: "'",
@@ -9,7 +9,7 @@ unless defined?(Readline)
9
9
  Object.send(:remove_const, :Readline) if Object.const_defined?(:Readline)
10
10
  Readline = Reline
11
11
  rescue LoadError
12
- require 'readline'
12
+ require 'readline' rescue LoadError
13
13
  end
14
14
  end
15
15
  end
@@ -53,7 +53,7 @@ module Squared
53
53
  end
54
54
  end
55
55
 
56
- def shell_quote(val, option: true, force: true, double: false, preserve: true, override: false)
56
+ def shell_quote(val, option: true, force: true, double: false, preserve: true, pass: false, override: false)
57
57
  val = val.to_s
58
58
  return val if (!force && !val.include?(' ')) || val.empty?
59
59
 
@@ -61,16 +61,16 @@ module Squared
61
61
  pat = /\A(?:-[^=\s-](?:=|\s+)?|(--)?[^=\s-][^=\s]*(?(1)(?:=|\s+)|=))(["']).+\2\z/m
62
62
  return val if val.match?(pat)
63
63
  end
64
- q = ->(s) { s.gsub("'\\\\''", "'") }
65
64
  if val =~ QUOTE_VALUE
66
- return val if $1 == '"' && Rake::Win32.windows? && val.match?(/(?:[#{File::SEPARATOR} ]|\\")/o)
65
+ return val if pass || ($1 == '"' && Rake::Win32.windows? && val.match?(/(?:[#{File::SEPARATOR} ]|\\")/o))
67
66
 
68
67
  base = $2 unless preserve
69
68
  end
69
+ q = -> { (base || val).gsub("'\\\\''", "'") }
70
70
  if double || Rake::Win32.windows? || (ARG[:QUOTE] == '"' && !override)
71
- "\"#{q.call(base || val).gsub(/(?<!\\)"/, '\\"')}\""
71
+ "\"#{q.call.gsub(/(?<!\\)"/, '\\"')}\""
72
72
  else
73
- base ? val : "'#{q.call(val).gsub("'", "'\\\\''")}'"
73
+ "'#{q.call.gsub("'", "'\\\\''")}'"
74
74
  end
75
75
  end
76
76
 
@@ -124,18 +124,18 @@ module Squared
124
124
  b = []
125
125
  c = []
126
126
  d = []
127
- e = [a, b]
127
+ target = [a, b]
128
128
  j = -1
129
129
  val.shellsplit.each_with_index do |opt, i|
130
130
  if opt == '--'
131
- e = [c, d]
131
+ target = [c, d]
132
132
  elsif opt =~ /\A--?[^=]+(=|\z)/
133
133
  j = $1 == '=' ? -1 : i
134
- e[0] << [opt]
134
+ target[0] << [opt]
135
135
  elsif j >= 0
136
- e[0][j] << opt
136
+ target[0][j] << opt
137
137
  else
138
- e[1] << shell_quote(opt, option: false, force: force)
138
+ target[1] << shell_quote(opt, option: false, force: force)
139
139
  end
140
140
  end
141
141
  ret = [[a, b], [], [c, d]].flat_map do |e, f|
@@ -29,6 +29,7 @@ module Squared
29
29
  module_function
30
30
 
31
31
  def shell(*args, name: :system, **kwargs)
32
+ kwargs.delete(:exception) unless name == :system
32
33
  if RUBY_ENGINE == 'jruby' && Rake::Win32.windows?
33
34
  ex = kwargs[:exception]
34
35
  if (dir = kwargs[:chdir]) && Dir.pwd != dir
@@ -43,7 +44,7 @@ module Squared
43
44
  else
44
45
  return Kernel.send(name, *args, **kwargs)
45
46
  end
46
- raise $?.to_s if !ret && ex && name == :system
47
+ raise $?.to_s if !ret && ex
47
48
 
48
49
  ret
49
50
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.7.3'
4
+ VERSION = '0.7.5'
5
5
  end
@@ -206,7 +206,7 @@ module Squared
206
206
 
207
207
  return self
208
208
  end
209
- raise_error 'method not found'
209
+ raise 'method not found'
210
210
  rescue => e
211
211
  warn log_message(Logger::WARN, e, subject: main, hint: hint || args)
212
212
  end
@@ -226,7 +226,7 @@ module Squared
226
226
  when Symbol
227
227
  @ref = val
228
228
  else
229
- raise_error TypeError, "not a group/ref: #{kind || 'nil'}" if block_given?
229
+ raise TypeError, "not a group/ref: #{kind || 'nil'}" if block_given?
230
230
  end
231
231
  if block_given?
232
232
  instance_eval(&blk)
@@ -934,8 +934,8 @@ module Squared
934
934
  group.each { |val| failed += val.action }
935
935
  puts log_message(Logger::ERROR, *failed, subject: 'failed placement', hint: false), pipe: 2
936
936
  end
937
- level.each_with_index do |grp, i|
938
- title = "Step #{i.succ}#{if sync.include?(grp) && !(grp.size == 1 && series.parallel.include?(grp.first))
937
+ level.each_with_index do |grp, j|
938
+ title = "Step #{j.succ}#{if sync.include?(grp) && !(grp.size == 1 && series.parallel.include?(grp.first))
939
939
  ' (sync)'
940
940
  end}"
941
941
  emphasize(grp, title: title, cols: level.flatten(1).push(title), border: theme[:border],
@@ -1027,6 +1027,7 @@ module Squared
1027
1027
  require_relative rb
1028
1028
  break
1029
1029
  end
1030
+ nil
1030
1031
  end
1031
1032
 
1032
1033
  def root?(path, pass: [])
@@ -399,7 +399,7 @@ module Squared
399
399
  end
400
400
 
401
401
  def with(**kwargs, &blk)
402
- @withargs = kwargs.empty? ? nil : kwargs
402
+ @withargs = (kwargs unless kwargs.empty?)
403
403
  if block_given?
404
404
  instance_eval(&blk)
405
405
  @withargs = nil
@@ -862,13 +862,14 @@ module Squared
862
862
  end
863
863
 
864
864
  def run(cmd = @session, var = nil, exception: exception?, sync: true, banner: true, from: nil, chdir: path,
865
- interactive: nil, hint: nil, series: false, timeout: nil, **)
865
+ interactive: nil, hint: nil, series: false, timeout: nil, send: :system, **)
866
866
  unless cmd
867
867
  print_error('no command session started', subject: project, hint: from, pass: true)
868
868
  return
869
869
  end
870
870
  cmd = cmd.target if cmd.is_a?(OptionPartition)
871
871
  if interactive && sync && (!@session || !option('y'))
872
+ print_item(series: true)
872
873
  msg, y, h = case interactive
873
874
  when Array
874
875
  interactive
@@ -901,7 +902,7 @@ module Squared
901
902
  end
902
903
  end
903
904
  args = var.is_a?(Hash) ? [var, cmd] : [cmd]
904
- ret = shell_t(*args, chdir: chdir, exception: exception, timeout: timeout || 0)
905
+ ret = shell_t(*args, name: send, chdir: chdir, exception: exception, timeout: timeout || 0)
905
906
  end
906
907
  rescue Timeout::Error => e
907
908
  print_error(Logger::ERROR, cmd, subject: name, hint: e)
@@ -1005,7 +1006,7 @@ module Squared
1005
1006
  run_set(output[0], *args, **kwargs)
1006
1007
  when :dependfile
1007
1008
  @dependindex = nil
1008
- @dependfile = val.nil? ? nil : basepath(*args)
1009
+ @dependfile = (basepath(*args) if val)
1009
1010
  else
1010
1011
  instance_variable_set(:"@#{key}", val)
1011
1012
  end
@@ -1113,7 +1114,7 @@ module Squared
1113
1114
  end
1114
1115
 
1115
1116
  def dependtype(*)
1116
- @dependindex ? @dependindex.succ : 0
1117
+ dependindex&.succ || 0
1117
1118
  end
1118
1119
 
1119
1120
  def dependname
@@ -1350,7 +1351,7 @@ module Squared
1350
1351
  else
1351
1352
  if series?(obj)
1352
1353
  obj.each(&:call)
1353
- elsif obj.is_a?(Array) && obj.any? { |val| !val.is_a?(String) }
1354
+ elsif obj.is_a?(Array) && obj.none?(String)
1354
1355
  build(*obj, **kwargs)
1355
1356
  elsif obj
1356
1357
  run_s(*Array(obj), **kwargs)
@@ -1667,8 +1668,8 @@ module Squared
1667
1668
  end
1668
1669
 
1669
1670
  def write_lines(data, grep: [], prefix: nil, sub: nil, banner: nil, loglevel: nil, pass: false, first: false)
1670
- grep = grep.empty? ? nil : matchmap(grep, prefix)
1671
- sub = stdin? ? nil : as_a(sub)
1671
+ grep = (matchmap(grep, prefix) unless grep.empty?)
1672
+ sub = (as_a(sub) unless stdin?)
1672
1673
  ret = 0
1673
1674
  lines = data.each_with_object([]) do |line, out|
1674
1675
  next if grep&.none? { |pat| pat.match?(line) }
@@ -2129,7 +2130,7 @@ module Squared
2129
2130
  force = false
2130
2131
  end
2131
2132
  val = readline(val, force: force)
2132
- ret << (val.empty? ? nil : val)
2133
+ ret << (val unless val.empty?)
2133
2134
  end
2134
2135
  end
2135
2136
  printsucc unless series
@@ -2188,7 +2189,7 @@ module Squared
2188
2189
  files = files.select { |val| projectpath?(val) }.tap do |list|
2189
2190
  next if pass || files.size == list.size
2190
2191
 
2191
- raise_error 'pathspec not within worktree'
2192
+ raise 'pathspec not within worktree'
2192
2193
  end
2193
2194
  end
2194
2195
  files.map do |val|
@@ -2565,13 +2566,19 @@ module Squared
2565
2566
  end
2566
2567
  end
2567
2568
 
2568
- def dependfile_set(list)
2569
+ def dependfile_set(list, default: 0)
2569
2570
  @dependindex = if @dependname
2570
2571
  @dependfile = basepath @dependname
2571
2572
  list.index(@dependname)
2572
2573
  else
2573
- list.index { |file| exist?(file) }.tap { |i: 0| @dependfile = basepath(list[i]) }
2574
- end
2574
+ list.index { |file| exist?(file) }.tap { |i| @dependfile = basepath(list[i || default]) }
2575
+ end || (list unless enabled?)
2576
+ end
2577
+
2578
+ def dependindex
2579
+ dependfile_set @dependindex if @dependindex.is_a?(Array)
2580
+
2581
+ @dependindex unless @dependindex.is_a?(Array)
2575
2582
  end
2576
2583
 
2577
2584
  def as_get(val, from, *type)
@@ -2709,6 +2716,10 @@ module Squared
2709
2716
  level.empty? ? ex != false && ex != Logger::INFO : ex.is_a?(Numeric) && level.include?(ex)
2710
2717
  end
2711
2718
 
2719
+ def strict?
2720
+ (ARG[:STRICT] || exception?(Logger::FATAL)) && env('STRICT', notequals: '0')
2721
+ end
2722
+
2712
2723
  def serve?
2713
2724
  false
2714
2725
  end
@@ -20,7 +20,7 @@ module Squared
20
20
  sbom=q].freeze
21
21
  }.freeze,
22
22
  compose: {
23
- common: %w[all-resources ansi|b compatibility dry-run env-file=p f|file=p parallel=n profile=b progress=b
23
+ common: %w[all-resources ansi=b compatibility dry-run env-file=p f|file=p parallel=n profile=b progress=b
24
24
  project-directory=p p|project-name=e].freeze,
25
25
  build: %w[check no-cache print pull push with-dependencies q|quiet build-arg=qq builder=b m|memory=b
26
26
  provenance=q sbom=q ssh=qq].freeze,
@@ -399,28 +399,28 @@ module Squared
399
399
  end
400
400
 
401
401
  def buildx(flag, opts = [], tag: nil, context: nil, from: nil)
402
+ if flag == :bake && context&.match?(%r{^["']?(https?|git)://}i)
403
+ shared = data[:shared].dup.push('f|file=q')
404
+ shared.delete('f|file=p')
405
+ end
402
406
  cmd, opts = docker_session('buildx', opts: opts)
403
407
  data = OPT_DOCKER[:buildx]
404
- op = OptionPartition.new(opts, data[:common], cmd, project: self)
408
+ op = OptionPartition.new(opts, data[:common], cmd, project: self, strict: strict?)
405
409
  op.append(flag, quote: false)
406
- .parse(data[flag == :bake ? :bake : :build] + data[:shared])
410
+ .parse(data[flag == :bake ? :bake : :build] + (shared || data[:shared]))
407
411
  case flag
408
412
  when :build, :context
409
413
  append_tag(tag || option('tag', ignore: false) || self.tag)
410
- append_context context
414
+ if shared
415
+ op.add_quote(context, preserve: false)
416
+ else
417
+ append_context context
418
+ end
411
419
  when :bake
412
420
  append_file(0, index: 3) unless from || op.arg?('f', 'file') || !anypath?(*COMPOSEFILE)
413
421
  unless op.empty?
414
- args = op.dup
415
- op.reset
416
- if Dir.exist?(args.last)
417
- if projectpath?(val = args.pop)
418
- context = val
419
- else
420
- op.push(val)
421
- end
422
- end
423
- op.append(args, escape: true, strip: /^:/)
422
+ context = op.pop if Dir.exist?(op.last) && projectpath?(op.last)
423
+ op.append(escape: true, strip: /^:/, clear: true)
424
424
  contextdir context if context
425
425
  end
426
426
  end
@@ -442,7 +442,7 @@ module Squared
442
442
  docker_session('compose', command, '--', *service)
443
443
  else
444
444
  cmd, opts = docker_session('compose', opts: opts)
445
- op = OptionPartition.new(opts, OPT_DOCKER[:compose][:common], cmd, project: self)
445
+ op = OptionPartition.new(opts, OPT_DOCKER[:compose][:common], cmd, project: self, strict: strict?)
446
446
  append_file(filetype, force: flag == :publish) unless op.arg?('f', 'file')
447
447
  op << flag
448
448
  op.parse(OPT_DOCKER[:compose].fetch(flag, []))
@@ -479,7 +479,7 @@ module Squared
479
479
  list = data.fetch(flag, [])
480
480
  list += data[:create] if (rc = flag == :run)
481
481
  list += data[:update] if rc ||= flag == :create
482
- op = OptionPartition.new(opts, list, cmd, project: self, args: rc || flag == :exec)
482
+ op = OptionPartition.new(opts, list, cmd, project: self, strict: strict?, args: rc || flag == :exec)
483
483
  from = symjoin 'container', flag
484
484
  case flag
485
485
  when :run, :create, :exec
@@ -562,7 +562,7 @@ module Squared
562
562
 
563
563
  def image(flag, opts = [], sync: true, id: nil, registry: nil, filter: nil)
564
564
  cmd, opts = docker_session('image', flag, opts: opts)
565
- op = OptionPartition.new(opts, OPT_DOCKER[:image].fetch(flag, []), cmd, project: self)
565
+ op = OptionPartition.new(opts, OPT_DOCKER[:image].fetch(flag, []), cmd, project: self, strict: strict?)
566
566
  exception = exception?
567
567
  banner = true
568
568
  from = symjoin 'image', flag
@@ -645,7 +645,7 @@ module Squared
645
645
 
646
646
  def network(flag, opts = [], target: nil)
647
647
  cmd, opts = docker_session('network', flag, opts: opts)
648
- op = OptionPartition.new(opts, OPT_DOCKER[:network].fetch(flag, []), cmd, project: self)
648
+ op = OptionPartition.new(opts, OPT_DOCKER[:network].fetch(flag, []), cmd, project: self, strict: strict?)
649
649
  .clear
650
650
  from = symjoin 'network', flag
651
651
  if flag == :create
@@ -712,7 +712,7 @@ module Squared
712
712
  def docker_session(*cmd, opts: nil)
713
713
  return session('docker', *cmd) unless opts
714
714
 
715
- op = OptionPartition.new(opts, OPT_DOCKER[:common], project: self)
715
+ op = OptionPartition.new(opts, OPT_DOCKER[:common], project: self, strict: strict?)
716
716
  [session('docker', *op.to_a, *cmd), op.extras]
717
717
  end
718
718
 
@@ -898,11 +898,11 @@ module Squared
898
898
  when :service
899
899
  ['Choose a service',
900
900
  'compose ps -a ' \
901
- "--format='table {{.Service}}\t{{.Name}}\t{{.Image}}\t{{.Command}}\t{{.Status}}\t{{.Ports}}'"]
901
+ '--format="table {{.Service}}\t{{.Name}}\t{{.Image}}\t{{.Command}}\t{{.Status}}\t{{.Ports}}"']
902
902
  else
903
903
  ['Choose an image',
904
904
  'images -a ' \
905
- "--format='table {{.ID}}\t{{.Repository}}\t{{.Tag}}\t{{.CreatedSince}}\t{{.Size}}'"]
905
+ '--format="table {{.ID}}\t{{.Repository}}\t{{.Tag}}\t{{.CreatedSince}}\t{{.Size}}"']
906
906
  end
907
907
  lines = `#{docker_output(cmd)}`.lines
908
908
  if lines.size <= 1