servies 0.2.0

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.
@@ -0,0 +1,17 @@
1
+ require 'rails/generators'
2
+
3
+ module Servies
4
+ class InstallGenerator < Rails::Generators::Base
5
+ def self.source_root
6
+ @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
7
+ end
8
+
9
+ def copy_backend_directory
10
+ directory 'backend', 'app/backend', recursive: true
11
+ end
12
+
13
+ def add_backend_to_autoload_paths
14
+ application "config.autoload_paths += %W(\#{config.root}/app/backend)"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ class Backend < Servies::Backend
2
+ # This class is a placeholder that will be expanded by a later feature branch
3
+ end
@@ -0,0 +1,3 @@
1
+ class Command
2
+ include Servies::Operation
3
+ end
@@ -0,0 +1,16 @@
1
+ class Interactor
2
+ include Servies::Operation
3
+
4
+ # If you want your interactors to be compatible with a backgrounding
5
+ # daemon, you can use this base class to add support.
6
+ #
7
+ # Example for Resque:
8
+ #
9
+ # def self.perform(*args)
10
+ # new(*args).call
11
+ # end
12
+
13
+ def authorized?
14
+ raise NotImplementedError
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ class Query
2
+ include Servies::Operation
3
+ end
@@ -0,0 +1,19 @@
1
+ module Servies
2
+ # this method is also available as constantize in Rails,
3
+ # but we want to be able to write classes and/or tests without Rails
4
+ def self.get_class_by_string classname
5
+ classname.constantize
6
+ end
7
+
8
+ def self.string_to_classname string
9
+ string.to_s.camelize
10
+ end
11
+ end
12
+
13
+ require_relative 'servies/engine' if defined?(Rails)
14
+ require_relative 'servies/access_denied'
15
+ require_relative 'servies/validation_error'
16
+ require_relative 'servies/validations'
17
+ require_relative 'servies/backend'
18
+ require_relative 'servies/operation'
19
+ require_relative 'servies/version'
@@ -0,0 +1,4 @@
1
+ module Servies
2
+ class AccessDenied < StandardError
3
+ end
4
+ end
@@ -0,0 +1,23 @@
1
+ require 'servies/operation_finder'
2
+
3
+ module Servies
4
+ class Backend
5
+ attr_reader :context
6
+
7
+ def initialize(context = {})
8
+ @context = context
9
+ end
10
+
11
+ def interactors
12
+ OperationFinder.new("Interactors", self, false)
13
+ end
14
+
15
+ def queries
16
+ OperationFinder.new("Queries", self, true)
17
+ end
18
+
19
+ def commands
20
+ OperationFinder.new("Commands", self, true)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,6 @@
1
+ require 'rails'
2
+
3
+ module Servies
4
+ class Engine < Rails::Engine
5
+ end
6
+ end
@@ -0,0 +1,77 @@
1
+ require 'active_support/concern'
2
+ require 'servies/validations'
3
+ require 'virtus'
4
+ require_relative 'access_denied'
5
+
6
+ module Servies
7
+ module Operation
8
+ include ActiveSupport::Concern
9
+ include Servies::Validations
10
+ include Virtus
11
+
12
+ attribute :backend, ::Servies::Backend
13
+
14
+ def validate
15
+ return false unless attributes_without_defaults_have_values
16
+ if respond_to? :valid?
17
+ raise Servies::ValidationError, "an argument is invalid" unless valid?
18
+ else
19
+ true
20
+ end
21
+ end
22
+
23
+ def call(*args, &block)
24
+ validate
25
+ check_authorization
26
+ execute(*args, &block)
27
+ end
28
+
29
+ private
30
+
31
+ def commands
32
+ backend.commands
33
+ end
34
+
35
+ def queries
36
+ backend.queries
37
+ end
38
+
39
+ def interactors
40
+ backend.interactors
41
+ end
42
+
43
+ def context
44
+ backend.context
45
+ end
46
+
47
+ def servies_options
48
+ @options
49
+ end
50
+
51
+ def raise_unauthorized(message='Unauthorized')
52
+ raise Servies::AccessDenied, message
53
+ end
54
+
55
+ def check_authorization
56
+ raise_unauthorized if respond_to? :authorized?, true and not authorized?
57
+ end
58
+
59
+ def attributes_without_defaults_have_values
60
+ attributes_without_value = attribute_set.select do |attribute|
61
+ not attribute.options.has_key?(:default) and send(attribute.name).nil?
62
+ end
63
+ attributes_without_value.empty?
64
+ end
65
+
66
+ module ClassMethods
67
+ # make our interactors behave as Resque jobs
68
+ def perform(*args)
69
+ new(*args).call
70
+ end
71
+
72
+ def queue
73
+ @queue || :interactor_operations
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,34 @@
1
+ require 'active_support/inflector'
2
+
3
+ module Servies
4
+ class OperationFinder
5
+ attr_reader :namespace, :backend
6
+
7
+ def initialize(namespace, backend, autocall = false)
8
+ @namespace = namespace
9
+ @backend = backend
10
+ @autocall = autocall
11
+ end
12
+
13
+ def method_missing(name, attributes = {})
14
+ klass = _find_klass(name)
15
+ instance = klass.new(attributes.merge(backend: backend))
16
+
17
+ if @autocall
18
+ instance.call
19
+ else
20
+ instance
21
+ end
22
+ end
23
+
24
+ def respond_to_missing?(name, include_private = false)
25
+ _find_klass(name)
26
+ end
27
+
28
+ private
29
+
30
+ def _find_klass(name)
31
+ namespace.constantize.const_get(name.to_s.camelize)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,4 @@
1
+ module Servies
2
+ class ValidationError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,45 @@
1
+ require 'servies/validation_error'
2
+
3
+ module Servies
4
+ module Validations
5
+ def validate_hexadecimal_string param_name, param
6
+ #warn "[DEPRECATION] `validate_hexadecimal_string` is deprecated. Please use the ActiveModel validation instead."
7
+ raise Servies::ValidationError, "#{param_name.to_s} should be an hexadecimal string." unless param.is_a? String and /\A[\da-fA-F]+\Z/.match param
8
+ end
9
+
10
+ def validate_regex param_name, param, regex, message
11
+ #warn "[DEPRECATION] `validate_integer` is deprecated. Please use the default format_of ActiveModel validator instead."
12
+ raise Servies::ValidationError, "#{param_name.to_s} #{message}" unless regex.match param
13
+ end
14
+
15
+ def validate_integer param_name, param, opts = {}
16
+ #warn "[DEPRECATION] `validate_integer` is deprecated. Please use the default numericality ActiveModel validator with the :only_integer option instead."
17
+ return if opts[:allow_blank] && param.blank?
18
+ raise Servies::ValidationError, "#{param_name.to_s} should be an integer." unless param.is_a? Integer
19
+ end
20
+
21
+ def validate_in_set param_name, param, set
22
+ raise Servies::ValidationError, "#{param_name.to_s} should be on of these values: #{set.inspect}." unless set.include? param
23
+ end
24
+
25
+ def validate_string param_name, param
26
+ #warn "[DEPRECATION] `validate_string` is deprecated. Please use the ActiveModel validation instead."
27
+ raise Servies::ValidationError, "#{param_name.to_s} should be a string." unless param.is_a? String
28
+ end
29
+
30
+ def validate_nonempty_string param_name, param
31
+ #warn "[DEPRECATION] `validate_string` is deprecated. Please use the ActiveModel validation with the :non_empty option instead."
32
+ raise Servies::ValidationError, "#{param_name.to_s} should be a nonempty string." unless param.is_a?(String) && not(param.nil?) && not(param.empty?)
33
+ end
34
+
35
+ def validate_integer_string param_name, param
36
+ #warn "[DEPRECATION] `validate_integer_string` is deprecated. Please use the ActiveModel validation instead."
37
+ raise Servies::ValidationError, "#{param_name.to_s} should be an integer string." unless param.is_a? String and /\A\d+\Z/.match param
38
+ end
39
+
40
+ def validate_not_nil param_name, param
41
+ #warn "[DEPRECATION] `validate_not_nil` is deprecated. Please use the default presence ActiveModel validator instead."
42
+ raise Servies::ValidationError, "#{param_name.to_s} should not be nil." if param.nil?
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ module Servies
2
+ VERSION = "0.2.0"
3
+ end
metadata ADDED
@@ -0,0 +1,257 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: servies
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Marten Veldthuis
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-07-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.2.7
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.2.7
30
+ - !ruby/object:Gem::Dependency
31
+ name: activemodel
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 3.2.7
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 3.2.7
46
+ - !ruby/object:Gem::Dependency
47
+ name: virtus
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - '='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.5.5
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.5.5
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 2.14.0
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 2.14.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: guard
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: guard-bundler
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: guard-rspec
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: terminal-notifier-guard
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: rb-fsevent
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: rake
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ - !ruby/object:Gem::Dependency
175
+ name: benchmark-ips
176
+ requirement: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ! '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ - !ruby/object:Gem::Dependency
191
+ name: coveralls
192
+ requirement: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ! '>='
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ type: :development
199
+ prerelease: false
200
+ version_requirements: !ruby/object:Gem::Requirement
201
+ none: false
202
+ requirements:
203
+ - - ! '>='
204
+ - !ruby/object:Gem::Version
205
+ version: '0'
206
+ description: Servies helps you to build a backend for your application.
207
+ email:
208
+ - marten@veldthuis.com
209
+ executables: []
210
+ extensions: []
211
+ extra_rdoc_files: []
212
+ files:
213
+ - lib/generators/servies/install_generator.rb
214
+ - lib/generators/servies/templates/backend/backend.rb
215
+ - lib/generators/servies/templates/backend/command.rb
216
+ - lib/generators/servies/templates/backend/interactor.rb
217
+ - lib/generators/servies/templates/backend/query.rb
218
+ - lib/servies.rb
219
+ - lib/servies/access_denied.rb
220
+ - lib/servies/backend.rb
221
+ - lib/servies/engine.rb
222
+ - lib/servies/operation.rb
223
+ - lib/servies/operation_finder.rb
224
+ - lib/servies/validation_error.rb
225
+ - lib/servies/validations.rb
226
+ - lib/servies/version.rb
227
+ homepage: https://github.com/marten/servies/
228
+ licenses: []
229
+ post_install_message:
230
+ rdoc_options: []
231
+ require_paths:
232
+ - lib
233
+ required_ruby_version: !ruby/object:Gem::Requirement
234
+ none: false
235
+ requirements:
236
+ - - ! '>='
237
+ - !ruby/object:Gem::Version
238
+ version: '0'
239
+ segments:
240
+ - 0
241
+ hash: -2216746290766598287
242
+ required_rubygems_version: !ruby/object:Gem::Requirement
243
+ none: false
244
+ requirements:
245
+ - - ! '>='
246
+ - !ruby/object:Gem::Version
247
+ version: '0'
248
+ segments:
249
+ - 0
250
+ hash: -2216746290766598287
251
+ requirements: []
252
+ rubyforge_project:
253
+ rubygems_version: 1.8.23
254
+ signing_key:
255
+ specification_version: 3
256
+ summary: A service object framework for Ruby, with extra support for Rails.
257
+ test_files: []