k_log 0.0.19 → 0.0.30

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: 243999c48416e082085f9c72519cd2cc97bb8585389ee6848592f18dc2cfc6bd
4
- data.tar.gz: '009abfdd9b635d89f6e31f8197516f0dd612ce14adc9dfb7f005c9a9da458684'
3
+ metadata.gz: 328dd6fd19c8872158c3de15cbcb0bc2cf222ca2124b8d03ce81a81040cd1411
4
+ data.tar.gz: f44defe61b5895b2505725c2cbad5c27c45c93e155e25460a85d1a083f1cb775
5
5
  SHA512:
6
- metadata.gz: f19cf492a22aaf8dbc89dcd9246aacc5732e3db7844d17030d63091e672c4fb201d11c221bbe24450cb1d8745b16d8b70bb21994cc821387ee703aaea4bbc69f
7
- data.tar.gz: f0355d0438831db47d1ec390ba7d336b763d76f8d1d23f9520c98a1641901f0114c9961e9ac5d158daa8cddf5658782c6311721aeea5f01cd6dbe7ba24a80c80
6
+ metadata.gz: 0753d0d203b0673a2526368fa92a6cd6fc0c7ba42f6d425dbaba54b489b9db8e8865bbba2a1b6c22804c6e47b74e1f885b1cb11c85cb9c922fb99d34c30ea21d
7
+ data.tar.gz: 436f881ffb78b39ded0f7d2649712286c74c39e104991b8fd28cfc7b7dc7417c91f64030d82ab9a54bb3d17ce6d6ae7c64bfe2ccc955b2ccff6f71b43d5dd72e
data/.rubocop.yml CHANGED
@@ -40,6 +40,8 @@ Layout/LineLength:
40
40
  # Ignores annotate output
41
41
  IgnoredPatterns: ['\A# \*\*']
42
42
  IgnoreCopDirectives: true
43
+ Exclude:
44
+ - "**/spec/**/*"
43
45
 
44
46
  Lint/UnusedMethodArgument:
45
47
  AllowUnusedKeywordArguments: true
@@ -61,6 +63,16 @@ Metrics/ClassLength:
61
63
  Metrics/ModuleLength:
62
64
  Exclude:
63
65
  - "**/spec/**/*"
66
+ Metrics/CyclomaticComplexity:
67
+ Exclude:
68
+ - "lib/k_log/log_structure.rb"
69
+ Metrics/PerceivedComplexity:
70
+ Exclude:
71
+ - "lib/k_log/log_structure.rb"
72
+ Metrics/AbcSize:
73
+ Exclude:
74
+ - "lib/k_log/log_structure.rb"
75
+
64
76
  Naming/MemoizedInstanceVariableName:
65
77
  Enabled: false
66
78
  Naming/VariableNumber:
data/Gemfile CHANGED
@@ -2,23 +2,18 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- # Specify your gem's dependencies in handlebars_helpers.gemspec
6
5
  gemspec
7
6
 
8
- # group :development do
9
- # # Currently conflicts with GitHub actions and so I remove it on push
10
- # # pry on steroids
11
- # gem 'jazz_fingers'
12
- # gem 'pry-coolline', github: 'owst/pry-coolline', branch: 'support_new_pry_config_api'
13
- # end
14
-
15
7
  group :development, :test do
8
+ gem 'dry-struct', '~> 1'
9
+
16
10
  gem 'guard-bundler'
17
11
  gem 'guard-rspec'
18
12
  gem 'guard-rubocop'
19
13
  gem 'rake', '~> 12.0'
20
14
  gem 'rake-compiler', require: false
21
15
  gem 'rspec', '~> 3.0'
16
+ gem 'rspec-collection_matchers'
22
17
  gem 'rubocop'
23
18
  gem 'rubocop-rake', require: false
24
19
  gem 'rubocop-rspec', require: false
data/k_log.gemspec CHANGED
@@ -38,6 +38,7 @@ Gem::Specification.new do |spec|
38
38
  spec.require_paths = ['lib']
39
39
  # spec.extensions = ['ext/k_log/extconf.rb']
40
40
 
41
+ spec.add_dependency 'k_util', '~> 0'
41
42
  spec.add_dependency 'table_print', '~> 1.5.7'
42
43
  # spec.add_dependency 'tty-box', '~> 0.5.0'
43
44
  end
@@ -43,6 +43,14 @@ module KLog
43
43
  green(character * size)
44
44
  end
45
45
 
