markdown_logging_proxy 1.0.0 → 1.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ede32c7a00afa640bd44e6ec610034cc8a968e369a214d80bc3071c5b902516
4
- data.tar.gz: c2032172bb4e05c3ebf6ac0ba30984c08623d4948b371f1afb77199ed4effae3
3
+ metadata.gz: aff578739daa97caef0a7014bf062fe113a495cc124da496f6a08d8c31790e49
4
+ data.tar.gz: 560c9efb88be9083d5d91b46a174c8b5c26c5c0b30289776c80f937b9ee81b1b
5
5
  SHA512:
6
- metadata.gz: a60b3241307b03bd0ef86b4cec3ca1fc149e3cb552dfea7eecffadf9e831f014f367cd714b4e3a3897d3f08b6258ece8e22111500989707e216f909726e45ab1
7
- data.tar.gz: 2dadcbef2a63e99aa6187751ee8cbf2c1318add028e0d6443f6f2331895dbadc27c4a20cdf740468df83937183a94f88bd28e6a8d46dee6fe21b5a3572f18bbe
6
+ metadata.gz: aa0ff0ff2637a3bd8eb9141cd6200e763478d071859958a07ca6585a2405fcce83160a9b03c49a88afa7f11428d3ed50bc4b3cde944bf96060c820b253406d20
7
+ data.tar.gz: 45f2d7f82f0e7d366857b8da7ab7a6397e582190969155013facd87a5ae66c7c441f006486fee4cfe9b388538d614eaa60c533f478ec4a7165f9038031e31dcb
data/CHANGELOG.md CHANGED
@@ -3,3 +3,29 @@
3
3
  ## [0.1.0] - 2022-08-22
4
4
 
5
5
  - Initial release
