clone_kit 0.3.1 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0b0aec7c705b57c2f5f5edc6b66569c9932b4364
4
- data.tar.gz: 239c4c973df017ed083b8ac80d204328d5c0fd28
3
+ metadata.gz: 12c6dfb57705d29b62b6902c77408277f3757268
4
+ data.tar.gz: e8ddf096944716d6c980fb69f768f3b79e927c7b
5
5
  SHA512:
6
- metadata.gz: 3ca9701c9985621966beea58a720fae62622bd67774909c544d45255150212a2042dcbe9a545d4c3ddfeec329f37528741596e9cc794980b09875e027b7d9a91
7
- data.tar.gz: 3ad4157dcc181fb178c16a4ee7c475ee12925d183a636bcae67971fbc3242817b351ad51e6b2a85a714ce5a9fb526907a6ef455f68db8e683b3ccc84700b00db
6
+ metadata.gz: 2a6b30be94b2de7d397fc724abd2107cdc59cd4f8f7d337d6bbcb9d3b58c8f0e2ea9da2878b53dbe7e16d61255844469625f5c51d99a4d2960d6ec0336f2d7d5
7
+ data.tar.gz: cba1dced859dc1d9dd89751d99e7e4242beba9059a2ea4e7ecc35de343ffd88e4d8a5f1e53cf1bb5c0bac3df7ca348fa0aa857fecf841956faa7edb73eba7346
data/.gitignore CHANGED
@@ -1,2 +1,4 @@
1
1
  Gemfile.lock
2
2
  vendor/ruby
3
+ .pryrc
4
+ coverage
@@ -28,6 +28,8 @@ AllCops:
28
28
  TargetRubyVersion: 2.3
29
29
  Style/AndOr:
30
30
  EnforcedStyle: conditionals
31
+ Style/BracesAroundHashParameters:
32
+ EnforcedStyle: context_dependent
31
33
  Style/CaseIndentation:
32
34
  IndentOneStep: true
33
35
  Style/Documentation:
@@ -97,3 +99,6 @@ Lint/PercentStringArray:
97
99
  Exclude:
98
100
  # SecureHeaders needs the single quotes in `%w[https: 'self']`
99
101
  - config/initializers/secure_headers.rb
102
+ Style/SignalException:
103
+ Description: 'Checks for proper usage of fail and raise.' # the proper usage is 'raise'
104
+ Enabled: false
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require "bundler/setup"
4
5
  require "clone_kit"
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
- # coding: utf-8
3
- lib = File.expand_path("../lib", __FILE__)
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require "clone_kit/version"
6
6
 
@@ -22,16 +22,21 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r(^exe/)) { |f| File.basename(f) }
23
23
  spec.require_paths = ["lib"]
24
24
 
25
- spec.add_runtime_dependency "redis"
26
25
  spec.add_runtime_dependency "activesupport", "> 3.0.0" # For core ext Array#wrap and Object#blank?
26
+ spec.add_runtime_dependency "redis"
27
27
 
28
+ spec.add_development_dependency "activerecord", "~> 4.0"
28
29
  spec.add_development_dependency "bundler", "~> 1.13"
29
- spec.add_development_dependency "mongoid", "~> 4.0.2"
30
+ spec.add_development_dependency "combustion", "~> 0.7.0"
30
31
  spec.add_development_dependency "database_cleaner", "1.5.3"
32
+ spec.add_development_dependency "fakeredis"
33
+ spec.add_development_dependency "mongoid", "~> 4.0.2"
34
+ spec.add_development_dependency "pg", "~> 0.18.4"
35
+ spec.add_development_dependency "pry"
36
+ spec.add_development_dependency "pry-byebug"
31
37
  spec.add_development_dependency "rake", "~> 11.0"
32
- spec.add_development_dependency "rspec", "~> 3.4"
33
38
  spec.add_development_dependency "rspec-collection_matchers"
