eitil 0.3.10 → 1.0.1.e.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +39 -331
  3. data/eitil_core/README.md +288 -0
  4. data/eitil_core/lib/eitil_core.rb +24 -0
  5. data/eitil_core/lib/eitil_core/application_controller.rb +2 -0
  6. data/eitil_core/lib/eitil_core/application_controller/slice_params.rb +14 -0
  7. data/eitil_core/lib/eitil_core/application_record.rb +4 -0
  8. data/eitil_core/lib/eitil_core/application_record/all_associations.rb +16 -0
  9. data/eitil_core/lib/eitil_core/application_record/find_by_like.rb +15 -0
  10. data/eitil_core/lib/eitil_core/application_record/where_like.rb +15 -0
  11. data/eitil_core/lib/eitil_core/argument_helpers.rb +5 -0
  12. data/eitil_core/lib/eitil_core/argument_helpers/all_args_to_ivars.rb +12 -0
  13. data/eitil_core/lib/eitil_core/argument_helpers/all_kwargs_to_ivars.rb +12 -0
  14. data/eitil_core/lib/eitil_core/argument_helpers/args_to_ivars.rb +12 -0
  15. data/eitil_core/lib/eitil_core/concerns.rb +2 -0
  16. data/{config/initializers/monkeys/module.rb → eitil_core/lib/eitil_core/concerns/include_concerns_of.rb} +3 -0
  17. data/eitil_core/lib/eitil_core/datetime.rb +2 -0
  18. data/{config/initializers/monkeys/date_time.rb → eitil_core/lib/eitil_core/datetime/prettify.rb} +3 -0
  19. data/eitil_core/lib/eitil_core/errors.rb +2 -0
  20. data/eitil_core/lib/eitil_core/errors/raise_error.rb +11 -0
  21. data/eitil_core/lib/eitil_core/float.rb +2 -0
  22. data/{config/initializers/monkeys/float.rb → eitil_core/lib/eitil_core/float/safe_to_i.rb} +0 -0
  23. data/eitil_core/lib/eitil_core/hash.rb +2 -0
  24. data/{config/initializers/monkeys/hash.rb → eitil_core/lib/eitil_core/hash/auto_dig.rb} +3 -0
  25. data/eitil_core/lib/eitil_core/lookups.rb +2 -0
  26. data/{config/initializers/monkeys/object.rb → eitil_core/lib/eitil_core/lookups/all_methods.rb} +3 -0
  27. data/eitil_core/lib/eitil_core/railtie.rb +37 -0
  28. data/eitil_core/lib/eitil_core/safe_executions.rb +3 -0
  29. data/eitil_core/lib/eitil_core/safe_executions/safe_call.rb +12 -0
  30. data/eitil_core/lib/eitil_core/safe_executions/safe_send.rb +12 -0
  31. data/eitil_core/lib/eitil_core/setters.rb +2 -0
  32. data/eitil_core/lib/eitil_core/setters/set_ivars.rb +12 -0
  33. data/eitil_core/lib/eitil_core/type_checkers.rb +2 -0
  34. data/{config/initializers/monkeys/string.rb → eitil_core/lib/eitil_core/type_checkers/is_num_or_nan.rb} +5 -5
  35. data/eitil_core/lib/eitil_core/validations.rb +2 -0
  36. data/eitil_core/lib/eitil_core/validations/run_validations.rb +10 -0
  37. data/eitil_integrate/README.md +8 -0
  38. data/eitil_integrate/lib/eitil_integrate.rb +0 -0
  39. data/eitil_integrate/lib/eitil_integrate/railtie.rb +10 -0
  40. data/eitil_store/README.md +16 -0
  41. data/eitil_store/lib/eitil_store.rb +4 -0
  42. data/eitil_store/lib/eitil_store/railtie.rb +10 -0
  43. data/eitil_store/lib/eitil_store/regex.rb +4 -0
  44. data/eitil_store/lib/eitil_store/regex/regex.rb +41 -0
  45. data/eitil_support/README.md +78 -0
  46. data/eitil_support/lib/eitil_support.rb +5 -0
  47. data/eitil_support/lib/eitil_support/directory.rb +2 -0
  48. data/eitil_support/lib/eitil_support/directory/lookups.rb +23 -0
  49. data/eitil_support/lib/eitil_support/railtie.rb +10 -0
  50. data/eitil_support/lib/eitil_support/stacktrace.rb +4 -0
  51. data/{app/models/eitil/stack_trace → eitil_support/lib/eitil_support/stacktrace}/audit.rb +2 -2
  52. data/{app/models/eitil/stack_trace → eitil_support/lib/eitil_support/stacktrace}/call.rb +1 -1
  53. data/{app/models/eitil/stack_trace → eitil_support/lib/eitil_support/stacktrace}/stack.rb +2 -2
  54. data/eitil_wrapper/README.md +181 -0
  55. data/eitil_wrapper/lib/eitil_wrapper.rb +7 -0
  56. data/eitil_wrapper/lib/eitil_wrapper/decorators.rb +3 -0
  57. data/{config/initializers/wrappers → eitil_wrapper/lib/eitil_wrapper}/decorators/application_decorator.rb +1 -1
  58. data/eitil_wrapper/lib/eitil_wrapper/decorators/controller_decorator.rb +60 -0
  59. data/eitil_wrapper/lib/eitil_wrapper/jobs.rb +4 -0
  60. data/eitil_wrapper/lib/eitil_wrapper/jobs/new_job.rb +34 -0
  61. data/eitil_wrapper/lib/eitil_wrapper/jobs/new_job_debugger.rb +37 -0
  62. data/eitil_wrapper/lib/eitil_wrapper/jobs/single_method_job.rb +8 -0
  63. data/eitil_wrapper/lib/eitil_wrapper/railtie.rb +49 -0
  64. data/eitil_wrapper/lib/eitil_wrapper/routes.rb +2 -0
  65. data/{config/initializers/wrappers → eitil_wrapper/lib/eitil_wrapper}/routes/extended_resources.rb +2 -2
  66. data/eitil_wrapper/lib/eitil_wrapper/scopes.rb +2 -0
  67. data/eitil_wrapper/lib/eitil_wrapper/scopes/default_scopes.rb +80 -0
  68. data/lib/eitil.rb +1 -1
  69. data/lib/eitil/all.rb +18 -0
  70. data/lib/eitil/engine.rb +24 -0
  71. data/lib/eitil/railtie.rb +6 -0
  72. data/lib/eitil/version.rb +3 -1
  73. metadata +82 -34
  74. data/app/controllers/eitil/application_controller.rb +0 -4
  75. data/app/jobs/eitil/application_job.rb +0 -4
  76. data/app/mailers/eitil/application_mailer.rb +0 -6
  77. data/app/models/eitil/application_record.rb +0 -5
  78. data/config/initializers/modules/dir.rb +0 -21
  79. data/config/initializers/monkeys/application_controller.rb +0 -14
  80. data/config/initializers/monkeys/application_record.rb +0 -30
  81. data/config/initializers/monkeys/kernel.rb +0 -48
  82. data/config/initializers/wrappers/decorators/controller_decorator.rb +0 -63
  83. data/config/initializers/wrappers/jobs/active_job_macros.rb +0 -52
  84. data/config/initializers/wrappers/jobs/single_method_job.rb +0 -24
  85. data/config/initializers/wrappers/scopes/default_scopes.rb +0 -83
  86. data/config/routes.rb +0 -2
