clowne 0.2.0 → 1.0.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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -0
  3. data/.travis.yml +6 -3
  4. data/CHANGELOG.md +14 -0
  5. data/Gemfile +1 -1
  6. data/README.md +30 -9
  7. data/clowne.gemspec +4 -3
  8. data/docs/active_record.md +2 -2
  9. data/docs/after_persist.md +80 -0
  10. data/docs/basic_example.md +22 -5
  11. data/docs/clone_mapper.md +62 -0
  12. data/docs/customization.md +2 -1
  13. data/docs/exclude_association.md +5 -4
  14. data/docs/finalize.md +2 -2
  15. data/docs/from_v02_to_v1.md +91 -0
  16. data/docs/implicit_cloner.md +1 -1
  17. data/docs/include_association.md +4 -4
  18. data/docs/init_as.md +10 -2
  19. data/docs/inline_configuration.md +4 -2
  20. data/docs/installation.md +31 -1
  21. data/docs/nullify.md +2 -2
  22. data/docs/operation.md +58 -0
  23. data/docs/overview.md +24 -0
  24. data/docs/parameters.md +5 -4
  25. data/docs/sequel.md +15 -18
  26. data/docs/supported_adapters.md +2 -2
  27. data/docs/testing.md +7 -5
  28. data/docs/web/README.md +6 -0
  29. data/docs/web/core/Footer.js +5 -9
  30. data/docs/web/i18n/en.json +8 -4
  31. data/docs/web/pages/en/index.js +1 -1
  32. data/docs/web/sidebars.json +10 -4
  33. data/docs/web/siteConfig.js +6 -4
  34. data/docs/web/static/css/custom.css +16 -10
  35. data/gemfiles/activerecord42.gemfile +3 -1
  36. data/gemfiles/jruby.gemfile +2 -0
  37. data/gemfiles/railsmaster.gemfile +2 -0
  38. data/lib/clowne.rb +3 -0
  39. data/lib/clowne/adapters/active_record.rb +2 -3
  40. data/lib/clowne/adapters/active_record/associations/base.rb +0 -4
  41. data/lib/clowne/adapters/active_record/associations/has_one.rb +2 -1
  42. data/lib/clowne/adapters/active_record/resolvers/association.rb +38 -0
  43. data/lib/clowne/adapters/base.rb +42 -43
  44. data/lib/clowne/adapters/base/association.rb +24 -15
  45. data/lib/clowne/adapters/registry.rb +49 -0
  46. data/lib/clowne/adapters/sequel.rb +10 -6
  47. data/lib/clowne/adapters/sequel/associations/base.rb +8 -4
  48. data/lib/clowne/adapters/sequel/associations/many_to_many.rb +6 -2
  49. data/lib/clowne/adapters/sequel/associations/one_to_many.rb +7 -2
  50. data/lib/clowne/adapters/sequel/associations/one_to_one.rb +7 -2
  51. data/lib/clowne/adapters/sequel/operation.rb +32 -0
  52. data/lib/clowne/adapters/sequel/record_wrapper.rb +0 -16
  53. data/lib/clowne/adapters/sequel/resolvers/after_persist.rb +22 -0
  54. data/lib/clowne/adapters/sequel/resolvers/association.rb +51 -0
  55. data/lib/clowne/adapters/sequel/specifications/after_persist_does_not_support.rb +15 -0
  56. data/lib/clowne/cloner.rb +27 -20
  57. data/lib/clowne/declarations.rb +2 -1
  58. data/lib/clowne/declarations/after_persist.rb +21 -0
  59. data/lib/clowne/declarations/finalize.rb +1 -0
  60. data/lib/clowne/declarations/include_association.rb +2 -1
  61. data/lib/clowne/declarations/init_as.rb +1 -0
  62. data/lib/clowne/declarations/nullify.rb +1 -0
  63. data/lib/clowne/declarations/trait.rb +1 -0
  64. data/lib/clowne/dsl.rb +9 -0
  65. data/lib/clowne/ext/lambda_as_proc.rb +1 -0
  66. data/lib/clowne/ext/record_key.rb +12 -0
  67. data/lib/clowne/ext/yield_self_then.rb +25 -0
  68. data/lib/clowne/planner.rb +6 -3
  69. data/lib/clowne/resolvers/after_persist.rb +18 -0
  70. data/lib/clowne/resolvers/finalize.rb +12 -0
  71. data/lib/clowne/resolvers/init_as.rb +13 -0
  72. data/lib/clowne/resolvers/nullify.rb +15 -0
  73. data/lib/clowne/rspec/helpers.rb +1 -0
  74. data/lib/clowne/utils/clone_mapper.rb +26 -0
  75. data/lib/clowne/utils/operation.rb +83 -0
  76. data/lib/clowne/utils/options.rb +39 -0
  77. data/lib/clowne/utils/params.rb +64 -0
  78. data/lib/clowne/utils/plan.rb +90 -0
  79. data/lib/clowne/version.rb +1 -1
  80. metadata +44 -18
  81. data/docs/configuration.md +0 -29
  82. data/docs/execution_order.md +0 -14
  83. data/docs/web/static/fonts/StemText.woff +0 -0
  84. data/docs/web/static/fonts/StemTextBold.woff +0 -0
  85. data/lib/clowne/adapters/active_record/association.rb +0 -34
  86. data/lib/clowne/adapters/base/finalize.rb +0 -19
  87. data/lib/clowne/adapters/base/init_as.rb +0 -21
  88. data/lib/clowne/adapters/base/nullify.rb +0 -19
  89. data/lib/clowne/adapters/sequel/association.rb +0 -47
  90. data/lib/clowne/params.rb +0 -62
  91. data/lib/clowne/plan.rb +0 -83
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Clowne
4
- VERSION = '0.2.0'
4
+ VERSION = '1.0.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clowne
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2018-02-21 00:00:00.000000000 Z
12
+ date: 2019-02-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '1.14'
20
+ version: '2.0'
21
21
  type: :development
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '1.14'
27
+ version: '2.0'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rake
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -73,14 +73,14 @@ dependencies:
73
73
  requirements:
74
74
  - - "~>"
75
75
  - !ruby/object:Gem::Version
76
- version: '0.51'
76
+ version: '0.61'
77
77
  type: :development
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
- version: '0.51'
83
+ version: '0.61'
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: rubocop-md
86
86
  requirement: !ruby/object:Gem::Requirement
@@ -95,6 +95,20 @@ dependencies:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0.2'
98
+ - !ruby/object:Gem::Dependency
99
+ name: rubocop-rspec
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '1.31'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '1.31'
98
112
  description: A flexible gem for cloning your models.
99
113
  email:
100
114
  - palkan@evilmartians.com
@@ -120,26 +134,30 @@ files:
120
134
  - clowne.gemspec
121
135
  - docs/.rubocop.yml
122
136
  - docs/active_record.md
137
+ - docs/after_persist.md
123
138
  - docs/alternatives.md
124
139
  - docs/architecture.md
125
140
  - docs/basic_example.md
126
- - docs/configuration.md
141
+ - docs/clone_mapper.md
127
142
  - docs/customization.md
128
143
  - docs/exclude_association.md
129
- - docs/execution_order.md
130
144
  - docs/finalize.md
145
+ - docs/from_v02_to_v1.md
131
146
  - docs/implicit_cloner.md
132
147
  - docs/include_association.md
133
148
  - docs/init_as.md
134
149
  - docs/inline_configuration.md
135
150
  - docs/installation.md
136
151
  - docs/nullify.md
152
+ - docs/operation.md
153
+ - docs/overview.md
137
154
  - docs/parameters.md
138
155
  - docs/sequel.md
139
156
  - docs/supported_adapters.md