34
- spec.add_development_dependency "pry-byebug"
35
- spec.add_development_dependency "pry"
36
- spec.add_development_dependency "fakeredis"
39
+ spec.add_development_dependency "rspec-rails", "~> 3.4"
40
+ spec.add_development_dependency "rubocop"
41
+ spec.add_development_dependency "simplecov", "~> 0.12.0"
37
42
  end
@@ -3,6 +3,8 @@
3
3
  require "clone_kit/version"
4
4
  require "clone_kit/graph"
5
5
  require "clone_kit/specification"
6
+ require "clone_kit/mongo_specification"
7
+ require "clone_kit/active_record_specification"
6
8
  require "clone_kit/operation"
7
9
  require "clone_kit/shared_id_map"
8
10
  require "clone_kit/rule"
@@ -24,6 +26,10 @@ module CloneKit
24
26
  @spec ||= {}
25
27
  end
26
28
 
29
+ def self.reset_graph!
30
+ @graph = nil
31
+ end
32
+
27
33
  def self.add_specification(specification)
28
34
  spec[specification.model.name] = specification
29
35
  refresh_specification(specification)
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "clone_kit/specification"
4
+ require "clone_kit/id_generators/uuid"
5
+
6
+ module CloneKit
7
+ class ActiveRecordSpecification < Specification
8
+ protected
9
+
10
+ def validate!
11
+ fail SpecificationError, "Model type not supported" unless active_record_document?
12
+ end
13
+
14
+ def active_record_document?
15
+ defined?(ActiveRecord) && model < ActiveRecord::Base
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "clone_kit/cloners/active_record_ruleset_cloner"
4
+
5
+ module CloneKit
6
+ module Cloners
7
+ class ActiveRecordMergingRulesetCloner < ActiveRecordRulesetCloner
8
+ ID = "id"
9
+
10
+ def initialize(model_klass, rules: [], merge_fields: ["name"])
11
+ super(model_klass, rules: rules)
12
+ self.merge_fields = merge_fields
13
+ end
14
+
15
+ def clone_ids(ids, operation)
16
+ @saved_id_map = {}
17
+ initialize_cloner(operation)
18
+ apply_rules_and_save(find_and_merge_existing_records(ids))
19
+ end
20
+
21
+ protected
22
+
23
+ # These methods are super simple and should usually be overridden to merge records in a more nuanced fashion
24
+
25
+ def compare(first, second)
26
+ merge_fields.all? { |name| first[name] == second[name] }
27
+ end
28
+
29
+ def merge(records)
30
+ result = nil
31
+ records.each do |rec|
32
+ result = if result.nil?
33
+ rec.deep_dup
34
+ else
35
+ result.merge(rec)
36
+ end
37
+ end
38
+
39
+ result
40
+ end
41
+
42
+ private
43
+
44
+ attr_accessor :merge_fields
45
+
46
+ def find_and_merge_existing_records(ids, mergeable: Set.new, skip: skip = Set.new)
47
+ all_records = []
48
+ each_existing_record(ids) do |rec|
49
+ all_records << rec
50
+ end
51
+
52
+ result = []
53
+
54
+ all_records.each_with_index do |record, i|
55
+ next if skip.include?(record[ID])
56
+ mergeable << record
57
+
58
+ all_records[i + 1..all_records.length].each do |other_record|
59
+ next unless compare(record, other_record)
60
+
61
+ mergeable << other_record
62
+ skip << other_record[ID]
63
+ end
64
+
65
+ new_id = generate_new_id
66
+ new_record = if mergeable.length == 1
67
+ copy = clone(mergeable.first)
68
+ @saved_id_map[copy[ID]] = new_id
69
+ copy
70
+ else
71
+ merged = merge(mergeable)
72
+
73
+ mergeable.each do |m|
74
+ @saved_id_map[m[ID]] ||= new_id
75
+ end
76
+ merged
77
+ end
78
+
79
+ new_record[ID] = new_id
80
+
81
+ result << new_record
82
+ end
83
+
84
+ CloneKit::SharedIdMap
85
+ .new(current_operation.id)
86
+ .insert_many(model_klass, @saved_id_map)
87
+
88
+ result
89
+ end
90
+
91
+ def apply_rules_and_save(records)
92
+ records.each do |attributes|
93
+ id = attributes[ID]
94
+ rules.each do |rule|
95
+ begin
96
+ rule.fix(@saved_id_map.key(id), attributes)
97
+ rescue StandardError => e
98
+ id = attributes[ID]
99
+ message = "Unhandled error when applying rule #{rule.class.name} to #{model_klass} #{id}: #{e.class}"
100
+ current_operation.error(message)
101
+ end
102
+ end
103
+
104
+ save_or_fail(attributes)
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "clone_kit/decorators/embedded_cloner_decorator"
4
+
5
+ module CloneKit
6
+ module Cloners
7
+ class ActiveRecordRulesetCloner
8
+ attr_accessor :rules, :id_generator
9
+
10
+ def initialize(model_klass, rules: [], id_generator: IdGenerators::Uuid)
11
+ self.model_klass = model_klass
12
+ self.rules = rules
13
+ self.id_generator = id_generator
14
+ end
15
+
16
+ def clone_ids(ids, operation)
17
+ initialize_cloner(operation)
18
+
19
+ map = {}
20
+ result = []
21
+
22
+ each_existing_record(ids) do |attributes|
23
+ attributes = clone(attributes)
24
+ result << apply_rules_and_save(map, attributes)
25
+ end
26
+
27
+ CloneKit::SharedIdMap.new(operation.id).insert_many(model_klass, map)
28
+
29
+ result
30
+ end
31
+
32
+ protected
33
+
34
+ attr_accessor :model_klass,
35
+ :current_operation
36
+
37
+ def clone(attributes)
38
+ attributes.deep_dup
39
+ end
40
+
41
+ def apply_rules_and_save(mapping, attributes)
42
+ new_id = generate_new_id
43
+ old_id = attributes["id"]
44
+ mapping[old_id] = new_id
45
+ attributes["id"] = new_id
46
+
47
+ rules.each do |rule|
48
+ rule.id_generator = id_generator
49
+
50
+ begin
51
+ rule.fix(old_id, attributes)
52
+ rescue StandardError => e
53
+ message = "Unhandled error when applying rule #{rule.class.name} to #{model_klass} #{new_id}: #{e.class}"
54
+ current_operation.error(message)
55
+ end
56
+ end
57
+
58
+ save_or_fail(attributes)
59
+ attributes
60
+ end
61
+
62
+ def generate_new_id
63
+ id_generator.next
64
+ end
65
+
66
+ def save_or_fail(attributes)
67
+ document_klass = model_klass
68
+ model_that_we_wont_save = document_klass.new(attributes)
69
+ if model_that_we_wont_save.valid?
70
+ insert(model_that_we_wont_save)
71
+ else
72
+ details = model_that_we_wont_save.errors.full_messages.to_sentence
73
+ id = attributes["id"]
74
+ current_operation.error("#{model_klass} #{id} failed model validation and was not cloned: #{details}")
75
+ end
76
+ end
77
+
78
+ def insert(model)
79
+ insert_op = model.class.arel_table.create_insert.tap do |insert_mgr|
80
+ insert_mgr.insert(
81
+ model.send(:arel_attributes_with_values_for_create, model.attribute_names)
82
+ )
83
+ end
84
+
85
+ connection.execute(insert_op.to_sql)
86
+ end
87
+
88
+ def each_existing_record(ids)
89
+ ids.each do |id|
90
+ record = model_klass.find_by(model_klass.primary_key => id).attributes
91
+ next if record.nil?
92
+
93
+ yield record
94
+ end
95
+ end
96
+
97
+ def initialize_cloner(operation)
98
+ @current_operation = operation
99
+
100
+ rules.each do |rule|
101
+ rule.current_operation = @current_operation
102
+ end
103
+ end
104
+
105
+ def connection
106
+ ActiveRecord::Base.connection
107
+ end
108
+ end
109
+ end
110
+ end
@@ -62,7 +62,7 @@ module CloneKit
62
62
  skip << other_record["_id"]
