nrser 0.3.5 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e9a0b7b61d0a481af1ca35a8eb86e7ab13aff165
4
- data.tar.gz: e7c16292a7f5ccfa34ce0e490a7f91313f9e34e5
3
+ metadata.gz: c4c0b136095e4afd7f800b70365fef71ab0d6aa8
4
+ data.tar.gz: 0e7ae07d35167aef235790e048469175e278678d
5
5
  SHA512:
6
- metadata.gz: e085701c29d0a89e2983734e8a2d120fe1d03248cf2d8bf5644761f1e00c5fd8d20bcf676a09785b312cb85c81cd1203330d5011ffcf956916f95dae3cdec16f
7
- data.tar.gz: 68bd8090335751c9ee51f2026c33d23acecdb4faad507b89879fe036fb3758f79a3ba934682a26a6613601ce36b129bd3048ee62613b8751e0089f0d32cf4b58
6
+ metadata.gz: dca7159d865ba58bb26a0fe3a24f4cdab90c09416509cc7f7d466aad6c5a23dd5fa6f5f0d35b4adb9a6d2e93c9ea52f03f8f63b03f237e5e3cabc3374f258d5f
7
+ data.tar.gz: 4de1a2e02822d68a529f37ce1bcf53f25c4f8100284fb841c3bf254509d0f0a85adacdc823c1a857da5de7f0d8c9911214bc3e1ab4984d576a468aaba3646d75
@@ -64,39 +64,161 @@ class NRSER::Log::Logger < SemanticLogger::Logger
64
64
  end # class Catcher
65
65
 
66
66
 
67
- class Notifier
68
-
69
- # Construction
70
- # ========================================================================
71
-
72
- # Instantiate a new `Notifier`.
73
- #
74
- # @param [NRSER::Log::Logger] logger
75
- # The logger to use if the block raises.
76
- #
77
- # @param [*] on_fail:
78
- # Value to return when `&block` raises.
79
- #
80
- def initialize logger
81
- @logger = logger
82
- end # #initialize
67
+ # Under JRuby a java exception is not a Ruby Exception
68
+ #
69
+ # Java::JavaLang::ClassCastException.new.is_a?(Exception) => false
70
+ #
71
+ def self.is_exception? value
72
+ value.is_a?( Exception) ||
73
+ [:backtrace, :message].all? { |name| value.respond_to? name }
74
+ end
75
+
76
+
77
+ # Normalizes the valid argument formats to {SemanticLogger::Logger}'s
78
+ # "standard logging methods" into a keywords hash.
79
+ #
80
+ # By "standard logging methods", we mean {SemanticLogger::Logger#debug},
81
+ # {SemanticLogger::Logger#info}, etc., as detailed in the
82
+ # [Semantic Logger API][] documentation.
83
+ #
84
+ # [Semantic Logger API]: https://rocketjob.github.io/semantic_logger/api.html
85
+ #
86
+ # Semantic Logger documents the standard logging methods API as
87
+ #
88
+ # log.info(message, payload_or_exception = nil, exception = nil, &block)
89
+ #
90
+ # or
91
+ #
92
+ # logger.info(
93
+ # message: String?,
94
+ # payload: Hash?,
95
+ # exception: Object?,
96
+ # **metric_keywords
97
+ # )
98
+ #
99
+ # Which means that the hash returned by this method can be used as the
100
+ # argument to the standard logging methods:
101
+ #
102
+ # def proxy_info_call *args, &block
103
+ # logger.info **NRSER::Log::Logger.args_to_kwds( *args ), &block
104
+ # end
105
+ #
106
+ # This makes this method very useful when pre-processing log call arguments,
107
+ # as is done in {NRSER::Log::Plugin} before passing the resulting keywords
108
+ # to {NRSER::Log::Plugin#call} because the hash this method returns is much
109
+ # easier to work with than the standard logging methods' multiple valid
110
+ # argument formats.
111
+ #
112
+ # @param [Array] *args
113
+ # Valid arguments for {SemanticLogger::Logger#debug}, etc. - see notes
114
+ # above.
115
+ #
116
+ # @return [Hash<Symbol, Object>]
117
+ # Always has the following keys (**all** of which can have `nil` value):
118
+ #
119
+ # - `message: String?` - we don't actually check that it's a {String},
120
+ # but that seems to be pretty much what Semantic Logger expects.
121
+ #
122
+ # - `payload: Hash?` - A hash of names to values to log. By convention
123
+ # names are {Symbol}, though I'm not sure what happens if they are not.
124
+ #
125
+ # - `exception: Object?` - An error to log. This will be an {Exception}
126
+ # in MRI. In JRuby, and perhaps elsewhere, they won't be, but they
127
+ # should always respond to `#message` and `#backtrace`.
128
+ #
129
+ # - `metric: Object?` -
130
+ #
131
+ def self.args_to_kwds *args
132
+ log_kwds = {
133
+ message: nil,
134
+ payload: nil,
135
+ exception: nil,
136
+ metric: nil,
137
+ }
83
138
 