@@ -0,0 +1,78 @@
1
+
2
+
3
+
4
+ # EitilSupport
5
+
6
+ EitilSupport provides utility through stand-alone classes and modules.
7
+
8
+
9
+
10
+ ## EitilSupport::Directory
11
+
12
+ ```ruby
13
+
14
+ require "eitil_support/directory"
15
+
16
+ ```
17
+
18
+ The EitilSupport::Directory module provides methods which help you introspect your Rails project.
19
+
20
+ ```ruby
21
+ EitilSupport::Directory.contents(directory='app')
22
+ # returns all files and subdirectories of a given directory
23
+ ```
24
+
25
+ ```ruby
26
+ EitilSupport::Directory.files(directory='app')
27
+ # returns all files of a given directory
28
+ ```
29
+
30
+ ```ruby
31
+ EitilSupport::Directory.subdirs(directory='app')
32
+ # returns all subdirectories of a given directory
33
+ ```
34
+
35
+ ```ruby
36
+ EitilSupport::Directory.lines(directory='app')
37
+ # returns the total amount of lines of all files of a given directory
38
+ ```
39
+
40
+
41
+ ## EitilSupport::StackTrace
42
+
43
+ ```ruby
44
+
45
+ require "eitil_support/stacktrace"
46
+
47
+ ```
48
+
49
+ The classes EitilSupport::Stack and EitilSupport::Call, and the module EitilSupport::Stack::Audit, provide the utility of easily viewing and storing the current stacktrace anywhere in your code – by initializing EitilSupport::Stack:
50
+
51
+ ```ruby
52
+ stack = EitilSupport::Stack.new
53
+ ```
54
+
55
+ ```ruby
56
+ stack.report
57
+ # returns the stacktrace as array, with each call being a stringified instance of EitilSupport::Call
58
+ ```
59
+
60
+ ```ruby
61
+ stack.show
62
+ # pretty prints the stack.report stacktrace
63
+ ```
64
+
65
+ ```ruby
66
+ stack.find
67
+ # accepts a block to find a specific call
68
+ ```
69
+
70
+ 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 EitilSupport::Stack::Audit into your model, and 2) add a :stacktrace column to your audits through the following migration.
71
+
72
+ ### Migration
73
+
74
+ ```ruby
75
+ def change
76
+ add_column :audits, :stacktrace, :text, array: true, default: []
77
+ end
78
+ ```
@@ -0,0 +1,5 @@
1
+
2
+ # require "eitil_support"
3
+
4
+ require "eitil_support/directory"
5
+ require "eitil_support/stacktrace"
@@ -0,0 +1,2 @@
1
+
2
+ require "eitil_support/directory/lookups"
@@ -0,0 +1,23 @@
1
+ module EitilSupport
2
+ module Directory
3
+ class << self
4
+
5
+ def contents(directory='app')
6
+ Dir[File.join(directory, '**', '*')]
7
+ end
8
+
9
+ def files(directory='app')
10
+ contents(directory).select { |file| File.file?(file) }
11
+ end
12
+
13
+ def subdirs(directory='app')
14
+ contents(directory).select { |file| File.directory?(file) }
15
+ end
16
+
17
+ def lines(directory='app')
18
+ files(directory).map { |file| File.open(file).count }.sum
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+
2
+ require "rails"
3
+ require "eitil_support"
4
+
5
+ module EitilSupport
6
+
7
+ class Railtie < Rails::Railtie
8
+ end
9
+
10
+ end
@@ -0,0 +1,4 @@
1
+
2
+ require "eitil_support/stacktrace/call"
3
+ require "eitil_support/stacktrace/stack"
4
+ require "eitil_support/stacktrace/audit"
@@ -1,4 +1,4 @@
1
- module Eitil::StackTrace::Audit
1
+ module EitilSupport::Stack::Audit
2
2
  extend ActiveSupport::Concern
