k_log 0.0.19 → 0.0.20

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: a5ce4190206d26b326f0295241cf8c087c3c56bfc0bb11b4e8dbb6f8d401447f
4
+ data.tar.gz: 3ed6be809644377525a00658e5f010b32e3979bb031e4d10037a4393c67c47d1
5
5
  SHA512:
6
- metadata.gz: f19cf492a22aaf8dbc89dcd9246aacc5732e3db7844d17030d63091e672c4fb201d11c221bbe24450cb1d8745b16d8b70bb21994cc821387ee703aaea4bbc69f
7
- data.tar.gz: f0355d0438831db47d1ec390ba7d336b763d76f8d1d23f9520c98a1641901f0114c9961e9ac5d158daa8cddf5658782c6311721aeea5f01cd6dbe7ba24a80c80
6
+ metadata.gz: 133ea34980568cb38ecf8e3b1d9efdf4aa292005b5a67ad9f8282da82200bf42611bb95dfe25bc2f1ee78b7b845cf9af4e65fbf136e0f73867cb07e092699419
7
+ data.tar.gz: 3606bca839c257f596f6ca6a0fb1e1b6cda1da58c3735ce0857236523c47e8ca13c0ce656936239ea0ffb2ce1c435e62dbd6b68b9f67a3677f1239c9ff0038ca
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
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
 