139
+ case args.length
140
+ when 0
141
+ # pass - they all stay `nil` (which it seems SemLog allows, so we'll
142
+ # stick to it)
84
143
 
85
- # Instance Methods
86
- # ========================================================================
144
+ when 1
145
+ case args[0]
146
+ when Hash
147
+ if [:message, :payload, :exception, :metric].
148
+ any? { |key| args[0].key? key }
149
+ log_kwds = args[0]
150
+ else
151
+ # It's the payload
152
+ log_kwds[:payload] = args[0]
153
+ end
154
+ else
155
+ if is_exception? args[0]
156
+ # It's the exception
157
+ log_kwds[:exception] = args[0]
158
+ else
159
+ # It's got to be the message
160
+ log_kwds[:message] = args[0]
161
+ end
162
+ end
87
163
 
88
- SemanticLogger::LEVELS.each do |level|
89
- define_method level do |message = nil, payload = nil, &block|
90
- begin
91
- block.call
92
- rescue Exception => error
93
- @logger.send level, message, payload, error
94
- @on_fail
164
+ when 2
165
+ if args[0].is_a? Hash
166
+ log_kwds[:payload] = args[0]
167
+ log_kwds[:exception] = args[1]
168
+ else
169
+ log_kwds[:message] = args[0]
170
+
171
+ if args[1].is_a? Hash
172
+ log_kwds[:payload] = args[1]
173
+ else
174
+ log_kwds[:exception] = args[1]
95
175
  end
96
176
  end
177
+
178
+ when 3
179
+ log_kwds[:message] = args[0]
180
+ log_kwds[:payload] = args[1]
181
+ log_kwds[:exception] = args[2]
182
+
183
+ else
184
+ raise NRSER::ArgumentError.new \
185
+ "Too many args dude - max 3",
186
+ args: args
187
+
97
188
  end
98
189
 
99
- end
190
+ log_kwds
191
+
192
+ end # .normalize_log_args
193
+
194
+
195
+ # Install a plugin, dynamically adding it's
196
+ # {NRSER::Log::Plugin.method_name} instance method.
197
+ #
198
+ # @param [Class<NRSER::Log::Plugin>] plugin_class
199
+ # The plugin class to add.
200
+ #
201
+ # @return [nil]
202
+ #
203
+ # @raise [NRSER::ConflictError]
204
+ # If this class already has an instance method defined with the name
205
+ # returned from `plugin_class.method_name`.
206
+ #
207
+ def self.plugin plugin_class
208
+ method_name = plugin_class.method_name
209
+
210
+ if instance_methods.include? method_name.to_sym
211
+ raise NRSER::ConflictError.new \
212
+ "Can not install", plugin_class.safe_name,
213
+ "Logger plugin: instance method", method_name, "already defined"
214
+ end
215
+
216
+ define_method method_name do |*args, &block|
217
+ plugin_class.new self, *args, &block
218
+ end
219
+
220
+ nil
221
+ end # .plugin
100
222
 
101
223
 
102
224
  # Attributes
@@ -185,6 +307,41 @@ class NRSER::Log::Logger < SemanticLogger::Logger
185
307
  # Instance Methods
