squared 0.4.39 → 0.4.41

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: ba521fe28499cd80a453a06d45ad6e7f3561fbeb7e346731b3c90a570e5d1d8c
4
- data.tar.gz: 3f1a4dc8c680f53bb44ba3e48560858ead77a61dbb4d962e8be7f26e123d9abb
3
+ metadata.gz: 0137c48f9621363ac233e21140260861850c84e7b443c9f57b9b1b4b08a2a975
4
+ data.tar.gz: 85b0d24ef514398a93dd28fe6ba08620647023344eed66eb1aef0540610f9afc
5
5
  SHA512:
6
- metadata.gz: a783109febd933dda7e85b97196e4085910b28067946c07fefe565c7bfe2f728acfe7bc88b1ac6b99ae1cd8c76ec3cfef9635f74e7c7fe9c3e2e4fd4ec77e117
7
- data.tar.gz: 2cb847e0e72dc274b567b37a4f6e91f21a850c0ecc4c787fecfa022d2f858fcc9a67d0a0d75a6788c551abe02e8409c8ba4e429b274a9069d5dc6b5e18d27ea4
6
+ metadata.gz: 1a6e89292a3c9e1c1cc1536750aa499f4d7c09981d5ffefa8da42879071d9861d23c03e761acd3762e08045827020050e302e07ecfd419fb9180173eae1597a7
7
+ data.tar.gz: e41b4bbbb2b42091ebe9429e0cf4f413b44bbf25da37bc07a2afdb06b96c59f52d1670605dece335b485b2d9bfdc7f2097bebdc22824489ae1f136e516b42975
data/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.41] - 2026-09-04
4
+
5
+ ### Added
6
+
7
+ - Common base argument SUCCESS for command confirmation was created.
8
+
9
+ ### Changed
10
+
11
+ - Program options prefer using quotes instead of escape.
12
+ - Docker container run arguments with a leading dash are concatenated.
13
+
14
+ ### Fixed
15
+
16
+ - Common prompt method choice did not grep list items.
17
+ - OptionPartition static method strip did not parse flags with dashes.
18
+ - Project base method choice_index did not support multiple selections.
19
+
20
+ ## [0.4.40] - 2026-08-06
21
+
22
+ ### Changed
23
+
24
+ - Series method exclude? was made compatible with v0.8 signature.
25
+
3
26
  ## [0.4.39] - 2026-07-04
4
27
 
5
28
  ### Changed
@@ -1240,6 +1263,8 @@
1240
1263
 
1241
1264
  - Changelog was created.
1242
1265
 
1266
+ [0.4.41]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.41
1267
+ [0.4.40]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.40
1243
1268
  [0.4.39]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.39
1244
1269
  [0.4.38]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.38
1245
1270
  [0.4.37]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.37
@@ -14,6 +14,7 @@ module Squared
14
14
  CHOICE: 25,
15
15
  QUOTE: "'",
16
16
  SPACE: ' => ',
17
+ SUCCESS: 'Success',
17
18
  GRAPH: ['|', '-', '|', '\\', '-'].freeze,
18
19
  BORDER: ['|', '-', '-', '-', '-', '-', '|', '|', '-', '-'].freeze,
19
20
  VIEW: 'view',
@@ -90,6 +91,13 @@ module Squared
90
91
  VAR[key.is_a?(::String) ? key.to_sym : key] = val
91
92
  end
92
93
 
94
+ def __arg__(key, name = nil, &blk)
95
+ ret = ARG[key.to_sym]
96
+ return ret unless name && ret.is_a?(::Hash)
97
+
98
+ ret[name = name.downcase] || (block_given? ? ret.fetch(name.to_sym, &blk) : ret[name.to_sym])
99
+ end
100
+
93
101
  def __freeze__
94
102
  PATH.freeze
95
103
  ARG.freeze
@@ -40,7 +40,7 @@ module Squared
40
40
  grep &&= Array(grep).map { |val| Regexp.new(val) }
41
41
  items = []
42
42
  list.each do |val|
43
- next if grep&.none? { |pat| pat.match?(line) }
43
+ next if grep&.none? { |pat| pat.match?(val) }
44
44
 
45
45
  items << val.to_s.chomp
46
46
  puts "#{items.size.to_s.rjust(2)}. #{val}"
@@ -54,7 +54,7 @@ module Squared
54
54
  end}] "
55
55
  end
56
56
  end
57
- valid = ->(s) { s.match?(/^-?\d+$/) && s.to_i.between?(min, max) }
57
+ valid = ->(s) { s.match?(/^-?\d+$/) && s.to_i.between?(min, max <= min ? Float::INFINITY : max) }
58
58
  Timeout.timeout(timeout) do
59
59
  begin
60
60
  while (ch = Readline.readline(msg))
@@ -122,7 +122,7 @@ module Squared
122
122
  end
123
123
 
124
124
  def env_key(*val)
125
- val.join('_').gsub(/\W+/, '_').upcase
125
+ val.join('_').sub(/\A\d+\W*/, '__').gsub(/\W+/, '_').upcase
126
126
  end
127
127
 
128
128
  def env_value(key, default = '', suffix: nil, strict: false)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.4.39'
4
+ VERSION = '0.4.41'
5
5
  end
@@ -1232,7 +1232,7 @@ module Squared
1232
1232
  def env(key, default = nil, suffix: nil, equals: nil, ignore: nil, strict: false)
1233
1233
  a = "#{key}_#{@envname}"
1234
1234
  ret = if suffix
1235
- ENV.fetch("#{a}_#{suffix}", '')
1235
+ ENV["#{a}_#{suffix}"] || (ignore == false && ENV["#{key}_#{suffix}"]) || ''
1236
1236
  elsif strict
1237
1237
  ENV[a].to_s
1238
1238
  else
@@ -1300,7 +1300,7 @@ module Squared
1300
1300
  end
1301
1301
 
1302
1302
  def print_success(*)
1303
- puts 'Success'
1303
+ puts ARG[:SUCCESS]
1304
1304
  end
1305
1305
 
1306
1306
  def print_error(*args, loglevel: Logger::WARN, **kwargs)
@@ -1465,7 +1465,7 @@ module Squared
1465
1465
  end
1466
1466
 
1467
1467
  def append_hash(data, target: @session || [], build: false)
1468
- if build && (type = env('BUILD', suffix: 'TYPE') || ENV['BUILD_TYPE'])
1468
+ if build && (type = env('BUILD', suffix: 'TYPE', ignore: false))
1469
1469
  type = "__#{type}__"
1470
1470
  if (extra = data[type] || data[type.to_sym]).is_a?(Hash)
1471
1471
  data = data.merge(extra)
@@ -1681,7 +1681,10 @@ module Squared
1681
1681
  if accept
1682
1682
  hint = Array(ret).map { |val| sub_style(val, styles: theme[:inline]) }.join(', ')
1683
1683
  accept = Array(accept).map { |val| Array(val) }
1684
- ret = Array(ret) if accept.any? { |val| val[1] == true }
1684
+ if accept.any? { |val| val[1] == true }
1685
+ ret = [ret]
1686
+ multiple = -1
1687
+ end
1685
1688
  loop do
1686
1689
  item = accept.first
1687
1690
  d, e = item[2] ? ['Y', '[Y/n]'] : ['N', '[y/N]']
@@ -1698,7 +1701,7 @@ module Squared
1698
1701
  exit 1 unless accept.empty?
1699
1702
  end
1700
1703
  if values
1701
- ret = Array(ret)
1704
+ ret = [ret] unless accept && multiple == -1
1702
1705
  Array(values).each do |val|
1703
1706
  if val.is_a?(Array)
1704
1707
  val, force = val
@@ -21,13 +21,13 @@ module Squared
21
21
  }.freeze,
22
22
  compose: {
23
23
  common: %w[all-resources compatibility dry-run ansi=b env-file=p f|file=p parallel=n profile=b progress=b
24
- project-directory=p p|project-name=e].freeze,
24
+ project-directory=p p|project-name=b].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,
27
- exec: %w[d|detach privileged e|env=qq index=i T|no-TTY=b? user=e w|workdir=q].freeze,
27
+ exec: %w[d|detach privileged e|env=qq index=i T|no-tty=!? user=b w|workdir=q].freeze,
28
28
  run: %w[build d|detach no-deps q|quiet quiet-build quiet-pull remove-orphans rm P|service-ports use-aliases
29
29
  cap-add=b cap-drop=b entrypoint=q e|env=qq env-from-file=p i|interactive=b? l|label=q name=b
30
- T|no-TTY=b? p|publish=q pull=b u|user=e v|volume=q w|workdir=q].freeze,
30
+ T|no-tty=!? p|publish=q pull=b u|user=b v|volume=qq w|workdir=q].freeze,
31
31
  up: %w[abort-on-container-exit abort-on-container-failure always-recreate-deps attach-dependencies build
32
32
  d|detach force-recreate menu no-build no-color no-deps no-log-prefix no-recreate no-start quiet-build
33
33
  quiet-pull remove-orphans V|renew-anon-volumes timestamps wait w|watch y|yes attach=b
@@ -36,9 +36,9 @@ module Squared
36
36
  }.freeze,
37
37
  container: {
38
38
  create: %w[init i|interactive no-healthcheck oom-kill-disable privileged P|publish-all q|quiet read-only
39
- rm t|tty use-api-socket add-host=q annotation=q a|attach=b blkio-weight=i blkio-weight-device=i
40
- cap-add=b cap-drop=b cgroup-parent=b cgroupns=b cidfile=p device=q device-cgroup-rule=q
41
- device-read-bps=q device-read-iops=q device-write-bps=q device-write-iops=q
39
+ rm t|tty=!? use-api-socket add-host=q annotation=q a|attach=b blkio-weight=i
40
+ blkio-weight-device=i cap-add=b cap-drop=b cgroup-parent=b cgroupns=b cidfile=p device=q
41
+ device-cgroup-rule=q device-read-bps=q device-read-iops=q device-write-bps=q device-write-iops=q
42
42
  disable-content-trust=b? dns=q dns-option=q dns-search=q domainname=b entrypoint=q e|env=qq
43
43
  env-file=p expose=q gpus=q group-add=b health-cmd=q health-interval=b health-retries=i
44
44
  health-start-interval=q health-start-period=q health-timeout=q hostname=q io-maxbandwidth=b
@@ -47,13 +47,14 @@ module Squared
47
47
  memory-swap=n memory-swappiness=n mount=qq name=b network=b network-alias=b oom-score-adj=b
48
48
  pid=b pids-limit=n platform=q p|publish=q pull=b restart=b runtime=b security-opt=q shm-size=b
49
49
  stop-signal=b stop-timeout=i storage-opt=q sysctl=q tmpfs=q ulimit=q u|user=b userns=b uts=b
50
- v|volume=q volume-driver=b volumes-from=b w|workdir=q].freeze,
50
+ v|volume=qq volume-driver=b volumes-from=b w|workdir=q].freeze,
51
51
  run: %w[d|detach detach-keys=q sig-proxy=b?].freeze,
52
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
53
53
  cpuset-cpus=b cpuset-mems=b m|memory=b memory-reservation=b memory-swap=b pids-limit=n
54
54
  restart=q].freeze,
55
- exec: %w[d|detach i|interactive privileged t|tty detach-keys=q e|env=qq env-file=p user=e
55
+ exec: %w[d|detach i|interactive privileged t|tty=!? detach-keys=q e|env=qq env-file=p user=b
56
56
  w|workdir=q].freeze,
57
+ rm: %w[f|force l|link v|volumes].freeze,
57
58
  commit: %w[a|author=q c|change=q m|message=q pause=b?].freeze,
58
59
  inspect: %w[s|size f|format=q type=b].freeze,
59
60
  start: %w[a|attach i|interactive detach-keys=q].freeze,
@@ -607,8 +608,22 @@ module Squared
607
608
  when :exec
608
609
  raise_error('no command args', hint: flag) if list.empty?
609
610
  end
610
- target << val << list.shift
611
- target << list.join(' && ') unless list.empty?
611
+ target << val
612
+ case list.first
613
+ when '--'
614
+ target.merge(list.drop(1))
615
+ when /\A(--|&&)(\s|\z)/
616
+ target.merge(list)
617
+ else
618
+ target << list.shift
619
+ unless list.empty?
620
+ if list.first.start_with?('-')
621
+ target.merge(list)
622
+ else
623
+ target << list.join(' && ')
624
+ end
625
+ end
626
+ end
612
627
  end
613
628
 
614
629
  def append_file(type, target: @session, index: 2)
@@ -783,7 +798,7 @@ module Squared
783
798
  end
784
799
  cmd.merge(Array(out).map! { |val| parse.call(val) })
785
800
  cmd << args
786
- print_success if success?(run(cmd)) && ctx.match?(/\A(?:network|tag|save)/)
801
+ print_success if success?(run(cmd, { 'NO_COLOR' => 'true' })) && ctx.match?(/\A(?:network|tag|save)/)
787
802
  end
788
803
  end
789
804
 
@@ -133,7 +133,6 @@ module Squared
133
133
  end
134
134
  File.write(@revfile, JSON.pretty_generate(@revdoc))
135
135
  rescue StandardError => e
136
- log&.debug e
137
136
  warn log_message(Logger::WARN, e, pass: true) if warning
138
137
  ensure
139
138
  @revlock = false
@@ -172,7 +171,7 @@ module Squared
172
171
  }.freeze,
173
172
  fetch: {
174
173
  base: %w[multiple progress P|prune-tags refetch stdin u|update-head-ok recurse-submodules-default=b].freeze,
175
- pull: %w[4 6 n t a|append atomic dry-run f|force k|keep negotiate-only prefetch p|prune q|quiet
174
+ pull: %w[n t 4|ipv4 6|ipv6 a|append atomic dry-run f|force k|keep negotiate-only prefetch p|prune q|quiet
176
175
  set-upstream unshallow update-shallow v|verbose deepen=i depth=i j|jobs=i negotiation-tip=q
177
176
  recurse-submodules=v refmap=q o|server-option=q shallow-exclude=b shallow-since=v
178
177
  upload-pack=q].freeze
@@ -208,7 +207,7 @@ module Squared
208
207
  ita-invisible-in-index minimal name-only name-status no-color-moved-ws no-prefix no-renames numstat
209
208
  patch-with-raw patch-with-stat patience pickaxe-all pickaxe-regex raw shortstat summary a|text
210
209
  abbrev=i? anchored=q break-rewrites=b? color=b color-moved=b color-moved-ws=b color-words=q?
211
- diff-algorithm=b diff-filter=e? X|dirstat=b? dirstat-by-file=b? dst-prefix=q find-copies=i?
210
+ diff-algorithm=b diff-filter=q? X|dirstat=b? dirstat-by-file=b? dst-prefix=q find-copies=i?
212
211
  find-object=b find-renames=b? ignore-matching-lines=q ignore-submodules=b? inter-hunk-context=i
213
212
  line-prefix=q output=p output-indicator-context=q output-indicator-new=q output-indicator-old=q
214
213
  relative=p rotate-to=p skip-to=p src-prefix=q stat=b? stat-count=i stat-width=i stat-name-width=i
@@ -263,7 +262,7 @@ module Squared
263
262
  checkout: %w[overwrite-ignore guess overlay progress recurse-submodules track].freeze,
264
263
  fetch: {
265
264
  base: %w[auto-gc auto-maintenance write-commit-graph write-fetch-head].freeze,
266
- pull: %w[all ipv4 ipv6 recurse-submodules show-forced-updates tags].freeze
265
+ pull: %w[all recurse-submodules show-forced-updates tags].freeze
267
266
  },
268
267
  log: {
269
268
  base: %w[decorate mailmap merges use-mailmap].freeze,
@@ -1718,7 +1717,7 @@ module Squared
1718
1717
  op.add_quote(remote) if remote
1719
1718
  out, banner, from = source(io: true)
1720
1719
  print_item banner
1721
- ret = write_lines(out, grep: op.extras, prefix: "refs/#{flag}/")
1720
+ ret = write_lines(out, grep: op.extras)
1722
1721
  list_result(ret, flag.to_s, grep: op.extras, banner: banner, from: from)
1723
1722
  end
1724
1723
 
@@ -159,7 +159,7 @@ module Squared
159
159
  log.warn "run script #{n} of #{list.size} (out of range)"
160
160
  end
161
161
  else
162
- case index
162
+ case (index > 1 && poetry? ? 0 : index)
163
163
  when 0
164
164
  found |= 1
165
165
  run(session_output('poetry', 'run', val), from: :run)
@@ -542,7 +542,7 @@ module Squared
542
542
  case flag
543
543
  when :hatch, :twine
544
544
  if op.empty?
545
- op.push("#{dist.call}/*")
545
+ op.push(dist.call.join('*'))
546
546
  else
547
547
  op.map! { |val| basepath(val) }
548
548
  end
@@ -74,7 +74,25 @@ module Squared
74
74
  return [] unless val
75
75
 
76
76
  val = shell_split val if val.is_a?(String)
77
- val.map { |s| s.sub(OPT_SINGLE, '\1=\2').sub(OPT_VALUE, '\1=\2').sub(OPT_NAME, '\2') }.reject(&:empty?)
77
+ ret = []
78
+ pass = -1
79
+ (args = Array(val)).each_with_index do |s, i|
80
+ next if s.empty? || pass == i
81
+
82
+ if s == '--'
83
+ ret << s << args[i.succ..-1].join(' ')
84
+ break
85
+ end
86
+ next ret << s unless s.start_with?('-')
87
+
88
+ if !s.include?('=') && (j = args[i.succ]) && !j.start_with?('-')
89
+ ret << "#{s.sub(/^-{1,2}/, '')}=#{j}"
90
+ pass = i.succ
91
+ else
92
+ ret << s.sub(OPT_SINGLE, '\1=\2').sub(OPT_VALUE, '\1=\2').sub(OPT_NAME, '\2')
93
+ end
94
+ end
95
+ ret
78
96
  end
79
97
 
80
98
  def select(list, bare: true, no: true, single: false, double: false)
@@ -103,7 +121,11 @@ module Squared
103
121
  end
104
122
 
105
123
  def pattern?(val)
106
- val.match?(/(?:\A\^|\$\z)/) || val.match?(/(?:\.[*+]|\(\?:|\\[dsw]|\[.+\]|\{\d+,?\d*})/)
124
+ Regexp.new(val)
125
+ val.start_with?('\A', '^') || val.end_with?('\z', '$') ||
126
+ val.match?(/[.)][*+?]|\(\?[:=!><]|\\[dsw\d]|\[.+\]|\{\d+,?\d*\}/i)
127
+ rescue RegexpError
128
+ false
107
129
  end
108
130
 
109
131
  private
@@ -233,7 +255,7 @@ module Squared
233
255
  end
234
256
  numtype = [
235
257
  [i, /\A\d+\z/],
236
- [f, /\A\d*(?:\.\d+)?\z/],
258
+ [f, /\A(\d+(\.\d*)?|\d*\.\d+)\z/],
237
259
  [si, /\A-?\d+\z/]
238
260
  ].freeze
239
261
  numcheck = ->(k, v) { numtype.any? { |flag, pat| flag.include?(k) && pat.match?(v) } }
@@ -258,8 +280,8 @@ module Squared
258
280
  elsif q.include?(key)
259
281
  add quote_option(key, val, double: qq.include?(key), merge: merge)
260
282
  elsif p.include?(key)
261
- if val.match?(/\A(["']).+\1\z/)
262
- add shell_option(key, val, escape: false, merge: merge)
283
+ if val =~ /\A(["']).+\1\z/
284
+ add shell_option(key, val, double: $1 == '"', escape: false, merge: merge)
263
285
  elsif path
264
286
  add quote_option(key, path + val, merge: merge)
265
287
  else
@@ -235,8 +235,9 @@ module Squared
235
235
  already_invoked? parallel, val
236
236
  end
237
237
 
238
- def exclude?(key, empty = false)
239
- @exclude.include?(key) || (empty && (!@data.key?(key) || @data[key].empty?))
238
+ def exclude?(key, fallback = false, empty: nil)
239
+ fallback = empty unless empty.nil?
240
+ @exclude.include?(key) || (fallback && (!@data.key?(key) || @data[key].empty?))
240
241
  end
241
242
 
242
243
  private
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squared
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.39
4
+ version: 0.4.41
5
5
  platform: ruby
6
6
  authors:
7
7
  - An Pham
@@ -125,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  - !ruby/object:Gem::Version
126
126
  version: '0'
127
127
  requirements: []
128
- rubygems_version: 4.0.10
128
+ rubygems_version: 4.0.19
129
129
  specification_version: 4
130
130
  summary: Rake task generator for managing multi-language workspaces.
131
131
  test_files: []