6
+
7
+ ## [1.0.0]
8
+
9
+ - Release of gem to rubygems
10
+ - Proxy now defines zero methods besides `method_missing`
11
+ - Addition of `bin/example` script
12
+
13
+ ## [1.0.1]
14
+
15
+ - Add missing CHANGELOG updates
16
+ - Commit updates to compiled `dist/` version of library
17
+
18
+ ## [1.0.2]
19
+
20
+ - Improved log formatting
21
+ - Fix to proxy method overwrite behavior
22
+
23
+ ## [1.1.0]
24
+
25
+ - Don't show object IDs for args arrays. It's confusing.
26
+ - BREAKING: Proxies most `Object` methods by default now
27
+
28
+ ## [1.1.1]
29
+
30
+ - Allow proxying of `nil`
31
+ - Add require statements to copy+paste version
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- markdown_logging_proxy (0.1.0)
4
+ markdown_logging_proxy (1.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -18,7 +18,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
18
18
 
19
19
  ### Copy+Paste
20
20
 
21
- Look at `dist/` for compiled versions of the gem which can safely (relatively) be copied into irb/pry sessions.
21
+ You can copy the contents of [`dist/markdown_logging_proxy.rb`](dist/markdown_logging_proxy.rb) into a live irb/pry session.
22
22
 
23
23
  ## Usage
24
24
 
@@ -1,149 +1,247 @@
1
+ require 'logger'
2
+ require 'securerandom'
3
+ require 'pp'
4
+ require 'time'
1
5
  module MarkdownLoggingProxy
2
- # frozen_string_literal: true
6
+ class MarkdownLogger
7
+ def self.inspect_object(object, show_id = true)
8
+ [
9
+ '```ruby',
10
+ ("# #{id_object(object)}" if show_id),
11
+ object.pretty_inspect.chomp,
12
+ '```'
13
+ ].compact.join("\n")
14
+ end
15
+
16
+ def self.id_object(object)
17
+ # #<Object:0x00007f5a0919e140>
18
+ "`#<#{object.class}:0x#{object.object_id.to_s(16)}>`"
19
+ end
20
+
21
+ def self.build(location, **options)
22
+ return location if location.is_a?(MarkdownLogger)
23
+ new(location, **options)
24
+ end
25
+
26
+ attr_reader :std_logger, :backtrace, :heading_level, :created_at
27
+
28
+ def initialize(location, backtrace: true)
29
+ @created_at = Time.now
30
+ @std_logger = create_logger(location)
31
+ @heading_level = 1
32
+ @backtrace = backtrace
33
+ end
34
+
35
+ def log(level, heading = 3, msg)
36
+ @heading_level = heading
37
+ std_logger.send(level, msg)
38
+ end
39
+
40
+ def inspect_backtrace(ignore = 4)
41
+ return unless backtrace
42
+ lines =
43
+ case backtrace
44
+ when true then caller(ignore)
45
+ when Regexp then caller(ignore).grep(backtrace)
46
+ else
47
+ []
48
+ end
49
+ <<~MSG.chomp
3
50
 
4
- require 'logger'
5
- require 'securerandom'
6
- require 'pp'
7
- require 'time'
51
+ Backtrace:
8
52
 
53
+ #{lines.map { |l| "* #{l.chop}`" }.join("\n")}
54
+ MSG
55
+ end
56
+
57
+ private
58
+
59
+ def logger_instance(location)
60
+ case location
61
+ when Logger then location
62
+ else
63
+ Logger.new(location)
64
+ end
65
+ end
66
+
67
+ def create_logger(location)
68
+ logger_instance(location).tap do |logger|
69
+ logger.formatter = markdown_formatter
70
+ end
71
+ end
72
+
73
+ def markdown_formatter
74
+ proc do |severity, time, __exec, msg|
75
+ elapsed = Time.now - created_at
76
+ "#{'#' * heading_level} #{severity} at +#{elapsed.round(5)} -- #{msg}\n\n"
77
+ end
78
+ end
79
+ end
80
+ end
81
+ module MarkdownLoggingProxy
82
+ # just a shortcut for Proxy.new
83
+ def self.new(*args, **options)
84
+ Proxy.new(*args, **options)
85
+ end
86
+ end
87
+ module MarkdownLoggingProxy
9
88
  class Proxy
89
+ # Object methods that should be proxied but won't hit method_missing
90
+ DEFAULT_OVERWRITES = %i[
91
+ ! != !~ <=> == === =~
92
+ clone display dup enum_for eql? equal? freeze frozen? hash inspect
93
+ is_a? itself kind_of? nil? taint tainted? tap then to_enum to_s
94
+ trust untaint unstrust untrusted? yield_self
95
+ ]
10
96
 
11
97
  def initialize(
12
- target:,
13
- logger: nil,
98
+ to_proxy = nil,
99
+ target: nil,
14
100
  location: STDOUT,
15
- backtrace: /projects/, # regex/true/false backtrace control
16
- ignore: [], # methods we shouldn't proxy
101
+ backtrace: true, # regex/true/false backtrace control
102
+ ignore: [], # methods we shouldn't log/proxy
17
103
  proxy_response: [], # methods we should return a proxy for
18
- overwrite: [] # methods defined on Object we should overwrite
104
+ overwrite: DEFAULT_OVERWRITES
105
+ )
106
+ @target = to_proxy || target
107
+ @logger = MarkdownLogger.build(location, backtrace: backtrace)
108
+ @tracer = Tracer.new(
109
+ target: @target,
110
+ proxy: self,
111
+ logger: @logger,
112
+ ignore: ignore,
113
+ proxy_response: proxy_response,
114
+ proxy_options: {
115
+ overwrite: overwrite,
116
+ backtrace: backtrace,
117
+ }
19
118
  )
20
- @ignore = (ignore + proxy_response).uniq
21
- @proxy_response = proxy_response
22
- @target = target
23
- @logger =
24
- if logger
25
- Utils.format_logger(logger)
26
- else
27
- Utils.create_logger(location)
28
- end
29
- @backtrace = backtrace
30
119
  overwrite.each do |meth|
31
- define_method(meth) do |*args, &blk|
32
- __trace_method(meth, args, &blk)
120
+ self.class.define_method(meth) do |*args, &blk|
121
+ @tracer.trace(meth, args, &blk)
33
122
  end
34
123
  end
35
124
  end
36
125
 
37
126
  def method_missing(meth, *args, &blk)
38
- __trace_method(meth, args, &blk)
127
+ @tracer.trace(meth, args, &blk)
39
128
  end
129
+ end
130
+ end
131
+ module MarkdownLoggingProxy
132
+ class Tracer
133
+ attr_reader :target, :logger, :ignore, :proxy
40
134
 
41
- private
135
+ def initialize(
136
+ target:,
137
+ proxy:,
138
+ logger: nil,
139
+ ignore: [],
140
+ proxy_response: [],
141
+ proxy_options: {}
142
+ )
143
+ @target = target
144
+ @logger = logger
145
+ @ignore = ignore
146
+ @proxy_response = proxy_response
147
+ @proxy_options = proxy_options
148
+ end
42
149
 
43
- def __trace_method(meth, args, &blk)
44
- __log :info, meth, 2, <<~MSG
45
- Calling `#{meth}`
150
+ def trace(meth, args, &blk)
151
+ log_call_signature(meth, args, &blk) unless ignore?(meth)
152
+ log_and_proxy_response(meth, args, &blk)
153
+ rescue StandardError => e
154
+ log_and_reraise_error(meth, e)
155
+ end
46
156
 
47
- Arguments:
157
+ def proxy_response?(meth)
158
+ case @proxy_response
159
+ when true, false then @proxy_response
160
+ else
161
+ @proxy_response.member?(meth)
162
+ end
163
+ end
48
164
 
49
- #{__inspect_object(args)}
165
+ def ignore?(meth)
166
+ @ignore.member?(meth)
167
+ end
50
168
 
51
- Block? #{block_given? ? 'Yes' : 'No'}
52
- #{__display_backtrace}
53
- MSG
169
+ private
54
170
 
55
- __proxy_response(meth, @target.public_send(meth, *args, &__proxy_block(meth, blk))).tap do |response|
56
- __log :info, meth, <<~MSG
57
- `#{meth}` Response
171
+ def log_call_signature(meth, args, &blk)
172
+ return if ignore.member?(meth)
173
+ logger.log :info, 1, <<~MSG.chomp
174
+ Calling `#{meth}` on #{MarkdownLogger.id_object(target)}
58
175
 
59
- #{__inspect_object(response)}
60
- MSG
61
- end
62
- rescue StandardError => e
63
- __log :error, meth, <<~MSG
64
- Error in `#{meth}`
176
+ Arguments:
65
177
 
66
- Type: #{e.class}
178
+ #{MarkdownLogger.inspect_object(args, false)}
67
179
 
68
- #{__inspect_object(e)}
180
+ Block given? #{block_given? ? 'Yes' : 'No'}
181
+ #{logger.inspect_backtrace}
69
182
  MSG
70
- raise e
71
183
  end
72
184
 
73
- def __display_backtrace(ignore = 3)
74
- displayed_trace =
75
- case @backtrace
76
- when true then caller(ignore)
77
- when Regexp then caller(ignore).grep(@backtrace)
78
- end
79
- displayed_trace.map { |l| "* #{l.chop}`" }.join("\n") if displayed_trace
80
- end
185
+ def log_and_proxy_response(meth, args, &blk)
186
+ response = target.public_send(meth, *args, &log_and_proxy_block(meth, blk))
187
+ log_response(meth, response) unless ignore?(meth)
188
+ return response unless proxy_response?(meth)
189
+ logger.log :info, 3, <<~MSG.chomp
190
+ Returning proxied response to `#{meth}`
81
191
 
82
- def __log(level, meth, heading = 3, msg)
83
- return if @ignore.member?(meth)
84
- @heading_level = heading
85
- @logger.send(level, msg)
86
- end
87
-
88
- def __proxy_response(meth, response)
89
- return response unless @proxy_response.member?(meth)
90
- __log :info, nil, <<~MSG
91
- Using proxied response for `#{meth}`
192
+ Proxy from `#{meth}` on #{MarkdownLogger.id_object(target)}
92
193
 
93
- Object to proxy:
194
+ Proxy for:
94
195
 
95
- #{__inspect_object(response)}
196
+ #{MarkdownLogger.inspect_object(response)}
96
197
  MSG
97
- self.class.new(target: response, logger: @logger)
198
+ Proxy.new(**@proxy_options.merge(
199
+ target: response,
200
+ location: logger,
201
+ proxy_response: @proxy_response,
202
+ ignore: @ignore,
203
+ ))
98
204
  end
99
205
 
100
- def __proxy_block(meth, block)
101
- return if block.nil?
102
- logger = @logger
206
+ def log_and_proxy_block(meth, blk)
207
+ return if blk.nil?
103
208
  proc do |*args|
104
- logger.info <<~MSG
105
- Yield to block in `#{meth}`
209
+ logger.log :info, 2, <<~MSG.chomp
210
+ Yield to block in `#{meth}` on #{MarkdownLogger.id_object(target)}
106
211
 
107
212
  Arguments:
108
213
 
109
- #{__inspect_object(args)}
214
+ #{MarkdownLogger.inspect_object(args, false)}
110
215
  MSG
111
- block.call(*args).tap do |response|
112
- logger.info <<~MSG
216
+ blk.call(*args).tap do |response|
217
+ logger.log :info, 3, <<~MSG.chomp
113
218
  Response from block in `#{meth}`
114
219
 
115
- #{__inspect_object(response)}
220
+ #{MarkdownLogger.inspect_object(response)}
116
221
  MSG
117
222
  end
118
223
  end
119
224
  end
120
225
 
121
- def __inspect_object(obj)
122
- ['```ruby', obj.pretty_inspect.chomp, '```'].join("\n")
123
- end
124
- end
226
+ def log_and_reraise_error(meth, error)
227
+ logger.log :error, 2, <<~MSG.chomp
228
+ Error in `#{meth}`
125
229
 
126
- end
127
- module MarkdownLoggingProxy
128
- module Utils
129
- def self.heading_level
130
- @heading_level || 1
131
- end
230
+ Type: #{error.class}
132
231
 
133
- def self.heading_level=(level)
134
- @heading_level = level
232
+ #{MarkdownLogger.inspect_object(error)}
233
+ MSG
234
+ raise error
135
235
  end
136
236
 
137
- def self.create_logger(location)
138
- logger = location.kind_of?(Logger) ? location : Logger.new(location)
139
- format_logger logger
140
- end
237
+ def log_response(meth, response)
238
+ return if ignore?(meth)
239
+ logger.log :info, 2, <<~MSG.chomp
240
+ `#{meth}` response
141
241
 
142
- def self.format_logger(logger)
143
- logger.formatter = proc do |severity, time, _, msg|
144
- "#{'#' * heading_level} #{severity} in #{Process.pid} at #{time.iso8601} -- #{msg}\n\n"
145
- end
146
- logger
242
+ #{MarkdownLogger.inspect_object(response)}
243
+ MSG
147
244
  end
148
245
  end
149
- end
246
+ end
247
+
@@ -1,12 +1,17 @@
1
1
  module MarkdownLoggingProxy
2
2
  class MarkdownLogger
3
- def self.inspect_object(object)
4
- ['```ruby', object.pretty_inspect.chomp, '```'].join("\n")
3
+ def self.inspect_object(object, show_id = true)
4
+ [
5
+ '```ruby',
6
+ ("# #{id_object(object)}" if show_id),
7
+ object.pretty_inspect.chomp,
8
+ '```'
9
+ ].compact.join("\n")
5
10
  end
6
11
 
7
12
  def self.id_object(object)
8
13
  # #<Object:0x00007f5a0919e140>
9
- "##{object.class}:0x#{object.object_id.to_s(16)}>"
14
+ "`#<#{object.class}:0x#{object.object_id.to_s(16)}>`"
10
15
  end
11
16
 
12
17
  def self.build(location, **options)
@@ -14,9 +19,10 @@ module MarkdownLoggingProxy
14
19
  new(location, **options)
15
20
  end
16
21
 
17
- attr_reader :std_logger, :backtrace, :heading_level
22
+ attr_reader :std_logger, :backtrace, :heading_level, :created_at
18
23
 
19
24
  def initialize(location, backtrace: true)
25
+ @created_at = Time.now
20
26
  @std_logger = create_logger(location)
21
27
  @heading_level = 1
22
28
  @backtrace = backtrace
@@ -62,7 +68,8 @@ module MarkdownLoggingProxy
62
68
 
63
69
  def markdown_formatter
64
70
  proc do |severity, time, __exec, msg|
65
- "#{'#' * heading_level} #{severity} in #{Process.pid} at #{time.iso8601} -- #{msg}\n\n"
71
+ elapsed = Time.now - created_at
72
+ "#{'#' * heading_level} #{severity} at +#{elapsed.round(5)} -- #{msg}\n\n"
66
73
  end
67
74
  end
68
75
  end
@@ -1,12 +1,12 @@
1
1
  module MarkdownLoggingProxy
2
- # frozen_string_literal: true
3
-
4
- require 'logger'
5
- require 'securerandom'
6
- require 'pp'
7
- require 'time'
8
-
9
2
  class Proxy
3
+ # Object methods that should be proxied but won't hit method_missing
4
+ DEFAULT_OVERWRITES = %i[
5
+ ! != !~ <=> == === =~
6
+ clone display dup enum_for eql? equal? freeze frozen? hash inspect
7
+ is_a? itself kind_of? nil? taint tainted? tap then to_enum to_s
8
+ trust untaint unstrust untrusted? yield_self
9
+ ]
10
10
 
11
11
  def initialize(
12
12
  to_proxy = nil,
@@ -15,10 +15,9 @@ module MarkdownLoggingProxy
15
15
  backtrace: true, # regex/true/false backtrace control
16
16
  ignore: [], # methods we shouldn't log/proxy
17
17
  proxy_response: [], # methods we should return a proxy for
18
- overwrite: [] # methods defined on Object we should overwrite
18
+ overwrite: DEFAULT_OVERWRITES
19
19
  )
20
20
  @target = to_proxy || target
21
- raise ArgumentError, "Missing required proxy target" unless @target
22
21
  @logger = MarkdownLogger.build(location, backtrace: backtrace)
23
22
  @tracer = Tracer.new(
24
23
  target: @target,
@@ -32,8 +31,8 @@ module MarkdownLoggingProxy
32
31
  }
33
32
  )