63
63
  end
64
64
 
65
- new_id = BSON::ObjectId.new
65
+ new_id = generate_new_id
66
66
  new_record = if mergeable.length == 1
67
67
  copy = clone(mergeable[0])
68
68
  @saved_id_map[copy["_id"]] = new_id
@@ -6,13 +6,14 @@ require "clone_kit/decorators/embedded_cloner_decorator"
6
6
  module CloneKit
7
7
  module Cloners
8
8
  class MongoidRulesetCloner
9
- attr_accessor :rules
9
+ attr_accessor :rules, :id_generator
10
10
 
11
- def initialize(model_klass, rules: [])
11
+ def initialize(model_klass, rules: [], id_generator: CloneKit::IdGenerators::Bson)
12
12
  self.model_klass = model_klass
13
13
  self.rules = [
14
14
  CloneKit::Rules::AllowOnlyMongoidFields.new(model_klass)
15
15
  ] + rules
16
+ self.id_generator = id_generator
16
17
  end
17
18
 
18
19
  def clone_ids(ids, operation)
@@ -58,7 +59,7 @@ module CloneKit
58
59
 
59
60
  return empty_embedded(metadata) if first_item.nil?
60
61
 
61
- cloner = MongoidRulesetCloner.new(polymorphic_class(metadata.class_name, first_item))
62
+ cloner = MongoidRulesetCloner.new(polymorphic_class(metadata.class_name, first_item), id_generator: id_generator)
62
63
  embedded_cloner = CloneKit::Decorators::EmbeddedClonerDecorator.new(cloner, records: Array.wrap(item))
