squared 0.6.0 → 0.6.2

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: ed078210213186745643650b4a73f7f376b5aba7033643c850b48d555c198501
4
- data.tar.gz: d4d8c0e6308f3bdc3aca66891980259ad52ce11f3a53112c7a22ae4de9e31f40
3
+ metadata.gz: c638ae780897008e5115630f70db5a8ce7e1930fd31e7d1984b16d775218e16b
4
+ data.tar.gz: 231f5fc087b0b3dfcff0289f5601b0c70f0a9e6db63ff7309b7c86d96ae0a1ef
5
5
  SHA512:
6
- metadata.gz: fcf308f894ee49566103575561b74459afc1aa7e03af8d5c5397c7bb7432dfce996cbb1291f4f81af792d5b1dd8ed6a9075ce7b2fab6f41dca0c56431e38b78c
7
- data.tar.gz: 19f25542363b33fa567cbfcb0267c79fbc55a313ce0fba8ab25ec17dd43f276b004b00304e8bfe38dba1338a2e554170a8f1535d1bdc5981407fae6e9bff2bf8
6
+ metadata.gz: 175e72f4f5821922928b2b95a7f831dc42e91bbc41f093686cd253a68794b4b34db8af2bb9d103871cd19dfdf4d21ddd1d2bf30efdd8a8b4f5a7475be77b9988
7
+ data.tar.gz: 7c619485cf6d8046ba0e2acd99afcb698137e6342fd68b454c1195f9f32517d133aada79783813c15978eb1af132113aa94c422d425ae76b36a033345c81a4e3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,79 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.2] - 2025-11-08
4
+
5
+ ### Added
6
+
7
+ - JoinSet methods [add|merge] were aliased to [push|concat].
8
+ - JoinSet supports values that can be used multiple times.
9
+
10
+ ### Changed
11
+
12
+ - Ruby command rake can multiple indexed tasks with separate options.
13
+
14
+ ### Fixed
15
+
16
+ - Session global program options were untested and worthless upon draft.
17
+
18
+ ## [0.5.15] - 2025-11-08
19
+
20
+ ### Fixed
21
+
22
+ - See `0.4.29`.
23
+
24
+ ## [0.4.29] - 2025-11-08
25
+
26
+ ### Fixed
27
+
28
+ - OptionPartition was created by mistake and is unreliable in every way.
29
+
30
+ ## [0.5.14] - 2025-11-08
31
+
32
+ ### Fixed
33
+
34
+ - See `0.4.28`.
35
+
36
+ ## [0.4.28] - 2025-11-08
37
+
38
+ ### Fixed
39
+
40
+ - Project base method build as arrays parsed unrelated arguments.
41
+ - OptionPartition method arg? does not check after "--" delimiter.
42
+ - OptionPartition did not support duplicate values after "--" delimiter.
43
+ - OptionPartition method opt? did not type check for String.
44
+
45
+ ## [0.6.1] - 2025-11-05
46
+
47
+ ### Added
48
+
49
+ - Ruby method rbs supports stored command options.
50
+ - Ruby command rbs with Steep target was created.
51
+ - Common shell defined String instance method stripquote.
52
+
53
+ ### Fixed
54
+
55
+ - Project base method run argument series was backwards.
56
+ - Project base choice range did not detect empty list result.
57
+ - Project base method build as arrays parsed unrelated arguments.
58
+
59
+ ## [0.5.13] - 2025-11-05
60
+
61
+ ### Fixed
62
+
63
+ - See `0.4.27`.
64
+
65
+ ## [0.4.27] - 2025-11-05
66
+
67
+ ### Changed
68
+
69
+ - OptionPartition does not add quotes when an option flag is detected.
70
+ - Common shell method argument option only parses options with values.
71
+ - Shell options with empty flags are treated as quoted strings.
72
+
73
+ ### Fixed
74
+
75
+ - OptionPartition did not detect flags with middle dashes.
76
+
3
77
  ## [0.6.0] - 2025-10-31
4
78
 
5
79
  ### Added
@@ -1277,7 +1351,12 @@
1277
1351
 
1278
1352
  - Changelog was created.
1279
1353
 
