eitil 1.0.1.e.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/eitil_core/README.md +288 -0
  3. data/eitil_core/lib/eitil_core.rb +24 -0
  4. data/eitil_core/lib/eitil_core/application_controller.rb +2 -0
  5. data/eitil_core/lib/eitil_core/application_controller/slice_params.rb +14 -0
  6. data/eitil_core/lib/eitil_core/application_record.rb +4 -0
  7. data/eitil_core/lib/eitil_core/application_record/all_associations.rb +16 -0
  8. data/eitil_core/lib/eitil_core/application_record/find_by_like.rb +15 -0
  9. data/eitil_core/lib/eitil_core/application_record/where_like.rb +15 -0
  10. data/eitil_core/lib/eitil_core/argument_helpers.rb +5 -0
  11. data/eitil_core/lib/eitil_core/argument_helpers/all_args_to_ivars.rb +12 -0
  12. data/eitil_core/lib/eitil_core/argument_helpers/all_kwargs_to_ivars.rb +12 -0
  13. data/eitil_core/lib/eitil_core/argument_helpers/args_to_ivars.rb +12 -0
  14. data/eitil_core/lib/eitil_core/concerns.rb +2 -0
  15. data/eitil_core/lib/eitil_core/concerns/include_concerns_of.rb +15 -0
  16. data/eitil_core/lib/eitil_core/datetime.rb +2 -0
  17. data/eitil_core/lib/eitil_core/datetime/prettify.rb +10 -0
  18. data/eitil_core/lib/eitil_core/errors.rb +2 -0
  19. data/eitil_core/lib/eitil_core/errors/raise_error.rb +11 -0
  20. data/eitil_core/lib/eitil_core/float.rb +2 -0
  21. data/eitil_core/lib/eitil_core/float/safe_to_i.rb +9 -0
  22. data/eitil_core/lib/eitil_core/hash.rb +2 -0
  23. data/eitil_core/lib/eitil_core/hash/auto_dig.rb +17 -0
  24. data/eitil_core/lib/eitil_core/lookups.rb +2 -0
  25. data/eitil_core/lib/eitil_core/lookups/all_methods.rb +32 -0
  26. data/eitil_core/lib/eitil_core/railtie.rb +37 -0
  27. data/eitil_core/lib/eitil_core/safe_executions.rb +3 -0
  28. data/eitil_core/lib/eitil_core/safe_executions/safe_call.rb +12 -0
  29. data/eitil_core/lib/eitil_core/safe_executions/safe_send.rb +12 -0
  30. data/eitil_core/lib/eitil_core/setters.rb +2 -0
  31. data/eitil_core/lib/eitil_core/setters/set_ivars.rb +12 -0
  32. data/eitil_core/lib/eitil_core/type_checkers.rb +2 -0
  33. data/eitil_core/lib/eitil_core/type_checkers/is_num_or_nan.rb +96 -0
  34. data/eitil_core/lib/eitil_core/validations.rb +2 -0
  35. data/eitil_core/lib/eitil_core/validations/run_validations.rb +10 -0
  36. data/eitil_integrate/README.md +8 -0
  37. data/eitil_integrate/lib/eitil_integrate.rb +0 -0
  38. data/eitil_integrate/lib/eitil_integrate/railtie.rb +10 -0
  39. data/eitil_store/README.md +16 -0
  40. data/eitil_store/lib/eitil_store.rb +4 -0
  41. data/eitil_store/lib/eitil_store/railtie.rb +10 -0
  42. data/eitil_store/lib/eitil_store/regex.rb +4 -0
  43. data/eitil_store/lib/eitil_store/regex/regex.rb +41 -0
  44. data/eitil_support/README.md +78 -0
  45. data/eitil_support/lib/eitil_support.rb +5 -0
  46. data/eitil_support/lib/eitil_support/directory.rb +2 -0
  47. data/eitil_support/lib/eitil_support/directory/lookups.rb +23 -0
  48. data/eitil_support/lib/eitil_support/railtie.rb +10 -0
  49. data/eitil_support/lib/eitil_support/stacktrace.rb +4 -0
  50. data/eitil_support/lib/eitil_support/stacktrace/audit.rb +15 -0
  51. data/eitil_support/lib/eitil_support/stacktrace/call.rb +17 -0
  52. data/eitil_support/lib/eitil_support/stacktrace/stack.rb +28 -0
  53. data/eitil_wrapper/README.md +181 -0
  54. data/eitil_wrapper/lib/eitil_wrapper.rb +7 -0
  55. data/eitil_wrapper/lib/eitil_wrapper/decorators.rb +3 -0
  56. data/eitil_wrapper/lib/eitil_wrapper/decorators/application_decorator.rb +19 -0
  57. data/eitil_wrapper/lib/eitil_wrapper/decorators/controller_decorator.rb +60 -0
  58. data/eitil_wrapper/lib/eitil_wrapper/jobs.rb +4 -0
  59. data/eitil_wrapper/lib/eitil_wrapper/jobs/new_job.rb +34 -0
  60. data/eitil_wrapper/lib/eitil_wrapper/jobs/new_job_debugger.rb +37 -0
  61. data/eitil_wrapper/lib/eitil_wrapper/jobs/single_method_job.rb +8 -0
  62. data/eitil_wrapper/lib/eitil_wrapper/railtie.rb +49 -0
  63. data/eitil_wrapper/lib/eitil_wrapper/routes.rb +2 -0
  64. data/eitil_wrapper/lib/eitil_wrapper/routes/extended_resources.rb +40 -0
  65. data/eitil_wrapper/lib/eitil_wrapper/scopes.rb +2 -0
  66. data/eitil_wrapper/lib/eitil_wrapper/scopes/default_scopes.rb +80 -0
  67. data/lib/eitil/version.rb +1 -1
  68. metadata +69 -4
@@ -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"
@@ -0,0 +1,15 @@
1
+ module EitilSupport::Stack::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 = EitilSupport::Stack.new.report
11
+ self.audits.last.update(stacktrace: stacktrace)
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ module EitilSupport
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 EitilSupport
2
+ class Stack
3
+
4
+ attr_reader :stack, :backtrace
5
+
6
+ def initialize
7
+ @stack = caller[1..]
8
+ @backtrace = stack.map { |call| EitilSupport::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,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"
@@ -0,0 +1,19 @@
1
+ module EitilWrapper
2
+ class ApplicationDecorator
3
+
4
+ include ActiveModel::Model
5
+
6
+ def initialize(attributes={}, **kwargs)
7
+ super attributes
8
+ all_kwargs_to_ivars binding
9
+ end
10
+
11
+ def self.method_missing(method_name, *args, **kwargs)
12
+ if %i$ web app $.include?(method_name.to_sym)
13
+ kwargs.any? ? send(:base, *args, **kwargs) : send(:base, *args)
14
+ end
15
+ super
16
+ end
17
+
18
+ end
19
+ end
@@ -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