34
33
  overwrite.each do |meth|
35
- define_method(meth) do |*args, &blk|
36
- @traceer.trace(meth, args, &blk)
34
+ self.class.define_method(meth) do |*args, &blk|
35
+ @tracer.trace(meth, args, &blk)
37
36
  end
38
37
  end
39
38
  end
@@ -1,7 +1,7 @@
1
1
  module MarkdownLoggingProxy
2
2
  class Tracer
3
3
  attr_reader :target, :logger, :ignore, :proxy
4
-
4
+
5
5
  def initialize(
6
6
  target:,
7
7
  proxy:,
@@ -12,7 +12,7 @@ module MarkdownLoggingProxy
12
12
  )
13
13
  @target = target
14
14
  @logger = logger
15
- @ignore = (ignore + proxy_response)
15
+ @ignore = ignore
16
16
  @proxy_response = proxy_response
17
17
  @proxy_options = proxy_options
18
18
  end
@@ -45,9 +45,9 @@ module MarkdownLoggingProxy
45
45
 
46
46
  Arguments:
47
47
 
48
- #{MarkdownLogger.inspect_object(args)}
48
+ #{MarkdownLogger.inspect_object(args, false)}
49
49
 
50
- Block? #{block_given? ? 'Yes' : 'No'}
50
+ Block given? #{block_given? ? 'Yes' : 'No'}
51
51
  #{logger.inspect_backtrace}