63
64
 
64
65
  embedded_attributes = embedded_cloner.clone_embedded(current_operation)
@@ -75,12 +76,14 @@ module CloneKit
75
76
  end
76
77
 
77
78
  def apply_rules_and_save(mapping, attributes)
78
- new_id = BSON::ObjectId.new
79
+ new_id = generate_new_id
79
80
  old_id = attributes["_id"]
80
81
  mapping[attributes["_id"]] = new_id
81
82
  attributes["_id"] = new_id
82
83
 
83
84
  rules.each do |rule|
85
+ rule.id_generator = id_generator
86
+
84
87
  begin
85
88
  rule.fix(old_id, attributes)
86
89
  rescue StandardError => e
@@ -93,6 +96,10 @@ module CloneKit
93
96
  attributes
94
97
  end
95
98
 
99
+ def generate_new_id
100
+ id_generator.next
101
+ end
102
+
96
103
  def save_or_fail(attributes)
97
104
  document_klass = model_klass
98
105
  document_klass = attributes["_type"].constantize if attributes.key?("_type")
@@ -3,6 +3,8 @@
3
3
  module CloneKit
4
4
  module Cloners
5
5
  class NoOp
6
+ attr_writer :id_generator
7
+
6
8
  def clone_ids(_ids, _operation)
7
9
  # NO_OP
8
10
  end
@@ -26,7 +26,7 @@ module CloneKit
26
26
  end
27
27
 
28
28
  def tsort_each_child(node, &block)
29
- @vertices[node].each(&block)
29
+ @vertices[node]&.each(&block)
30
30
  end
31
31
 
32
32
  def add_vertex(vertex, *neighbors)
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CloneKit
4
+ module IdGenerators
5
+ module Bson
6
+ def self.next
7
+ BSON::ObjectId.new
8
+ end
9
+
10
+ def self.from_string(val)
11
+ BSON::ObjectId.from_string(val)
12
+ rescue BSON::ObjectId::Invalid => error
13
+ raise InvalidId, error
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CloneKit
4
+ module IdGenerators
5
+ class InvalidId < StandardError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CloneKit
4
+ module IdGenerators
5
+ module Uuid
6
+ def self.next
7
+ SecureRandom.uuid
8
+ end
9
+
10
+ def self.from_string(val)
11
+ val
12
+ end
13
+ end
14
+ end
15
+ end
@@ -72,7 +72,7 @@ module CloneKit
72
72
  attributes.each do |att|