186
308
  # ========================================================================
187
309
 
310
+ # Log message at the specified level
311
+ def build_log level,
312
+ index,
313
+ message = nil,
314
+ payload = nil,
315
+ exception = nil,
316
+ &block
317
+ log = SemanticLogger::Log.new name, level, index
318
+ should_log =
319
+ if payload.nil? && exception.nil? && message.is_a?( Hash )
320
+ # Check if someone just logged a hash payload instead of meaning to call semantic logger
321
+ if message.key?( :message ) ||
322
+ message.key?( :payload ) ||
323
+ message.key?( :exception ) ||
324
+ message.key?( :metric )
325
+ log.assign message
326
+ else
327
+ log.assign_positional nil, message, nil, &block
328
+ end
329
+ else
330
+ log.assign_positional message, payload, exception, &block
331
+ end
332
+
333
+ # Log level may change during assign due to :on_exception_level
334
+ [ log, should_log && should_log?( log ) ]
335
+ end
336
+
337
+
338
+ # Log message at the specified level
339
+ # def log_internal *args, &block
340
+ # log, should_log = build_log *args
341
+ # self.log( log ) if should_log
342
+ # end
343
+
344
+
188
345
  # A sweet way to try something and just log any {Exception}.
189
346
  #
190
347
  # Useful for situations where the operation is question is not necessary
@@ -0,0 +1,153 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ # Requirements
5
+ # =======================================================================
6
+
7
+ # Deps
8
+ # -----------------------------------------------------------------------
9
+
10
+ # Need {SemanticLogger::Logger}
11
+ require 'semantic_logger'
12
+
13
+
14
+ # Refinements
15
+ # =======================================================================
16
+
17
+
18
+ # Namespace
19
+ # =======================================================================
20
+
21
+ module NRSER
22
+ module Log
23
+
24
+
25
+ # Definitions
26
+ # =======================================================================
27
+
28
+ # Abstract base class that wraps a {NRSER::Log::Logger} and exposes the
29
+ # level logging methods - `#debug`, `#info`, etc. - routing those calls
30
+ # through it's {#call} method and on to the logger's method, allowing
31
+ # concrete subclasses to hook into those calls and provide additional
32
+ # functionality and logic.
33
+ #
34
+ # Convention is
35
+ #
36
+ # @abstract
37
+ #
38
+ # @see NRSER::Log::Logger::Catcher
39
+ # @see NRSER::Log::Logger::Notifier
40
+ #
41
+ # @todo
42
+ # Make plugins "stackable".
43
+ #
44
+ # Not sure if this example in particular would make any sense, but you can
45
+ # get the idea:
46
+ #
47
+ # logger.notify.catcher.warn
48
+ #
49
+ class Plugin
50
+
51
+ # Class Methods
52
+ # ========================================================================
53
+
54
+ # The {NRSER::Log::Logger} method name that will create plugin instances.
55
+ #
56
+ # Looks for the `@method_name` class instance variable, and defaults to
57
+ # `safe_name.demodulize.underscore` if that is not found.
58
+ #
59
+ # @return [Symbol | String]
60
+ #
61
+ def self.method_name
62
+ @method_name || safe_name.demodulize.underscore
63
+ end # .method_name
64
+
65
+
66
+ # Attributes
67
+ # ========================================================================
68
+
69
+ # The wrapped logger instance.
70
+ #
71
+ # @return [NRSER::Log::Logger]
72
+ #
73
+ attr_reader :logger
74
+
75
+
76
+ # Construction
77
+ # ========================================================================
78
+
79
+ # Instantiate a new plugin instance.
80
+ #
81
+ # @param [NRSER::Log::Logger] logger
82
+ # The wrapper logger instance.
83
+ #
84
+ def initialize logger
85
+ @logger = logger
86
+ end # #initialize
87
+
88
+
89
+ # Instance Methods
90
+ # ========================================================================
91
+
92
+ # This is where realizing subclasses can hook into log calls.
93
+ #
94
+ # This base implementation just calls the `level` method on {#logger}
95
+ # with the `args` and `block`.
96
+ #
97
+ # @note
98
+ # Though the logging methods don't use a block at this time, it's there
99
+ # for completeness and possible futures.
100
+ #
101
+ # @param [Symbol] level:
102
+ # The log level of the call; one of {SemanticLogger::LEVELS}.
103
+ #
104
+ # @param [String?] message:
105
+ # Log message.
106
+ #
107
+ # @param [Hash?] payload:
108
+ # Map of names to values to log.
109
+ #
110
+ # @param [Object?] exception:
111
+ # An error to log. This will be an {Exception} in MRI, but *won't* be in
112
+ # JRuby and possibly other runtimes.
113
+ #
114
+ # @param [Object?] metric:
115
+ # I don't know what this is. I found it in the SemLog code.
116
+ #
117
+ # @param [Proc] &block
118
+ # Block to pass to the {#logger}'s `level` method. Not currently used
119
+ # (see note above).
120
+ #
121
+ def call level:, message:, payload:, exception:, metric:, &block
122
+ logger.send \
123
+ level,
124
+ message: message,
125
+ payload: payload,
126
+ exception: exception,
127
+ metric: metric,
128
+ &block
129
+ end
130
+
131
+
132
+ # Dynamically define each logging method.
133
+ SemanticLogger::LEVELS.each do |level|
134
+ define_method level do |*args, &block|
135
+ call level: level, **NRSER::Log::Logger.args_to_kwds( *args ), &block
136
+ end
137
+ end
138
+
139
+
140
+ # @return [String]
141
+ # Short string description of the instance.
142
+ def to_s
143
+ "#<#{ self.class.safe_name } #{ logger }>"
144
+ end
145
+
146
+ end # class Plugin
147
+
148
+
149
+ # /Namespace
150
+ # =======================================================================
151
+
152
+ end # module Log
153
+ end # module NRSER
@@ -1,7 +1,4 @@
1
- require 'nrser/refinements'
2
1
  require 'nrser/types/type'