46
+ def self.dynamic_heading(heading, size: 70, type: :heading)
47
+ return heading(heading, size) if type == :heading
48
+ return subheading(heading, size) if type == :subheading
49
+ return [section_heading(heading, size)] if %i[section_heading section].include?(type)
50
+
51
+ []
52
+ end
53
+
46
54
  def self.heading(heading, size = 70)
47
55
  line = line(size)
48
56
 
@@ -69,7 +77,8 @@ module KLog
69
77
  def self.section_heading(heading, size = 70)
70
78
  brace_open = green('[ ')
71
79
  brace_close = green(' ]')
72
- line = line(size - heading.length - 4, '-')
80
+ line_length = size - heading.length - 4
81
+ line = line_length.positive? ? line(line_length, '-') : ''
73
82
 
74
83
  # It is important that you set the colour after you have calculated the size
75
84
  "#{brace_open}#{heading}#{brace_close}#{green(line)}"
@@ -106,8 +115,60 @@ module KLog
106
115
  end
107
116
  # rubocop:enable Metrics/CyclomaticComplexity
108
117
 
118
+ def self.red(value)
119
+ "\033[31m#{value}\033[0m"
120
+ end
121
+
109
122
  def self.green(value)
110
123
  "\033[32m#{value}\033[0m"
111
124
  end
125
+
126
+ def self.yellow(value)
127
+ "\033[33m#{value}\033[0m"
128
+ end
129
+
130
+ def self.blue(value)
131
+ "\033[34m#{value}\033[0m"
132
+ end
133
+
134
+ def self.purple(value)
135
+ "\033[35m#{value}\033[0m"
136
+ end
137
+
138
+ def self.cyan(value)
139
+ "\033[36m#{value}\033[0m"
140
+ end
141
+
142
+ def self.grey(value)
143
+ "\033[37m#{value}\033[0m"
144
+ end
145
+
146
+ def self.bg_red(value)
147
+ "\033[41m#{value}\033[0m"
148
+ end
149
+
150
+ def self.bg_green(value)
151
+ "\033[42m#{value}\033[0m"
152
+ end
153
+
154
+ def self.bg_yellow(value)
155
+ "\033[43m#{value}\033[0m"
156
+ end
157
+
158
+ def self.bg_blue(value)
159
+ "\033[44m#{value}\033[0m"
160
+ end
161
+
162
+ def self.bg_purple(value)
163
+ "\033[45m#{value}\033[0m"
164
+ end
165
+
166
+ def self.bg_cyan(value)
167
+ "\033[46m#{value}\033[0m"
168
+ end
169
+
170
+ def self.bg_grey(value)
171
+ "\033[47m#{value}\033[0m"
172
+ end
112
173
  end
113
174
  end