73
73
  mergeable.reverse_each do |m|
74
74
  val = m[att]
75
- unless val.blank?
75
+ if val.present?
76
76
  target[att] = val
77
77
  break
78
78
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "clone_kit/specification"
4
+ require "clone_kit/id_generators/bson"
5
+
6
+ module CloneKit
7
+ class MongoSpecification < Specification
8
+ protected
9
+
10
+ def validate!
11
+ fail SpecificationError, "Model type not supported" unless mongoid_document?
12
+ fail SpecificationError, "Cannot clone embedded documents" if mongoid_embedded_document?
13
+ end
14
+
15
+ def mongoid_document?
16
+ defined?(Mongoid) && model < Mongoid::Document
17
+ end
18
+
19
+ def mongoid_embedded_document?
20
+ mongoid_document? && model.embedded?
21
+ end
22
+ end
23
+ end
@@ -2,6 +2,12 @@
2
2
 
3
3
  module CloneKit
4
4
  class Rule
5
+ attr_accessor :id_generator
6
+
7
+ def initialize(id_generator: nil)
8
+ @id_generator = id_generator
9
+ end
10
+
5
11
  def current_operation=(operation)
6
12
  @shared_id_map = nil
7
13
  @current_operation = operation
@@ -3,7 +3,8 @@
3
3
  module CloneKit
4
4
  module Rules
5
5
  class Remap < CloneKit::Rule
6
- def initialize(model_name, remap_hash = {})
6
+ def initialize(model_name, remap_hash = {}, id_generator: nil)
7
+ super(id_generator: id_generator)
7
8
  self.remap_hash = remap_hash
8
9
  self.model_name = model_name
9
10
  end
@@ -14,7 +15,7 @@ module CloneKit
14
15
  next unless try?(attributes, att)
15
16
 
16
17
  attributes[att] = if attributes[att].is_a?(Array)
17
- attributes[att].map { |id| remap(klass, id) unless id.blank? }.compact
18
+ attributes[att].map { |id| remap(klass, id) if id.present? }.compact
18
19
  else
19
20
  remap(klass, attributes[att])
20
21
  end
@@ -25,14 +26,14 @@ module CloneKit
25
26
  protected
26
27
 
27
28
  def remap(klass, old_id)
28
- shared_id_map.lookup(klass, old_id)
29
+ shared_id_map.lookup(klass, old_id, id_generator: id_generator)
29
30
  rescue ArgumentError
30
31
  error_event("#{model_name} missing remapped id for #{klass} #{old_id}")
31
32
  nil
32
33
  end
33
34
 
34
35
  def try?(attributes, key)
35
- attributes.key?(key) && !attributes[key].blank?
36
+ attributes.key?(key) && attributes[key].present?
36
37
  end
37
38
 
38
39
  private
@@ -5,15 +5,16 @@ require "clone_kit/rules/remap"
5
5
  module CloneKit
6
6
  module Rules
7
7
  class SafeRemap < Remap
8
- def initialize(model_name, remap_hash = {}, safe_value = nil)
8
+ def initialize(model_name, remap_hash = {}, safe_value = nil, id_generator: nil)
9
+ super(model_name, remap_hash, id_generator: id_generator)
9
10
  self.safe_value = safe_value
10
- super(model_name, remap_hash)
11
11
  end
12
12
 
13
13
  protected
14
14
 
15
15
  def remap(klass, old_id)
16
- result = shared_id_map.lookup_safe(klass, old_id, safe_value)
16
+ result = shared_id_map
17
+ .lookup_safe(klass, old_id, safe_value, id_generator: id_generator)
17
18
  warn_event("#{model_name} missing remapped id for #{klass}/#{old_id}") if result == safe_value
18
19
  result
19
20
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "redis"
4
+ require "clone_kit/id_generators/invalid_id"
4
5
 