3
-
4
- using NRSER
5
2
 
6
3
  module NRSER::Types
7
4
  class Bounded < NRSER::Types::Type
@@ -1,6 +1,4 @@
1
- require 'nrser/refinements'
2
1
  require 'nrser/types/type'
3
- using NRSER
4
2
 
5
3
  module NRSER::Types
6
4
  # Type satisfied by class membership (or mixin presence for modules).
@@ -1,10 +1,8 @@
1
- require 'nrser/refinements'
2
1
  require 'nrser/types/type'
3
2
  require 'nrser/types/is_a'
4
3
  require 'nrser/types/combinators'
5
4
  require 'nrser/types/bounded'
6
5
 
7
- using NRSER
8
6
 
9
7
  module NRSER::Types
10
8
  # Parse a string into a number.
data/lib/nrser/version.rb CHANGED
@@ -18,7 +18,7 @@ module NRSER
18
18
  #
19
19
  # @return [String]
20
20
  #
21
- VERSION = '0.3.5'
21
+ VERSION = '0.3.6'
22
22
 
23
23
 
24
24
  module Version
@@ -1,9 +1,3 @@
1
- require 'spec_helper'
2
-
3
- require 'nrser/refinements'
4
- using NRSER
5
-
6
-
7
1
  # NRSER.merge_by
8
2
  # ========================================================================
9
3
  #
@@ -1,8 +1,3 @@
1
- require 'spec_helper'
2
-
3
- require 'nrser/refinements'
4
- using NRSER
5
-
6
1
  describe "NRSER.each_branch" do
7
2
 
8
3
  subject { NRSER.method :each_branch }
@@ -65,7 +60,7 @@ describe "NRSER.each_branch" do
65
60
  input = [:x, :y, :z]
66
61
  result = {}
67
62
  super().call( input ) { |index, value|
68
- result[index] = value
63
+ result[index] = value
69
64
  }
70
65
  result
71
66
  }
@@ -79,4 +74,3 @@ describe "NRSER.each_branch" do
79
74
  end # called with a block
80
75
 
81
76
  end # NRSER.each_branch
