scripterator 1.2.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b2c3c2f5e186a3e9f766ac33a72903f835ae2f5e
4
- data.tar.gz: 196848f11699fc575a26708163e6271babb9a8bd
2
+ SHA256:
3
+ metadata.gz: e6b0a2c0390962d5310ff31c294faa74b5d74186c949ed04170c62f0506dc656
4
+ data.tar.gz: 123f12425a1ee3e941b5cdbdff78d8f7bdfcf49d968dc4c006ba21f240931856
5
5
  SHA512:
6
- metadata.gz: 8592a34342273e61e5f23999a5233f4e3ee3d22bc78bd60e3cb640a8ddecf048238b63f823e3ebb874454ad44c00266039e51a14f8c9ee2de6d1b9aab39453f6
7
- data.tar.gz: c31e9a4c791c1a18ccdb5245fed0b9d4ffa099c5731614e006b5a1c903d3b2acffa8371c16ef9af64b81e2e92715d85e8c9b4d8cb1c6ada7db0d7c92c6c6e2a4
6
+ metadata.gz: b90ca2a2ef31b7e112c96d3a9560a0d40f27feae22ccea6e79614387d5527a9f891c630467b66cf14dde73315f0b832d075b680efc3f99edb4709a91ac3baf08
7
+ data.tar.gz: 65f43d3eebeae7b0b5b64fe9e259ac61b6f43984eed5b976e76660ba3fa06d7b1ca567ce3f1b358aa60c305a5334820857ac645ebed52a10d065a2d890053947
data/.gitignore CHANGED
@@ -3,7 +3,7 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
- Gemfile.lock
6
+ Gemfile*.lock
7
7
  InstalledFiles
8
8
  _yardoc
9
9
  coverage
data/.travis.yml CHANGED
@@ -1,8 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - ruby-2.1.6
3
+ - 2.5.8
4
4
  script: bundle exec rspec
5
-
6
- env:
7
- - 'RAILS_VERSION=3.2'
8
- - 'RAILS_VERSION=4.0'
5
+ gemfile:
6
+ - Gemfile-rails-5.0.x
7
+ - Gemfile-rails-5.1.x
8
+ - Gemfile-rails-5.2.x
data/CHANGELOG.md CHANGED
@@ -1,2 +1,17 @@
1
+ # 1.4.0
2
+ - Update redis to 4+
3
+ - Update rspec
4
+ - Update fakeredis
5
+
6
+ # 1.3.2
7
+ - Rails 5 support
8
+
9
+ # 1.3.1
10
+ - Fix things from 1.3.0 that didn't work
11
+
12
+ # 1.3.0
13
+ - Add support for changing batch size
14
+ - Add support for `after_batch` and `before_batch` callbacks
15
+
1
16
  # 1.2.0
2
- Add support for ActiveRecord versions 3.0 through 4.2
17
+ - Add support for ActiveRecord versions 3.0 through 4.2
data/Gemfile CHANGED
@@ -1,6 +1,2 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in scripterator.gemspec
4
- gemspec
5
-
6
- gem 'activerecord', ENV['RAILS_VERSION'] || '~> 3.2'
1
+ ENV['BUNDLE_GEMFILE'] = File.expand_path('../Gemfile-rails-5.2.x', __FILE__)
2
+ Bundler.load
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'activerecord', '< 5.1'
6
+ gem 'sqlite3', '~> 1.3.0'
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'activerecord', '< 5.2'
6
+ gem 'sqlite3', '~> 1.4.0'
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'activerecord', '< 6.0'
6
+ gem 'sqlite3', '~> 1.4.0'
data/README.md CHANGED
@@ -32,10 +32,18 @@ Scripterator.run "Convert users from legacy auth data" do
32
32
  User.skip_some_callbacks_we_want_to_avoid_during_script_running
33
33
  end
34
34
 
35
+ before_batch do |batch|
36
+ # do stuff
37
+ end
38
+
35
39
  for_each_user do |user|
36
40
  user.do_legacy_conversion
37
41
  end
38
42
 
43
+ after_batch do |batch|
44
+ # do stuff
45
+ end
46
+
39
47
  after do
40
48
  # some code to run after everything's finished
41
49
  end
@@ -93,6 +101,7 @@ Environment variable options:
93
101
 
94
102
  - `START`: first model ID to scripterate
95
103
  - `END`: last model ID to scripterate
104
+ - `BATCH_SIZE`: how many records to process in a batch
96
105
  - `ID_LIST`: comma-delimited list of IDs to scripterate (e.g. "ID_LIST=1,99,440,23")