52
52
  MSG
53
53
  end
@@ -56,12 +56,14 @@ module MarkdownLoggingProxy
56
56
  response = target.public_send(meth, *args, &log_and_proxy_block(meth, blk))
57
57
  log_response(meth, response) unless ignore?(meth)
58
58
  return response unless proxy_response?(meth)
59
- logger.log :info, 3, <<~MSG
59
+ logger.log :info, 3, <<~MSG.chomp
60
60
  Returning proxied response to `#{meth}`
61
-
61
+
62
62
  Proxy from `#{meth}` on #{MarkdownLogger.id_object(target)}
63
-
64
- Proxy for: #{MarkdownLogger.id_object(response)}
63
+
64
+ Proxy for:
65
+
66
+ #{MarkdownLogger.inspect_object(response)}
65
67
  MSG
66
68
  Proxy.new(**@proxy_options.merge(
67
69
  target: response,
@@ -74,15 +76,15 @@ module MarkdownLoggingProxy
74
76
  def log_and_proxy_block(meth, blk)
75
77
  return if blk.nil?
76
78
  proc do |*args|
77
- logger.log :info, 3, <<~MSG
79
+ logger.log :info, 2, <<~MSG.chomp
78
80
  Yield to block in `#{meth}` on #{MarkdownLogger.id_object(target)}
79
81
 
80
82
  Arguments:
81
83
 
82
- #{MarkdownLogger.inspect_object(args)}
84
+ #{MarkdownLogger.inspect_object(args, false)}
83
85
  MSG
84
86
  blk.call(*args).tap do |response|
85
- logger.log :info, 4, <<~MSG
87
+ logger.log :info, 3, <<~MSG.chomp
86
88
  Response from block in `#{meth}`
87
89
 
88
90
  #{MarkdownLogger.inspect_object(response)}
@@ -92,7 +94,7 @@ module MarkdownLoggingProxy
92
94
  end
93
95
 
94
96
  def log_and_reraise_error(meth, error)
95
- logger.log :error, 2, <<~MSG
97
+ logger.log :error, 2, <<~MSG.chomp
96
98
  Error in `#{meth}`
97
99
 
98
100
  Type: #{error.class}
@@ -0,0 +1,33 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = "markdown_logging_proxy"
3
+ spec.version = "1.1.1"
4
+ spec.authors = ["Carl Zulauf"]
5
+ spec.email = ["carl@linkleaf.com"]
6
+
7
+ spec.summary = "Proxy object for debugging"
8
+ spec.description = "Wrap your ruby objects in a proxy to find out what happens to them"
9
+ spec.homepage = "https://github.com/carlzulauf/markdown_logging_proxy"
10
+ spec.license = "MIT"
11
+ spec.required_ruby_version = ">= 2.6.0"
12
+
13
+ spec.metadata["homepage_uri"] = spec.homepage
14
+ spec.metadata["source_code_uri"] = "https://github.com/carlzulauf/markdown_logging_proxy"
15
+ spec.metadata["changelog_uri"] = "https://github.com/carlzulauf/markdown_logging_proxy/blob/main/CHANGELOG.md"
16
+
17
+ # Specify which files should be added to the gem when it is released.
18
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
+ spec.files = Dir.chdir(__dir__) do
20
+ `git ls-files -z`.split("\x0").reject do |f|
21
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
22
+ end
23
+ end
24
+ spec.bindir = "exe"
25
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
26
+ spec.require_paths = ["lib"]
27
+
28
+ # Uncomment to register a new dependency of your gem
29
+ # spec.add_dependency "example-gem", "~> 1.0"
30
+
31
+ # For more information and examples about making a new gem, check out our
32
+ # guide at: https://bundler.io/guides/creating_gem.html
33
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markdown_logging_proxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carl Zulauf
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-28 00:00:00.000000000 Z
11
+ date: 2022-08-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Wrap your ruby objects in a proxy to find out what happens to them
14
14
  email:
@@ -31,6 +31,7 @@ files:
31
31
  - lib/markdown_logging_proxy/module_methods.rb
32
32
  - lib/markdown_logging_proxy/proxy.rb
33
33
  - lib/markdown_logging_proxy/tracer.rb
34
+ - markdown_logging_proxy.gemspec
34
35
  homepage: https://github.com/carlzulauf/markdown_logging_proxy
35
36
  licenses:
36
37
  - MIT
@@ -53,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
53
54
  - !ruby/object:Gem::Version
54
55
  version: '0'
55
56
  requirements: []
56
- rubygems_version: 3.3.7
57
+ rubygems_version: 3.3.20
57
58
  signing_key:
58
59
  specification_version: 4
59
60
  summary: Proxy object for debugging