eitil 0.3.4 → 0.3.9

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
  SHA256:
3
- metadata.gz: f35510328554ac09ddfb48b697e0b7dd2b6a801b20954505b14849c2f1a3227a
4
- data.tar.gz: 9d8edf28b695b3835d4dacaf46bd1dbe7dc1e9ebcd9ae2bce403b9a12ffe7529
3
+ metadata.gz: ac7bd5bff2af923e06936b0016f4f07f8d4eba225a68dc193bdf5f277bcdbb97
4
+ data.tar.gz: 193b41fa2a5fde545b189b79a2c94328c242bf45d71ff5802cfab3fb7b95c402
5
5
  SHA512:
6
- metadata.gz: 2cec6226350e58696fb8d814d9cd7e57b768a39c5bc392d6686792d80ecc2dab328a64c131ce32bf05d49627f30b10606544e3c1a6170c4e6941054649dd931d
7
- data.tar.gz: cbb2ad53d5727feffad6007bde83d34edaf4336f47330ad95f096348f423fc0d3fca02375a3d34c38f420f9df99d30ec0f713b2436b62488879594a5e4e9bee3
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::VerlofVerzoekenController.controller_ivars' # => [:user, :env]
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 :print_hello_world, call as: new_job :hello_world
237
- # => method :hello_world_job
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
- def self.all_associations
8
- reflect_on_all_associations.map do |assoc|
9
- { assoc.name => assoc.association_class.to_s.demodulize }
10
- end.inject &:merge
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
@@ -8,7 +8,7 @@ class Hash
8
8
  return answer if answer
9
9
  end
10
10
 
11
- false
11
+ nil
12
12
  end
13
13
 
14
14
  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
- def new_job(_method)
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
- Eitil::SingleMethodJob.perform_later(_class: self.class.to_s, _method: _method.to_s, id: id)
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
- Eitil::SingleMethodJob.perform_later(_class: to_s, _method: _method.to_s)
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
- def perform(_class:, _method:, id: nil)
6
- object = id ? _class.constantize.find(id) : _class.constantize
7
- object.send _method
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", -> { where(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
@@ -1,3 +1,3 @@
1
1
  module Eitil
2
- VERSION = '0.3.4'
2
+ VERSION = '0.3.9'
3
3
  end
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
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-05-21 00:00:00.000000000 Z
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