140
157
  - docs/testing.md
141
158
  - docs/traits.md
142
159
  - docs/web/.gitignore
160
+ - docs/web/README.md
143
161
  - docs/web/core/Footer.js
144
162
  - docs/web/i18n/en.json
145
163
  - docs/web/package.json
@@ -151,8 +169,6 @@ files:
151
169
  - docs/web/static/css/custom.css
152
170
  - docs/web/static/fonts/FiraCode-Medium.woff
153
171
  - docs/web/static/fonts/FiraCode-Regular.woff
154
- - docs/web/static/fonts/StemText.woff
155
- - docs/web/static/fonts/StemTextBold.woff
156
172
  - docs/web/static/img/favicon/favicon.ico
157
173
  - docs/web/yarn.lock
158
174
  - gemfiles/activerecord42.gemfile
@@ -160,7 +176,6 @@ files:
160
176
  - gemfiles/railsmaster.gemfile
161
177
  - lib/clowne.rb
162
178
  - lib/clowne/adapters/active_record.rb
163
- - lib/clowne/adapters/active_record/association.rb
164
179
  - lib/clowne/adapters/active_record/associations.rb
165
180
  - lib/clowne/adapters/active_record/associations/base.rb
166
181
  - lib/clowne/adapters/active_record/associations/has_and_belongs_to_many.rb
@@ -168,14 +183,11 @@ files:
168
183
  - lib/clowne/adapters/active_record/associations/has_one.rb
169
184
  - lib/clowne/adapters/active_record/associations/noop.rb
170
185
  - lib/clowne/adapters/active_record/dsl.rb
186
+ - lib/clowne/adapters/active_record/resolvers/association.rb
171
187
  - lib/clowne/adapters/base.rb
172
188
  - lib/clowne/adapters/base/association.rb
173
- - lib/clowne/adapters/base/finalize.rb
174
- - lib/clowne/adapters/base/init_as.rb
175
- - lib/clowne/adapters/base/nullify.rb
176
189
  - lib/clowne/adapters/registry.rb
177
190
  - lib/clowne/adapters/sequel.rb
178
- - lib/clowne/adapters/sequel/association.rb
179
191
  - lib/clowne/adapters/sequel/associations.rb
180
192
  - lib/clowne/adapters/sequel/associations/base.rb
181
193
  - lib/clowne/adapters/sequel/associations/many_to_many.rb
@@ -183,9 +195,14 @@ files:
183
195
  - lib/clowne/adapters/sequel/associations/one_to_many.rb
184
196
  - lib/clowne/adapters/sequel/associations/one_to_one.rb
185
197
  - lib/clowne/adapters/sequel/copier.rb
198
+ - lib/clowne/adapters/sequel/operation.rb
186
199
  - lib/clowne/adapters/sequel/record_wrapper.rb
200
+ - lib/clowne/adapters/sequel/resolvers/after_persist.rb
201
+ - lib/clowne/adapters/sequel/resolvers/association.rb
202
+ - lib/clowne/adapters/sequel/specifications/after_persist_does_not_support.rb
187
203
  - lib/clowne/cloner.rb
188
204
  - lib/clowne/declarations.rb
205
+ - lib/clowne/declarations/after_persist.rb
189
206
  - lib/clowne/declarations/base.rb
190
207
  - lib/clowne/declarations/exclude_association.rb
191
208
  - lib/clowne/declarations/finalize.rb
@@ -196,14 +213,23 @@ files:
196
213
  - lib/clowne/dsl.rb
197
214
  - lib/clowne/ext/lambda_as_proc.rb
198
215
  - lib/clowne/ext/orm_ext.rb
216
+ - lib/clowne/ext/record_key.rb
199
217
  - lib/clowne/ext/string_constantize.rb
200
- - lib/clowne/params.rb
201
- - lib/clowne/plan.rb
218
+ - lib/clowne/ext/yield_self_then.rb
202
219
  - lib/clowne/planner.rb
