eitil 0.3.4 → 0.3.9
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 +4 -4
- data/README.md +80 -5
- data/app/models/eitil/stack_trace/audit.rb +15 -0
- data/app/models/eitil/stack_trace/call.rb +17 -0
- data/app/models/eitil/stack_trace/stack.rb +28 -0
- data/config/initializers/modules/dir.rb +21 -0
- data/config/initializers/monkeys/application_record.rb +18 -4
- data/config/initializers/monkeys/hash.rb +1 -1
- data/config/initializers/monkeys/string.rb +96 -0
- data/config/initializers/wrappers/jobs/active_job_macros.rb +41 -7
- data/config/initializers/wrappers/jobs/single_method_job.rb +17 -3
- data/config/initializers/wrappers/scopes/default_scopes.rb +1 -1
- data/lib/eitil/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac7bd5bff2af923e06936b0016f4f07f8d4eba225a68dc193bdf5f277bcdbb97
|
4
|
+
data.tar.gz: 193b41fa2a5fde545b189b79a2c94328c242bf45d71ff5802cfab3fb7b95c402
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52c86de08e26441922852f3cd5563a36ac46c585a3ab50745e1f0fc2dacf9dc6187574f54c7c33ba415fdd3be006e0c45b7245076b209fd74a3782b07c1ace34
|
7
|
+
data.tar.gz: 0bf06bc0226924db17b2c9b7f9138eac75116cb4d351fe9818690f2745cfaa68d43eac837dbfb0825b6870eeeb0ab4b50cb091ed05243b533501498d8ca60eac
|
data/README.md
CHANGED
@@ -103,6 +103,22 @@ include_concerns_of(*directories, namespace: nil)
|
|
103
103
|
|
104
104
|
|
105
105
|
|
106
|
+
## String
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
is_num?
|
110
|
+
# returns true if a string matches the Rubinius source code regex for strings and integers, false otherwise
|
111
|
+
# comes in handy since ruby plays it safe on string to number conversion ('aaa'.to_f returns 0.0, thus is valid)
|
112
|
+
# this method is also implemented for all other classes, such as Integer, Float, NilClass, TrueClass, Hash and so on...
|
113
|
+
|
114
|
+
is_nan?
|
115
|
+
# returns true if a string does NOT match the Rubinius source code regex for strings and integers, false otherwise
|
116
|
+
# comes in handy since ruby plays it safe on string to number conversion ('aaa'.to_f returns 0.0, thus is valid)
|
117
|
+
# this method is also implemented for all other classes, such as Integer, Float, NilClass, TrueClass, Hash and so on...
|
118
|
+
```
|
119
|
+
|
120
|
+
|
121
|
+
|
106
122
|
## Hash
|
107
123
|
|
108
124
|
```ruby
|
@@ -131,6 +147,14 @@ slice_params(*args)
|
|
131
147
|
self.all_associations
|
132
148
|
# returns all associations for a given model
|
133
149
|
# call as: Environment.all_associations
|
150
|
+
|
151
|
+
self.where_like(_hash)
|
152
|
+
# runs .where with your string field made into a wildcard and case insensitive
|
153
|
+
# call as: User.where_like(name: 'jurriaan')
|
154
|
+
|
155
|
+
self.find_by_like(_hash)
|
156
|
+
# runs .find_by with your string field made into a wildcard and case insensitive
|
157
|
+
# call as: User.find_by_like(name: 'jurriaan')
|
134
158
|
```
|
135
159
|
|
136
160
|
|
@@ -177,7 +201,7 @@ decorate(dec_item, dec_method: nil, dec_class: nil, **dec_kwargs)
|
|
177
201
|
# initializers/eitil.rb
|
178
202
|
|
179
203
|
Eitil.set_config do |config|
|
180
|
-
config.get_controller_ivars_method = 'API::
|
204
|
+
config.get_controller_ivars_method = 'API::BaseController.controller_ivars' # => [:user, :env]
|
181
205
|
end
|
182
206
|
```
|
183
207
|
|
@@ -227,14 +251,18 @@ The router wrapper is a single module which is automatically included into your
|
|
227
251
|
|
228
252
|
### Info
|
229
253
|
|
230
|
-
The Eitil jobs wrapper enables you to create perform_later jobs on the fly, without the need to create a new class and file. The macro new_job accepts a :method as argument and defines a new method :method_job. The newly defined :method_job, when called, performs the orginal :method in the background. The new_job macro accepts both instance methods and singleton methods, which are defined within there own method scope.
|
254
|
+
The Eitil jobs wrapper enables you to create perform_now and perform_later jobs on the fly, without the need to create a new class and file. The macro new_job accepts a :method as argument and defines a new method :method_job. The newly defined :method_job, when called, performs the orginal :method in the background. The new_job macro accepts both instance methods and singleton methods, which are defined within there own method scope. In contrast, the new_job_debugger macro defines a new :method_job_debugger method, which performs in the foreground.
|
231
255
|
|
232
256
|
### Job Macro
|
233
257
|
|
234
258
|
```ruby
|
235
|
-
new_job(_method)
|
236
|
-
# assuming a method :
|
237
|
-
# =>
|
259
|
+
new_job(_method, *args, **kwargs)
|
260
|
+
# assuming a method :hello_world, call as: new_job :hello_world
|
261
|
+
# => defines :hello_world_job
|
262
|
+
|
263
|
+
new_job_debugger(_method, *args, **kwargs)
|
264
|
+
# assuming a method :hello_world, call as: new_job_debugger :hello_world
|
265
|
+
# => defines :hello_world_job_debugger
|
238
266
|
```
|
239
267
|
|
240
268
|
- method is
|
@@ -304,3 +332,50 @@ Scopes are generated through the columns of your model's database table. Which s
|
|
304
332
|
Your models should inherit the module Eitil::DefaultScopes through inclusion in a superclass, such as ApplicationRecord.
|
305
333
|
|
306
334
|
|
335
|
+
|
336
|
+
# Modules & Classes
|
337
|
+
|
338
|
+
|
339
|
+
|
340
|
+
## Eitil::Dir
|
341
|
+
|
342
|
+
### Info
|
343
|
+
|
344
|
+
The Eitil::Dir module provides methods which help you introspect your Rails project.
|
345
|
+
|
346
|
+
### Methods
|
347
|
+
|
348
|
+
```ruby
|
349
|
+
Eitil::Dir.contents(directory='app')
|
350
|
+
# returns all files and subdirectories of a given directory
|
351
|
+
|
352
|
+
Eitil::Dir.files(directory='app')
|
353
|
+
# returns all files of a given directory
|
354
|
+
|
355
|
+
Eitil::Dir.subdirs(directory='app')
|
356
|
+
# returns all subdirectories of a given directory
|
357
|
+
|
358
|
+
Eitil::Dir.lines(directory='app')
|
359
|
+
# returns the total amount of lines of all files of a given directory
|
360
|
+
```
|
361
|
+
|
362
|
+
|
363
|
+
|
364
|
+
## Eitil::StackTrace
|
365
|
+
|
366
|
+
### Info
|
367
|
+
|
368
|
+
The two classes Eitil::StackTrace::Stack and Eitil::StackTrace::Call, and the single module Eitil::StackTrace::Audit, provide the utility of easily viewing and storing the current stacktrace anywhere in your code. By initializing stack = Eitil::StackTrace::Stack.new, you can call methods as stack.report (returns the stacktrace as array), stack.show (pretty prints the stacktrace) and stack.find (accepts a block to find a call).
|
369
|
+
|
370
|
+
You can also store the stacktrace of a record's update action into its audit. In order to do so, you need 1) to include Eitil::StackTrace::Audit into your model, and 2) add a :stacktrace column to your audits through the following migration.
|
371
|
+
|
372
|
+
### Migration
|
373
|
+
|
374
|
+
```ruby
|
375
|
+
def change
|
376
|
+
add_column :audits, :stacktrace, :text, array: true, default: []
|
377
|
+
end
|
378
|
+
```
|
379
|
+
|
380
|
+
|
381
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Eitil::StackTrace::Audit
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
included do
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
after_update :add_stacktrace_to_audit
|
8
|
+
|
9
|
+
def add_stacktrace_to_audit
|
10
|
+
stacktrace = Eitil::StackTrace::Stack.new.report
|
11
|
+
self.audits.last.update(stacktrace: stacktrace)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Eitil::StackTrace
|
2
|
+
class Call
|
3
|
+
|
4
|
+
attr_reader :program, :line, :meth
|
5
|
+
|
6
|
+
CALL_RE = /(.*):(\d+):in `(.*)'/
|
7
|
+
|
8
|
+
def initialize(string)
|
9
|
+
@program, @line, @meth = CALL_RE.match(string).captures
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
"#{"#{meth}".ljust(50)} #{"(#{line})".ljust(6)} #{program}"
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Eitil::StackTrace
|
2
|
+
class Stack
|
3
|
+
|
4
|
+
attr_reader :stack, :backtrace
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@stack = caller[1..]
|
8
|
+
@backtrace = stack.map { |call| Eitil::StackTrace::Call.new(call) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def report
|
12
|
+
backtrace.map(&:to_s)
|
13
|
+
end
|
14
|
+
|
15
|
+
def show
|
16
|
+
ap report
|
17
|
+
end
|
18
|
+
|
19
|
+
def find(&block)
|
20
|
+
backtrace.find(&block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.parse(array_as_string)
|
24
|
+
array_as_string.sub('[', ' ').reverse.sub(']','').reverse.split(',').flatten
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Eitil::Dir
|
2
|
+
class << self
|
3
|
+
|
4
|
+
def contents(directory='app')
|
5
|
+
Dir[File.join(directory, '**', '*')]
|
6
|
+
end
|
7
|
+
|
8
|
+
def files(directory='app')
|
9
|
+
contents(directory).select { |file| File.file?(file) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def subdirs(directory='app')
|
13
|
+
contents(directory).select { |file| File.directory?(file) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def lines(directory='app')
|
17
|
+
files(directory).map { |file| File.open(file).count }.sum
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -4,10 +4,24 @@ module ApplicationRecordMonkey
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
included do
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def all_associations
|
10
|
+
reflect_on_all_associations.map do |assoc|
|
11
|
+
{ assoc.name => assoc.association_class.to_s.demodulize }
|
12
|
+
end.inject &:merge
|
13
|
+
end
|
14
|
+
|
15
|
+
def where_like(_hash)
|
16
|
+
column, like = _hash.first
|
17
|
+
where("LOWER(#{column}) LIKE ?", "%#{like.downcase}%")
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_by_like(_hash)
|
21
|
+
column, like = _hash.first
|
22
|
+
find_by("LOWER(#{column}) LIKE ?", "%#{like.downcase}%")
|
23
|
+
end
|
24
|
+
|
11
25
|
end
|
12
26
|
|
13
27
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
class String
|
2
|
+
|
3
|
+
# The NumberRegex belows comes from the Rubinius source code and
|
4
|
+
# identifies both integers and floats correctly.
|
5
|
+
|
6
|
+
NumberRegex = /^\s*[+-]?((\d+_?)*\d+(\.(\d+_?)*\d+)?|\.(\d+_?)*\d+)(\s*|([eE][+-]?(\d+_?)*\d+)\s*)$/
|
7
|
+
|
8
|
+
def is_nan?
|
9
|
+
self !~ NumberRegex
|
10
|
+
end
|
11
|
+
|
12
|
+
def is_num?
|
13
|
+
!is_nan?
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
# Descending classes which are always numeric
|
19
|
+
|
20
|
+
class Numeric
|
21
|
+
|
22
|
+
def is_nan?
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_num?
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
# Classes which are never numeric
|
33
|
+
|
34
|
+
class NilClass
|
35
|
+
|
36
|
+
def is_nan?
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
def is_num?
|
41
|
+
false
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
class TrueClass
|
48
|
+
|
49
|
+
def is_nan?
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
def is_num?
|
54
|
+
false
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
class FalseClass
|
61
|
+
|
62
|
+
def is_nan?
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
66
|
+
def is_num?
|
67
|
+
false
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
class Hash
|
74
|
+
|
75
|
+
def is_nan?
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
79
|
+
def is_num?
|
80
|
+
false
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
class Array
|
87
|
+
|
88
|
+
def is_nan?
|
89
|
+
true
|
90
|
+
end
|
91
|
+
|
92
|
+
def is_num?
|
93
|
+
false
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -1,18 +1,52 @@
|
|
1
1
|
Kernel.module_eval do
|
2
2
|
|
3
|
-
|
3
|
+
# BEWARE: _self is currently not accepted in perform_later jobs due to serialization errors
|
4
|
+
|
5
|
+
# The cases of 'id' and '_self' both handle instances, with the difference
|
6
|
+
# being that 'id' works for objects that have a database record, while '_self'
|
7
|
+
# works for non database supported instanes, such as an Exporter instance.
|
8
|
+
|
9
|
+
def new_job(_method, *args, **kwargs)
|
4
10
|
|
5
11
|
if instance_methods(false).include? _method
|
6
|
-
define_method "#{_method}_job" do
|
7
|
-
|
12
|
+
define_method "#{_method}_job" do |_self = nil, *args, **kwargs|
|
13
|
+
|
14
|
+
Eitil::SingleMethodJob.perform_later(
|
15
|
+
*args, _class: self.class.to_s, _method: _method.to_s, id: safe_send(:id), _self: self.to_json, **kwargs
|
16
|
+
)
|
8
17
|
end
|
9
18
|
|
10
|
-
elsif singleton_methods(false).include? _method
|
11
|
-
define_singleton_method "#{_method}_job" do
|
12
|
-
|
19
|
+
elsif singleton_methods(false).include? _method
|
20
|
+
define_singleton_method "#{_method}_job" do |*args, **kwargs|
|
21
|
+
|
22
|
+
Eitil::SingleMethodJob.perform_later(
|
23
|
+
*args, _class: to_s, _method: _method.to_s, **kwargs
|
24
|
+
)
|
13
25
|
end
|
14
|
-
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# BEWARE: This is an exact copy of the above method, except for .perform_now instead of .perform_later and the method's name.
|
30
|
+
# The reason for not using helper methods is to not unnecessarily fill and potentially fuck up the Kernel environment.
|
31
|
+
|
32
|
+
def new_job_debugger(_method, *args, **kwargs)
|
15
33
|
|
34
|
+
if instance_methods(false).include? _method
|
35
|
+
define_method "#{_method}_job_debugger" do |_self = nil, *args, **kwargs|
|
36
|
+
|
37
|
+
Eitil::SingleMethodJob.perform_now(
|
38
|
+
*args, _class: self.class.to_s, _method: _method.to_s, id: safe_send(:id), _self: self.to_json, **kwargs
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
elsif singleton_methods(false).include? _method
|
43
|
+
define_singleton_method "#{_method}_job_debugger" do |*args, **kwargs|
|
44
|
+
|
45
|
+
Eitil::SingleMethodJob.perform_now(
|
46
|
+
*args, _class: to_s, _method: _method.to_s, **kwargs
|
47
|
+
)
|
48
|
+
end
|
49
|
+
end
|
16
50
|
end
|
17
51
|
|
18
52
|
end
|
@@ -2,9 +2,23 @@ module Eitil
|
|
2
2
|
class SingleMethodJob < ApplicationJob
|
3
3
|
queue_as :default
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
# BEWARE: _self is currently not accepted in perform_later jobs due to serialization errors
|
6
|
+
|
7
|
+
# The cases of 'id' and '_self' both handle instances, with the difference
|
8
|
+
# being that 'id' works for objects that have a database record, while '_self'
|
9
|
+
# works for non database supported instanes, such as an Exporter instance.
|
10
|
+
|
11
|
+
def perform(*args, _class:, _method:, id: nil, _self: nil, **kwargs)
|
12
|
+
object =
|
13
|
+
if id
|
14
|
+
_class.constantize.find(id)
|
15
|
+
elsif _self
|
16
|
+
_self
|
17
|
+
else
|
18
|
+
_class.constantize
|
19
|
+
end
|
20
|
+
|
21
|
+
object.send _method, *args, **kwargs
|
8
22
|
end
|
9
23
|
end
|
10
24
|
end
|
@@ -48,7 +48,7 @@ module Eitil
|
|
48
48
|
|
49
49
|
def create_eitil_boolean_scopes
|
50
50
|
columns_of_type(:boolean)&.map do |column, object|
|
51
|
-
eitil_scope :"#{column}_true",
|
51
|
+
eitil_scope :"#{column}_true", -> { where(column => true) }
|
52
52
|
eitil_scope :"#{column}_false", -> { where(column => [false, nil]) }
|
53
53
|
end
|
54
54
|
end
|
data/lib/eitil/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eitil
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jurriaan Schrofer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -52,6 +52,10 @@ files:
|
|
52
52
|
- app/jobs/eitil/application_job.rb
|
53
53
|
- app/mailers/eitil/application_mailer.rb
|
54
54
|
- app/models/eitil/application_record.rb
|
55
|
+
- app/models/eitil/stack_trace/audit.rb
|
56
|
+
- app/models/eitil/stack_trace/call.rb
|
57
|
+
- app/models/eitil/stack_trace/stack.rb
|
58
|
+
- config/initializers/modules/dir.rb
|
55
59
|
- config/initializers/monkeys/application_controller.rb
|
56
60
|
- config/initializers/monkeys/application_record.rb
|
57
61
|
- config/initializers/monkeys/date_time.rb
|
@@ -59,6 +63,7 @@ files:
|
|
59
63
|
- config/initializers/monkeys/kernel.rb
|
60
64
|
- config/initializers/monkeys/module.rb
|
61
65
|
- config/initializers/monkeys/object.rb
|
66
|
+
- config/initializers/monkeys/string.rb
|
62
67
|
- config/initializers/wrappers/decorators/application_decorator.rb
|
63
68
|
- config/initializers/wrappers/decorators/controller_decorator.rb
|
64
69
|
- config/initializers/wrappers/jobs/active_job_macros.rb
|