97
106
  - `REDIS_EXPIRATION`: amount of time (in seconds) before Redis result sets (checked IDs and failed IDs) are expired
98
107
 
data/lib/scripterator.rb CHANGED
@@ -18,6 +18,7 @@ module Scripterator
18
18
  options = {}.tap do |o|
19
19
  o[:start_id] = ENV['START'].try(:to_i)
20
20
  o[:end_id] = ENV['END'].try(:to_i)
21
+ o[:batch_size] = ENV['BATCH_SIZE'].try(:to_i)
21
22
  o[:id_list] = ENV['ID_LIST'].try(:split, ',')
22
23
  o[:redis_expiration] = ENV['REDIS_EXPIRATION'].try(:to_i) || config.redis_expiration
23
24
  end
@@ -23,6 +23,7 @@ module Scripterator
23
23
  @id_list = options[:id_list] || []
24
24
  @start_id = options[:start_id] || 1
25
25
  @end_id = options[:end_id]
26
+ @batch_size = options[:batch_size] || 1000
26
27
  @redis_expiration = options[:redis_expiration]
27
28
  @output_stream = options[:output_stream] || $stdout
28
29
 
@@ -34,7 +35,7 @@ module Scripterator
34
35
  output_stats
35
36
  end
36
37
 
37
- %w(model before per_record after).each do |callback|
38
+ %w(model before per_record after before_batch after_batch).each do |callback|
38
39
  define_method callback do |&block|
39
40
  instance_variable_set "@#{callback}", block
40
41
  end
@@ -102,20 +103,25 @@ module Scripterator
102
103
  end
103
104
 
104
105
  def run_loop
105
- if @id_list.count > 0
106
- run_for_id_list
107
- elsif @end_id
108
- @id_list = (@start_id..@end_id)
109
- run_for_id_list
106
+ @id_list = (@start_id..@end_id) if @end_id
107
+ relation = model_finder
108
+ opts = {
109
+ batch_size: @batch_size
110
+ }
111
+
112
+ if @id_list.count < 1
113
+ opts[:start] = @start_id
110
114
  else
111
- model_finder.find_each(start: @start_id) { |record| transform_one_record(record) }
115
+ relation = model_finder.where(id: @id_list)
112
116
  end
113
117
 
114
- expire_redis_sets
115
- end
118
+ relation.find_in_batches(opts) do |group|
119
+ self.instance_exec(group, &@before_batch) if @before_batch
120
+ group.each { |record| transform_one_record(record) }
121
+ self.instance_exec(group, &@after_batch) if @after_batch
122
+ end
116
123
 
117
- def run_for_id_list
118
- model_finder.where(id: @id_list).find_each { |record| transform_one_record(record) }
124
+ expire_redis_sets
119
125
  end
120
126
 
121
127
  def transform_one_record(record)
@@ -1,3 +1,3 @@
1
1
  module Scripterator
2
- VERSION = '1.2.0'
2
+ VERSION = '1.4.0'.freeze
3
3
  end
data/scripterator.gemspec CHANGED
@@ -15,10 +15,10 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Scripterator::VERSION
17
17
 
18
- gem.add_dependency 'activerecord', '< 5.0'
19
- gem.add_dependency 'redis', '~> 3.0'
18
+ gem.add_dependency 'activerecord', '< 6'
19
+ gem.add_dependency 'redis', '~> 4.0'
20
20
 
21
- gem.add_development_dependency 'fakeredis', '~> 0.4'
22
- gem.add_development_dependency 'rspec', '~> 2.13'
23
- gem.add_development_dependency 'sqlite3', '~> 1.3.8'
21
+ gem.add_development_dependency 'fakeredis', '~> 0.8.0'
22
+ gem.add_development_dependency 'rspec', '~> 3.0'
23
+ gem.add_development_dependency 'sqlite3'
24
24
  end
data/spec/runner_spec.rb CHANGED
@@ -10,6 +10,7 @@ describe Scripterator::Runner do
10
10
  Proc.new do
11
11
  before { Widget.before_stuff }
12
12
  for_each_widget { |widget| Widget.transform_a_widget(widget) }
13
+ after_batch { |batch| Widget.after_batch_stuff(batch) }
13
14
  end
14
15
  end
15
16
 
@@ -17,12 +18,12 @@ describe Scripterator::Runner do
17
18
 
18
19
  shared_examples_for 'raises an error' do
19
20
  specify do