5
6
  module CloneKit
6
7
  class SharedIdMap
@@ -11,18 +12,18 @@ module CloneKit
11
12
  self.redis = redis
12
13
  end
13
14
 
14
- def lookup(klass, original_id)
15
- BSON::ObjectId.from_string(redis.hget(hash_key(klass), original_id.to_s))
16
- rescue BSON::ObjectId::Invalid
15
+ def lookup(klass, original_id, id_generator: IdGenerators::Bson)
16
+ id_generator.from_string(redis.hget(hash_key(klass), original_id.to_s))
17
+ rescue IdGenerators::InvalidId
17
18
  raise ArgumentError, "No mapping found for #{klass}. This usually indicates a dependency has not be specified"
18
19
  end
19
20
 
20
- def lookup_safe(klass, original_id, default = nil)
21
+ def lookup_safe(klass, original_id, default = nil, id_generator: IdGenerators::Bson)
21
22
  val = redis.hget(hash_key(klass), original_id.to_s)
22
23
  if val.blank?
23
24
  default
24
25
  else
25
- BSON::ObjectId.from_string(val)
26
+ id_generator.from_string(val)
26
27
  end
27
28
  end
28
29
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "clone_kit/emitters/empty"
4
4
  require "clone_kit/cloners/no_op"
5
+ require "clone_kit/id_generators/uuid"
5
6
 
6
7
  module CloneKit
7
8
  class SpecificationError < StandardError; end
@@ -21,12 +22,13 @@ module CloneKit
21
22
  self.emitter = EMPTY_EMITTER
22
23
  self.cloner = NO_OP_CLONER
23
24
  self.dependencies = []
24
- self.after_operation_block = -> (_op) {}
25
+ self.after_operation_block = ->(_op) {}
26
+
27
+ configure
25
28
 
26
29
  validate!
27
30
 
28
31
  model.instance_exec(self, &block)
29
-
30
32
  CloneKit.add_specification(self)
31
33
  end
32
34
 
@@ -34,19 +36,10 @@ module CloneKit
34
36
  self.after_operation_block = block
35
37
  end
36
38
 
37
- private
38
-
39
- def validate!
40
- fail SpecificationError, "Model type not supported" unless mongoid_document?
41
- fail SpecificationError, "Cannot clone embedded documents" if mongoid_embedded_document?
42
- end
39
+ protected
43
40
 
44
- def mongoid_document?
45
- defined?(Mongoid) && model < Mongoid::Document
46
- end
41
+ def configure; end
47
42
 
48
- def mongoid_embedded_document?
49
- mongoid_document? && model.embedded?
50
- end
43
+ def validate!; end
51
44
  end
52
45
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CloneKit
4
- VERSION = "0.3.1"
4
+ VERSION = "0.4.0"
5
5
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clone_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Croft
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-04-26 00:00:00.000000000 Z
11
+ date: 2018-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: 3.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">"
25
+ - !ruby/object:Gem::Version
26
+ version: 3.0.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: redis
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -25,19 +39,19 @@ dependencies:
25
39
  - !ruby/object:Gem::Version
26
40
  version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
- name: activesupport
42
+ name: activerecord
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - ">"
45
+ - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: 3.0.0
34
- type: :runtime
47
+ version: '4.0'
48
+ type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - ">"
52
+ - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: 3.0.0
54
+ version: '4.0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -53,19 +67,19 @@ dependencies:
53
67
  - !ruby/object:Gem::Version
54
68
  version: '1.13'
55
69
  - !ruby/object:Gem::Dependency
56
- name: mongoid
70
+ name: combustion
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: 4.0.2
75
+ version: 0.7.0
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: 4.0.2
82
+ version: 0.7.0
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: database_cleaner
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -81,35 +95,49 @@ dependencies:
81
95
  - !ruby/object:Gem::Version
82
96
  version: 1.5.3
83
97
  - !ruby/object:Gem::Dependency
84
- name: rake
98
+ name: fakeredis
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: mongoid
85
113
  requirement: !ruby/object:Gem::Requirement