@@ -0,0 +1,436 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'k_util'
4
+
5
+ module KLog
6
+ # Log Structure is flexible logger for working through a complex object graph
7
+ class LogStructure
8
+ attr_reader :indent
9
+ attr_reader :title
10
+ attr_reader :title_type
11
+ attr_reader :heading
12
+ attr_reader :heading_type
13
+ attr_reader :line_width
14
+ attr_reader :key_width
15
+ attr_reader :show_array_count
16
+ attr_reader :graph
17
+ attr_reader :formatter
18
+ attr_reader :convert_data_to
19
+
20
+ attr_reader :recursion_depth
21
+ attr_reader :key_format
22
+ attr_reader :graph_path
23
+ attr_reader :graph_node
24
+
25
+ attr_reader :lines
26
+ attr_reader :output_as
27
+ attr_reader :output_file
28
+
29
+ # Log a structure
30
+ #
31
+ # Can handle Hash, Array, OpenStruct, Struct, DryStruct, Hash convertible custom classes
32
+ #
33
+ # @option opts [String] :indent Indent with string, defaults to ' '
34
+ # @option opts [String] :heading Log heading using logger.dynamic_heading
35
+ # @option opts [String] :heading_type :heading, :subheading, :section_heading
36
+ # @option opts [String] :line_width line width defaults to 80, but can be overridden here
37
+ # @option opts [String] :key_width key width defaults to 30, but can be overridden here
38
+ # @option opts [String] :formatter is a complex configuration for formatting different data within the structure
39
+ def initialize(opts)
40
+ @indent = opts[:indent] || ' '
41
+ @title = opts[:title]
42
+ @title_type = opts[:title_type] || :heading
43
+
44
+ @heading = opts[:heading]
45
+ @heading_type = opts[:heading_type] || :heading
46
+ puts ':heading should be :title' if opts[:heading]
47
+ puts ':heading_type should be :title_type' if opts[:heading_type]
48
+
49
+ @formatter = opts[:formatter] || {}
50
+ @graph = parse_graph(opts[:graph] || {})
51
+ @convert_data_to = opts[:convert_data_to] || :raw # by default leave data as is
52
+
53
+ @line_width = opts[:line_width] || 80
54
+ @key_width = opts[:key_width] || 30
55
+ @show_array_count = opts[:show_array_count] || false
56
+ @output_as = opts[:output_as] || [:console]
57
+ @output_as = [@output_as] unless @output_as.is_a?(Array)
58
+ @output_file = opts[:output_file]
59
+
60
+ @recursion_depth = 0
61
+ @key_format = nil
62
+ @graph_path = []
63
+ @lines = []
64
+
65
+ update_indent_label
66
+ end
67
+
68
+ def l
69
+ @l ||= KLog::LogUtil.new(KLog.logger)
70
+ end
71
+
72
+ def log(data)
73
+ log_heading(title, title_type) if title
74
+
75
+ data = convert_data(data)
76
+
77
+ log_data(data)
78
+
79
+ add_line(KLog::LogHelper.line(line_width))
80
+
81
+ render_output
82
+ end
83
+
84
+ def content
85
+ @content ||= lines.join("\n")
86
+ end
87
+
88
+ def clean_content
89
+ # remove color escape codes
90
+ @clean_content ||= content.gsub(/\x1B\[\d*m/, '')
91
+ end
92
+
93
+ def clean_lines
94
+ # remove color escape codes
95
+ lines.flat_map { |line| line.gsub(/\x1B\[\d*m/, '').split("\n") }
96
+ end
97
+
98
+ def add_lines(lines)
99
+ @lines += lines
100
+ end
101
+
102
+ def add_line(line)
103
+ @lines << line
104
+ end
105
+
106
+ private
107
+
108
+ # format_config = @formatter[:_root] if format_config.nil? && @recursion_depth.zero?
109
+
110
+ def data_enumerator(data)
111
+ return data.attributes if data.respond_to?(:attributes)
112
+
113
+ data
114
+ end
115
+
116
+ def log_data(data)
117
+ data_enumerator(data).each_pair do |k, v|
118
+ key = k.is_a?(String) ? k.to_sym : k
119
+
120
+ graph_path.push(key)
121
+ @graph_node = GraphNode.for(self, graph, graph_path)
122
+ # l.kv 'key', "#{key.to_s.ljust(15)}#{graph_node.skip?.to_s.ljust(6)}#{@recursion_depth}"
123
+
124
+ if graph_node.skip?
125
+ # l.kv 'key', 'skipping...'
126
+ @graph_path.pop
127
+ next
128
+ end
129
+
130
+ 'puts xmen' if graph_node.pry_at?(:before_value)
131
+
132
+ value = graph_node.transform? ? graph_node.transform(v) : v
133
+
134
+ 'puts xmen' if graph_node.pry_at?(:after_value)
135
+ if value.is_a?(OpenStruct) || value.respond_to?(:attributes)
136
+
137
+ # l.kv 'go', 'open struct ->'
138
+ 'puts xmen' if graph_node.pry_at?(:before_structure)
139
+ log_structure(key, value)
140
+ # l.kv 'go', 'open struct <-'
141
+ elsif value.is_a?(Array)
142
+ # l.kv 'go', 'array ->'
143
+ log_array(key, value)
144
+ # l.kv 'go', 'array <-'
145
+ else
146
+ # l.kv 'go', 'value ->'
147
+ 'puts xmen' if graph_node.pry_at?(:before_kv)
148
+ log_heading(graph_node.heading, graph_node.heading_type) if graph_node.heading
149
+ add_line KLog::LogHelper.kv("#{@indent_label}#{key}", value, key_width)
150
+ # l.kv 'go', 'value <-'
151
+ end
152
+
153
+ # l.line
154
+ # @graph_node = graph.for_path(graph_path)
155
+ # l.line
156
+ @graph_path.pop
157
+ end
158
+ nil
159
+ end
160
+
161
+ def log_structure(key, value)
162
+ log_heading(graph_node.heading, graph_node.heading_type) if graph_node.heading
163
+ add_line(KLog::LogHelper.green("#{@indent_label}#{key}"))
164
+ log_child_data(value)
165
+ end
166
+
167
+ def log_child_data(value)
168
+ depth_down
169
+ log_data(value)
170
+ depth_up
171
+ end
172
+
173
+ def log_array(key, array)
174
+ 'puts xmen' if graph_node.pry_at?(:before_array)
175
+
176
+ items = array.clone
177
+ items.select! { |item| graph_node.filter(item) } if graph_node.filter?
178
+ items = items.take(graph_node.take) if graph_node.limited?
179
+ items.sort!(&graph_node.sort) if graph_node.sort?
180
+
181
+ 'puts xmen' if graph_node.pry_at?(:before_array_print)
182
+
183
+ return if items.length.zero? && graph_node.skip_empty?
184
+
185
+ log_heading(graph_node.heading, graph_node.heading_type) if graph_node.heading
186
+
187
+ if primitive?(items)
188
+ add_line KLog::LogHelper.kv "#{@indent_label}#{key}", items.map(&:to_s).join(', ')
189
+ else
190
+ table_print items, tp_columns(items)
191
+
192
+ # NEED SUPPORT FOR A configured ARRAY COUNT with width and label
193
+ add_line KLog::LogHelper.kv key.to_s, items.count if show_array_count
194
+ end
195
+ rescue StandardError => e
196
+ KLog.logger.exception(e)
197
+ end
198
+
199
+ def table_print(items, columns)
200
+ io = TablePrintIo.new(self)
201
+
202
+ tp.set :io, io
203
+ tp items, columns
204
+ tp.clear :io
205
+ end
206
+
207
+ def primitive?(items)
208
+ item = items.first
209
+ KUtil.data.basic_type?(item)
210
+ end
211
+
212
+ def log_heading(heading, heading_type)
213
+ add_lines(KLog::LogHelper.dynamic_heading(heading, size: line_width, type: heading_type))
214
+ end
215
+
216
+ def tp_columns(items)
217
+ # Use configured array columns
218
+ return graph_node.columns if graph_node.columns
219
+
220
+ # Slow but complete list of keys
221
+ # items.flat_map { |v| v.to_h.keys }.uniq
222
+
223
+ items.first.to_h.keys
224
+ end
225
+
226
+ def update_indent_label
227
+ # puts "indent_label: #{indent} - #{@recursion_depth} - #{(indent * @recursion_depth)}"
228
+ @indent_label = (indent * @recursion_depth)
229
+ end
230
+
231
+ def indent_in
232
+ @indent = "#{@indent} "
233
+ end
234
+
235
+ def indent_out
236
+ @indent = indent.chomp(' ')
237
+ end
238
+
239
+ def depth_down
240
+ @recursion_depth = recursion_depth + 1
241
+ update_indent_label
242
+ end
243
+
244
+ def depth_up
245
+ @recursion_depth = recursion_depth - 1
246
+ update_indent_label
247
+ end
248
+
249
+ def render_output
250
+ puts content if output_as.include?(:console)
251
+ File.write(output_file, clean_content) if output_as.include?(:file) && output_file
252
+ # content
253
+ end
254
+
255
+ # convert_data_to: :open_struct
256
+ def convert_data(data)
257
+ return KUtil.data.to_open_struct(data) if convert_data_to == :open_struct
258
+
259
+ data
260
+ end
261
+
262
+ def parse_graph(data)
263
+ if data.is_a?(Hash)
264
+ transform_hash = data.each_with_object({}) do |(key, value), new_hash|
265
+ new_hash[key] = if key == :columns && value.is_a?(Array)
266
+ # Don't transform the table_print GEM columns definition as it must stay as a hash
267
+ value
268
+ else
269
+ parse_graph(value)
270
+ end
271
+ end
272
+
273
+ return OpenStruct.new(transform_hash.to_h)
274
+ end
275
+
276
+ return data.map { |o| parse_graph(o) } if data.is_a?(Array)
277
+ return parse_graph(data.to_h) if data.respond_to?(:to_h) # hash_convertible?(data)
278
+
279
+ # Some primitave type: String, True/False or an ObjectStruct
280
+ data
281
+ end
282
+
283
+ # def hash_convertible?(value)
284
+ # # Nil is a special case, it responds to :to_h but generally
285
+ # # you only want to convert nil to {} in specific scenarios
286
+ # return false if value.nil?
287
+
288
+ # value.is_a?(Array) ||
289
+ # value.is_a?(Hash) ||
290
+ # value.is_a?(Struct) ||
291
+ # value.is_a?(OpenStruct) ||
292
+ # value.respond_to?(:to_h)
293
+ # end
294
+
295
+ # Format configuration for a specific key
296
+ #
297
+ # @example Example configuration for key: tables
298
+ #
299
+ # configuration = {
300
+ # tables: {
301
+ # heading: 'Database Tables',
302
+ # take: :all,
303
+ # columns: [
304
+ # :name,
305
+ # :force,
306
+ # :primary_key,
307
+ # :id,
308
+ # columns: { display_method: lambda { |row| row.columns.map { |c| c.name }.join(', ') }, width: 100 }
309
+ # ]
310
+ # },
311
+ # people: {
312
+ # ... people configuration goes here
313
+ # }
314
+ # }
315
+ #
316
+
317
+ # Override table_print IO stream so that it writes into the structure
318
+ class TablePrintIo
319
+ def initialize(log_structure)
320
+ @log_structure = log_structure
321
+ end
322
+
323
+ def puts(line)
324
+ @log_structure.add_line(line)
325
+ end
326
+ end
327
+
328
+ class GraphNode
329
+ attr_reader :log_structure
330
+ attr_accessor :config
331
+
332
+ class << self
333
+ def null
334
+ @null ||= OpenStruct.new
335
+ end
336
+
337
+ def for(log_structure, graph, graph_path)
338
+ # node_config = graph_path.inject(graph, :send) # (uses deep nesting, but fails when nil is returned) https://stackoverflow.com/questions/15862455/ruby-nested-send
339
+ # node.nil? ? null : node.send(name) || null
340
+ node_config = graph_path.reduce(graph) do |node, name|
341
+ result = node.send(name)
342
+
343
+ break null if result.nil?
344
+
345
+ result
346
+ end
347
+
348
+ new(log_structure, node_config)
349
+ end
350
+ end
351
+
352
+ def initialize(log_structure, config)
353
+ @log_structure = log_structure
354
+ @config = config || OpenStruct.new
355
+ end
356
+
357
+ # table_print compatible configuration for displaying columns for an array
358
+ def columns
359
+ config.columns
360
+ end
361
+
362
+ # Optional heading for the node
363
+ def heading
364
+ config.heading
365
+ end
366
+
367
+ # Type of heading [:heading, :subheading, :section]
368
+ def heading_type
369
+ config.heading_type || :section
370
+ end
371
+
372
+ # Node data is to be transformed
373
+ def transform?
374
+ config&.transform.respond_to?(:call)
375
+ end
376
+
377
+ # Transform node value
378
+ def transform(value)
379
+ config.transform.call(value)
380
+ end
381
+
382
+ # Array rows are filtered
383
+ def filter?
384
+ config&.filter.respond_to?(:call)
385
+ end
386
+
387
+ # Array rows are filtered via this predicate
388
+ def filter(value)
389
+ config.filter.call(value)
390
+ end
391
+
392
+ # How any array rows to take
393
+ def take
394
+ config.take
395
+ end
396
+
397
+ # Array rows are limited, see take
398
+ def limited?
399
+ config.take&.is_a?(Integer)
400
+ end
401
+
402
+ # Array rows are sorted using .sort
403
+ def sort?
404
+ config&.sort.respond_to?(:call)
405
+ end
406
+
407
+ # Use array.sort?
408
+ def sort
409
+ config.sort
410
+ end
411
+
412
+ # Skip this node
413
+ def skip?
414
+ config.skip == true
415
+ end
416
+
417
+ # Useful in complex debug scenarios
418
+ def pry_at
419
+ config.pry_at || []
420
+ end
421
+
422
+ def pry_at?(section)
423
+ pry_at.include?(section)
424
+ end
425
+
426
+ # Skip empty array node (my be useful for other nodes, but not yet)
427
+ def skip_empty?
428
+ config.skip_empty == true
429
+ end
430
+
431
+ def show_array_count
432
+ log_structure.show_array_count
433
+ end
434
+ end
435
+ end
436
+ end
@@ -72,6 +72,12 @@ module KLog
72
72
  @logger.info(message)
73
73
  end
74
74
 
75
+ def dynamic_heading(heading, size: 70, type: :heading)
76
+ KLog.logger.heading(heading, size) if type == :heading
77
+ KLog.logger.subheading(heading, size) if type == :subheading
78
+ KLog.logger.section_heading(heading, size) if %i[section_heading section].include?(type)
79
+ end
80
+
75
81
  def heading(heading, size = 70)
76
82
  lines = LogHelper.heading(heading, size)
77
83
  info_multi_lines(lines)
@@ -131,7 +137,23 @@ module KLog
131
137
  end
132
138
  alias j json
133
139
 
140
+ # Log a structure
141
+ #
142
+ # Can handle Hash, Array, OpenStruct, Struct, DryStruct, Hash convertible custom classes
143
+ #
144
+ # @param [Hash] **opts Options
145
+ # @option opts [String] :indent Indent with string, defaults to ''
146
+ # @option opts [String] :depth is a computered
147
+ # @option opts [String] :heading Log title using logger.dynamic_heading
148
+ # @option opts [String] :heading_type :heading, :subheading, :section_heading
149
+ # @option opts [Boolean] :skip_array Arrays items can be skipped
150
+ def structure(data, **opts)
151
+ structure = LogStructure.new(opts)
152
+ structure.log(data)
153
+ end
154
+
134
155
  # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/AbcSize
156
+ # DEPRECATE
135
157
  def open_struct(data, indent = '', **opts)
136
158
  KLog.logger.heading(opts[:heading], 88) unless opts[:heading].nil?
137
159
  KLog.logger.subheading(opts[:subheading], 88) unless opts[:subheading].nil?
@@ -176,8 +198,9 @@ module KLog
176
198
  def exception(exception)
177
199
  line
178
200
 
179
- @logger.info(exception.message)
180
- @logger.info(exception.backtrace.join("\n"))
201
+ @logger.info(KLog::LogHelper.bg_red(exception.message))
202
+
203
+ @logger.info(KLog::LogHelper.yellow(exception.backtrace.map { |row| row.start_with?(Dir.pwd) ? KLog::LogHelper.yellow(row) : KLog::LogHelper.red(row) }.join("\n")))
181
204
 
182
205
  line
183
206
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'k_util'
4
+
5
+ module KLog
6
+ module Tools
7
+ # This tool will build a Log Structure Formatter configuration by working
8
+ # through the object graph you would like to use with Log Structure
9
+ class BuildFormatterConfigurationForLogStructure
10
+ # Build a sample configuration based on the structure
11
+ def build_sample_config(data)
12
+ open_struct_data = KUtil.data.to_open_struct(data)
13
+
14
+ lines = [
15
+ '# Usage:',
16
+ '',
17
+ "formatter = #{infer_config(open_struct_data)}",
18
+ '',
19
+ "log.structure(data, heading: 'Insert Heading', line_width: 150, formatter: formatter)"
20
+ ]
21
+ KLog.logger.line
22
+ puts lines
23
+ KLog.logger.line
24
+ end
25
+
26
+ private
27
+
28
+ def infer_config(data)
29
+ result = {}
30
+
31
+ data.each_pair do |key, value|
32
+ next unless value.is_a?(Array)
33
+ next if KUtil.data.basic_type?(value.first)
34
+
35
+ result[key] = {
36
+ heading: key.to_s,
37
+ take: :all,
38
+ array_columns: value.first.to_h.keys
39
+ }
40
+ end
41
+
42
+ # This is essentially a pretty hash
43
+ JSON.pretty_generate(result)
44
+ .gsub(/(?:"|')(?<key>[^"]*)(?:"|')(?=:)(?::)/) do |_|
45
+ "#{Regexp.last_match(:key)}:"
46
+ end
47
+ .gsub('take: "all"', 'take: :all')
48
+ end
49
+ end
50
+ end
51
+ end
data/lib/k_log/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KLog
4
- VERSION = '0.0.19'
4
+ VERSION = '0.0.30'
5
5
  end
data/lib/k_log.rb CHANGED
@@ -5,6 +5,7 @@ require 'table_print'
5
5
  require 'k_log/version'
6
6
  require 'k_log/log_formatter'
7
7
  require 'k_log/log_helper'
8
+ require 'k_log/log_structure'
8
9
  require 'k_log/log_util'
9
10
  require 'k_log/logging'
10
11
 
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: k_log
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.19
4
+ version: 0.0.30
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cruwys
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-11 00:00:00.000000000 Z
11
+ date: 2021-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: k_util
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: table_print
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -55,8 +69,10 @@ files:
55
69
  - lib/k_log/examples.rb
56
70
  - lib/k_log/log_formatter.rb
57
71
  - lib/k_log/log_helper.rb
72
+ - lib/k_log/log_structure.rb
58
73
  - lib/k_log/log_util.rb
59
74
  - lib/k_log/logging.rb
75
+ - lib/k_log/tools/build_formatter_configuration_for_log_structure.rb
60
76
  - lib/k_log/version.rb
61
77
  - usage.png
62
78
  homepage: http://appydave.com/gems/k-log