3
3
  included do
4
4
 
@@ -7,7 +7,7 @@ module Eitil::StackTrace::Audit
7
7
  after_update :add_stacktrace_to_audit
8
8
 
9
9
  def add_stacktrace_to_audit
10
- stacktrace = Eitil::StackTrace::Stack.new.report
10
+ stacktrace = EitilSupport::Stack.new.report
11
11
  self.audits.last.update(stacktrace: stacktrace)
12
12
  end
13
13
 
@@ -1,4 +1,4 @@
1
- module Eitil::StackTrace
1
+ module EitilSupport
2
2
  class Call
3
3
 
4
4
  attr_reader :program, :line, :meth
@@ -1,11 +1,11 @@
1
- module Eitil::StackTrace
1
+ module EitilSupport
2
2
  class Stack
3
3
 
4
4
  attr_reader :stack, :backtrace
5
5
 
6
6
  def initialize
7
7
  @stack = caller[1..]
8
- @backtrace = stack.map { |call| Eitil::StackTrace::Call.new(call) }
8
+ @backtrace = stack.map { |call| EitilSupport::Call.new(call) }
9
9
  end
10
10
 
11
11
  def report
@@ -0,0 +1,181 @@
1
+
2
+
3
+
4
+ # EitilWrapper
5
+
6
+ EitilWrapper wraps core rails operations with extended utilities – such as routing, jobs and decoraters.
7
+
8
+
9
+
10
+
11
+
12
+ ## EitilWrapper::Decorators
13
+
14
+ ```ruby
15
+
16
+ require "eitil_wrapper/decorators"
17
+
18
+ ```
19
+
20
+ The Eitil decorator wrappers help you to standardize the calling of the right decorator method from within your controller action. Basically it provides you with a decorate macro in each controller.
21
+
22
+ ```ruby
23
+ decorate(dec_item, dec_method: nil, dec_class: nil, **dec_kwargs)
24
+ ```
25
+
26
+ - dec_item is the instance that will be decorated
27
+ - dec_method enabled you to set the desired decorator method. If not provided, it will look into the request params: if params["isMobile"] is present it will call .app, if params["isWeb"] is present it will call :app. If neither is provided in the params, it will call the default method :base.
28
+ - dec_class enables you to overwrite the decorator class that will be called. If not provided, the decorator class will be inferred from the instance model's classname (User => UserDecorator).
29
+ - dec_kwargs enables you to provide additional arguments, which will be passed to your decorator method.
30
+
31
+
32
+ ### Configuration
33
+
34
+ 1. Your decorator classes should inherit from Eitil::ApplicationDecorator.
35
+ 2. Your controllers should inherit the module Eitil::ControllerDecorator, through inclusion in a superclass.
36
+ 3. If you set controller ivars for each request, you can make them available in your decorators by providing Eitil a method which returns the names of your ivars as an array of symbols:
37
+
38
+ ```ruby
39
+ # initializers/eitil.rb
40
+
41
+ Eitil.set_config do |config|
42
+ config.get_controller_ivars_method = 'API::BaseController.controller_ivars' # => [:user, :env]
43
+ end
44
+ ```
45
+
46
+
47
+
48
+
49
+
50
+ ## EitilWrapper::Jobs
51
+
52
+ ```ruby
53
+
54
+ require "eitil_wrapper/jobs"
55
+
56
+ ```
57
+
58
+ 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.
59
+
60
+ 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.
61
+
62
+ In contrast, the new_job_debugger macro defines a new :method_job_debugger method, which performs in the foreground.
63
+
64
+ ```ruby
65
+ # require "eitil_wrapper/jobs/new_job"
66
+
67
+ new_job(_method, *args, **kwargs)
68
+ # assuming a method :hello_world, call as: new_job :hello_world
69
+ # => defines :hello_world_job
70
+ ```
71
+
72
+ ```ruby
73
+ # require "eitil_wrapper/jobs/new_job_debugger"
74
+
75
+ new_job_debugger(_method, *args, **kwargs)
76
+ # assuming a method :hello_world, call as: new_job_debugger :hello_world
77
+ # => defines :hello_world_job_debugger
78
+ ```
79
+
80
+
81
+
82
+
83
+
84
+ ## EitilWrapper::Routes
85
+
86
+ ```ruby
87
+
88
+ require "eitil_wrapper/routes"
89
+
90
+ ```
91
+
92
+ The Eitil router wrapper enables you to easily create new routes that can be shared among controllers. In that sense, it is as a custom extension of the built-in resourceful routes.
93
+
94
+ ### New route
95
+
96
+ The first macro, .new_route, enables you to create new route objects which may be called and used by different controllers.
97
+
98
+ ```ruby
99
+ # require "eitil_wrapper/routes/extended_resources"
100
+
101
+ new_route(verb, _method, action, scope)
102
+ # call as: new_route :post, :attachment, "add_attachment", :member
103
+ ```
104
+
105
+ - verb refers to the http_verb, e.g. :put.
106
+ - method refers to the given http method (e.g. 'users/:id'). Additionally, this is the name you will refer to in order to include the route into a controller. Therefore the argument should be unique among all other routes.
107
+ - action refers to the controller action to which you want to redirect to request, e.g. :update_user.
108
+ - scope refers to the url and can be set to either :member or :collection.
109
+
110
+ ### Add route
111
+
112
+ The second macro, extended_resources, enables you to create all standard resources for a controller and add your own standardized routes. This macro works the same as the built-in :resources, except that you can pass more arguments to only: [], which adds the routes to your controller.
113
+
114
+ ```ruby
115
+ # require "eitil_wrapper/routes/extended_resources"
116
+
117
+ extended_resources(controller, **kwargs)
118
+ # call as: extended_resources :posts, only: [:create, :update, :attachment]
119
+ ```
120
+
121
+
122
+
123
+
124
+
125
+ ## EitilWrapper::Scopes
126
+
127
+ ```ruby
128
+
129
+ require "eitil_wrapper/scopes"
130
+
131
+ ```
132
+
133
+ Scopes are generated through the columns of your model's database table. Which scopes are generated depends on the datatype of a column. For example, if your User model with table users has a column is_manager, a scope :is_manager_true is generated for your User model. A scope method is defined only if it does not already responds to another method of the same name. The scopes generated are:
134
+
135
+ ```ruby
136
+ # require "eitil_wrapper/scopes/default_scopes"
137
+
138
+ # columns of datatype: boolean
139
+ .{column_name}_true
140
+ .{column_name}_false
141
+
142
+ # columns of datatype: datetime
143
+ .{column_name}_today
144
+ .{column_name}_past
145
+ .{column_name}_future
146
+ .{column_name}_on_date(date)
147
+ .{column_name}_before_date(date)
148
+ .{column_name}_after_date(date)
149
+ .{column_name}_between_dates(start_date, end_date)
150
+ .{column_name}_oldest_first
151
+ .{column_name}_newest_first
152
+
153
+ # columns of datatype: date
154
+ .{column_name}_today
155
+ .{column_name}_past
156
+ .{column_name}_future
157
+ .{column_name}_on_date(date)
158
+ .{column_name}_before_date(date)
159
+ .{column_name}_after_date(date)
160
+ .{column_name}_between_dates(start_date, end_date)
161
+ .{column_name}_oldest_first
162
+ .{column_name}_newest_first
163
+
164
+ # columns of datatype: integer
165
+ .{column_name}_equal_to(number)
166
+ .{column_name}_lower_than(number)
167
+ .{column_name}_higher_than(number)
168
+ .{column_name}_between(min, max)
169
+ .{column_name}_ascending
170
+ .{column_name}_descending
171
+
172
+ # columns of datatype: float
173
+ .{column_name}_equal_to(number)
174
+ .{column_name}_lower_than(number)
175
+ .{column_name}_higher_than(number)
176
+ .{column_name}_between(min, max)
177
+ .{column_name}_ascending
178
+ .{column_name}_descending
179
+ ```
180
+
181
+
@@ -0,0 +1,7 @@
1
+
2
+ require "eitil_wrapper"
3
+
4
+ require "eitil_wrapper/jobs"
5
+ require "eitil_wrapper/scopes"
6
+ require "eitil_wrapper/routes"
7
+ require "eitil_wrapper/decorators"
@@ -0,0 +1,3 @@
1
+
2
+ require "eitil_wrapper/decorators/application_decorator"
3
+ require "eitil_wrapper/decorators/controller_decorator"
@@ -1,4 +1,4 @@
1
- module Eitil
1
+ module EitilWrapper
2
2
  class ApplicationDecorator
