k_log 0.0.1

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.
data/hooks/pre-commit ADDED
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'English'
5
+
6
+ # NOTE: you may need change file permissions
7
+ # chmod +x hooks/pre-commit
8
+
9
+ exit 0 if ARGV.include?('--no-verify')
10
+
11
+ warning_keywords = %w[console.log]
12
+ keywords = %w[binding.pry console.dir byebug debugger]
13
+ files_changed = `git diff-index --name-only HEAD --`.split
14
+
15
+ # puts '----------------------------------------------------------------------'
16
+ # puts remove files changed from the pre-commit checking if they are one of the following files
17
+ # puts '----------------------------------------------------------------------'
18
+ # files_changed = files_changed - ['hooks/pre-commit']
19
+ # files_changed = files_changed - ['hooks/update-version']
20
+
21
+ # byebug may need to be in these files
22
+ files_changed -= ['Gemfile']
23
+ files_changed -= ['Gemfile.lock']
24
+ files_changed -= ['.gitignore']
25
+ files_changed -= ['README.md']
26
+
27
+ files_changed = files_changed.reject { |f| f.downcase.end_with?('.json') }
28
+ files_changed = files_changed.reject { |f| f.downcase.end_with?('.yml') }
29
+
30
+ # ignore files from specific folders
31
+
32
+ file_groups = files_changed.select do |item|
33
+ item.start_with?('hooks') # ||
34
+ # item.start_with?('lib/generators')
35
+ end
36
+
37
+ files_changed -= file_groups
38
+
39
+ # remove files that are changed because they are deleted
40
+ files_changed = files_changed.select { |filename| File.file?(filename) }
41
+
42
+ # puts '----------------------------------------------------------------------'
43
+ # puts 'Files Changed'
44
+ # puts '----------------------------------------------------------------------'
45
+ # puts files_changed
46
+ # puts '----------------------------------------------------------------------'
47
+
48
+ unless files_changed.length.zero?
49
+ # puts "#{keywords.join('|')}"
50
+ # puts "#{files_changed.join(' ')}"
51
+
52
+ `git grep -q -E "#{warning_keywords.join('|')}" #{files_changed.join(' ')}`
53
+
54
+ if $CHILD_STATUS.exitstatus.zero?
55
+ puts '' # Check following lines:''
56
+ puts $CHILD_STATUS.exitstatus
57
+ files_changed.each do |file|
58
+ warning_keywords.each do |keyword|
59
+ # puts "#{keyword} ::: #{file}"
60
+ `git grep -q -E #{keyword} #{file}`
61
+ if $CHILD_STATUS.exitstatus.zero?
62
+ line = `git grep -n #{keyword} #{file} | awk -F ":" '{print $2}'`.split.join(', ')
63
+ puts "WARNING:\t\033[31m#{file}\033[0m contains #{keyword} at line \033[33m#{line}\033[0m."
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ `git grep -q -E "#{keywords.join('|')}" #{files_changed.join(' ')}`
70
+
71
+ if $CHILD_STATUS.exitstatus.zero?
72
+ puts '' # Check following lines:''
73
+ puts $CHILD_STATUS.exitstatus
74
+ files_changed.each do |file|
75
+ keywords.each do |keyword|
76
+ # puts "#{keyword} ::: #{file}"
77
+ `git grep -q -E #{keyword} #{file}`
78
+ if $CHILD_STATUS.exitstatus.zero?
79
+ line = `git grep -n #{keyword} #{file} | awk -F ":" '{print $2}'`.split.join(', ')
80
+ puts "ERROR :\t\033[31m#{file}\033[0m contains #{keyword} at line \033[33m#{line}\033[0m."
81
+ end
82
+ end
83
+ end
84
+ puts '# Force commit with --no-verify'
85
+ exit 1
86
+ end
87
+ end
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # NOTE: you may need change file permissions
5
+ # chmod +x hooks/update-version
6
+
7
+ exit 1 if ARGV.empty?
8
+
9
+ version = ARGV[0]
10
+ version = version[1..-1] # revoke 'v' character, e.g. v0.1.1 becomes 0.1.1
11
+
12
+ namespaces = %w[KLog]
13
+
14
+ indent = 0
15
+ output = ['# frozen_string_literal: true', '']
16
+
17
+ namespaces.each do |namespace|
18
+ output.push "#{' ' * indent}module #{namespace}"
19
+ indent += 1
20
+ end
21
+
22
+ output.push "#{' ' * indent}VERSION = \'#{version}'"
23
+ indent -= 1
24
+
25
+ namespaces.each do
26
+ output.push "#{' ' * indent}end"
27
+ indent -= 1
28
+ end
29
+
30
+ output.push('')
31
+
32
+ printf "%-25<label>s : %<version>s\n", label: 'GEM VERSION', version: version
33
+ File.open('lib/k_log/version.rb', 'w+') { |f| f.write(output.join("\n")) }
data/k_log.gemspec ADDED
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/k_log/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.required_ruby_version = '>= 2.5'
7
+ spec.name = 'k_log'
8
+ spec.version = KLog::VERSION
9
+ spec.authors = ['David Cruwys']
10
+ spec.email = ['david@ideasmen.com.au']
11
+
12
+ spec.summary = 'KLog provides console logging helpers and formatters'
13
+ spec.description = <<-TEXT
14
+ KLog provides console logging helpers and formatters
15
+ TEXT
16
+ spec.homepage = 'http://appydave.com/gems/k-log'
17
+ spec.license = 'MIT'
18
+
19
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
20
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
21
+ raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.' unless spec.respond_to?(:metadata)
22
+
23
+ # spec.metadata['allowed_push_host'] = "Set to 'http://mygemserver.com'"
24
+
25
+ spec.metadata['homepage_uri'] = spec.homepage
26
+ spec.metadata['source_code_uri'] = 'https://github.com/klueless-io/k_log'
27
+ spec.metadata['changelog_uri'] = 'https://github.com/klueless-io/k_log/commits/master'
28
+
29
+ # Specify which files should be added to the gem when it is released.
30
+ # The `git ls-files -z` loads the RubyGem files that have been added into git.
31
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
32
+ `git ls-files -z`.split("\x0").reject do |f|
33
+ f.match(%r{^(test|spec|features)/})
34
+ end
35
+ end
36
+ spec.bindir = 'exe'
37
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
38
+ spec.require_paths = ['lib']
39
+ # spec.extensions = ['ext/k_log/extconf.rb']
40
+
41
+ # spec.add_dependency 'tty-box', '~> 0.5.0'
42
+ end
data/lib/k_log.rb ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'k_log/version'
4
+
5
+ module KLog
6
+ # raise KLog::Error, 'Sample message'
7
+ class Error < StandardError; end
8
+
9
+ # Your code goes here...
10
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KDsl
4
+ module Logger
5
+ # Styled Log formatter
6
+ class LogFormatter < ::Logger::Formatter
7
+ attr_accessor :show_caller
8
+
9
+ SEVERITY_TO_COLOR_MAP = {
10
+ 'DEBUG' => '34',
11
+ 'INFO' => '32',
12
+ 'WARN' => '33',
13
+ 'ERROR' => '31',
14
+ 'FATAL' => '37'
15
+ }.freeze
16
+
17
+ def call(severity, _timestamp, _progname, msg)
18
+ severity = severity.upcase
19
+
20
+ color = SEVERITY_TO_COLOR_MAP[severity]
21
+
22
+ severity_value = format("\033[#{color}m%<severity>-5.5s\033[0m", { severity: severity })
23
+
24
+ msg = msg.is_a?(String) ? msg : msg.inspect
25
+
26
+ format(
27
+ "%<time>s %<severity>s %<message>s\n", {
28
+ time: Time.now.strftime('%d|%H:%M:%S'),
29
+ severity: severity_value,
30
+ message: msg
31
+ }
32
+ )
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Log Helper is an internal class that takes care of a lot of the formating of different content types
4
+ # e.g key/values, lines, progress counters and headings
5
+ # it is different to the formatter becuase the formatter is used by Rails Logger to change the output stream style and format
6
+ class LogHelper
7
+ @progress_section = ''
8
+ @progress_position = 0
9
+
10
+ class << self
11
+ attr_accessor :progress_position
12
+ attr_accessor :progress_section
13
+ end
14
+
15
+ def self.kv(key, value, key_width = 30)
16
+ "#{green(key.to_s.ljust(key_width))}: #{value}"
17
+ end
18
+
19
+ def self.progress(pos = nil, section = nil)
20
+ @progress_position = pos.nil? ? @progress_position : pos
21
+
22
+ unless section.nil?
23
+ # Pl.info 'here'
24
+ @progress_section = section
25
+ end
26
+
27
+ # puts '@progress_position'
28
+ # puts @progress_position
29
+ # puts '@progress_section'
30
+ # puts @progress_section
31
+
32
+ section_length = 28
33
+
34
+ section = if @progress_section.nil?
35
+ ' ' * section_length
36
+ else
37
+ ' ' + @progress_section.ljust(section_length - 1, ' ')
38
+ end
39
+
40
+ # puts 'section'
41
+ # puts section
42
+
43
+ result = '..' + section + ':' + @progress_position.to_s.rjust(4)
44
+
45
+ @progress_position += 1
46
+
47
+ result
48
+ end
49
+
50
+ def self.line(size = 70, character = '=')
51
+ green(character * size)
52
+ end
53
+
54
+ def self.heading(heading, size = 70)
55
+ line = line(size)
56
+
57
+ [
58
+ line,
59
+ heading,
60
+ line
61
+ ]
62
+ end
63
+
64
+ def self.subheading(heading, size = 70)
65
+ line = line(size, '-')
66
+ [
67
+ line,
68
+ heading,
69
+ line
70
+ ]
71
+ end
72
+
73
+ # A section heading
74
+ #
75
+ # example:
76
+ # [ I am a heading ]----------------------------------------------------
77
+ def self.section_heading(heading, size = 70)
78
+ heading = "[ #{heading} ]"
79
+ line = line(size - heading.length, '-')
80
+
81
+ # It is important that you set the colour after you have calculated the size
82
+ "#{green(heading)}#{line}"
83
+ end
84
+
85
+ # :sql_array should be an array with SQL and values
86
+ # example: L.sql(["name = :name and group_id = :value OR parent_id = :value", name: "foo'bar", value: 4])
87
+ # def sql(sql_array)
88
+ # value = ActiveRecord::Base.send(:sanitize_sql_array, sql_array)
89
+
90
+ # info(value)
91
+ # end
92
+
93
+ # rubocop:disable Metrics/CyclomaticComplexity
94
+ def self.block(messages, include_line = true, title: nil)
95
+ result = include_line ? [line] : []
96
+
97
+ unless title.nil?
98
+ result.push(title)
99
+ result.push(line(70, ','))
100
+ end
101
+
102
+ result.push messages if messages.is_a?(String) || messages.is_a?(Integer)
103
+
104
+ if messages.is_a? Array
105
+ messages.each do |message|
106
+ result.push message
107
+ end
108
+ end
109
+
110
+ result.push line if include_line
111
+
112
+ result
113
+ end
114
+ # rubocop:enable Metrics/CyclomaticComplexity
115
+
116
+ def self.green(value)
117
+ "\033[32m#{value}\033[0m"
118
+ end
119
+ end
@@ -0,0 +1,332 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Format Logger Util provides static helper methods that delegate responsibility to the underlying
4
+ # Format Logger, you can use the Util instead Rails.logger so that you have access to IDE intellisense around
5
+ # available methods and so that you can use the same logger calls from controllers/models which normally have
6
+ # access to to a logger variable and services which do not have access to a logger varialbe
7
+ #
8
+ # I usually alias the call to FormatLoggerUtil by doing L = FormatLoggerUtil
9
+
10
+ # require_relative 'format_logger'
11
+ # require_relative 'format_logger_helper'
12
+
13
+ class LogUtil
14
+ def initialize(logger)
15
+ @logger = logger
16
+ @fuck = true
17
+ end
18
+
19
+ # include ActiveSupport::LoggerThreadSafeLevel
20
+ # include LoggerSilence
21
+
22
+ #----------------------------------------------------------------------------------------------------
23
+ # Standard Accessors that are on the standard rails Logger
24
+ #----------------------------------------------------------------------------------------------------
25
+ def debug(value)
26
+ @logger.debug(value)
27
+ end
28
+
29
+ def info(value)
30
+ @logger.info(value)
31
+ end
32
+
33
+ def warn(value)
34
+ @logger.warn(value)
35
+ end
36
+
37
+ def error(value)
38
+ @logger.error(value)
39
+ end
40
+
41
+ def fatal(value)
42
+ @logger.fatal(value)
43
+ end
44
+
45
+ #----------------------------------------------------------------------------------------------------
46
+ # Helper Log output Methods
47
+ #----------------------------------------------------------------------------------------------------
48
+
49
+ # Write a Key/Value Pair
50
+ def kv(key, value, key_width = 30)
51
+ message = LogHelper.kv(key, value, key_width)
52
+ @logger.info(message)
53
+ end
54
+
55
+ # Write a progress point, progress will update on it's own
56
+ def progress(pos = nil, section = nil)
57
+ message = LogHelper.progress(pos, section)
58
+ # @logger.debug(message)
59
+ @logger.info(message)
60
+
61
+ LogHelper.progress_position
62
+ end
63
+
64
+ # prints out a line to the log
65
+ def line(size = 70, character: '=')
66
+ message = LogHelper.line(size, character)
67
+
68
+ @logger.info(message)
69
+ end
70
+
71
+ def heading(heading, size = 70)
72
+ lines = LogHelper.heading(heading, size)
73
+ info_multi_lines(lines)
74
+ end
75
+
76
+ def subheading(heading, size = 70)
77
+ lines = LogHelper.subheading(heading, size)
78
+
79
+ info_multi_lines(lines)
80
+ end
81
+
82
+ # A section heading
83
+ #
84
+ # example:
85
+ # [ I am a heading ]----------------------------------------------------
86
+ def section_heading(heading, size = 70)
87
+ heading = LogHelper.section_heading(heading, size)
88
+
89
+ info(heading)
90
+ end
91
+
92
+ def block(messages, include_line = true, title: nil)
93
+ lines = LogHelper.block(messages, include_line, title: title)
94
+
95
+ info_multi_lines(lines)
96
+ end
97
+
98
+ # # :sql_array should be an array with SQL and values or with SQL and Hash
99
+ # # example:
100
+ # # L.sql(["name = :name and group_id = :value OR parent_id = :value", name: "foo'bar", value: 4])
101
+ # # L.sql([sql_exact_match_skills_in_use, {names: self.segments_container.segment_values}])
102
+ # def sql(sql_array)
103
+ # value = ActiveRecord::Base.send(:sanitize_sql_array, sql_array)
104
+
105
+ # info(value)
106
+ # end
107
+
108
+ def yaml(data, is_line = true)
109
+ line if is_line
110
+
111
+ @logger.info(data.to_yaml) if data.is_a?(Hash)
112
+
113
+ @logger.info(data.marshal_dump.to_yaml) if data.is_a?(OpenStruct)
114
+
115
+ if data.is_a? Array
116
+ data.each do |d|
117
+ @logger.info(d.to_yaml)
118
+ end
119
+ end
120
+
121
+ line if is_line
122
+ end
123
+
124
+ def json(data)
125
+ @logger.info(JSON.pretty_generate(data))
126
+ end
127
+ alias j json
128
+
129
+ def open_struct(data, indent = '', **opts)
130
+ data.each_pair do |key, value|
131
+ if value.is_a?(OpenStruct)
132
+ if value['rows'].is_a?(Array)
133
+ # L.subheading(key)
134
+ opts[:subheading] = key
135
+ open_struct(value, indent, **opts)
136
+ opts.delete(:subheading)
137
+ else
138
+ L.kv "#{indent}#{key}", ''
139
+ indent = "#{indent} "
140
+ open_struct(value, indent, **opts)
141
+ indent = indent.chomp(' ')
142
+ end
143
+ elsif value.is_a?(Array)
144
+ next if opts[:skip_array].present?
145
+ # puts LogHelper.subheading(key, 88)# if opts[:subheading].present?
146
+ puts LogHelper.subheading(opts[:subheading], 88) if opts[:subheading].present?
147
+ if value.length > 0
148
+ if value.first.is_a?(String)
149
+ L.kv "#{indent}#{key}", value.join(', ')
150
+ else
151
+ tp value, value.first.to_h.keys
152
+ end
153
+ end
154
+ else
155
+ L.kv "#{indent}#{key}", value
156
+ end
157
+ end
158
+ nil
159
+ end
160
+ alias ostruct open_struct
161
+ alias o open_struct
162
+
163
+ def exception(e)
164
+ line
165
+
166
+ @logger.info(e.message)
167
+ @logger.info(e.backtrace.join("\n"))
168
+
169
+ line
170
+ end
171
+
172
+ #----------------------------------------------------------------------------------------------------
173
+ # Pretty Loggers
174
+ #----------------------------------------------------------------------------------------------------
175
+
176
+ # NOTE: using pretty_inspect is an existing namespace conflict
177
+ def pretty_class(instance)
178
+ c = instance.class
179
+
180
+ line
181
+
182
+ kv('Full Class', c.name)
183
+ kv('Module', c.name.deconstantize)
184
+ kv('Class', c.name.demodulize)
185
+
186
+ source_location = c.instance_methods(false).map { |m|
187
+ c.instance_method(m).source_location.first
188
+ }.uniq
189
+
190
+ begin
191
+ kv('Source Location', source_location)
192
+ rescue => e
193
+ warn e
194
+ end
195
+
196
+ line
197
+ end
198
+
199
+ # NOTE: using pretty_inspect is an existing namespace conflict
200
+ def pretty_params(params)
201
+ line
202
+
203
+ params.each do |k,v|
204
+ if (params[k].is_a?(Hash))
205
+
206
+ params[k].each do |childK, childV|
207
+ kv("#{k}[#{childK}]",childV)
208
+ end
209
+
210
+ else
211
+ kv(k, v)
212
+ end
213
+ end
214
+
215
+ line
216
+ end
217
+
218
+ def help_all_symbols
219
+ # Produces a lot of data, need some sort of filter I think before this is useful
220
+ Symbol.all_symbols.each do |s|
221
+ info s
222
+ # debug s
223
+ end
224
+ end
225
+
226
+ #----------------------------------------------------------------------------------------------------
227
+ # Internal Methods
228
+ #----------------------------------------------------------------------------------------------------
229
+
230
+ def self.samples
231
+ L.debug 'some debug message'
232
+ L.info 'some info message'
233
+ L.warn 'some warning message'
234
+ L.error 'some error message'
235
+ L.fatal 'some fatal message'
236
+
237
+ L.kv('First Name', 'David')
238
+ L.kv('Last Name', 'Cruwys')
239
+ L.kv('Age', 45)
240
+ L.kv('Sex', 'male')
241
+
242
+ L.progress(0, 'Section 1')
243
+ L.progress
244
+ L.progress
245
+ save_progress = L.progress
246
+
247
+ L.progress(10, 'Section 2')
248
+ L.progress
249
+ L.progress
250
+ L.progress
251
+
252
+ L.progress(save_progress, 'Section 1')
253
+ L.progress
254
+ L.progress
255
+ L.progress
256
+
257
+ L.line
258
+ L.line(20)
259
+ L.line(20, character: '-')
260
+
261
+ L.heading('Heading')
262
+ L.subheading('Sub Heading')
263
+
264
+ L.block ['Line 1', 12, 'Line 3', true,'Line 5']
265
+
266
+ yaml1 = Hash.new
267
+ yaml1['title'] = 'Software Architect'
268
+ yaml1['age'] = 45
269
+ yaml1['name'] = 'David'
270
+
271
+ yaml3 = Hash.new
272
+ yaml3['title'] = 'Develoer'
273
+ yaml3['age'] = 20
274
+ yaml3['name'] = 'Jin'
275
+
276
+ L.yaml(yaml1)
277
+
278
+ yaml2 = OpenStruct.new
279
+ yaml2.title = 'Software Architect'
280
+ yaml2.age = 45
281
+ yaml2.name = 'David'
282
+
283
+ L.yaml(yaml2)
284
+
285
+ mixed_yaml_array = [yaml1, yaml2]
286
+
287
+ # This fails because we don't correctly pre-process the array
288
+ L.yaml(mixed_yaml_array)
289
+
290
+ hash_yaml_array = [yaml1, yaml3]
291
+
292
+ L.yaml(hash_yaml_array)
293
+
294
+ begin
295
+ raise 'Here is an error'
296
+ rescue StandardError => e
297
+ L.exception(e)
298
+ end
299
+ end
300
+
301
+ private
302
+
303
+ def debug_multi_lines(lines)
304
+ lines.each do |line|
305
+ debug(line)
306
+ end
307
+ end
308
+
309
+ def info_multi_lines(lines)
310
+ lines.each do |line|
311
+ info(line)
312
+ end
313
+ end
314
+
315
+ def warn_multi_lines(lines)
316
+ lines.each do |line|
317
+ warn(line)
318
+ end
319
+ end
320
+
321
+ def error_multi_lines(lines)
322
+ lines.each do |line|
323
+ error(line)
324
+ end
325
+ end
326
+
327
+ def fatal_multi_lines(lines)
328
+ lines.each do |line|
329
+ fatal(line)
330
+ end
331
+ end
332
+ end