1354
+ [0.6.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.2
1355
+ [0.6.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.1
1280
1356
  [0.6.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.0
1357
+ [0.5.15]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.15
1358
+ [0.5.14]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.14
1359
+ [0.5.13]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.13
1281
1360
  [0.5.12]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.12
1282
1361
  [0.5.11]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.11
1283
1362
  [0.5.10]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.10
@@ -1291,6 +1370,9 @@
1291
1370
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
1292
1371
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
1293
1372
  [0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
1373
+ [0.4.29]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.29
1374
+ [0.4.28]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.28
1375
+ [0.4.27]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.27
1294
1376
  [0.4.26]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.26
1295
1377
  [0.4.25]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.25
1296
1378
  [0.4.24]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.24
@@ -266,8 +266,8 @@ module Squared
266
266
  sub.each { |h| s = sub_style(s, **h) }
267
267
  s = "#{b0} #{s} #{b0}"
268
268
  if border
269
- s = sub_style(s, **opt_style(border, /\A(#{Regexp.escape(b0)})(.+)\z/m))
270
- s = sub_style(s, **opt_style(border, /\A(.+)(#{Regexp.escape(b0)})\z/m, 2))
269
+ s = sub_style(s, **opt_style(border, /\A(#{Regexp.escape(b0)})(.+)\z/om))
270
+ s = sub_style(s, **opt_style(border, /\A(.+)(#{Regexp.escape(b0)})\z/om, 2))
271
271
  end
272
272
  s
273
273
  end
@@ -6,11 +6,16 @@ require 'shellwords'
6
6
  module Squared
7
7
  module Common
8
8
  module Shell
9
+ QUOTE_VALUE = /\A(["'])(.*)\1\z/m.freeze
10
+ private_constant :QUOTE_VALUE
11
+
12
+ String.define_method(:stripquote) { sub(QUOTE_VALUE, '\2') }
13
+
9
14
  module_function
10
15
 
11
16
  def shell_escape(val, quote: false, force: false, double: false, option: false, override: false)
12
- if (r = /\A(--?)([^= ]+)((=|\s+)(["'])?(?(5)(.*)\5|(.*)))?\z/m.match(val = val.to_s))
13
- if (data = r[2].match(/\A(["'])(.+)\1\z/))
17
+ if (r = /\A(--?)([^=\s]+)((=|\s+)(["'])?(?(5)(.*)\5|(.*)))?\z/m.match(val = val.to_s))
18
+ if (data = r[2].match(QUOTE_VALUE))
14
19
  double = data[1] == '"'
15
20
  override = true
16
21
  elsif !r[3] || r[6]
@@ -25,9 +30,9 @@ module Squared
25
30
 
26
31
  r[7]
27
32
  end
28
- r[1] + (data ? data[2] : r[2]) + r[4] + shell_quote(opt, double: double, force: force, override: override)
29
- elsif option && val =~ /\A([^=]+)=(.+)\z/m
30
- return val if $2.match?(/\A(["']).+\1\z/m)
33
+ r[1] + (data ? data[2] : r[2]) + r[4] + shell_quote(opt, force: force, double: double, override: override)
34
+ elsif option && val =~ /\A(-{0,2}[^\[\]=\s-][^\[\]=\s]*)=(.+)\z/m
35
+ return val if $2.match?(QUOTE_VALUE)
31
36
 
32
37
  "#{$1}=%s" % if $2.include?(' ')
33
38
  shell_quote($2, option: false)
@@ -37,7 +42,7 @@ module Squared
37
42
  Shellwords.escape($2)
38
43
  end
39
44
  elsif Rake::Win32.windows?
40
- quote ? shell_quote(val, double: double, force: force) : val
45
+ quote ? shell_quote(val, force: force, double: double) : val
41
46
  elsif val.empty?
42
47
  ''
43
48
  else
@@ -45,46 +50,56 @@ module Squared
45
50
  end
46
51
  end
47
52
 
48
- def shell_quote(val, option: true, force: true, double: false, override: false)
53
+ def shell_quote(val, option: true, force: true, double: false, preserve: true, override: false)
49
54
  val = val.to_s
50
55
  return val if (!force && !val.include?(' ')) || val.empty?
51
56
 
52
- if option && val.match?(/(?:\A|\A[^=\s]+(?:=|\s+)|#{Rake::Win32.windows? ? '[\\\/]' : '\/'})(["']).+\1\z/mo)
53
- val
54
- elsif double || Rake::Win32.windows? || (ARG[:QUOTE] == '"' && !override)
55
- "\"#{val.gsub(/(?<!\\)"/, '\\"')}\""
57
+ if option
58
+ pat = /\A(?:-[^\[\]=\s-](?:=|\s+)?|(--)?[^\[\]=\s-][^\[\]=\s]*(?(1)(?:=|\s+)|=))(["']).+\2\z/m
59
+ return val if val.match?(pat)
60
+ end
61
+ q = ->(s) { s.gsub("'\\\\''", "'") }
62
+ if val =~ QUOTE_VALUE
63
+ return val if $1 == '"' && Rake::Win32.windows? && val.match?(/(?:[#{File::SEPARATOR} ]|\\")/o)
64
+
65
+ base = $2 unless preserve
66
+ end
67
+ if double || Rake::Win32.windows? || (ARG[:QUOTE] == '"' && !override)
68
+ "\"#{q.call(base || val).gsub(/(?<!\\)"/, '\\"')}\""
56
69
  else
57
- "'#{val.gsub("'", "'\\\\''")}'"
70
+ base ? val : "'#{q.call(val).gsub("'", "'\\\\''")}'"
58
71
  end
59
72
  end
60
73
 
61
74
  def shell_option(flag, val = nil, sep: '=', escape: true, quote: true, force: true, double: false, merge: false,
62
75
  override: false)
63
76
  flag = flag.to_s
64
- if flag =~ /\A(["'])(.+)\1\z/
77
+ if flag =~ QUOTE_VALUE
65
78
  double = $1 == '"'
66
79
  flag = $2
67
80
  escape = false
68
81
  override = true
69
82
  end
70
- b = if flag[0] == '-'
71
- flag[1] == '-' ? sep : ' '
72
- elsif flag.size == 1
73
- a = '-'
74
- merge ? '' : ' '
75
- else
76
- a = '--'
77
- sep
78
- end
79
- "#{a}#{flag}#{unless val.nil?
80
- "#{b}#{if escape
81
- shell_escape(val, quote: quote, double: double, override: override)
82
- elsif quote
83
- shell_quote(val, option: false, force: force, double: double, override: override)
84
- else
85
- val
86
- end}"
87
- end}"
83
+ sep = unless flag.empty?
84
+ if flag[0] == '-'
85
+ flag[1] == '-' ? sep : ' '
86
+ elsif flag.size == 1
87
+ pre = '-'
88
+ merge ? '' : ' '
89
+ else
90
+ pre = '--'
91
+ sep
92
+ end
93
+ end
94
+ "#{pre}#{flag}#{unless val.nil?
95
+ "#{sep}#{if escape
96
+ shell_escape(val, quote: quote, double: double, override: override)
97
+ elsif quote
98
+ shell_quote(val, option: false, force: force, double: double, override: override)
99
+ else
100
+ val
101
+ end}"
102
+ end}"
88
103
  end
89
104
 
90
105
  def shell_split(val, join: nil, **kwargs)
@@ -131,8 +146,8 @@ module Squared
131
146
 
132
147
  def shell_bin(name, env: true)
133
148
  key = name.upcase
134
- shell_quote((env && ENV["PATH_#{key}"]) || PATH[key] || PATH[key.to_sym] || name, option: false, force: false,
135
- double: true)
149
+ shell_quote((env && ENV["PATH_#{key}"]) || PATH[key] || PATH[key.to_sym] || name,
150
+ option: false, force: false, double: true)
136
151
  end
137
152
 
138
153
  def line_width(lines)
@@ -141,6 +156,7 @@ module Squared
141
156
  end
142
157
 
143
158
  def fill_option(val, **kwargs)
159
+ return val unless val.is_a?(::String)
144
160
  return "-#{val}" if val.match?(/\A(?:[a-z]\d*|\d)\z/i)
145
161
 
146
162
  shell_escape(val.start_with?('-') ? val : "--#{val}", **kwargs)
@@ -271,7 +271,7 @@ module Squared
271
271
  end
272
272
  end
273
273
  rescue StandardError
274
- log&.warn "#{Viewer}(#{type}) => #{file && "#{file} "}{#{key}: undefined}"
274
+ log&.warn "#{Viewer}(#{type}) => #{"#{file} " if file}{#{key}: undefined}"
275
275
  val = Regexp.escape($!.message)
276
276
  key = key.sub(/(#{val})\.|\.(#{val})|(#{val})/) do
277
277
  s = "<#{$3 || $2 || $1}>"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.6.0'
4
+ VERSION = '0.6.2'
5
5
  end
@@ -553,31 +553,31 @@ module Squared
553
553
  cmd = cmd.join(' && ')
554
554
  else
555
555
  cmd, opts, var, flags, extra = args
556
- end
557
- if cmd
558
- return run_b(cmd, sync: sync, from: from) if cmd.is_a?(Proc) || cmd.is_a?(Method)
559
-
560
- cmd = as_get cmd, from
561
- opts = compose(opts, script: false) if opts && respond_to?(:compose)
562
- flags = append_hash(flags, target: []).join(' ') if flags.is_a?(Hash)
563
- case opts
564
- when Hash
565
- cmd = Array(cmd).push(flags)
566
- .concat(append_hash(opts, target: [], build: true))
567
- .compact
568
- .join(' ')
569
- when Enumerable
570
- cmd = Array(cmd).concat(opts.to_a)
571
- cmd.map! { |val| "#{val} #{flags}" } if flags
572
- cmd = cmd.join(' && ')
556
+ if cmd
557
+ return run_b(cmd, sync: sync, from: from) if cmd.is_a?(Proc) || cmd.is_a?(Method)
558
+
559
+ cmd = as_get cmd, from
560
+ opts = compose(opts, script: false) if opts && respond_to?(:compose)
561
+ flags = append_hash(flags, target: []).join(' ') if flags.is_a?(Hash)
562
+ cmd = case opts
563
+ when Hash
564
+ Array(cmd).push(flags)
565
+ .concat(append_hash(opts, target: [], build: true))
566
+ .compact
567
+ .join(' ')
568
+ when Enumerable
569
+ cmd = Array(cmd).concat(opts.to_a)
570
+ cmd.map! { |val| "#{val} #{flags}" } if flags
571
+ cmd.join(' && ')
572
+ else
573
+ [cmd, flags, opts].compact.join(' ')
574
+ end
573
575
  else
574
- cmd = [cmd, flags, opts].compact.join(' ') if opts || flags
575
- end
576
- else
577
- return unless (opts || extra) && respond_to?(:compose)
576
+ return unless (opts || extra) && respond_to?(:compose)
578
577
 
579
- cmd = compose(as_get(opts, from), flags, script: true, args: extra, from: from)
580
- from = :script if from == :run && script?
578
+ cmd = compose(as_get(opts, from), flags, script: true, args: extra, from: from)
579
+ from = :script if from == :run && script?
580
+ end
581
581
  end
582
582
  run(cmd, var, sync: sync, banner: banner, from: from)
583
583
  end
@@ -596,12 +596,12 @@ module Squared
596
596
  if proj.respond_to?(meth.to_sym)
597
597
  begin
598
598
  proj.__send__(meth, sync: sync)
599
- next
600
599
  rescue StandardError => e
601
600
  on_error(e, :prereqs, exception: true)
602
601
  end
602
+ else
603
+ print_error(name, "method: #{meth}", subject: 'prereqs', hint: 'undefined')
603
604
  end
604
- print_error(name, 'method not found', subject: 'prereqs', hint: meth)
605
605
  end
606
606
  elsif proj.build?
607
607
  proj.build(sync: sync)
@@ -769,7 +769,7 @@ module Squared
769
769
  end
770
770
  break uri = url if data
771
771
  end
772
- unless data && (ext ||= URI.parse(uri).path[/\.(\w+)(?:\?|\z)/, 1])
772
+ unless data && (ext ||= URI.decode_www_form_component(URI.parse(uri).path[/\.([\w%]+)(?:\?|\z)/, 1]))
773
773
  raise_error(data ? TypeError : RuntimeError, "no content#{data ? ' type' : ''}", hint: uri)
774
774
  end
775
775
  end
@@ -913,7 +913,7 @@ module Squared
913
913
  end
914
914
 
915
915
  def run(cmd = @session, var = nil, exception: self.exception, sync: true, banner: true, from: nil, chdir: path,
916
- interactive: nil, hint: nil, series: true, **)
916
+ interactive: nil, hint: nil, series: false, **)
917
917
  return print_error('no command session started', subject: project, hint: from, pass: true) unless cmd
918
918
 
919
919
  cmd = cmd.target if cmd.is_a?(OptionPartition)
@@ -1023,6 +1023,8 @@ module Squared
1023
1023
  end
1024
1024
 
1025
1025
  def exist?(*args)
1026
+ return false if (args = args.compact).empty?
1027
+
1026
1028
  basepath(*args).exist?
1027
1029
  end
1028
1030
 
@@ -1359,10 +1361,10 @@ module Squared
1359
1361
  ret = JoinSet.new(cmd.flatten(1))
1360
1362
  if options
1361
1363
  env("#{prefix.upcase}_OPTIONS") do |val|
1362
- if val.start_with('-')
1363
- ret.concat(shell_parse(val))
1364
+ if val.start_with?('-')
1365
+ ret.merge(shell_parse(val))
1364
1366
  else
1365
- split_escape(val) { |opt| ret.last(fill_option(opt), /\A(--?[^= ]+)[= ].+\z/m) }
1367
+ split_escape(val) { |opt| ret.last(fill_option(opt), /\A(--?[^\[\]=\s-][^\[\]=\s]*)[=\s].+\z/m) }
1366
1368
  end
1367
1369
  end
1368
1370
  end
@@ -1468,9 +1470,9 @@ module Squared
1468
1470
  printsucc
1469
1471
  end
1470
1472
 
1471
- def print_item(*val, series: true)
1473
+ def print_item(*val, series: false)
1472
1474
  puts unless printfirst?
1473
- printsucc if series
1475
+ printsucc unless series
1474
1476
  puts val unless val.empty? || (val.size == 1 && !val.first)
1475
1477
  end
1476
1478
 
@@ -1699,11 +1701,12 @@ module Squared
1699
1701
  **kwargs)
1700
1702
  return if list.empty?
1701
1703
 
1704
+ kwargs[:ignore] = false if no && !kwargs.key?(:ignore)
1702
1705
  [].tap do |ret|
1703
1706
  list.flatten.each do |flag|
1704
1707
  next unless (val = option(flag, target: target, **kwargs))
1705
1708
 
1706
- if val == '0' && no
1709
+ if no && val == '0'
1707
1710
  flag = "no-#{flag}"
1708
1711
  val = nil
1709
1712
  end
@@ -1804,6 +1807,12 @@ module Squared
1804
1807
  print_error(e, subject: name)
1805
1808
  end
1806
1809
 
1810
+ def parse_env(key)
1811
+ env(key) do |val|
1812
+ val.start_with?('-') ? shell_parse(val) : split_escape(val).map! { |opt| fill_option(opt) }
1813
+ end || []
1814
+ end
1815
+
1807
1816
  def param_guard(action, flag, args:, key: nil, pat: nil, values: nil)
1808
1817
  if args && key
1809
1818
  val = args.fetch(key, nil)
@@ -1841,7 +1850,7 @@ module Squared
1841
1850
  force: true, **kwargs)
1842
1851
  puts unless series || printfirst?
1843
1852
  ret = choice(msg, list, multiple: multiple, force: force, **kwargs).tap do |val|
1844
- next unless val.to_s.empty?
1853
+ next unless !val || val.empty?
1845
1854
 
1846
1855
  exit 1 if force
1847
1856
  return nil
@@ -1853,7 +1862,7 @@ module Squared
1853
1862
  ret = ret.first unless multiple
1854
1863
  end
1855
1864
  if accept
1856
- hint = Array(ret).map { |val| sub_style(val, styles: theme[:inline]) }.join(', ')
1865
+ hint = Array(ret).map { |val| sub_style(val.to_s, styles: theme[:inline]) }.join(', ')
1857
1866
  accept = Array(accept).map { |val| Array(val) }
1858
1867
  ret = Array(ret) if accept.any? { |val| val[1] == true }
1859
1868
  loop do
@@ -2012,7 +2021,7 @@ module Squared
2012
2021
  end
2013
2022
 
2014
2023
  def indexerror(val, list = nil)
2015
- raise_error IndexError, "requested index #{val}", hint: list && "of #{list.size}"
2024
+ raise_error IndexError, "requested index #{val}", hint: ("of #{list.size}" if list)
2016
2025
  end
2017
2026
 
2018
2027
  def indexchar
@@ -2333,15 +2342,33 @@ module Squared
2333
2342
  end
2334
2343
 
2335
2344
  def has_value?(target, *args)
2345
+ return false unless target.is_a?(Enumerable)
2346
+
2336
2347
  args = args.first if args.size == 1 && args.first.is_a?(Enumerable)
2337
2348
  case target
2338
2349
  when Hash
2339
2350
  args.is_a?(Enumerable) ? args.any? { |obj| target.value?(obj) } : target.value?(args)
2340
- when Enumerable
2341
- args.is_a?(Enumerable) ? args.any? { |obj| target.include?(obj) } : target.include?(args)
2342
2351
  else
2343
- false
2352
+ args.is_a?(Enumerable) ? args.any? { |obj| target.include?(obj) } : target.include?(args)
2353
+ end
2354
+ end
2355
+
2356
+ def has_value!(target, *args, first: false)
2357
+ return unless target.is_a?(Enumerable)
2358
+
2359
+ args = args.first if args.size == 1 && args.first.is_a?(Enumerable)
2360
+ found = false
2361
+ args.each do |val|
2362
+ if target.respond_to?(:delete?)
2363
+ found = true if target.delete?(val)
2364
+ elsif target.respond_to?(:delete)
2365
+ found = true if target.delete(val)
2366
+ elsif target.include?(val)
2367
+ found = true
2368
+ end
2369
+ break if found && first
2344
2370
  end
2371
+ target if found
2345
2372
  end
2346
2373
 
2347
2374
  def variables
@@ -154,12 +154,8 @@ module Squared
154
154
  task action, [:command] do |_, args|
155
155
  command = param_guard(action, 'command', args: args, key: :command)
156
156
  args = args.extras
157
- a = args.delete('a') || args.delete('all')
158
157
  ls = case command
159
- when 'network'
160
- a = nil
161
- 'ls'
162
- when 'image', 'container'
158
+ when 'image', 'container', 'network'
163
159
  'ls'
164
160
  when 'compose'
165
161
  'ps'
@@ -167,7 +163,7 @@ module Squared
167
163
  raise_error ArgumentError, 'unrecognized command', hint: command
168
164
  end
169
165
  data = VAL_DOCKER[:ls][command.to_sym]
170
- if args.delete('s') || args.delete('standard')
166
+ if has_value!(args, 's', 'standard')
171
167
  cols = data.first(data.index('CreatedAt'))
172
168
  else
173
169
  cols = []
@@ -184,7 +180,8 @@ module Squared
184
180
  cols = choice_index('Select a column', data, multiple: true, force: true, attempts: 1)
185
181
  end
186
182
  end
187
- cmd = docker_output(command, ls, a && '-a')
183
+ cmd = docker_output command, ls
184
+ cmd << '-a' unless command == 'network' || !has_value!(args, 'a', 'all')
188
185
  cmd << quote_option('format', "table #{cols.map! { |val| "{{.#{val}}}" }.join("\t")}")
189
186
  run(cmd, banner: false, from: :ls)
190
187
  end
@@ -949,8 +946,7 @@ module Squared
949
946
  end
950
947
 
951
948
  def tagjoin(*args, char: '/')
952
- args.compact!
953
- args.join(char) unless args.empty?
949
+ args.join(char) unless (args = args.compact).empty?
954
950
  end
955
951
 
956
952
  def tagname(val)