20
- expect { subject }.to raise_error
21
+ expect { subject }.to raise_error(StandardError)
21
22
  end
22
23
  end
23
24
 
24
25
  it 'infers the model from the for_each block' do
25
- runner.send(:model_finder).should == Widget
26
+ expect(runner.send(:model_finder)).to eq Widget
26
27
  end
27
28
 
28
29
  context 'when a model block is defined' do
@@ -31,14 +32,15 @@ describe Scripterator::Runner do
31
32
  model { Widget.where(name: 'bla') }
32
33
  before { Widget.before_stuff }
33
34
  for_each_widget { |widget| Widget.transform_a_widget(widget) }
35
+ after_batch { |batch| Widget.after_batch_stuff(batch) }
34
36
  end
35
37
  end
36
38
  let!(:widget1) { Widget.create(name: 'foo') }
37
39
  let!(:widget2) { Widget.create(name: 'bla') }
38
40
 
39
41
  it 'uses the given model finder code' do
40
- Widget.should_receive(:transform_a_widget).once.with(widget2)
41
- Widget.should_not_receive(:transform_a_widget).with(widget1)
42
+ expect(Widget).to receive(:transform_a_widget).once.with(widget2)
43
+ expect(Widget).not_to receive(:transform_a_widget).with(widget1)
42
44
  subject
43
45
  end
44
46
  end
@@ -57,8 +59,8 @@ describe Scripterator::Runner do
57
59
 
58
60
  it 'transforms each widget in the list' do
59
61
  options[:id_list].each do |id|
60
- runner.should_receive(:transform_one_record) do |arg1|
61
- arg1.id.should == id
62
+ expect(runner).to receive(:transform_one_record) do |arg1|
63
+ expect(arg1.id).to eq id
62
64
  end
63
65
  end
64
66
  subject
@@ -76,14 +78,14 @@ describe Scripterator::Runner do
76
78
  it_behaves_like 'raises an error'
77
79
 
78
80
  it 'does not run any other given blocks' do
79
- Widget.should_not_receive :before_stuff
81
+ expect(Widget).to_not receive(:before_stuff)
80
82
  subject rescue nil
81
83
  end
82
84
  end
83
85
 
84
86
  context 'when there are no records for the specified model' do
85
87
  it 'does not run the per-record block' do
86
- Widget.should_not_receive :transform_a_widget
88
+ expect(Widget).to_not receive(:transform_a_widget)
87
89
  subject
88
90
  end
89
91
  end
@@ -94,8 +96,9 @@ describe Scripterator::Runner do
94
96
  before { num_widgets.times { Widget.create! } }
95
97
 
96
98
  it 'runs the given script blocks' do
97
- Widget.should_receive :before_stuff
98
- Widget.should_receive(:transform_a_widget).exactly(num_widgets).times
99
+ expect(Widget).to receive(:before_stuff)
100
+ expect(Widget).to receive(:transform_a_widget).exactly(num_widgets).times
101
+ expect(Widget).to receive(:after_batch_stuff)
99
102
  subject
100
103
  end
101
104
 
@@ -104,10 +107,10 @@ describe Scripterator::Runner do
104
107
 
105
108
  it 'marks only the checked IDs as checked' do
106
109
  subject
107
- Scripterator.already_run_for?(description, Widget.first.id).should be_false
108
- Scripterator.checked_ids(description).should_not include Widget.first.id
109
- Scripterator.already_run_for?(description, Widget.last.id).should be_true
110
- Scripterator.checked_ids(description).should include Widget.last.id
110
+ expect(Scripterator.already_run_for?(description, Widget.first.id)).to be_falsey
111
+ expect(Scripterator.checked_ids(description)).to_not include Widget.first.id
112
+ expect(Scripterator.already_run_for?(description, Widget.last.id)).to be_truthy
113
+ expect(Scripterator.checked_ids(description)).to include Widget.last.id
111
114
  end
112
115
  end
113
116
 
@@ -115,20 +118,20 @@ describe Scripterator::Runner do
115
118
  let(:checked_ids) { [Widget.first.id] }
116
119
 
117
120
  before do
118
- Scripterator.stub(checked_ids: checked_ids)
119
- Scripterator::ScriptRedis.any_instance.stub(already_run_for?: false)
120
- Scripterator::ScriptRedis.any_instance.stub(:already_run_for?).with(Widget.first.id).and_return(true)
121
+ allow(Scripterator).to receive(:checked_ids).and_return(checked_ids)
122
+ allow_any_instance_of(Scripterator::ScriptRedis).to receive(:already_run_for?).and_return(false)
123
+ allow_any_instance_of(Scripterator::ScriptRedis).to receive(:already_run_for?).with(Widget.first.id).and_return(true)
121
124
  end
