k_log 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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