schlepper 0.8.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 +7 -0
- data/.codeclimate.yml +3 -0
- data/.gitignore +9 -0
- data/.travis.yml +10 -0
- data/Gemfile +4 -0
- data/README.md +124 -0
- data/Rakefile +28 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/generators/schlepper/USAGE +8 -0
- data/lib/generators/schlepper/task_generator.rb +14 -0
- data/lib/generators/schlepper/templates/onetime_script.rb.erb +27 -0
- data/lib/schlepper.rb +10 -0
- data/lib/schlepper/abstract_method_helper.rb +97 -0
- data/lib/schlepper/process.rb +102 -0
- data/lib/schlepper/railtie.rb +9 -0
- data/lib/schlepper/task.rb +46 -0
- data/lib/schlepper/version.rb +3 -0
- data/lib/tasks/schlepper.rake +6 -0
- data/schlepper.gemspec +38 -0
- metadata +175 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 016dfc80524ce816117be4a59df49b79fee2a0db
|
4
|
+
data.tar.gz: ed4cf319356ef633959784efb926b883114a8747
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ad3fd1c25b0dbcfa93a20a32cc82e7d9dc81cf97f8ac116744f9a11a2b52c01d26f0505aff0bb47b67221e49da9b56f45eb8f38307e5c3864a6a01f5e1210c56
|
7
|
+
data.tar.gz: 5c5f2a1eed5ec112caf730cd258ef1ddd8bfee0e5c36d249666bfab8e8655c52b1ca0ab61774ed0214787b8d794e5b8f6438809d932d8421d2715ee29d4b689d
|
data/.codeclimate.yml
ADDED
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# Schlepper
|
2
|
+
[](https://codeclimate.com/repos/57cf60bd8ffd8f13f100096b/feed)
|
3
|
+
[](https://codeclimate.com/repos/57cf60bd8ffd8f13f100096b/coverage)
|
4
|
+
[](https://travis-ci.org/ConsultingMD/schlepper)
|
5
|
+
|
6
|
+
_Schlepper: a person who carries, a task runner_
|
7
|
+
|
8
|
+
A gem for running and keeping track of one time tasks in a Rails application. Tasks
|
9
|
+
are versioned and tracked much like Rails migrations.
|
10
|
+
|
11
|
+
The purpose of Schlepper is to provide an alternative to onetime data tasks inside migrations, while
|
12
|
+
offering the conventions, convenience and tracking like Rails migrations.
|
13
|
+
|
14
|
+
## Requirements
|
15
|
+
|
16
|
+
Rails 3.2+
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
Add this line to your application's Gemfile:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
gem 'schlepper'
|
24
|
+
```
|
25
|
+
|
26
|
+
And then execute:
|
27
|
+
|
28
|
+
$ bundle
|
29
|
+
|
30
|
+
Or install it yourself as:
|
31
|
+
|
32
|
+
$ gem install schlepper
|
33
|
+
|
34
|
+
## Usage
|
35
|
+
|
36
|
+
Schlepper comes with a generator for creating a new task, and a Rake task that will
|
37
|
+
run any pending onetime tasks.
|
38
|
+
|
39
|
+
To create a new onetime task, run `rails generate schlepper:task name_of_task`; where name\_of\_task
|
40
|
+
follows the same pattern as the Rails' migration generator. Here, a new file is created in `script/schleppers`
|
41
|
+
that looks like `numerictimestamp_name_of_task.rb`. These also follow the same pattern as Rails' migrations.
|
42
|
+
|
43
|
+
Edit the file that was generated and you see a class has been created with some methods for you to
|
44
|
+
override:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
class NameOfTask < Schlepper::Task
|
48
|
+
attr_reader :failure_message
|
49
|
+
|
50
|
+
# @return [String] A short note on what the purpose of this task is
|
51
|
+
def description
|
52
|
+
<<-DOC.strip_heredoc
|
53
|
+
Add your documentation here.
|
54
|
+
DOC
|
55
|
+
fail NotImplementedError, "Documentation has not been added for #{self.class.name}"
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [String] The individuals that are responsible for this task
|
59
|
+
def owner
|
60
|
+
"John Bjön"
|
61
|
+
fail NotImplementedError, "Ownership has not been claimed for #{self.class.name}"
|
62
|
+
end
|
63
|
+
|
64
|
+
# This is the entry point for your task. The full Rails stack is available.
|
65
|
+
# Return true if it was successful, false if not. If not successful,
|
66
|
+
# set @failure_message to something meaningful. Tasks that return false
|
67
|
+
# will not be marked as run and will be continue to be run in subsequent
|
68
|
+
# batch runs
|
69
|
+
# @return [Bool] Success or failure
|
70
|
+
def run
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
These methods are self-explanatory. The generator places a failure inside the required methods to ensure that
|
77
|
+
there is nothing overlooked. The `owner` and `description` methods are utilized in the task running
|
78
|
+
process to insert that information into the database.
|
79
|
+
|
80
|
+
The entry point for the task is in the `run` method. Take special note of the meaning of the return value
|
81
|
+
of the `run` method. You must return a literal `true` to signal to the task runner that this task
|
82
|
+
has completed successfully. Any return value other than `true` will signal to the task runner
|
83
|
+
that this task has not completed successfully, and will not be marked as successful.
|
84
|
+
|
85
|
+
Also take note of the instance variable `@failure_message`. Setting this to something
|
86
|
+
descriptive if your task fails provides meaningful output to the person running the task.
|
87
|
+
|
88
|
+
Use `rake schlepper:run` to start the task running process. The task running procedure is as follows:
|
89
|
+
|
90
|
+
- Load the Rails app, the `schlepper:run` task inherits from `environment`
|
91
|
+
- Create the schlepper\_tasks table if it does not exist
|
92
|
+
- Select all of the version numbers from the schlepper\_tasks table
|
93
|
+
- Load all task files that have not yet been run
|
94
|
+
- For each task file
|
95
|
+
- Begin a database transaction
|
96
|
+
- Create a new instance of the Task class defined in the file
|
97
|
+
- Execute the `run` method of that class
|
98
|
+
- If the return value of `run` is true
|
99
|
+
- Commit the transaction
|
100
|
+
- Insert into the schlepper\_tasks table the owner, description, and
|
101
|
+
verison of the tasks
|
102
|
+
- Otherwise
|
103
|
+
- Roll back transaction
|
104
|
+
- Display the name of the owner, and @failure\_message if provided
|
105
|
+
|
106
|
+
## Development
|
107
|
+
|
108
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
109
|
+
|
110
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
111
|
+
|
112
|
+
## Contributing
|
113
|
+
|
114
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ConsultingMD/schlepper.
|
115
|
+
|
116
|
+
## License
|
117
|
+
|
118
|
+
Schlepper is released under the [MIT License](https://opensource.org/licenses/MIT).
|
119
|
+
|
120
|
+
## TODO
|
121
|
+
|
122
|
+
Implement saving the change registry by providing some back-ends.
|
123
|
+
|
124
|
+
Implement rolling back a task
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
|
+
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << "test"
|
6
|
+
t.libs << "lib"
|
7
|
+
t.test_files = FileList['test/**/*_test.rb']
|
8
|
+
end
|
9
|
+
|
10
|
+
desc 'Opens a interactive session with this library already loaded'
|
11
|
+
task :console do
|
12
|
+
require 'schlepper'
|
13
|
+
|
14
|
+
begin
|
15
|
+
require 'pry'
|
16
|
+
rescue
|
17
|
+
require 'irb'
|
18
|
+
end
|
19
|
+
|
20
|
+
if defined? Pry
|
21
|
+
Pry.start
|
22
|
+
else
|
23
|
+
ARGV.clear
|
24
|
+
IRB.start
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
task default: :test
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "schlepper"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module Schlepper
|
2
|
+
class TaskGenerator < Rails::Generators::NamedBase
|
3
|
+
source_root File.expand_path('../templates', __FILE__)
|
4
|
+
|
5
|
+
def onetime_script
|
6
|
+
@now = Time.now
|
7
|
+
template 'onetime_script.rb.erb', "script/schleppers/#{stringified_timestamp}_#{file_name}.rb"
|
8
|
+
end
|
9
|
+
|
10
|
+
def stringified_timestamp
|
11
|
+
@now.strftime '%Y%m%d%H%M%S'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class <%= file_name.classify %> < Schlepper::Task
|
2
|
+
attr_reader :failure_message
|
3
|
+
|
4
|
+
# @return [String] A short note on what the purpose of this task is
|
5
|
+
def description
|
6
|
+
<<-DOC.strip_heredoc
|
7
|
+
Add your documentation here.
|
8
|
+
DOC
|
9
|
+
fail NotImplementedError, "Documentation has not been added for #{self.class.name}"
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [String] The individuals that owns this task
|
13
|
+
def owner
|
14
|
+
"John Bjön"
|
15
|
+
fail NotImplementedError, "Ownership has not been claimed for #{self.class.name}"
|
16
|
+
end
|
17
|
+
|
18
|
+
# This is the entry point for your script. The full Rails stack is available.
|
19
|
+
# Return true if it was successful, false if not. If not successful,
|
20
|
+
# set @failure_message to something meaningful. Tasks that return false
|
21
|
+
# will not be marked as run and will be continue to be run in subsequent
|
22
|
+
# batch runs
|
23
|
+
# @return [Bool] Success or failure
|
24
|
+
def run
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
data/lib/schlepper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
module Schlepper
|
2
|
+
if defined? Rails::Railtie
|
3
|
+
require_relative './schlepper/railtie'
|
4
|
+
end
|
5
|
+
|
6
|
+
autoload :VERSION, 'schlepper/version'
|
7
|
+
autoload :Process, 'schlepper/process'
|
8
|
+
autoload :Task, 'schlepper/task'
|
9
|
+
autoload :AbstractMethodHelper, 'schlepper/abstract_method_helper'
|
10
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Schlepper
|
2
|
+
module AbstractMethodHelper
|
3
|
+
def self.included(base)
|
4
|
+
base.instance_variable_set :@__abstract_methods__, {}
|
5
|
+
base.send :extend, Schlepper::AbstractMethodHelper::ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
# @param [Symbol, String] method_name
|
9
|
+
# @return [Bool]
|
10
|
+
def abstract_method? method_name
|
11
|
+
self.class.__abstract_methods__.fetch method_name.to_sym, false
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
# @private
|
16
|
+
def __abstract_methods__
|
17
|
+
@__abstract_methods__
|
18
|
+
end
|
19
|
+
|
20
|
+
# We want a subclass to know what is abstract or not
|
21
|
+
# We DO NOT want to use a class variable as they are shared from
|
22
|
+
# all subclasses of the base class.
|
23
|
+
# @private
|
24
|
+
def inherited subclass
|
25
|
+
super
|
26
|
+
subclass.instance_variable_set :@__abstract_methods__, @__abstract_methods__.dup
|
27
|
+
end
|
28
|
+
|
29
|
+
# Marks a method as 'abstract'. That is, it is not intended to be used
|
30
|
+
# without overriding and implementing. Essentially re-defines the method
|
31
|
+
# to throw a NotImplementedError if called directly or
|
32
|
+
# when subclassed and not overridden.
|
33
|
+
# @param [String, Symbol] Name of method to mark as abstract
|
34
|
+
# @return [Symbol] Name of method
|
35
|
+
def abstract method_name
|
36
|
+
# this implementation is a little long on purpose to encapsulate
|
37
|
+
# all of the logic into one method. we do not want to pollute the destination
|
38
|
+
# class, so no extraction techniques are available
|
39
|
+
method_name = method_name.to_sym
|
40
|
+
@__abstract_methods__.store method_name, true
|
41
|
+
|
42
|
+
instance_eval do
|
43
|
+
# undefine any existing method to prevent warnings
|
44
|
+
undef_method method_name if method_defined? method_name
|
45
|
+
|
46
|
+
define_method method_name do
|
47
|
+
# check to see if the method we are calling is directly on the class
|
48
|
+
# that implements the abstract method
|
49
|
+
#
|
50
|
+
# that is, if A#override_me is implemented as abstract, we want to notify the
|
51
|
+
# callee that this method is abstract and can not be called directly
|
52
|
+
# otherwise, we want to notify the callee that the subclass
|
53
|
+
# needs to implement the abstract method before calling it
|
54
|
+
#
|
55
|
+
# that is, if B subclasses A and A implements override_me
|
56
|
+
# as abstract, then B#override_me should notify the callee that
|
57
|
+
# #override_me is declared abstract on A and needs to be overridden
|
58
|
+
# on B
|
59
|
+
failure_message = (
|
60
|
+
if self.class.instance_method(__method__).owner == self.class
|
61
|
+
<<-MESSAGE
|
62
|
+
The method #{method_name} is designated as abstract on #{self.class.name}.
|
63
|
+
You must subclass #{self.class.name} and override this method yourself.
|
64
|
+
MESSAGE
|
65
|
+
else
|
66
|
+
# now we want the inheritance chain without any inherited modules, and without
|
67
|
+
# Object and BasicObject. the returned array looks like [self, D, C, B, A]
|
68
|
+
# we want to notify the callee exactly where the method was declared abstract
|
69
|
+
# in the chain
|
70
|
+
parent_abstract_class = (self.class.ancestors - self.class.included_modules)[1..-3].
|
71
|
+
find { |klass| klass.method_defined? method_name }
|
72
|
+
<<-MESSAGE
|
73
|
+
The class #{self.class.name} does not implement the abstract method #{method_name}, which
|
74
|
+
is declared as abstract on #{parent_abstract_class.name}.
|
75
|
+
MESSAGE
|
76
|
+
end
|
77
|
+
)
|
78
|
+
fail NotImplementedError, failure_message
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
method_name
|
83
|
+
end
|
84
|
+
|
85
|
+
# @private
|
86
|
+
def method_added method_name
|
87
|
+
# figure out if we are adding a new method from `define_method` above
|
88
|
+
# we don't want to mark this is not abstract when overriding the
|
89
|
+
# defined method with an abstract definition
|
90
|
+
return if caller.grep(/#{__FILE__}/).grep(/define_method/).any?
|
91
|
+
if @__abstract_methods__.key?(method_name)
|
92
|
+
@__abstract_methods__.store method_name, false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
module Schlepper
|
5
|
+
class Process
|
6
|
+
def run_all
|
7
|
+
create_table_if_necessary
|
8
|
+
fetch_script_numbers_from_database
|
9
|
+
load_tasks_that_need_run
|
10
|
+
|
11
|
+
puts "#{Schlepper::Task.children.count} tasks to process"
|
12
|
+
puts '~~~~~~~~~~~~~~~~~~~~~'
|
13
|
+
|
14
|
+
Schlepper::Task.children.each { |klass| process_one klass }
|
15
|
+
rescue => e
|
16
|
+
offending_file = e.send(:caller_locations).first.path.split("/").last
|
17
|
+
puts "#{offending_file} caused an error: "
|
18
|
+
raise e
|
19
|
+
end
|
20
|
+
|
21
|
+
private def create_table_if_necessary
|
22
|
+
# table_exists? changes behavior in Rails 5.1
|
23
|
+
finder_method = if ActiveRecord::VERSION::MAJOR >= 5
|
24
|
+
:data_source_exists?
|
25
|
+
else
|
26
|
+
:table_exists?
|
27
|
+
end
|
28
|
+
create_script_table unless ActiveRecord::Base.connection.send(finder_method, 'schlepper_tasks')
|
29
|
+
end
|
30
|
+
|
31
|
+
private def create_script_table
|
32
|
+
migrator_class = ActiveRecord::Migration
|
33
|
+
|
34
|
+
# Rails 5 adds ActiveRecord::Migration.[] to specify an exact migration version
|
35
|
+
if migrator_class.respond_to? :[]
|
36
|
+
migrator_class = migrator_class["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"]
|
37
|
+
end
|
38
|
+
|
39
|
+
migrator = Class.new(migrator_class) do
|
40
|
+
def change
|
41
|
+
create_table :schlepper_tasks, id: false do |t|
|
42
|
+
t.string :version
|
43
|
+
t.string :owner
|
44
|
+
t.text :description
|
45
|
+
t.datetime :completed_at
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# stop migration output
|
50
|
+
def announce(*); end
|
51
|
+
def say(*); end
|
52
|
+
end
|
53
|
+
|
54
|
+
migrator.migrate :up
|
55
|
+
end
|
56
|
+
|
57
|
+
private def fetch_script_numbers_from_database
|
58
|
+
@versions ||= ActiveRecord::Base.
|
59
|
+
connection.
|
60
|
+
exec_query('SELECT version FROM schlepper_tasks').
|
61
|
+
map { |r| [r.fetch('version').to_s, true] }.to_h
|
62
|
+
end
|
63
|
+
|
64
|
+
private def load_tasks_that_need_run
|
65
|
+
Dir.glob("#{Rails.root}/script/schleppers/*.rb").
|
66
|
+
map { |f| File.basename(f) }.
|
67
|
+
reject { |f| f.scan(/\A(\d{10,})/).empty? }.
|
68
|
+
reject { |f| @versions.has_key?(f.scan(/\A(\d{10,})/).first.first) }.
|
69
|
+
each { |f| require File.join(Rails.root, 'script', 'schleppers', f) }
|
70
|
+
end
|
71
|
+
|
72
|
+
private def process_one klass
|
73
|
+
runner = klass.new
|
74
|
+
|
75
|
+
puts ''
|
76
|
+
puts "Processing #{klass.name} from #{runner.owner}:"
|
77
|
+
puts "#{runner.description}"
|
78
|
+
puts ''
|
79
|
+
|
80
|
+
ActiveRecord::Base.transaction do
|
81
|
+
if runner.run
|
82
|
+
ActiveRecord::Base.connection.execute <<-SQL
|
83
|
+
INSERT INTO schlepper_tasks (version, owner, description, completed_at)
|
84
|
+
VALUES (#{runner.version_number}, "#{runner.owner}", "#{runner.description}", "#{Time.now}");
|
85
|
+
SQL
|
86
|
+
else
|
87
|
+
puts "#{klass.name} ran without errors, but was not successful"
|
88
|
+
if runner.failure_message
|
89
|
+
puts "The resulting falure was: #{runner.failure_message}"
|
90
|
+
else
|
91
|
+
puts "The falure message was not set. Find #{runner.owner} to help investigate"
|
92
|
+
end
|
93
|
+
fail ActiveRecord::Rollback
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
puts ''
|
98
|
+
puts "Finished #{klass.name}"
|
99
|
+
puts '~~~~~~~~~~~~~~~~~~~~~'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Schlepper
|
2
|
+
# Tasks live in your rails app under /script/tasks. They have the same filename
|
3
|
+
# pattern as rails migrations, {version time stamp}_class_name.rb
|
4
|
+
# A functional generator is provided using `rails generate schlepper:task name_of_task`
|
5
|
+
class Task
|
6
|
+
include Schlepper::AbstractMethodHelper
|
7
|
+
|
8
|
+
@children = []
|
9
|
+
|
10
|
+
def self.children
|
11
|
+
@children
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.inherited obj
|
15
|
+
super
|
16
|
+
children.push obj
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Fixnum] The version number of the current class
|
20
|
+
def version_number
|
21
|
+
# We have to find the actual file where the class is defined which is the reason for
|
22
|
+
# the method source location weirdness
|
23
|
+
@version_number ||= File.basename(method(:run).source_location.first).scan(/\A(\d{10,})/).first.first
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [String] Short note on the intent of this script
|
27
|
+
# @abstract
|
28
|
+
abstract def description
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [String] Name of the person or people who have ownership of the script
|
32
|
+
# @abstract
|
33
|
+
abstract def owner
|
34
|
+
end
|
35
|
+
|
36
|
+
# This is the entry point for your script. The full Rails stack is available.
|
37
|
+
# Return true if it was successful, false if not. If not successful,
|
38
|
+
# set @failure_message to something meaningful. Runs that return false
|
39
|
+
# will not be marked as run and will be continue to be run in subsequent
|
40
|
+
# batch runs
|
41
|
+
# @return [Bool] Success or failure
|
42
|
+
# @abstract
|
43
|
+
abstract def run
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/schlepper.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'schlepper/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "schlepper"
|
8
|
+
spec.version = Schlepper::VERSION
|
9
|
+
spec.authors = ["Rory O'Connell"]
|
10
|
+
spec.email = ["rory.oconnell@grandrounds.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Adds tracking of one off data scripts for Rails.}
|
13
|
+
spec.description = %q{}
|
14
|
+
spec.homepage = "https://github.com/ConsultingMD/schlepper"
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
|
+
if spec.respond_to?(:metadata)
|
19
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
20
|
+
else
|
21
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
22
|
+
end
|
23
|
+
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
spec.bindir = "exe"
|
26
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ["lib"]
|
28
|
+
|
29
|
+
spec.add_dependency 'activerecord', '>= 3.2'
|
30
|
+
|
31
|
+
spec.add_development_dependency 'codeclimate-test-reporter'
|
32
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
33
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
34
|
+
spec.add_development_dependency "minitest", ">= 5.0"
|
35
|
+
spec.add_development_dependency 'rails', '>= 3.2'
|
36
|
+
spec.add_development_dependency 'sqlite3'
|
37
|
+
spec.add_development_dependency 'pry'
|
38
|
+
end
|
metadata
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: schlepper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.8.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rory O'Connell
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: codeclimate-test-reporter
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.12'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.12'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '5.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '5.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rails
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.2'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.2'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: sqlite3
|
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: pry
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
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
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: ''
|
126
|
+
email:
|
127
|
+
- rory.oconnell@grandrounds.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".codeclimate.yml"
|
133
|
+
- ".gitignore"
|
134
|
+
- ".travis.yml"
|
135
|
+
- Gemfile
|
136
|
+
- README.md
|
137
|
+
- Rakefile
|
138
|
+
- bin/console
|
139
|
+
- bin/setup
|
140
|
+
- lib/generators/schlepper/USAGE
|
141
|
+
- lib/generators/schlepper/task_generator.rb
|
142
|
+
- lib/generators/schlepper/templates/onetime_script.rb.erb
|
143
|
+
- lib/schlepper.rb
|
144
|
+
- lib/schlepper/abstract_method_helper.rb
|
145
|
+
- lib/schlepper/process.rb
|
146
|
+
- lib/schlepper/railtie.rb
|
147
|
+
- lib/schlepper/task.rb
|
148
|
+
- lib/schlepper/version.rb
|
149
|
+
- lib/tasks/schlepper.rake
|
150
|
+
- schlepper.gemspec
|
151
|
+
homepage: https://github.com/ConsultingMD/schlepper
|
152
|
+
licenses: []
|
153
|
+
metadata:
|
154
|
+
allowed_push_host: https://rubygems.org
|
155
|
+
post_install_message:
|
156
|
+
rdoc_options: []
|
157
|
+
require_paths:
|
158
|
+
- lib
|
159
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
161
|
+
- - ">="
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '0'
|
164
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
|
+
requirements:
|
166
|
+
- - ">="
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '0'
|
169
|
+
requirements: []
|
170
|
+
rubyforge_project:
|
171
|
+
rubygems_version: 2.5.2
|
172
|
+
signing_key:
|
173
|
+
specification_version: 4
|
174
|
+
summary: Adds tracking of one off data scripts for Rails.
|
175
|
+
test_files: []
|