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 +4 -4
- data/lib/nrser/log/logger.rb +183 -26
- data/lib/nrser/log/plugin.rb +153 -0
- data/lib/nrser/types/bounded.rb +0 -3
- data/lib/nrser/types/is_a.rb +0 -2
- data/lib/nrser/types/numbers.rb +0 -2
- data/lib/nrser/version.rb +1 -1
- data/spec/lib/nrser/functions/merge_by_spec.rb +0 -6
- data/spec/lib/nrser/functions/tree/each_branch_spec.rb +1 -7
- data/spec/lib/nrser/functions/tree/map_branch_spec.rb +0 -5
- data/spec/lib/nrser/functions/tree/map_tree_spec.rb +0 -5
- data/spec/lib/nrser/functions/tree/transform_spec.rb +0 -5
- data/spec/lib/nrser/functions/tree/transformer_spec.rb +1 -9
- data/spec/lib/nrser/op/message_spec.rb +2 -7
- data/spec/lib/nrser/refinements/format_exception_spec.rb +2 -7
- data/spec/lib/nrser/refinements/indent_spec.rb +0 -5
- data/spec/lib/nrser/refinements/pathname_spec.rb +0 -5
- data/spec/lib/nrser/types/pairs_spec.rb +0 -6
- data/spec/lib/nrser/types/strings_spec.rb +0 -5
- data/spec/lib/nrser/types/symbols_spec.rb +0 -5
- data/spec/lib/nrser/types/tuples_spec.rb +0 -5
- data/spec/lib/nrser/types_spec.rb +1 -6
- metadata +3 -3
- data/lib/nrser/log/notify.rb +0 -94
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4c0b136095e4afd7f800b70365fef71ab0d6aa8
|
4
|
+
data.tar.gz: 0e7ae07d35167aef235790e048469175e278678d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dca7159d865ba58bb26a0fe3a24f4cdab90c09416509cc7f7d466aad6c5a23dd5fa6f5f0d35b4adb9a6d2e93c9ea52f03f8f63b03f237e5e3cabc3374f258d5f
|
7
|
+
data.tar.gz: 4de1a2e02822d68a529f37ce1bcf53f25c4f8100284fb841c3bf254509d0f0a85adacdc823c1a857da5de7f0d8c9911214bc3e1ab4984d576a468aaba3646d75
|
data/lib/nrser/log/logger.rb
CHANGED
@@ -64,39 +64,161 @@ class NRSER::Log::Logger < SemanticLogger::Logger
|
|
64
64
|
end # class Catcher
|
65
65
|
|
66
66
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
-
|
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
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
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
|
-
|
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
|
data/lib/nrser/types/bounded.rb
CHANGED
data/lib/nrser/types/is_a.rb
CHANGED
data/lib/nrser/types/numbers.rb
CHANGED
data/lib/nrser/version.rb
CHANGED
@@ -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,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
|
-
|
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
|
-
|
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.
|
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-
|
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/
|
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
|
data/lib/nrser/log/notify.rb
DELETED
@@ -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
|