effective_developer 0.0.2
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/MIT-LICENSE +20 -0
- data/README.md +121 -0
- data/Rakefile +8 -0
- data/app/models/effective/access_denied.rb +17 -0
- data/app/models/effective/csv_importer.rb +131 -0
- data/config/effective_developer.rb +4 -0
- data/lib/effective_developer/engine.rb +11 -0
- data/lib/effective_developer/version.rb +3 -0
- data/lib/effective_developer.rb +17 -0
- data/lib/generators/effective_developer/install_generator.rb +16 -0
- data/lib/tasks/effective_csv_importer.rake +46 -0
- data/lib/tasks/pg_pull.rake +66 -0
- metadata +70 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c29066e84e43bb85a6bbb3b355537784ca8a8634
|
4
|
+
data.tar.gz: aa3035ca68b854b7f2b0416ca59b92680a07ae72
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 412c6fe2018b272ef2a3208a25d3a5d9477414f1b02aa15718fcece18e3d82957cc12740078423f672ad4fcd6ed1a9b4eebb3964bbed108fd81e53cebe867746
|
7
|
+
data.tar.gz: 730983166244c70d25a519f97a69a5717bfbeff1f681d74c0cd824460bf6ecd5a3dfe34a37ba37848083e788ffec4f4a5f6e42644cc2f12d23f36936c5e6a25f
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2016 Code and Effect Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
# Effective Developer
|
2
|
+
|
3
|
+
This is a small gem with some developer quality of life scripts.
|
4
|
+
|
5
|
+
## Getting Started
|
6
|
+
|
7
|
+
Add to your Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
group :development
|
11
|
+
gem 'effective_developer'
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
Run the bundle command to install it:
|
16
|
+
|
17
|
+
```console
|
18
|
+
bundle install
|
19
|
+
```
|
20
|
+
|
21
|
+
## gem_release
|
22
|
+
|
23
|
+
A command line shell script that quickly bumps the version of any ruby gem.
|
24
|
+
|
25
|
+
It checks for any uncommitted files, updates the gem's `version.rb` with the given version, makes a single file `git commit` with a tag and message, then runs `git push origin master`, `gem build` and `gem push` to rubygems.
|
26
|
+
|
27
|
+
To use with any gem, add the following folder to your `PATH` (~/.bashrc or ~/.profile):
|
28
|
+
|
29
|
+
```console
|
30
|
+
export PATH="$PATH:$HOME/effective_developer/bin"
|
31
|
+
```
|
32
|
+
|
33
|
+
Once included in your `PATH`, `gem_release` should be run from the root directory of any ruby gem.
|
34
|
+
|
35
|
+
To print the current gem version:
|
36
|
+
|
37
|
+
```console
|
38
|
+
> gem_release
|
39
|
+
```
|
40
|
+
|
41
|
+
To release a new gem version:
|
42
|
+
|
43
|
+
```console
|
44
|
+
> gem_release 1.0.0
|
45
|
+
```
|
46
|
+
|
47
|
+
## CSV Importer
|
48
|
+
|
49
|
+
Extend a class from `Effective::CSVImporter` to quickly build a csv importer.
|
50
|
+
|
51
|
+
Put your importer in `lib/csv_importers/users_importer.rb` and the data in `lib/csv_importers/data/users.csv`. Both filenames should be pluralized.
|
52
|
+
|
53
|
+
A rake command will be dynamically created `rake import:users`.
|
54
|
+
|
55
|
+
### Required Methods
|
56
|
+
|
57
|
+
The importer requires two instance methods be defined:
|
58
|
+
|
59
|
+
- `def columns` a hash of names to columns. The constants `A` == 0, `B` == 1, upto `AT` == 45 are defined to work better with spreadsheets.
|
60
|
+
- `def process_row` will be run for each row of data. Any exceptions will be caught and logged as errors.
|
61
|
+
|
62
|
+
Inside the script, there are a few helpful functions:
|
63
|
+
|
64
|
+
- `col(:email)` will return the normalized value in that column.
|
65
|
+
- `last_row_col(:email)` will return the normalized value for this column in the previous row.
|
66
|
+
- `raw_col(:email)` will return the raw value in that column
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
module CsvImporters
|
70
|
+
class UsersImporter < Effective::CSVImporter
|
71
|
+
def columns
|
72
|
+
{
|
73
|
+
email: A,
|
74
|
+
first_name: B,
|
75
|
+
last_name: C,
|
76
|
+
admin?: D
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def process_row
|
81
|
+
User.new(email: col(:email), first_name: col(:first_name), last_name: col(:last_name), admin: col(:admin?)).save!
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
88
|
+
When using `col()` or `last_row_col()` helpers, the value is normalized.
|
89
|
+
|
90
|
+
- Any column that ends with a `?` will be converted into a boolean.
|
91
|
+
- Any column that ends with `_at` will be converted into a DateTime.
|
92
|
+
- Any column that ends with `_on` will be converted into a Date.
|
93
|
+
- Override `def normalize` to add your own.
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
def normalize(column, value)
|
97
|
+
if column == :first_name
|
98
|
+
value.upcase
|
99
|
+
else
|
100
|
+
super
|
101
|
+
end
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
Override `before_import()` or `after_import()` to run code before or after the import.
|
106
|
+
|
107
|
+
## License
|
108
|
+
|
109
|
+
MIT License. Copyright [Code and Effect Inc.](http://www.codeandeffect.com/)
|
110
|
+
|
111
|
+
Code and Effect is the product arm of [AgileStyle](http://www.agilestyle.com/), an Edmonton-based shop that specializes in building custom web applications with Ruby on Rails.
|
112
|
+
|
113
|
+
|
114
|
+
## Contributing
|
115
|
+
|
116
|
+
1. Fork it
|
117
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
118
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
119
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
120
|
+
5. Bonus points for test coverage
|
121
|
+
6. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
unless defined?(Effective::AccessDenied)
|
2
|
+
module Effective
|
3
|
+
class AccessDenied < StandardError
|
4
|
+
attr_reader :action, :subject
|
5
|
+
|
6
|
+
def initialize(message = nil, action = nil, subject = nil)
|
7
|
+
@message = message
|
8
|
+
@action = action
|
9
|
+
@subject = subject
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
@message || I18n.t(:'unauthorized.default', :default => 'Access Denied')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module Effective
|
4
|
+
class CSVImporter
|
5
|
+
attr_reader :current_row, :last_row
|
6
|
+
|
7
|
+
A=0;B=1;C=2;D=3;E=4;F=5;G=6;H=7;I=8;J=9;K=10;L=11;M=12;N=13;
|
8
|
+
O=14;P=15;Q=16;R=17;S=18;T=19;U=20;V=21;W=22;X=23;Y=24;Z=25;
|
9
|
+
AA=26;AB=27;AC=28;AD=29;AE=30;AF=31;AG=32;AH=33;AI=34;AJ=35;
|
10
|
+
AK=36;AL=37;AM=38;AN=39;AO=40;AP=41;AQ=42;AR=43;AS=44;AT=45;
|
11
|
+
|
12
|
+
def initialize(csv_file, has_header_row = true)
|
13
|
+
@csv_file = csv_file.to_s
|
14
|
+
@has_header_row = has_header_row
|
15
|
+
end
|
16
|
+
|
17
|
+
def csv_file
|
18
|
+
@csv_file
|
19
|
+
end
|
20
|
+
|
21
|
+
def import!
|
22
|
+
log "Importing #{csv_file.split('/').last.sub('.csv', '')}"
|
23
|
+
|
24
|
+
@errors_count = 0
|
25
|
+
|
26
|
+
before_import()
|
27
|
+
with_each_row { process_row }
|
28
|
+
after_import()
|
29
|
+
|
30
|
+
log "Import complete (#{@errors_count} errors in #{@has_header_row ? @current_row_number-1 : @current_row_number} rows)"
|
31
|
+
end
|
32
|
+
|
33
|
+
def with_each_row(&block)
|
34
|
+
@current_row_number = (@has_header_row ? 2 : 1)
|
35
|
+
|
36
|
+
CSV.foreach(csv_file, headers: @has_header_row) do |row|
|
37
|
+
@current_row = row
|
38
|
+
|
39
|
+
begin
|
40
|
+
yield
|
41
|
+
print colorize('.', :green)
|
42
|
+
rescue => e
|
43
|
+
error(e.message)
|
44
|
+
puts row
|
45
|
+
puts e.backtrace.first(3)
|
46
|
+
end
|
47
|
+
|
48
|
+
@current_row_number += 1
|
49
|
+
@last_row = row
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def columns
|
54
|
+
raise "Please define a method 'def columns' returning a Hash of {id: A, name: B}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def process_row
|
58
|
+
raise "Please define a method 'def process_row' to process your row"
|
59
|
+
end
|
60
|
+
|
61
|
+
# Override me if you need some before/after hooks
|
62
|
+
def before_import ; end
|
63
|
+
def after_import ; end
|
64
|
+
|
65
|
+
# Normalize the value based on column name
|
66
|
+
def normalize(column, value)
|
67
|
+
column = column.to_s
|
68
|
+
value = value.to_s
|
69
|
+
|
70
|
+
if column.ends_with?('?') # Boolean
|
71
|
+
::ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES.include?(value)
|
72
|
+
elsif column.ends_with?('_at') # DateTime
|
73
|
+
Time.zone.parse(value) rescue nil
|
74
|
+
elsif column.ends_with?('_on') # Date
|
75
|
+
Time.zone.parse(value).beginning_of_day rescue nil
|
76
|
+
else
|
77
|
+
value.presence || ''.freeze
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def log(message)
|
82
|
+
puts "\n#{message}";
|
83
|
+
end
|
84
|
+
|
85
|
+
def error(message)
|
86
|
+
@errors_count += 1
|
87
|
+
puts "\n#{colorize('Error', :red)} (.csv line #{@current_row_number}) #{message}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def warn(message)
|
91
|
+
puts "\n#{colorize('Warning', :yellow)} (.csv line #{@current_row_number}) #{message}"
|
92
|
+
end
|
93
|
+
|
94
|
+
protected
|
95
|
+
|
96
|
+
def col(column)
|
97
|
+
raise "unknown column :#{column} passed to col()" unless columns.key?(column) || column.kind_of?(Integer)
|
98
|
+
|
99
|
+
value = current_row[columns[column] || column].try(:strip).presence
|
100
|
+
|
101
|
+
normalize(column, value)
|
102
|
+
end
|
103
|
+
|
104
|
+
def raw_col(column)
|
105
|
+
raise "unknown column :#{column} passed to raw_col()" unless columns.key?(column) || column.kind_of?(Integer)
|
106
|
+
current_row[columns[column] || column]
|
107
|
+
end
|
108
|
+
|
109
|
+
def last_row_col(column)
|
110
|
+
raise "unknown column :#{column} passed to last_row_col()" unless columns.key?(column) || column.kind_of?(Integer)
|
111
|
+
|
112
|
+
value = last_row[columns[column] || column].try(:strip).presence
|
113
|
+
|
114
|
+
normalize(column, value)
|
115
|
+
end
|
116
|
+
|
117
|
+
def colorize(text, color)
|
118
|
+
code = case color
|
119
|
+
when :cyan ; 36
|
120
|
+
when :magenta ; 35
|
121
|
+
when :blue ; 34
|
122
|
+
when :yellow ; 33
|
123
|
+
when :green ; 32
|
124
|
+
when :red ; 31
|
125
|
+
end
|
126
|
+
|
127
|
+
"\e[#{code}m#{text}\e[0m"
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module EffectiveDeveloper
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
engine_name 'effective_developer'
|
4
|
+
|
5
|
+
# Set up our default configuration options.
|
6
|
+
initializer 'effective_developer.defaults', before: :load_config_initializers do |app|
|
7
|
+
# Set up our defaults, as per our initializer template
|
8
|
+
eval File.read("#{config.root}/config/effective_developer.rb")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'effective_developer/engine'
|
2
|
+
require 'effective_developer/version'
|
3
|
+
|
4
|
+
module EffectiveDeveloper
|
5
|
+
|
6
|
+
def self.setup
|
7
|
+
yield self
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.authorized?(controller, action, resource)
|
11
|
+
if authorization_method.respond_to?(:call) || authorization_method.kind_of?(Symbol)
|
12
|
+
raise Effective::AccessDenied.new() unless (controller || self).instance_exec(controller, action, resource, &authorization_method)
|
13
|
+
end
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module EffectiveDeveloper
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
include Rails::Generators::Migration
|
5
|
+
|
6
|
+
desc 'Creates an EffectiveDeveloper initializer in your application.'
|
7
|
+
|
8
|
+
source_root File.expand_path(('../' * 4), __FILE__)
|
9
|
+
|
10
|
+
def copy_initializer
|
11
|
+
template 'config/effective_developer.rb', 'config/initializers/effective_developer.rb'
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# effective_csv_importer 1.0
|
2
|
+
|
3
|
+
# Creates one rake task per importer model, as well as a `rake import:all` task.
|
4
|
+
|
5
|
+
# Usage:
|
6
|
+
|
7
|
+
# Put your importer in /lib/csv_importers/posts.rb
|
8
|
+
# Put your csv data in /lib/csv_importers/data/posts.csv
|
9
|
+
# Both filenames should be pluralized
|
10
|
+
|
11
|
+
# rake import:posts (one task created per model)
|
12
|
+
# rake import:all
|
13
|
+
|
14
|
+
namespace :import do
|
15
|
+
Dir['lib/csv_importers/*.rb'].each do |file|
|
16
|
+
importer = file.sub('lib/csv_importers/', '').sub('_importer.rb', '')
|
17
|
+
csv_file = "lib/csv_importers/data/#{importer}.csv"
|
18
|
+
next unless File.exists?(csv_file)
|
19
|
+
|
20
|
+
# Create a rake task to import this file
|
21
|
+
desc "Import #{importer} from #{csv_file}"
|
22
|
+
|
23
|
+
task importer => :environment do
|
24
|
+
klass = "CsvImporters::#{importer.classify.pluralize}Importer".safe_constantize
|
25
|
+
raise "unable to constantize CsvImporters::#{importer.classify.pluralize}Importer for #{file}" unless klass
|
26
|
+
|
27
|
+
klass.new(csv_file).import!
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# This task is kind of naive, because some imports could be order dependent. Use at your own risk.
|
33
|
+
namespace :import do
|
34
|
+
desc "Import all from /lib/csv_importers/*.rb"
|
35
|
+
|
36
|
+
task :all => :environment do
|
37
|
+
Dir['lib/csv_importers/*.rb'].each do |file|
|
38
|
+
importer = file.sub('lib/csv_importers/', '').sub('_importer.rb', '')
|
39
|
+
csv_file = "lib/csv_importers/data/#{importer}.csv"
|
40
|
+
next unless File.exists?(csv_file)
|
41
|
+
|
42
|
+
Rake::Task["import:#{importer}"].invoke
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
namespace :pg do
|
2
|
+
# Creates a new backup on heroku, downloads that backup to latest.dump, and then calls pg:load
|
3
|
+
#
|
4
|
+
# bundle exec rake pg:pull
|
5
|
+
# bundle exec rake pg:pull[staging]
|
6
|
+
desc 'Pulls a newly captured backup from heroku (--remote heroku by default) and calls pg:load'
|
7
|
+
task :pull, [:remote] => :environment do |t, args|
|
8
|
+
args.with_defaults(:remote => 'heroku')
|
9
|
+
|
10
|
+
puts "=== Pulling remote '#{args.remote}' database into latest.dump"
|
11
|
+
|
12
|
+
Bundler.with_clean_env do
|
13
|
+
unless system("heroku pg:backups capture --remote #{args.remote}")
|
14
|
+
puts "Error capturing backup"
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
|
18
|
+
if system("curl -o latest.dump `heroku pg:backups public-url --remote #{args.remote}`")
|
19
|
+
puts "Downloading database completed"
|
20
|
+
else
|
21
|
+
puts "Error downloading database"
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Rake::Task['pg:load'].invoke
|
27
|
+
end
|
28
|
+
|
29
|
+
# Drops and re-creates the local database then initializes database with latest.dump
|
30
|
+
#
|
31
|
+
# bundle exec rake pg:load => Will replace the current database with latest.dump
|
32
|
+
# bundle exec rake pg:load[something.dump] => Will replace the current database with latest.dump
|
33
|
+
desc 'Loads a postgresql .dump file into the development database (latest.dump by default)'
|
34
|
+
task :load, [:file_name] => :environment do |t, args|
|
35
|
+
args.with_defaults(:file_name => 'latest.dump')
|
36
|
+
db = ActiveRecord::Base.configurations
|
37
|
+
|
38
|
+
puts "=== Loading #{args.file_name} into local '#{db[Rails.env]['database']}' database"
|
39
|
+
|
40
|
+
Rake::Task['db:drop'].invoke
|
41
|
+
Rake::Task['db:create'].invoke
|
42
|
+
|
43
|
+
if system("pg_restore --no-acl --no-owner -h localhost -U #{db[Rails.env]['username']} -d #{db[Rails.env]['database']} #{args.file_name}")
|
44
|
+
puts "Loading database completed"
|
45
|
+
else
|
46
|
+
puts "Error loading database"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# bundle exec rake pg:save => Will dump the database to latest.dump
|
51
|
+
# bundle exec rake pg:save[something.dump] => Will dump the database to something.dump
|
52
|
+
desc 'Saves the development database to a postgresql .dump file (latest.dump by default)'
|
53
|
+
task :save, [:file_name] => :environment do |t, args|
|
54
|
+
args.with_defaults(:file_name => 'latest.dump')
|
55
|
+
db = ActiveRecord::Base.configurations
|
56
|
+
|
57
|
+
puts "=== Saving local '#{db[Rails.env]['database']}' database to #{args.file_name}"
|
58
|
+
|
59
|
+
if system("pg_dump -Fc --no-acl --no-owner -h localhost -U '#{db[Rails.env]['username']}' '#{db[Rails.env]['database']}' > #{args.file_name}")
|
60
|
+
puts "Saving database completed"
|
61
|
+
else
|
62
|
+
puts "Error saving postgres database"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: effective_developer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Code and Effect
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-04-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.2.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.2.0
|
27
|
+
description: Provides some quality of life developer tools.
|
28
|
+
email:
|
29
|
+
- info@codeandeffect.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- MIT-LICENSE
|
35
|
+
- README.md
|
36
|
+
- Rakefile
|
37
|
+
- app/models/effective/access_denied.rb
|
38
|
+
- app/models/effective/csv_importer.rb
|
39
|
+
- config/effective_developer.rb
|
40
|
+
- lib/effective_developer.rb
|
41
|
+
- lib/effective_developer/engine.rb
|
42
|
+
- lib/effective_developer/version.rb
|
43
|
+
- lib/generators/effective_developer/install_generator.rb
|
44
|
+
- lib/tasks/effective_csv_importer.rake
|
45
|
+
- lib/tasks/pg_pull.rake
|
46
|
+
homepage: https://github.com/code-and-effect/effective_developer
|
47
|
+
licenses:
|
48
|
+
- MIT
|
49
|
+
metadata: {}
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
requirements: []
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 2.4.5.1
|
67
|
+
signing_key:
|
68
|
+
specification_version: 4
|
69
|
+
summary: Provides some quality of life developer tools.
|
70
|
+
test_files: []
|