3
3
 
4
4
  include ActiveModel::Model
@@ -0,0 +1,60 @@
1
+ module EitilWrapper
2
+ module ControllerDecorator
3
+
4
+ private
5
+
6
+ def decorate(dec_item, dec_method: nil, dec_class: nil, **dec_kwargs)
7
+ all_args_to_ivars binding
8
+ set_ivars :dec_class, :dec_method, :decorator
9
+ send_to_decorator
10
+ end
11
+
12
+ def send_to_decorator
13
+ @dec_kwargs.any? ? @decorator.send(@dec_method, @dec_item, @dec_kwargs)
14
+ : @decorator.send(@dec_method, @dec_item)
15
+
16
+ rescue NoMethodError => e
17
+ inform_no_method_for_decorator_error
18
+ @dec_item
19
+ end
20
+
21
+ def inform_no_method_for_decorator_error
22
+ message = "Warning: NoMethodError for #{@dec_class}.#{@dec_method}, returned @dec_item instead."
23
+ Logger.new("#{Rails.root}/log/decorator_log.log").warn message
24
+ warn message
25
+ end
26
+
27
+ def set_dec_method
28
+ @dec_method = @dec_method || derived_dec_method || :base
29
+ end
30
+
31
+ def derived_dec_method
32
+ return unless respond_to? :params
33
+ return :app if params["isMobile"]
34
+ return :web if params["isWeb"]
35
+ end
36
+
37
+ def set_dec_class
38
+ @dec_class = @dec_class ? manual_set_dec_class : derived_dec_class
39
+ end
40
+
41
+ def manual_set_dec_class
42
+ "#{@dec_class}Decorator".constantize
43
+ end
44
+
45
+ def derived_dec_class
46
+ "#{@dec_item.class.name}Decorator".constantize
47
+ end
48
+
49
+ def set_decorator
50
+ @decorator = @dec_class.new controller_ivars
51
+ end
52
+
53
+ def controller_ivars
54
+ eval(Eitil.get_controller_ivars_method).map do |ivar|
55
+ { ivar => instance_variable_get("@#{ivar.to_s}") }
56
+ end.inject &:merge
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,4 @@
1
+
2
+ require "eitil_wrapper/jobs/new_job"
3
+ require "eitil_wrapper/jobs/new_job_debugger"
4
+ require "eitil_wrapper/jobs/single_method_job"
@@ -0,0 +1,34 @@
1
+
2
+ # require "eitil_wrapper/jobs/new_job"
3
+
4
+ require "eitil_wrapper/jobs/single_method_job"
5
+
6
+ Kernel.module_eval do
7
+
8
+ # BEWARE: _self is currently not accepted in perform_later jobs due to serialization errors
9
+
10
+ # The cases of 'id' and '_self' both handle instances, with the difference
11
+ # being that 'id' works for objects that have a database record, while '_self'
12
+ # works for non database supported instanes, such as an Exporter instance.
13
+
14
+ def new_job(_method, *args, **kwargs)
15
+
16
+ if instance_methods(false).include? _method
17
+ define_method "#{_method}_job" do |_self = nil, *args, **kwargs|
18
+
19
+ EitilWrapper::SingleMethodJob.perform_later(
20
+ *args, _class: self.class.to_s, _method: _method.to_s, id: safe_send(:id), _self: self.to_json, **kwargs
21
+ )
22
+ end
23
+
24
+ elsif singleton_methods(false).include? _method
25
+ define_singleton_method "#{_method}_job" do |*args, **kwargs|
26
+
27
+ EitilWrapper::SingleMethodJob.perform_later(
28
+ *args, _class: to_s, _method: _method.to_s, **kwargs
29
+ )
30
+ end
31
+ end
32
+ end
33
+
34
+ end