122
125
 
123
126
  it 'only runs the per-record code for unchecked records' do
124
- Widget.should_receive(:transform_a_widget).exactly(num_widgets - 1).times
127
+ expect(Widget).to receive(:transform_a_widget).exactly(num_widgets - 1).times
125
128
  subject
126
129
  end
127
130
  end
128
131
 
129
132
  context 'when the code for some records fails' do
130
133
  before do
131
- Widget.stub :transform_a_widget do |widget|
134
+ allow(Widget).to receive(:transform_a_widget) do |widget|
132
135
  raise 'Last widget expl0de' if widget.id == Widget.last.id
133
136
  true
134
137
  end
@@ -136,8 +139,8 @@ describe Scripterator::Runner do
136
139
 
137
140
  it 'marks only the failed IDs as failed' do
138
141
  subject
139
- Scripterator.failed_ids(description).should_not include Widget.first.id
140
- Scripterator.failed_ids(description).should include Widget.last.id
142
+ expect(Scripterator.failed_ids(description)).to_not include Widget.first.id
143
+ expect(Scripterator.failed_ids(description)).to include Widget.last.id
141
144
  end
142
145
  end
143
146
 
@@ -147,7 +150,7 @@ describe Scripterator::Runner do
147
150
 
148
151
  it 'runs without Redis' do
149
152
  expect { subject }.not_to raise_error
150
- Scripterator.checked_ids(description).should be_empty
153
+ expect(Scripterator.checked_ids(description)).to be_empty
151
154
  end
152
155
  end
153
156
  end
@@ -10,5 +10,6 @@ end
10
10
  class Widget < ActiveRecord::Base
11
11
  # some dummy methods for setting message expectations in specs
12
12
  def self.before_stuff; end
13
+ def self.after_batch_stuff(batch); end
13
14
  def self.transform_a_widget(widget); true; end
14
15
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scripterator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ted Dumitrescu
8
8
  - Carl Furrow
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-02-25 00:00:00.000000000 Z
12
+ date: 2021-04-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -17,70 +17,70 @@ dependencies:
17
17
  requirements:
18
18
  - - "<"
19
19
  - !ruby/object:Gem::Version
20
- version: '5.0'
20
+ version: '6'
21
21
  type: :runtime
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: '5.0'
27
+ version: '6'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: redis
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: '3.0'
34
+ version: '4.0'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: '3.0'
41
+ version: '4.0'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: fakeredis
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '0.4'
48
+ version: 0.8.0
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '0.4'
55
+ version: 0.8.0
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: rspec
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '2.13'
62
+ version: '3.0'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: '2.13'
69
+ version: '3.0'
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: sqlite3
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
- - - "~>"
74
+ - - ">="
75
75
  - !ruby/object:Gem::Version
76
- version: 1.3.8
76
+ version: '0'
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: 1.3.8
83
+ version: '0'
84
84
  description: Script iterator for ActiveRecord models
85
85
  email:
86
86
  - ted@lumoslabs.com
@@ -94,6 +94,9 @@ files:
94
94
  - ".travis.yml"
95
95
  - CHANGELOG.md
96
96
  - Gemfile
97
+ - Gemfile-rails-5.0.x
98
+ - Gemfile-rails-5.1.x
99
+ - Gemfile-rails-5.2.x
97
100
  - LICENSE
98
101
  - README.md
99
102
  - lib/scripterator.rb
@@ -108,7 +111,7 @@ files:
108
111
  homepage: http://lumosity.com
109
112
  licenses: []
110
113
  metadata: {}
111
- post_install_message:
114
+ post_install_message:
112
115
  rdoc_options: []
113
116
  require_paths:
114
117
  - lib
@@ -123,13 +126,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
126
  - !ruby/object:Gem::Version
124
127
  version: '0'
125
128
  requirements: []
126
- rubyforge_project:
127
- rubygems_version: 2.2.3
128
- signing_key:
129
+ rubygems_version: 3.1.2
130
+ signing_key:
129
131
  specification_version: 4
130
132
  summary: DSL for running operations on each of a set of models
131
133
  test_files:
132
134
  - spec/runner_spec.rb
133
135
  - spec/spec_helper.rb
134
136
  - spec/support/widget.rb
135
- has_rdoc: