squared 0.6.1 → 0.6.3

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: 6a3b6e4109938a7ee4ddc9d778c798ad412cd2941a6b887cc62f9bd39779b4ad
4
- data.tar.gz: 6912a295b0e64223d3130d8793bce44e954c0903fd74b65eb0f420726a41f82d
3
+ metadata.gz: ac2411d2abc2d5caca8296cd25de89f28ede8458dd42809216e9ecb60dbc12e3
4
+ data.tar.gz: 2574d5d757f7405c47d792c47f83520325a633514801885706404efc3a10fa8b
5
5
  SHA512:
6
- metadata.gz: 137851028240806e553b125ec638df63cb20c25b6f73328a1c08f7af7603d666a1b61ff04dde1da27995a13d0bf2a6c28e644d20b6e8beb6e26fba061191d908
7
- data.tar.gz: 21c7fce48d7638aa90b9c0ef40282b30557205065f6117e0602248771cee9e628910f90125295dac4a831615adda43296112809b437f31b4db0aa9d3f03de437
6
+ metadata.gz: 6623132213ca2b9510f867ffd711ce8541ef3d707290a51ae40eeca20dbe8ec027c4b47630d67ba96527faa9630a71b9befd89020bbba2ac329fc76925200c61
7
+ data.tar.gz: 909a95ac73cd5261d4d2bf184fb90ae6069d92fc30ba850d574da048f73938090ddea6ea7693fc6d0353df8a63213d964b2a964f44e3afa9f8f4188c47f8f5aa
data/CHANGELOG.md CHANGED
@@ -1,5 +1,84 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.3] - 2025-11-14
4
+
5
+ ### Added
6
+
7
+ - Node command package action rebuild was implemented.
8
+ - Node command add can remove packages using "-" prefix.
9
+ - Git command log action grep was implemented.
10
+ - Node command package action add was implemented.
11
+
12
+ ### Changed
13
+
14
+ - Application class extended Enumerable collection class.
15
+ - OptionPartition class is lazily loaded using autoload.
16
+ - Requiring individual project classes in Rakefile is optional.
17
+ - Application class uses static method register instead of series_wrap.
18
+ - Project support modules are required inside Base class module.
19
+ - Project graph print did not display parent and last child consequetively.
20
+ - Project outdated interactive prompts use exact column alignments.
21
+
22
+ ## [0.5.16] - 2025-11-14
23
+
24
+ ### Fixed
25
+
26
+ - See `0.4.30`.
27
+
28
+ ## [0.4.30] - 2025-11-14
29
+
30
+ ### Added
31
+
32
+ - Config viewer can read items by index in an Array.
33
+
34
+ ### Fixed
35
+
36
+ - Node command add uses event name "add" and not "depend".
37
+ - Node command add did not include packages with Yarn and PNPM.
38
+ - Git method revbuild did not splat build arguments.
39
+
40
+ ## [0.6.2] - 2025-11-08
41
+
42
+ ### Added
43
+
44
+ - JoinSet methods [add|merge] were aliased to [push|concat].
45
+ - JoinSet supports values that can be used multiple times.
46
+
47
+ ### Changed
48
+
49
+ - Ruby command rake can multiple indexed tasks with separate options.
50
+
51
+ ### Fixed
52
+
53
+ - Session global program options were untested and worthless upon draft.
54
+
55
+ ## [0.5.15] - 2025-11-08
56
+
57
+ ### Fixed
58
+
59
+ - See `0.4.29`.
60
+
61
+ ## [0.4.29] - 2025-11-08
62
+
63
+ ### Fixed
64
+
65
+ - OptionPartition was created by mistake and is unreliable in every way.
66
+
67
+ ## [0.5.14] - 2025-11-08
68
+
69
+ ### Fixed
70
+
71
+ - See `0.4.28`.
72
+
73
+ ## [0.4.28] - 2025-11-08
74
+
75
+ ### Fixed
76
+
77
+ - Project base method build as arrays parsed unrelated arguments.
78
+ - OptionPartition method arg? does not check after "--" delimiter.
79
+ - OptionPartition did not support duplicate values after "--" delimiter.
80
+ - OptionPartition method opt? did not type check for String.
81
+
3
82
  ## [0.6.1] - 2025-11-05
4
83
 
5
84
  ### Added
@@ -12,6 +91,7 @@
12
91
 
13
92
  - Project base method run argument series was backwards.
14
93
  - Project base choice range did not detect empty list result.
94
+ - Project base method build as arrays parsed unrelated arguments.
15
95
 
16
96
  ## [0.5.13] - 2025-11-05
17
97
 
@@ -1308,8 +1388,13 @@
1308
1388
 
1309
1389
  - Changelog was created.
1310
1390
 
1391
+ [0.6.3]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.3
1392
+ [0.6.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.2
1311
1393
  [0.6.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.1
1312
1394
  [0.6.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.6.0
1395
+ [0.5.16]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.16
1396
+ [0.5.15]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.15
1397
+ [0.5.14]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.14
1313
1398
  [0.5.13]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.13
1314
1399
  [0.5.12]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.12
1315
1400
  [0.5.11]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.11
@@ -1324,6 +1409,9 @@
1324
1409
  [0.5.2]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.2-ruby
1325
1410
  [0.5.1]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.1-ruby
1326
1411
  [0.5.0]: https://github.com/anpham6/squared-ruby/releases/tag/v0.5.0-ruby
1412
+ [0.4.30]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.30
1413
+ [0.4.29]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.29
1414
+ [0.4.28]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.28
1327
1415
  [0.4.27]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.27
1328
1416
  [0.4.26]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.26
1329
1417
  [0.4.25]: https://github.com/anpham6/squared-ruby/releases/tag/v0.4.25
data/README.md CHANGED
@@ -75,6 +75,10 @@ require "squared/app" # All workspace related mod
75
75
  # sqd-serve = /workspaces/squared/publish/sqd-serve
76
76
  # sqd = /workspaces/squared/sqd
77
77
 
78
+ # Load external Project classes (optional)
79
+ Workspace::Application.load_ref('/home/user/.gem/ruby/3.4.0/gems/squared-0.6.0/lib/squared/workspace/project') # ref = :node => node.rb (absolute)
80
+ Workspace::Application.load_ref('lib/squared/workspace/project', gem: 'squared') # bundle env (relative)
81
+
78
82
  Workspace::Application
79
83
  .new(Dir.pwd, main: "squared") # Dir.pwd? (main? is implicitly basename)
80
84
  .banner("group", "project", styles: ["yellow", "black"], border: "bold") # name | project | path | ref | group? | parent? | version?
@@ -150,13 +154,13 @@ Node = Workspace::Project::Node # tsc
150
154
  Node.options("build:dev", "target=es2022", project: "tsconfig.json") # :node (ref)
151
155
  Node.options("build:dev", "outDir=tmp", :squared) # squared (project name)
152
156
 
153
- Ruby = Workspace::Project::Ruby # ruby | gem | rake | bundle | irb
157
+ Ruby = Workspace::Project::Ruby # ruby | gem | rake | bundle | irb | rbs
154
158
  Ruby.options("lint", "rubocop", opts: ["gemfile=Gemfile"]) # :ruby
155
159
  Ruby.options("lint", "--parallel", :squared)
156
160
 
157
- Python = Workspace::Project::Python # pip
158
- Python.options("build", opts: ["r=requirements.txt"]) # :python
159
- Python.options(:build, "build:dev", opts: ["no-deps"])
161
+ Python = Workspace::Project::Python # pip
162
+ Python.options("build", opts: ["r=requirements.txt"]) # :python
163
+ Python.options(:build, "build:dev", opts: ["no-deps"]) # inherits "build" as "build:dev"
160
164
 
161
165
  Workspace::Application
162
166
  .new(ENV["SQUARED_HOME"], prefix: "rb", common: false) # Local styles
@@ -692,7 +696,8 @@ GIT_AUTOSTASH_${NAME}=0 # rebase (project only)
692
696
  | checkout | track | COUNT=n |
693
697
  | checkout | global path | HEAD=s PATHSPEC=s |
694
698
  | checkout | * | F|FORCE MERGE |
695
- | clone | * | DEPTH=n ORIGIN=s BRANCH=s REVISION=s LOCAL=0,1 |
699
+ | clone | * | DEPTH=n ORIGIN=s BRANCH=s REVISION=s BARE=1 LOCAL=0,1 |
700
+ | | | SINGLE_BRANCH=0,1 NO_CHECKOUT=1 NO_TAGS=1 QUIET=1 |
696
701
  | commit | * | UPSTREAM=s DRY_RUN EDIT=0 M|MESSAGE=s |
697
702
  | diff | -between -contain | MERGE_BASE |
698
703
  | diff | head branch | INDEX=n |
@@ -742,14 +747,19 @@ BUILD_SQUARED_OPTS="NODE_TAG=24 RUBY_VERSION=3.4.0" DOCKER_SQUARED_OPTS="--no-ca
742
747
  docker build --no-cache --label=v1 --build-arg='NODE_TAG=24' --build-arg='RUBY_VERSION=3.4.0' .
743
748
  ```
744
749
 
745
- | Command | Flag | ENV |
746
- | :--------- | :---------------- | :---------------------------------------------- |
747
- | buildx | build | TAG=s |
748
- | buildx | bake | SERVICE=s |
749
- | compose | build | TARGET=s |
750
- | container | commit | REGISTRY=s PLATFORM=s DISABLE_CONTENT_TRUST=0,1 |
751
- | image | rm | Y=0,1 |
752
- | image | push | TAG=s REGISTRY=s |
750
+ | Command | Flag | ENV |
751
+ | :--------- | :----------------- | :---------------------------------------------- |
752
+ | buildx | build context | TAG=s |
753
+ | buildx | bake | SERVICE=s |
754
+ | compose | build | TARGET=s |
755
+ | compose | run | VERSION=s |
756
+ | container | commit | REGISTRY=s PLATFORM=s DISABLE_CONTENT_TRUST=0,1 |
757
+ | container | -run -create -exec | ALL=1 |
758
+ | | -update -commit | |
759
+ | image | rm | Y=1 |
760
+ | image | push | TAG=s REGISTRY=s |
761
+ | image | -push | ALL=1 |
762
+ | network | * | ALL=1 |
753
763
 
754
764
  ### asdf
755
765
 
@@ -14,8 +14,8 @@ module Squared
14
14
  CHOICE: 25,
15
15
  QUOTE: "'",
16
16
  SPACE: ' => ',
17
- GRAPH: ['|', '-', '|', '\\', '-'].freeze,
18
- BORDER: ['|', '-', '-', '-', '-', '-', '|', '|', '-', '-'].freeze,
17
+ GRAPH: %w[| - | \\ -].freeze,
18
+ BORDER: %w[| - - - - - | | - -].freeze,
19
19
  VIEW: 'view',
20
20
  BACKTRACE: $DEBUG || !$VERBOSE.nil?,
21
21
  LEVEL: ENV.fetch('LOG_LEVEL', 0).to_i,
@@ -28,8 +28,8 @@ module Squared
28
28
  bright_cyan!: '106',
29
29
  bright_white!: '107'
30
30
  }.freeze
31
- BOX_GRAPH = ['', '', '', '', ''].freeze
32
- BOX_BORDER = ['', '', '', '', '', '', '', '', '', ''].tap do |val|
31
+ BOX_GRAPH = %w[│ ─ ├ └ ┬].freeze
32
+ BOX_BORDER = %w[│ ─ ┌ ┐ ┘ └ ├ ┤ ┬ ┴].tap do |val|
33
33
  if ENV['TERM']&.end_with?('256color')
34
34
  val.slice!(2, 4)
35
35
  val.insert(2, '╭', '╮', '╯', '╰')
@@ -61,25 +61,25 @@ module Squared
61
61
  def sub_style(val, *args, styles: nil, pat: nil, index: 1)
62
62
  return val unless ARG[:COLOR]
63
63
 
64
- if pat && index != 0
65
- return val unless (data = pat.match(val))
64
+ ret = if pat && index != 0
65
+ return val unless (data = pat.match(val))
66
66
 
67
- ret = index == -1 ? data.to_a.drop(1) : data[index]
68
- else
69
- ret = val
70
- index = 0
71
- end
67
+ index == -1 ? data.to_a.drop(1) : data[index]
68
+ else
69
+ index = 0
70
+ val
71
+ end
72
72
  wrap = ->(s, n) { "\x1B[#{n.join(';')}m#{s}\x1B[0m" }
73
73
  code = []
74
+ args.clear if args.size == 1 && args.first.nil?
74
75
  args.concat(Array(styles)).flatten.each_with_index do |type, i|
75
76
  next unless type
76
77
 
77
- if index == -1
78
- s = ret[i]
79
- next ret[i] = '' if s.nil?
80
- else
81
- s = ret
82
- end
78
+ s = if index == -1
79
+ ret[i] || (next ret[i] = '')
80
+ else
81
+ ret
82
+ end
83
83
  if type.is_a?(::Numeric)
84
84
  f, b = type.to_s.split('.')
85
85
  s = wrap.call(s, ['38', '5', f]) if f[0] != '-' && f.to_i <= 255
@@ -125,6 +125,10 @@ module Squared
125
125
  out
126
126
  end
127
127
 
128
+ def sub_style!(val, *args, **kwargs)
129
+ val.replace(sub_style(val, *args, **kwargs))
130
+ end
131
+
128
132
  def check_style(args, empty: true)
129
133
  ret = []
130
134
  colors = __get__(:colors)
@@ -192,9 +196,9 @@ module Squared
192
196
  ref.add(level, message(subject, *args, hint: hint, space: ', ')) if ref.is_a?(::Logger)
193
197
  end
194
198
  end
195
- return false if !pass && level < ARG[:LEVEL]
199
+ return false unless pass || level >= ARG[:LEVEL]
196
200
  end
197
- if (args.size > 1 && !hint) || hint == false
201
+ if hint.nil? ? args.size > 1 : !hint
198
202
  title = log_title(level, color: false)
199
203
  emphasize(args,
200
204
  title: title + (subject ? " #{subject}" : ''),
@@ -204,7 +208,9 @@ module Squared
204
208
  end)
205
209
  else
206
210
  msg = [log_title(level, color: color)]
207
- msg << (color ? sub_style(subject.to_s, styles: (@theme && @theme[:subject]) || :bold) : subject) if subject
211
+ if subject
212
+ msg << (color ? sub_style(subject.to_s, (@theme.is_a?(::Hash) && @theme[:subject]) || :bold) : subject)
213
+ end
208
214
  msg << args.shift if msg.size == 1
209
215
  message(msg.join(' '), *args, hint: hint)
210
216
  end
@@ -236,7 +242,7 @@ module Squared
236
242
  end
237
243
 
238
244
  def emphasize(val, title: nil, footer: nil, right: false, cols: nil, sub: nil, pipe: nil,
239
- border: @theme && @theme[:border])
245
+ border: @theme.is_a?(::Hash) && @theme[:border])
240
246
  n = 0
241
247
  max = ->(a) { n = [n, a.max_by(&:size).size].max }
242
248
  set = ->(s) { Array(s).map(&:to_s).tap { |a| max.call(a) } }
@@ -257,17 +263,19 @@ module Squared
257
263
  out = []
258
264
  draw = lambda do |a, b|
259
265
  ret = a + (b1 * (n + 2)) + b
260
- ret = sub_style(ret, styles: border) if border
261
- ret
266
+ next ret unless border
267
+
268
+ sub_style ret, border
262
269
  end
263
270
  sub = sub.is_a?(::Hash) ? [sub] : Array(sub)
264
271
  pr = lambda do |line|
265
272
  s = line.ljust(n)
266
- sub.each { |h| s = sub_style(s, **h) }
273
+ sub.each { |h| sub_style!(s, **h) }
267
274
  s = "#{b0} #{s} #{b0}"
268
275
  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))
276
+ [[/\A(#{Regexp.escape(b0)})(.+)\z/om], [/\A(.+)(#{Regexp.escape(b0)})\z/om, 2]].each do |args|
277
+ sub_style!(s, **opt_style(border, *args))
278
+ end
271
279
  end
272
280
  s
273
281
  end
@@ -282,7 +290,7 @@ module Squared
282
290
  unless sub.empty? && !right
283
291
  footer.map! do |s|
284
292
  s = s.rjust(n + 4) if right
285
- sub.each { |h| s = sub_style(s, **h) }
293
+ sub.each { |h| sub_style!(s, **h) }
286
294
  s
287
295
  end
288
296
  end
@@ -291,17 +299,16 @@ module Squared
291
299
  if block_given?
292
300
  yield out
293
301
  elsif pipe
302
+ return out if pipe == -1
303
+
294
304
  case pipe
295
- when -1
296
- return out
297
305
  when 0
298
- pipe = $stdin
306
+ $stdin
299
307
  when 2
300
- pipe = $stderr
308
+ $stderr
301
309
  else
302
- pipe = $stdout unless pipe.respond_to?(:puts)
303
- end
304
- pipe.puts out
310
+ pipe.respond_to?(:puts) ? pipe : $stdout
311
+ end.puts(out)
305
312
  else
306
313
  err ? warn(out) : puts(out)
307
314
  end
@@ -19,7 +19,7 @@ module Squared
19
19
  module Prompt
20
20
  module_function
21
21
 
22
- def confirm(msg, default = nil, agree: 'Y', cancel: 'N', attempts: 3, timeout: 60)
22
+ def confirm(msg, default = nil, agree: 'Y', cancel: 'N', force: false, attempts: 3, timeout: 60)
23
23
  require 'timeout'
24
24
  if agree == 'Y' && cancel == 'N' && !msg.match?(%r{\[(?:Yn|nY|Y/n|y/N)\]})
25
25
  case default
@@ -38,6 +38,7 @@ module Squared
38
38
  when agree
39
39
  return true
40
40
  when cancel
41
+ exit 1 if force
41
42
  return false
42
43
  end
43
44
  attempts -= 1
@@ -47,6 +48,7 @@ module Squared
47
48
  puts
48
49
  exit 0
49
50
  else
51
+ exit 1 if force
50
52
  false
51
53
  end
52
54
  end
@@ -129,7 +131,7 @@ module Squared
129
131
  multiline = if multiline && Readline.respond_to?(:readmultiline)
130
132
  multiline.is_a?(::Enumerable) || block_given? ? multiline : [multiline.to_s]
131
133
  end
132
- prompt = lambda do
134
+ read = lambda do
133
135
  if !multiline
134
136
  Readline.readline(msg, history)
135
137
  elsif block_given?
@@ -145,12 +147,12 @@ module Squared
145
147
  else
146
148
  [force ? ':' : '?', '']
147
149
  end
148
- ret = (prompt.call || '').strip
150
+ ret = (read.call || '').strip
149
151
  multiline.each { |val| break if ret.delete_suffix!(val.to_s) } if multiline.is_a?(::Enumerable)
150
152
  exit 1 if force && ret.empty?
151
153
  ret
152
154
  else
153
- prompt.call
155
+ read.call
154
156
  end
155
157
  end
156
158
  end
@@ -13,7 +13,7 @@ module Squared
13
13
 
14
14
  module_function
15
15
 
16
- def shell_escape(val, quote: false, force: false, double: false, option: false, override: false)
16
+ def shell_escape(val, quote: false, option: false, force: false, double: false, override: false)
17
17
  if (r = /\A(--?)([^=\s]+)((=|\s+)(["'])?(?(5)(.*)\5|(.*)))?\z/m.match(val = val.to_s))
18
18
  if (data = r[2].match(QUOTE_VALUE))
19
19
  double = data[1] == '"'
@@ -31,7 +31,7 @@ module Squared
31
31
  r[7]
32
32
  end
33
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
34
+ elsif option && val =~ /\A(-{0,2}[^=\s-][^=\s]*)=(.+)\z/m
35
35
  return val if $2.match?(QUOTE_VALUE)
36
36
 
37
37
  "#{$1}=%s" % if $2.include?(' ')
@@ -55,7 +55,7 @@ module Squared
55
55
  return val if (!force && !val.include?(' ')) || val.empty?
56
56
 
57
57
  if option
58
- pat = /\A(?:-[^\[\]=\s-](?:=|\s+)?|(--)?[^\[\]=\s-][^\[\]=\s]*(?(1)(?:=|\s+)|=))(["']).+\2\z/m
58
+ pat = /\A(?:-[^=\s-](?:=|\s+)?|(--)?[^=\s-][^=\s]*(?(1)(?:=|\s+)|=))(["']).+\2\z/m
59
59
  return val if val.match?(pat)
60
60
  end
61
61
  q = ->(s) { s.gsub("'\\\\''", "'") }
@@ -103,7 +103,7 @@ module Squared
103
103
  end
104
104
 
105
105
  def shell_split(val, join: nil, **kwargs)
106
- ret = val.shellsplit.map! { |opt| shell_escape(opt, double: true, option: true, **kwargs) }
106
+ ret = val.shellsplit.map! { |opt| shell_escape(opt, option: true, double: true, **kwargs) }
107
107
  return ret unless join
108
108
 
109
109
  ret.join(join.is_a?(::String) ? join : ' ')
@@ -156,6 +156,7 @@ module Squared
156
156
  end
157
157
 
158
158
  def fill_option(val, **kwargs)
159
+ return val unless val.is_a?(::String)
159
160
  return "-#{val}" if val.match?(/\A(?:[a-z]\d*|\d)\z/i)
160
161
 
161
162
  shell_escape(val.start_with?('-') ? val : "--#{val}", **kwargs)
@@ -12,15 +12,14 @@ module Squared
12
12
  include Rake::DSL
13
13
 
14
14
  class << self
15
- def parse(gem, namespace, ext = [pkg])
15
+ def parse(gem, namespace, ext = [gem])
16
16
  require gem
17
- obj = eval namespace
18
- Array(ext).each { |val| @@mime_obj[val] = [obj, ext] }
17
+ [eval(namespace), Array(ext)].tap do |data|
18
+ data.last.each { |key| @@mime_obj[key] = data }
19
+ end
19
20
  rescue LoadError, NameError => e
20
21
  warn e
21
22
  nil
22
- else
23
- @@mime_obj[ext.first]
24
23
  end
25
24
 
26
25
  def link(project, main = project.dependfile.basename, name = nil, **kwargs, &blk)
@@ -245,7 +244,7 @@ module Squared
245
244
  opt_style(theme[:key], /\A((?~ : ))( : (?!undefined).+)\z/m),
246
245
  opt_style(theme[:number], /\A((?~: ): )(-?[\d.]+)(\s*)\z/m, 2),
247
246
  opt_style(theme[:string], /\A((?~: ): ")(.+)("\s*)\z/m, 2),
248
- opt_style(theme[:hash], /\A((?~: ): \{)(.+)(\}\s*)\z/m, 2),
247
+ opt_style(theme[:hash], /\A((?~: ): \{)(.+)(}\s*)\z/m, 2),
249
248
  opt_style(theme[:array], /\A((?~: ): \[)(.+)(\]\s*)\z/m, 2),
250
249
  opt_style(theme[:boolean], /\A((?~: ): )(true|false)(\s*)\z/m, 2),
251
250
  opt_style(theme[:value], /\A((?~: ): (?!undefined))([^"\[{].*)\z/m, 2)
@@ -259,7 +258,7 @@ module Squared
259
258
  symbolize = opts[:symbolize_names]
260
259
  keys.each do |key|
261
260
  begin
262
- items = key.split('.')
261
+ items = key.split('.').flat_map { |name| name =~ /^(.+)\[(\d+)\]$/ ? [$1, $2.to_i] : name }
263
262
  items = items.map(&:to_sym) if symbolize
264
263
  val = data.dig(*items)
265
264
  if val.nil?
@@ -271,7 +270,7 @@ module Squared
271
270
  end
272
271
  end
273
272
  rescue StandardError
274
- log&.warn "#{Viewer}(#{type}) => #{file && "#{file} "}{#{key}: undefined}"
273
+ log&.warn "#{Viewer}(#{type}) => #{"#{file} " if file}{#{key}: undefined}"
275
274
  val = Regexp.escape($!.message)
276
275
  key = key.sub(/(#{val})\.|\.(#{val})|(#{val})/) do
277
276
  s = "<#{$3 || $2 || $1}>"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Squared
4
- VERSION = '0.6.1'
4
+ VERSION = '0.6.3'
5
5
  end