86
114
  requirements:
87
115
  - - "~>"
88
116
  - !ruby/object:Gem::Version
89
- version: '11.0'
117
+ version: 4.0.2
90
118
  type: :development
91
119
  prerelease: false
92
120
  version_requirements: !ruby/object:Gem::Requirement
93
121
  requirements:
94
122
  - - "~>"
95
123
  - !ruby/object:Gem::Version
96
- version: '11.0'
124
+ version: 4.0.2
97
125
  - !ruby/object:Gem::Dependency
98
- name: rspec
126
+ name: pg
99
127
  requirement: !ruby/object:Gem::Requirement
100
128
  requirements:
101
129
  - - "~>"
102
130
  - !ruby/object:Gem::Version
103
- version: '3.4'
131
+ version: 0.18.4
104
132
  type: :development
105
133
  prerelease: false
106
134
  version_requirements: !ruby/object:Gem::Requirement
107
135
  requirements:
108
136
  - - "~>"
109
137
  - !ruby/object:Gem::Version
110
- version: '3.4'
138
+ version: 0.18.4
111
139
  - !ruby/object:Gem::Dependency
112
- name: rspec-collection_matchers
140
+ name: pry
113
141
  requirement: !ruby/object:Gem::Requirement
114
142
  requirements:
115
143
  - - ">="
@@ -137,7 +165,21 @@ dependencies:
137
165
  - !ruby/object:Gem::Version
138
166
  version: '0'
139
167
  - !ruby/object:Gem::Dependency
140
- name: pry
168
+ name: rake
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '11.0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '11.0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: rspec-collection_matchers
141
183
  requirement: !ruby/object:Gem::Requirement
142
184
  requirements:
143
185
  - - ">="
@@ -151,7 +193,21 @@ dependencies:
151
193
  - !ruby/object:Gem::Version
152
194
  version: '0'
153
195
  - !ruby/object:Gem::Dependency
154
- name: fakeredis
196
+ name: rspec-rails
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '3.4'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '3.4'
209
+ - !ruby/object:Gem::Dependency
210
+ name: rubocop
155
211
  requirement: !ruby/object:Gem::Requirement
156
212
  requirements:
157
213
  - - ">="
@@ -164,6 +220,20 @@ dependencies:
164
220
  - - ">="
165
221
  - !ruby/object:Gem::Version
166
222
  version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: simplecov
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: 0.12.0
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: 0.12.0
167
237
  description: Supports rules-based cloning, Mongoid, and distributed operations
168
238
  email:
169
239
  - brandon@kapost.com
@@ -183,6 +253,9 @@ files:
183
253
  - bin/setup
184
254
  - clone_kit.gemspec
185
255
  - lib/clone_kit.rb
256
+ - lib/clone_kit/active_record_specification.rb
257
+ - lib/clone_kit/cloners/active_record_merging_ruleset_cloner.rb
258
+ - lib/clone_kit/cloners/active_record_ruleset_cloner.rb
186
259
  - lib/clone_kit/cloners/mongoid_merging_ruleset_cloner.rb
187
260
  - lib/clone_kit/cloners/mongoid_ruleset_cloner.rb
188
261
  - lib/clone_kit/cloners/no_op.rb
@@ -190,7 +263,11 @@ files:
190
263
  - lib/clone_kit/emitters/empty.rb
191
264
  - lib/clone_kit/event_outlet.rb
192
265
  - lib/clone_kit/graph.rb
266
+ - lib/clone_kit/id_generators/bson.rb
267
+ - lib/clone_kit/id_generators/invalid_id.rb
268
+ - lib/clone_kit/id_generators/uuid.rb
193
269
  - lib/clone_kit/merge_attributes_tool.rb
270
+ - lib/clone_kit/mongo_specification.rb
194
271
  - lib/clone_kit/operation.rb
195
272
  - lib/clone_kit/rule.rb
196
273
  - lib/clone_kit/rules/allow_only_mongoid_fields.rb