82
-
@@ -1,8 +1,3 @@
1
- require 'spec_helper'
2
-
3
- require 'nrser/refinements'
4
- using NRSER
5
-
6
1
  describe "NRSER.map_branches" do
7
2
  # ========================================================================
8
3
 
@@ -1,8 +1,3 @@
1
- require 'spec_helper'
2
-
3
- require 'nrser/refinements'
4
- using NRSER
5
-
6
1
  describe_method "NRSER.map_tree" do
7
2
  # ========================================================================
8
3
 
@@ -1,8 +1,3 @@
1
- require 'spec_helper'
2
-
3
- require 'nrser/refinements'
4
- using NRSER
5
-
6
1
  describe "NRSER.transform" do
7
2
  subject { NRSER.transform tree, source }
8
3
 
@@ -1,10 +1,3 @@
1
- # Refinements
2
- # =======================================================================
3
-
4
- require 'nrser/refinements'
5
- using NRSER
6
-
7
-
8
1
  # Examples
9
2
  # =====================================================================
10
3
 
@@ -135,7 +128,7 @@ describe_method "NRSER.transformer" do
135
128
  users: {
136
129
  { contact_id: address.parent.id } => {
137
130
  addresses: {
138
- {
131
+ {
139
132
  address_id: address.id } => {
140
133
  district: address[:address],
141
134
  line_1: address[:street2],
@@ -176,4 +169,3 @@ describe_method "NRSER.transformer" do
176
169
 
177
170
 
178
171
  end # NRSER.transform
179
-
@@ -1,8 +1,3 @@
1
- require 'spec_helper'
2
-
3
- require 'nrser/refinements'
4
- using NRSER
5
-
6
1
  require 'nrser/refinements/types'
7
2
  using NRSER::Types
8
3
 
@@ -18,13 +13,13 @@ describe NRSER::Message, type: :class do
18
13
 
19
14
  describe_called_with NRSER::Message.new( :length ) do
20
15
  it { is_expected.to eq [0, 1, 2] }
21
- end # called with
16
+ end # called with
22
17
 
23
18
  describe_called_with NRSER::Message.new( :first ) do
24
19
  it { is_expected.to eq [nil, 1, 1] }
25
20
  end # called with :first
26
21
 
27
- end # enum
22
+ end # enum
28
23
 
29
24
  end # mapping an Enumerable using &message
30
25
 
@@ -1,11 +1,6 @@
1
- require 'spec_helper'
2
- require 'nrser/refinements'
3
-
4
- using NRSER
5
-
6
1
  describe "NRSER.format_exception" do
7
2
  let(:error) {
8
- begin
3
+ begin
9
4
  raise StandardError.new "blah blah blah"
10
5
  rescue Exception => e
11
6
  e
@@ -17,4 +12,4 @@ describe "NRSER.format_exception" do
17
12
  expect( str ).to start_with "blah blah blah (StandardError):"
18
13
  expect( str.lines.drop(1) ).to all( start_with ' ' )
19
14
  end
20
- end
15
+ end
@@ -1,8 +1,3 @@
1
- require 'spec_helper'
2
- require 'nrser/refinements'
3
-
4
- using NRSER
5
-
6
1
  describe "NRSER.indent" do
7
2
  it "refines String to add indent" do
8
3
  expect(
@@ -1,8 +1,3 @@
1
- require 'spec_helper'
2
- require 'nrser/refinements'
3
-
4
- using NRSER
5
-
6
1
  describe 'Pathname' do
7
2
 
8
3
  describe '#start_with?' do
@@ -1,8 +1,3 @@
1
- require 'spec_helper'
2
-
3
- require 'nrser/refinements'
4
- using NRSER
5
-
6
1
  require 'nrser/refinements/types'
7
2
  using NRSER::Types
8
3
 
@@ -38,4 +33,3 @@ describe "NRSER::Types.hash_pair" do
38
33
  end # NRSER::Types.hash_pair
39
34
 
40
35
  # ************************************************************************
41
-
@@ -1,8 +1,3 @@
1
- require 'spec_helper'
2
-
3
- require 'nrser/refinements'
4
- using NRSER
5
-
6
1
  require 'nrser/refinements/types'
7
2
  using NRSER::Types
8
3
 
@@ -1,8 +1,3 @@
1
- require 'spec_helper'
2
-
3
- require 'nrser/refinements'
4
- using NRSER
5
-
6
1
  require 'nrser/refinements/types'
7
2
  using NRSER::Types
8
3
 
@@ -1,8 +1,3 @@
1
- require 'spec_helper'
2
-
3
- require 'nrser/refinements'
4
- using NRSER
5
-
6
1
  require 'nrser/refinements/types'
7
2
  using NRSER::Types
8
3
 
@@ -1,8 +1,3 @@
1
- require 'spec_helper'
2
-
3
- require 'nrser/refinements'
4
- using NRSER
5
-
6
1
  require 'nrser/refinements/types'
7
2
  using NRSER::Types
8
3
 
@@ -203,4 +198,4 @@ describe NRSER::Types do
203
198
  end
204
199
  end # #from_repr
205
200
 
206
- end # QB::Types
201
+ end # QB::Types
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nrser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - nrser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-25 00:00:00.000000000 Z
11
+ date: 2018-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hamster
@@ -331,7 +331,7 @@ files:
331
331
  - lib/nrser/log/formatters/mixin.rb
332
332
  - lib/nrser/log/logger.rb
333
333
  - lib/nrser/log/mixin.rb
334
- - lib/nrser/log/notify.rb
334
+ - lib/nrser/log/plugin.rb
335
335
  - lib/nrser/mean_streak.rb
336
336
  - lib/nrser/mean_streak/document.rb
337
337
  - lib/nrser/message.rb
@@ -1,94 +0,0 @@
1
- # encoding: UTF-8
2
- # frozen_string_literal: true
3
-
4
- # Requirements
5
- # =======================================================================
6
-
7
- # Stdlib
8
- # -----------------------------------------------------------------------
9
-
10
- # Deps
11
- # -----------------------------------------------------------------------
12
-
13
- # Project / Package
14
- # -----------------------------------------------------------------------
15
-
16
- # Need {NRSER::LazyAttr} decorator.
17
- require 'nrser/meta/lazy_attr'
18
-
19
-
20
- # Namespace
21
- # =======================================================================
22
-
23
- module NRSER
24
- module Log
25
-
26
-
27
- # Definitions
28
- # =======================================================================
29
-
30
- # Abstraction to attempt to notify interactive users.
31
- #
32
- module Notify
33
-
34
- +NRSER::LazyAttr
35
- # Is the `terminal-notifier` gem available?
36
- #
37
- # [terminal-notifier][] is not an NRSER dependency since it does not make
38
- # sense for many systems and situations. It must be installed separately.
39
- #
40
- # [terminal-notifier]: https://rubygems.org/gems/terminal-notifier
41
- #
42
- # Tests by trying to `require` it.
43
- #
44
- # @return [Boolean]
45
- #
46
- def self.terminal_notifier?
47
- begin
48
- require 'terminal-notifier'
49
- rescue LoadError => error
50
- false
51
- else
52
- true
53
- end
54
- end # .terminal_notifier?
55
-
56
-
57
- +NRSER::LazyAttr
58
- # Can we send notification to the user?
59
- #
60
- # Right now, only {.terminal_notifier?} is tested, but we can add more
61
- # options in the future.
62
- #
63
- # @return [Boolean]
64
- #
65
- def self.available?
66
- terminal_notifier?
67
- end # .available?
68
-
69
-
70
- # Send a notification to the use *if* notifications are {.available?}.
71
- #
72
- #
73
- def self.notify *args, &block
74
- return false unless available?
75
-
76
- notify! *args, &block
77
- end
78
-
79
-
80
- def self.notify! *args, &block
81
- require 'terminal-notifier'
82
-
83
- TerminalNotifier.notify *args, &block
84
- end
85
-
86
-
87
- end # module Notify
88
-
89
-
90
- # /Namespace
91
- # =======================================================================
92
-
93
- end # module Log
94
- end # module NRSER