@@ -0,0 +1,214 @@
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_accessor :indent
9
+ attr_accessor :heading
10
+ attr_accessor :heading_type
11
+ attr_accessor :line_width
12
+ attr_accessor :formatter
13
+ attr_accessor :skip_array
14
+
15
+ attr_accessor :recursion_depth
16
+ attr_accessor :key_format
17
+
18
+ # Log a structure
19
+ #
20
+ # Can handle Hash, Array, OpenStruct, Struct, DryStruct, Hash convertible custom classes
21
+ #
22
+ # @option opts [String] :indent Indent with string, defaults to ' '
23
+ # @option opts [String] :heading Log heading using logger.dynamic_heading
24
+ # @option opts [String] :heading_type :heading, :subheading, :section_heading
25
+ # @option opts [String] :line_width line width defaults to 80, but can be overridden here
26
+ # @option opts [String] :formatter is a complex configuration for formatting different data within the structure
27
+ def initialize(opts)
28
+ @indent = opts[:indent] || ' '
29
+ @heading = opts[:heading]
30
+ @heading_type = opts[:heading_type] || :heading
31
+ @formatter = opts[:formatter] || {}
32
+
33
+ @line_width = opts[:line_width] || 80
34
+ # @skip_array = opts[:skip_array]
35
+
36
+ @recursion_depth = 0
37
+ @key_format = nil
38
+ update_indent_label
39
+ end
40
+
41
+ def log(data)
42
+ log_heading(heading, heading_type)
43
+
44
+ open_struct_data = KUtil.data.to_open_struct(data)
45
+
46
+ log_data(open_struct_data)
47
+
48
+ KLog.logger.line(line_width)
49
+ end
50
+
51
+ # Build a sample configuration based on the structure (move to own class)
52
+ def build_sample_config(_data)
53
+ # open_struct_data = KUtil.data.to_open_struct(data)
54
+ {
55
+ to: :do
56
+ }
57
+ end
58
+
59
+ private
60
+
61
+ def build_key_format(key)
62
+ format_config = @formatter[key]
63
+ format_config = @formatter[:_root] if format_config.nil? && @recursion_depth.zero?
64
+ @key_format = KeyFormat.new(format_config)
65
+ end
66
+
67
+ def log_data(data)
68
+ data.each_pair do |key, value|
69
+ build_key_format(key)
70
+ case value
71
+ when OpenStruct
72
+ log_structure(key, value) unless @key_format.ignore?
73
+ when Array
74
+ log_array(key, value) unless @key_format.ignore?
75
+ else
76
+ KLog.logger.kv "#{@indent_label}#{key}", value
77
+ end
78
+ end
79
+ nil
80
+ end
81
+
82
+ def log_structure(key, value)
83
+ # This is specifically for k_doc, I should use a configuration instead of this technique
84
+ if value['rows'].is_a?(Array)
85
+ # KLog.logger.subheading(key)
86
+ # opts[:subheading] = key
87
+ # opts.delete(:subheading)
88
+ else
89
+ KLog.logger.kv "#{@indent_label}#{key}", ''
90
+ end
91
+ log_child_data(value)
92
+ end
93
+
94
+ def log_child_data(value)
95
+ depth_down
96
+ log_data(value)
97
+ depth_up
98
+ end
99
+
100
+ # rubocop:disable Metrics/AbcSize
101
+ def log_array(key, array)
102
+ # next unless opts[:skip_array].nil?
103
+ return unless array.length.positive?
104
+
105
+ log_heading(key_format.heading, key_format.heading_type)
106
+
107
+ filter_items = key_format.take_all ? array : array.take(key_format.take)
108
+
109
+ if primitive?(filter_items)
110
+ KLog.logger.kv "#{indent}#{key}", filter_items.map(&:to_s).join(', ')
111
+ else
112
+ tp filter_items, tp_columns(filter_items)
113
+ end
114
+ end
115
+ # rubocop:enable Metrics/AbcSize
116
+
117
+ def primitive?(items)
118
+ item = items.first
119
+ KUtil.data.basic_type?(item)
120
+ end
121
+
122
+ def log_heading(heading, heading_type)
123
+ return unless heading
124
+
125
+ KLog.logger.dynamic_heading(heading, size: line_width, type: heading_type)
126
+ end
127
+
128
+ def tp_columns(items)
129
+ # Use configured array columns
130
+ return key_format.array_columns if key_format.array_columns
131
+
132
+ # Slow but complete list of keys
133
+ # items.flat_map { |v| v.to_h.keys }.uniq
134
+
135
+ items.first.to_h.keys
136
+ end
137
+
138
+ def update_indent_label
139
+ @indent_label = (indent * @recursion_depth)
140
+ end
141
+
142
+ def indent_in
143
+ @indent = "#{@indent} "
144
+ end
145
+
146
+ def indent_out
147
+ @indent = indent.chomp(' ')
148
+ end
149
+
150
+ def depth_down
151
+ @recursion_depth = recursion_depth + 1
152
+ update_indent_label
153
+ end
154
+
155
+ def depth_up
156
+ update_indent_label
157
+ @recursion_depth = recursion_depth - 1
158
+ end
159
+
160
+ # Format configuration for a specific key
161
+ #
162
+ # @example Example configuration for key: tables
163
+ #
164
+ # configuration = {
165
+ # tables: {
166
+ # heading: 'Database Tables',
167
+ # take: :all,
168
+ # array_columns: [
169
+ # :name,
170
+ # :force,
171
+ # :primary_key,
172
+ # :id,
173
+ # columns: { display_method: lambda { |row| row.columns.map { |c| c.name }.join(', ') }, width: 100 }
174
+ # ]
175
+ # },
176
+ # people: {
177
+ # ... people configuration goes here
178
+ # }
179
+ # }
180
+ #
181
+ # format = KeyFormat.new(configuration[:tables])
182
+ class KeyFormat
183
+ attr_accessor :config
184
+
185
+ def initialize(config)
186
+ @config = OpenStruct.new(config)
187
+ end
188
+
189
+ def array_columns
190
+ config.array_columns
191
+ end
192
+
193
+ def heading
194
+ config.heading
195
+ end
196
+
197
+ def heading_type
198
+ config.heading_type || :section_heading
199
+ end
200
+
201
+ def take
202
+ config.take
203
+ end
204
+
205
+ def take_all
206
+ config.take.nil? || config.take == :all
207
+ end
208
+
209
+ def ignore?
210
+ config.ignore == true
211
+ end
212
+ end
213
+ end
214
+ 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 type == :section_heading
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?
@@ -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.20'
5
5
  end
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.20
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-08-08 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