220
+ - lib/clowne/resolvers/after_persist.rb
221
+ - lib/clowne/resolvers/finalize.rb
222
+ - lib/clowne/resolvers/init_as.rb
223
+ - lib/clowne/resolvers/nullify.rb
203
224
  - lib/clowne/rspec.rb
204
225
  - lib/clowne/rspec/clone_association.rb
205
226
  - lib/clowne/rspec/clone_associations.rb
206
227
  - lib/clowne/rspec/helpers.rb
228
+ - lib/clowne/utils/clone_mapper.rb
229
+ - lib/clowne/utils/operation.rb
230
+ - lib/clowne/utils/options.rb
231
+ - lib/clowne/utils/params.rb
232
+ - lib/clowne/utils/plan.rb
207
233
  - lib/clowne/version.rb
208
234
  homepage: https://github.com/palkan/clowne
209
235
  licenses:
@@ -225,7 +251,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
251
  version: '0'
226
252
  requirements: []
227
253
  rubyforge_project:
228
- rubygems_version: 2.7.4
254
+ rubygems_version: 2.7.6
229
255
  signing_key:
230
256
  specification_version: 4
231
257
  summary: A flexible gem for cloning your models.
@@ -1,29 +0,0 @@
1
- ---
2
- id: configuration
3
- title: Configuration
4
- ---
5
-
6
- Basic cloner implementation looks like
7
-
8
- ```ruby
9
- class SomeCloner < Clowne::Cloner
10
- adapter :active_record # or adapter Clowne::ActiveRecord::Adapter
11
- # some implementation ...
12
- end
13
- ```
14
-
15
- But you can configure the default adapter for cloners:
16
-
17
- ```ruby
18
- # somewhere in initializers
19
- Clowne.default_adapter = :active_record
20
- ```
21
-
22
- and skip adapter declaration
23
-
24
- ```ruby
25
- class SomeCloner < Clowne::Cloner
26
- # some implementation ...
27
- end
28
- ```
29
- See the list of [available adapters](supported_adapters.md).
@@ -1,14 +0,0 @@
1
- ---
2
- id: execution_order
3
- title: Execution Order
4
- ---
5
-
6
- The order of cloning actions depends on the adapter (i.e., could be customized).
7
-
8
- All built-in adapters have the same order:
9
- - init clone (see [`init_as`](init_as.md))
10
- - clone associations
11
- - nullify attributes
12
- - run [`finalize`](finalize.md) blocks
13
-
14
- The order of [`finalize`](finalize.md) blocks is the order they've been written.
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Clowne
4
- module Adapters # :nodoc: all
5
- class ActiveRecord
6
- class UnknownAssociation < StandardError; end
7
-
8
- class Association
9
- class << self
10
- def call(source, record, declaration, params:, **_options)
11
- reflection = source.class.reflections[declaration.name.to_s]
12
-
13
- if reflection.nil?
14
- raise UnknownAssociation,
15
- "Association #{declaration.name} couldn't be found for #{source.class}"
16
- end
17
-
18
- cloner_class = Associations.cloner_for(reflection)
19
-
20
- cloner_class.new(reflection, source, declaration, params).call(record)
21
-
22
- record
23
- end
24
- end
25
- end
26
- end
27
- end
28
- end
29
-
30
- Clowne::Adapters::ActiveRecord.register_resolver(
31
- :association,
32
- Clowne::Adapters::ActiveRecord::Association,
33
- before: :nullify
34
- )
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Clowne
4
- module Adapters
5
- class Base
6
- module Finalize # :nodoc: all
7
- def self.call(source, record, declaration, params:, **_options)
8
- declaration.block.call(source, record, params)
9
- record
10
- end
11
- end
12
- end
13
- end
14
- end
15
-
16
- Clowne::Adapters::Base.register_resolver(
17
- :finalize, Clowne::Adapters::Base::Finalize,
18
- after: :nullify
19
- )
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Clowne
4
- module Adapters
5
- class Base
6
- module InitAs # :nodoc: all
7
- # rubocop: disable Metrics/ParameterLists
8
- def self.call(source, _record, declaration, params:, adapter:, **_options)
9
- adapter.init_record(declaration.block.call(source, **params))
10
- end
11
- # rubocop: enable Metrics/ParameterLists
12
- end
13
- end
14
- end
15
- end
16
-
17
- Clowne::Adapters::Base.register_resolver(
18
- :init_as,
19
- Clowne::Adapters::Base::InitAs,
20
- prepend: true
21
- )
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Clowne
4
- module Adapters
5
- class Base
6
- module Nullify # :nodoc: all
7
- def self.call(_source, record, declaration, **_options)
8
- declaration.attributes.each do |attr|
9
- record.__send__("#{attr}=", nil)
10
- end
11
-
12
- record
13
- end
14
- end
15
- end
16
- end
17
- end
18
-
19
- Clowne::Adapters::Base.register_resolver(:nullify, Clowne::Adapters::Base::Nullify)
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Clowne
4
- module Adapters # :nodoc: all
5
- class Sequel
6
- class Association
7
- class << self
8
- def call(source, record, declaration, params:, **_options)
9
- with_clonable(source, record, declaration) do
10
- reflection = source.class.association_reflections[declaration.name.to_sym]
11
-
12
- cloner_class = Associations.cloner_for(reflection)
13
-
14
- cloner_class.new(reflection, source, declaration, params).call(record)
15
-
16
- record
17
- end
18
- end
19
-
20
- private
21
-
22
- def with_clonable(source, record, declaration)
23
- if clonable_assoc?(source, declaration)
24
- yield(record)
25
- else
26
- warn <<-WARN
27
- Relation #{declaration.name} of #{source.class.name} does not configure for Sequel::Plugins::NestedAttributes
28
- WARN
29
- end
30
-
31
- record
32
- end
33
-
34
- def clonable_assoc?(source, declaration)
35
- source.class.plugins.include?(::Sequel::Plugins::NestedAttributes) &&
36
- source.respond_to?(:"#{declaration.name.to_s}_attributes=")
37
- end
38
- end
39
- end
40
- end
41
- end
42
- end
43
-
44
- Clowne::Adapters::Sequel.register_resolver(
45
- :association,
46
- Clowne::Adapters::Sequel::Association
47
- )
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'clowne/ext/lambda_as_proc'
4
-
5
- module Clowne
6
- class Params # :nodoc: all
7
- class BaseProxy
8
- attr_reader :value
9
-
10
- def initialize(value)
11
- @value = value
12
- end
13
-
14
- def permit(_params)
15
- raise NotImplementedError
16
- end
17
- end
18
-
19
- class PassProxy < BaseProxy
20
- def permit(params:, **)
21
- params
22
- end
23
- end
24
-
25
- class NullProxy < BaseProxy
26
- def permit(_params)
27
- {}
28
- end
29
- end
30
-
31
- class BlockProxy < BaseProxy
32
- using Clowne::Ext::LambdaAsProc
33
-
34
- def permit(params:, parent:)
35
- value.to_proc.call(params, parent)
36
- end
37
- end
38
-
39
- class KeyProxy < BaseProxy
40
- def permit(params:, **)
41
- nested_params = params.fetch(value)
42
- return nested_params if nested_params.is_a?(Hash)
43
-
44
- raise KeyError, "value by key '#{value}' must be a Hash"
45
- end
46
- end
47
-
48
- class << self
49
- def proxy(value)
50
- if value == true
51
- PassProxy
52
- elsif value.nil? || value == false
53
- NullProxy
54
- elsif value.is_a?(Proc)
55
- BlockProxy
56
- else
57
- KeyProxy
58
- end.new(value)
59
- end
60
- end
61
- end
62
- end