snfoil 0.9.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/Gemfile +6 -0
  4. data/LICENSE.txt +201 -0
  5. data/README.md +95 -505
  6. data/docs/build-context.md +56 -0
  7. data/docs/create-context.md +109 -0
  8. data/docs/destroy-context.md +102 -0
  9. data/docs/index-context.md +70 -0
  10. data/docs/show-context.md +71 -0
  11. data/docs/update-context.md +107 -0
  12. data/lib/{sn_foil → snfoil}/adapters/orms/active_record.rb +14 -0
  13. data/lib/{sn_foil → snfoil}/adapters/orms/base_adapter.rb +15 -1
  14. data/lib/snfoil/crud/build_context.rb +49 -0
  15. data/lib/snfoil/crud/change_context.rb +48 -0
  16. data/lib/snfoil/crud/context.rb +41 -0
  17. data/lib/snfoil/crud/create_context.rb +45 -0
  18. data/lib/snfoil/crud/destroy_context.rb +57 -0
  19. data/lib/snfoil/crud/index_context.rb +46 -0
  20. data/lib/snfoil/crud/setup_context.rb +90 -0
  21. data/lib/snfoil/crud/show_context.rb +52 -0
  22. data/lib/snfoil/crud/update_context.rb +60 -0
  23. data/lib/snfoil/version.rb +19 -0
  24. data/lib/snfoil.rb +69 -0
  25. data/snfoil.gemspec +47 -0
  26. metadata +100 -33
  27. data/Rakefile +0 -4
  28. data/lib/sn_foil/context.rb +0 -24
  29. data/lib/sn_foil/contexts/build_context.rb +0 -67
  30. data/lib/sn_foil/contexts/change_context.rb +0 -101
  31. data/lib/sn_foil/contexts/create_context.rb +0 -158
  32. data/lib/sn_foil/contexts/destroy_context.rb +0 -164
  33. data/lib/sn_foil/contexts/index_context.rb +0 -64
  34. data/lib/sn_foil/contexts/setup_context.rb +0 -119
  35. data/lib/sn_foil/contexts/show_context.rb +0 -61
  36. data/lib/sn_foil/contexts/update_context.rb +0 -168
  37. data/lib/sn_foil/policy.rb +0 -55
  38. data/lib/sn_foil/searcher.rb +0 -123
  39. data/lib/sn_foil/version.rb +0 -5
  40. data/lib/sn_foil.rb +0 -49
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Matthew Howes
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'active_support/concern'
18
+ require_relative './change_context'
19
+
20
+ module SnFoil
21
+ module CRUD
22
+ module CreateContext
23
+ extend ActiveSupport::Concern
24
+
25
+ included do
26
+ include BuildContext
27
+ include ChangeContext
28
+
29
+ action :create, with: :create_action
30
+
31
+ setup_create { |options| run_interval(:setup, **options) }
32
+ setup_create { |options| run_interval(:setup_build, **options) }
33
+ setup_create { |options| run_interval(:setup_change, **options) }
34
+ before_create { |options| run_interval(:before_change, **options) }
35
+ after_create_success { |options| run_interval(:after_change_success, **options) }
36
+ after_create_failure { |options| run_interval(:after_change_failure, **options) }
37
+ after_create { |options| run_interval(:after_change, **options) }
38
+
39
+ def create_action(options)
40
+ wrap_object(options[:object]).save
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Matthew Howes
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'active_support/concern'
18
+ require_relative './setup_context'
19
+ require_relative './change_context'
20
+
21
+ module SnFoil
22
+ module CRUD
23
+ module DestroyContext
24
+ extend ActiveSupport::Concern
25
+
26
+ included do
27
+ include SetupContext
28
+ include ChangeContext
29
+
30
+ action :destroy, with: :destroy_action
31
+
32
+ setup_destroy { |options| run_interval(:setup, **options) }
33
+ setup_destroy { |options| run_interval(:setup_change, **options) }
34
+ before_destroy { |options| run_interval(:before_change, **options) }
35
+ after_destroy_success { |options| run_interval(:after_change_success, **options) }
36
+ after_destroy_failure { |options| run_interval(:after_change_failure, **options) }
37
+ after_destroy { |options| run_interval(:after_change, **options) }
38
+
39
+ setup_destroy do |options|
40
+ raise ArgumentError, 'one of the following keywords is required: id, object' unless options[:id] || options[:object]
41
+
42
+ options
43
+ end
44
+
45
+ before_destroy do |options|
46
+ options[:object] ||= scope.resolve.find(options[:id])
47
+
48
+ options
49
+ end
50
+
51
+ def destroy_action(options)
52
+ wrap_object(options[:object]).destroy
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Matthew Howes
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'active_support/concern'
18
+ require_relative './change_context'
19
+
20
+ module SnFoil
21
+ module CRUD
22
+ module IndexContext
23
+ extend ActiveSupport::Concern
24
+
25
+ included do
26
+ include SetupContext
27
+
28
+ action :index, with: :index_action
29
+
30
+ setup_index { |options| run_interval(:setup, **options) }
31
+
32
+ before_index do |options|
33
+ options[:object] ||= options.fetch(:searcher) { self.class.snfoil_searcher }
34
+ .new(scope: scope.resolve)
35
+ .search(options.fetch(:params) { {} })
36
+
37
+ options
38
+ end
39
+
40
+ def index_action(**options)
41
+ options[:object]
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Matthew Howes
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'snfoil/context'
18
+
19
+ require 'active_support/concern'
20
+ require 'active_support/core_ext/string/inflections'
21
+
22
+ module SnFoil
23
+ module CRUD
24
+ module SetupContext
25
+ extend ActiveSupport::Concern
26
+
27
+ included do
28
+ include SnFoil::Context
29
+
30
+ interval :setup
31
+
32
+ authorize do |options|
33
+ options.fetch(:policy) { policy }
34
+ .new(entity, options[:object], **options)
35
+ .send(options.fetch(:authorize) { "#{options[:action]}?" })
36
+ end
37
+ end
38
+
39
+ class_methods do
40
+ attr_reader :snfoil_model, :snfoil_policy, :snfoil_searcher
41
+
42
+ def searcher(klass = nil)
43
+ @snfoil_searcher = klass
44
+ end
45
+
46
+ def model(klass = nil)
47
+ @snfoil_model = klass
48
+ end
49
+
50
+ def policy(klass = nil)
51
+ @snfoil_policy = klass
52
+ end
53
+ end
54
+
55
+ def model
56
+ self.class.snfoil_model
57
+ end
58
+
59
+ def policy
60
+ self.class.snfoil_policy
61
+ end
62
+
63
+ def scope(_object_class = nil, **options)
64
+ "#{policy.name}::Scope".safe_constantize.new(wrap_object(model), entity, **options)
65
+ end
66
+
67
+ def wrap_object(object)
68
+ return object unless adapter
69
+
70
+ adapter.new(object)
71
+ end
72
+
73
+ def unwrap_object(object)
74
+ return object unless adapter
75
+
76
+ adapter?(object) ? object.__getobj__ : object
77
+ end
78
+
79
+ def adapter?(object)
80
+ return false unless adapter
81
+
82
+ object.instance_of? adapter
83
+ end
84
+
85
+ def adapter
86
+ @adapter ||= SnFoil.adapter
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Matthew Howes
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'active_support/concern'
18
+ require_relative './setup_context'
19
+
20
+ module SnFoil
21
+ module CRUD
22
+ module ShowContext
23
+ extend ActiveSupport::Concern
24
+
25
+ included do
26
+ include SetupContext
27
+
28
+ action :show, with: :show_action
29
+
30
+ setup_show do |options|
31
+ raise ArgumentError, 'one of the following keywords is required: id, object' unless options[:id] || options[:object]
32
+
33
+ options
34
+ end
35
+
36
+ setup_show do |options|
37
+ run_interval(:setup, **options)
38
+ end
39
+
40
+ before_show do |**options|
41
+ options[:object] ||= scope.resolve.find(options[:id])
42
+
43
+ options
44
+ end
45
+
46
+ def show_action(options)
47
+ options[:object]
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Matthew Howes
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'active_support/concern'
18
+ require_relative './setup_context'
19
+ require_relative './change_context'
20
+
21
+ module SnFoil
22
+ module CRUD
23
+ module UpdateContext
24
+ extend ActiveSupport::Concern
25
+
26
+ included do
27
+ include SetupContext
28
+ include ChangeContext
29
+
30
+ action :update, with: :update_action
31
+
32
+ setup_update { |options| run_interval(:setup, **options) }
33
+ setup_update { |options| run_interval(:setup_change, **options) }
34
+ before_update { |options| run_interval(:before_change, **options) }
35
+ after_update_success { |options| run_interval(:after_change_success, **options) }
36
+ after_update_failure { |options| run_interval(:after_change_failure, **options) }
37
+ after_update { |options| run_interval(:after_change, **options) }
38
+
39
+ setup_update do |options|
40
+ raise ArgumentError, 'one of the following keywords is required: id, object' unless options[:id] || options[:object]
41
+
42
+ options
43
+ end
44
+
45
+ before_update do |options|
46
+ params = options.fetch(:params) { {} }
47
+ options[:object] ||= scope.resolve.find(options[:id])
48
+
49
+ wrap_object(options[:object]).attributes = params
50
+
51
+ options
52
+ end
53
+
54
+ def update_action(options)
55
+ wrap_object(options[:object]).save
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Matthew Howes
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module SnFoil
18
+ VERSION = '1.0.0'
19
+ end
data/lib/snfoil.rb ADDED
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Matthew Howes
4
+
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'active_support/core_ext/module/attribute_accessors'
18
+ require 'logger'
19
+ require 'snfoil/context'
20
+ require 'snfoil/policy'
21
+ require 'snfoil/searcher'
22
+
23
+ require_relative 'snfoil/version'
24
+
25
+ require_relative 'snfoil/crud/build_context'
26
+ require_relative 'snfoil/crud/change_context'
27
+ require_relative 'snfoil/crud/create_context'
28
+ require_relative 'snfoil/crud/destroy_context'
29
+ require_relative 'snfoil/crud/index_context'
30
+ require_relative 'snfoil/crud/setup_context'
31
+ require_relative 'snfoil/crud/show_context'
32
+ require_relative 'snfoil/crud/update_context'
33
+ require_relative 'snfoil/crud/context'
34
+
35
+ require_relative 'snfoil/adapters/orms/base_adapter'
36
+ require_relative 'snfoil/adapters/orms/active_record'
37
+
38
+ module SnFoil
39
+ class Error < StandardError; end
40
+
41
+ mattr_accessor :orm, default: 'active_record'
42
+ mattr_writer :logger
43
+
44
+ class << self
45
+ def logger
46
+ @logger ||= Logger.new($stdout).tap do |log|
47
+ log.progname = name
48
+ end
49
+ end
50
+
51
+ def adapter
52
+ return @adapter if @adapter
53
+
54
+ @adapter ||= if orm.instance_of?(String) || orm.instance_of?(Symbol)
55
+ if Object.const_defined?("SnFoil::Adapters::ORMs::#{orm.camelcase}")
56
+ "SnFoil::Adapters::ORMs::#{orm.camelcase}".constantize
57
+ else
58
+ orm.constantize
59
+ end
60
+ else
61
+ orm
62
+ end
63
+ end
64
+
65
+ def configure
66
+ yield self
67
+ end
68
+ end
69
+ end
data/snfoil.gemspec ADDED
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/snfoil/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'snfoil'
7
+ spec.version = SnFoil::VERSION
8
+ spec.authors = ['Matthew Howes', 'Danny Murphy', 'Cliff Campbell']
9
+ spec.email = ['howeszy@gmail.com', 'dmurph24@gmail.com', 'cliffcampbell@hey.com']
10
+
11
+ spec.summary = 'A Toolbox of Context Behaviors'
12
+ spec.description = 'A collection of SnFoil gems and additional helper classes'
13
+ spec.homepage = 'https://github.com/limited-effort/snfoil'
14
+ spec.license = 'Apache-2.0'
15
+ spec.required_ruby_version = '>= 2.7'
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = spec.homepage
19
+ spec.metadata['changelog_uri'] = 'https://github.com/limited-effort/snfoil/blob/main/CHANGELOG.md'
20
+ spec.metadata['rubygems_mfa_required'] = 'true'
21
+
22
+ # Specify which files should be added to the gem when it is released.
23
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
+ ignore_list = %r{\A(?:test/|spec/|bin/|features/|Rakefile|\.\w)}
25
+ spec.files = Dir.chdir(File.expand_path(__dir__)) { `git ls-files -z`.split("\x0").reject { |f| f.match(ignore_list) } }
26
+
27
+ spec.bindir = 'exe'
28
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ['lib']
30
+
31
+ spec.add_dependency 'activesupport', '>= 5.2.6'
32
+ spec.add_dependency 'logger', '~> 1.0'
33
+ spec.add_dependency 'pundit', '~> 2.0'
34
+ spec.add_dependency 'snfoil-context', '~> 1.0'
35
+ spec.add_dependency 'snfoil-policy', '~> 1.0'
36
+ spec.add_dependency 'snfoil-searcher', '~> 1.0'
37
+
38
+ spec.add_development_dependency 'bundle-audit', '~> 0.1.0'
39
+ spec.add_development_dependency 'dry-struct', '~> 1.0'
40
+ spec.add_development_dependency 'fasterer', '~> 0.10.0'
41
+ spec.add_development_dependency 'pry-byebug', '~> 3.9'
42
+ spec.add_development_dependency 'rake', '~> 13.0'
43
+ spec.add_development_dependency 'rspec', '~> 3.9'
44
+ spec.add_development_dependency 'rubocop', '~> 1.29'
45
+ spec.add_development_dependency 'rubocop-performance', '~> 1.11'
46
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.4'
47
+ end