aws-record-generator 1.0.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 88db52d888ba8ab309db4f229686bc1cb036397d
4
+ data.tar.gz: 7ee3a11e989280135d8854d3eadf6acf04a7ac7d
5
+ SHA512:
6
+ metadata.gz: 47607097dc142faee512968f5845a2ef511c53fa11ece5f352804faac451f4895f2d1e54f168b0b538b5b1416cf9dbbd925f58d82563c308b98a56707e6580c7
7
+ data.tar.gz: cb09166ed00e62c040732380b38ffde75a37065cb8755c2589f473ec12092d6b38513612c67c16681f4d73dd31f60c0638fcf3bf0632326c267b3531865dd2ca
@@ -0,0 +1,28 @@
1
+ # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You may not
4
+ # use this file except in compliance with the License. A copy of the License is
5
+ # located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is distributed on
10
+ # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
+ # or implied. See the License for the specific language governing permissions
12
+ # and limitations under the License.
13
+
14
+ require_relative 'generators/generated_attribute'
15
+ require_relative 'generators/secondary_index'
16
+ require_relative 'generators/test_helper'
17
+ require_relative 'generators/aws_record/model/model_generator'
18
+
19
+ require 'aws-record'
20
+ require 'rails/railtie'
21
+
22
+ module AwsRecord
23
+ class Railtie < Rails::Railtie
24
+ rake_tasks do
25
+ load 'tasks/table_config_migrate_task.rake'
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,21 @@
1
+ Description:
2
+ rails generator for aws-record models
3
+
4
+ Pass the name of the model (preferably in singular form), and an optional list of attributes
5
+
6
+ Attributes are declarations of the fields that you wish to store within a model. You can pass
7
+ a type and list of options for each attribtue in the form: `name:type:options` if you do not provide
8
+ a type, it is assumed that the attribute is of type `string_attr`
9
+
10
+ Each model should have an hkey, if one is not present a `uuid:hkey` will be created for you.
11
+
12
+ Timestamps are not added by default but you can add them using the `--timestamps` flag
13
+ More information can be found at: https://github.com/awslabs/aws-record-generator/blob/master/README.md
14
+
15
+ Example:
16
+ rails generate aws_record:model Forum forum_uuid:hkey post_id:rkey post_title post_body tags:sset:default_value{Set.new} created_at:datetime:d_attr_name{PostCreatedAtTime} moderation:boolean:default_value{false}
17
+
18
+ This will create:
19
+ app/models/forum.rb
20
+ db/table_config/forum_config.rb
21
+ lib/tasks/table_config_migrate_task.rake # This is created once the first time the generator is run
@@ -0,0 +1,230 @@
1
+ # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You may not
4
+ # use this file except in compliance with the License. A copy of the License is
5
+ # located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is distributed on
10
+ # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
+ # or implied. See the License for the specific language governing permissions
12
+ # and limitations under the License.
13
+
14
+ require 'rails/generators'
15
+ require 'aws-record-generator'
16
+
17
+ module AwsRecord
18
+ module Generators
19
+ class ModelGenerator < Rails::Generators::NamedBase
20
+
21
+ source_root File.expand_path('../templates', __FILE__)
22
+ argument :attributes, type: :array, default: [], banner: "field[:type][:opts]...", desc: "Describes the fields in the model"
23
+ check_class_collision
24
+
25
+ class_option :disable_mutation_tracking, type: :boolean, desc: "Disables dirty tracking"
26
+ class_option :timestamps, type: :boolean, desc: "Adds created, updated timestamps to the model"
27
+ class_option :table_config, type: :hash, default: {}, banner: "primary:R-W [SecondaryIndex1:R-W]...", desc: "Declares the r/w units for the model as well as any secondary indexes", :required => true
28
+ class_option :gsi, type: :array, default: [], banner: "name:hkey{field_name}[,rkey{field_name},proj_type{ALL|KEYS_ONLY|INCLUDE}]...", desc: "Allows for the declaration of secondary indexes"
29
+
30
+ class_option :required, type: :array, default: [], banner: "field1...", desc: "A list of attributes that are required for an instance of the model"
31
+ class_option :length_validations, type: :hash, default: {}, banner: "field1:MIN-MAX...", desc: "Validations on the length of attributes in a model"
32
+
33
+ attr_accessor :primary_read_units, :primary_write_units, :gsi_rw_units, :gsis, :required_attrs, :length_validations
34
+
35
+ def create_model
36
+ template "model.rb", File.join("app/models", class_path, "#{file_name}.rb")
37
+ end
38
+
39
+ def create_table_config
40
+ template "table_config.rb", File.join("db/table_config", class_path, "#{file_name}_config.rb")
41
+ end
42
+
43
+ private
44
+
45
+ def initialize(args, *options)
46
+ @parse_errors = []
47
+
48
+ super
49
+ ensure_unique_fields
50
+ ensure_hkey
51
+ parse_gsis!
52
+ parse_table_config!
53
+ parse_validations!
54
+
55
+ if !@parse_errors.empty?
56
+ STDERR.puts "The following errors were encountered while trying to parse the given attributes"
57
+ STDERR.puts
58
+ STDERR.puts @parse_errors
59
+ STDERR.puts
60
+
61
+ abort("Please fix the errors before proceeding.")
62
+ end
63
+ end
64
+
65
+ def parse_attributes!
66
+
67
+ self.attributes = (attributes || []).map do |attr|
68
+ begin
69
+ GeneratedAttribute.parse(attr)
70
+ rescue ArgumentError => e
71
+ @parse_errors << e
72
+ next
73
+ end
74
+ end
75
+ self.attributes = self.attributes.compact
76
+
77
+ if options['timestamps']
78
+ self.attributes << GeneratedAttribute.parse("created:datetime:default_value{Time.now}")
79
+ self.attributes << GeneratedAttribute.parse("updated:datetime:default_value{Time.now}")
80
+ end
81
+ end
82
+
83
+ def ensure_unique_fields
84
+ used_names = Set.new
85
+ duplicate_fields = []
86
+
87
+ self.attributes.each do |attr|
88
+
89
+ if used_names.include? attr.name
90
+ duplicate_fields << [:attribute, attr.name]
91
+ end
92
+ used_names.add attr.name
93
+
94
+ if attr.options.key? :database_attribute_name
95
+ raw_db_attr_name = attr.options[:database_attribute_name].delete('"') # db attribute names are wrapped with " to make template generation easier
96
+
97
+ if used_names.include? raw_db_attr_name
98
+ duplicate_fields << [:database_attribute_name, raw_db_attr_name]
99
+ end
100
+
101
+ used_names.add raw_db_attr_name
102
+ end
103
+ end
104
+
105
+ if !duplicate_fields.empty?
106
+ duplicate_fields.each do |invalid_attr|
107
+ @parse_errors << ArgumentError.new("Found duplicated field name: #{invalid_attr[1]}, in attribute#{invalid_attr[0]}")
108
+ end
109
+ end
110
+ end
111
+
112
+ def ensure_hkey
113
+ uuid_member = nil
114
+ hkey_member = nil
115
+ rkey_member = nil
116
+
117
+ self.attributes.each do |attr|
118
+ if attr.options.key? :hash_key
119
+ if hkey_member
120
+ @parse_errors << ArgumentError.new("Redefinition of hash_key attr: #{attr.name}, original declaration of hash_key on: #{hkey_member.name}")
121
+ next
122
+ end
123
+
124
+ hkey_member = attr
125
+ elsif attr.options.key? :range_key
126
+ if rkey_member
127
+ @parse_errors << ArgumentError.new("Redefinition of range_key attr: #{attr.name}, original declaration of range_key on: #{hkey_member.name}")
128
+ next
129
+ end
130
+
131
+ rkey_member = attr
132
+ end
133
+
134
+ if attr.name.include? "uuid"
135
+ uuid_member = attr
136
+ end
137
+ end
138
+
139
+ if !hkey_member
140
+ if uuid_member
141
+ uuid_member.options[:hash_key] = true
142
+ else
143
+ self.attributes.unshift GeneratedAttribute.parse("uuid:hkey")
144
+ end
145
+ end
146
+ end
147
+
148
+ def mutation_tracking_disabled?
149
+ options['disable_mutation_tracking']
150
+ end
151
+
152
+ def has_validations?
153
+ !@required_attrs.empty? || !@length_validations.empty?
154
+ end
155
+
156
+ def parse_table_config!
157
+ @primary_read_units, @primary_write_units = parse_rw_units("primary")
158
+
159
+ @gsi_rw_units = @gsis.map { |idx|
160
+ [idx.name, parse_rw_units(idx.name)]
161
+ }.to_h
162
+
163
+ options['table_config'].each do |config, rw_units|
164
+ if config == "primary"
165
+ next
166
+ else
167
+ gsi = @gsis.select { |idx| idx.name == config}
168
+
169
+ if gsi.empty?
170
+ @parse_errors << ArgumentError.new("Could not find a gsi declaration for #{config}")
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ def parse_rw_units(name)
177
+ if !options['table_config'].key? name
178
+ @parse_errors << ArgumentError.new("Please provide a table_config definition for #{name}")
179
+ else
180
+ rw_units = options['table_config'][name]
181
+ return rw_units.gsub(/[,.-]/, ':').split(':').reject { |s| s.empty? }
182
+ end
183
+ end
184
+
185
+ def parse_gsis!
186
+ @gsis = (options['gsi'] || []).map do |raw_idx|
187
+ begin
188
+ idx = SecondaryIndex.parse(raw_idx)
189
+
190
+ attributes = self.attributes.select { |attr| attr.name == idx.hash_key}
191
+ if attributes.empty?
192
+ @parse_errors << ArgumentError.new("Could not find attribute #{idx.hash_key} for gsi #{idx.name} hkey")
193
+ next
194
+ end
195
+
196
+ if idx.range_key
197
+ attributes = self.attributes.select { |attr| attr.name == idx.range_key}
198
+ if attributes.empty?
199
+ @parse_errors << ArgumentError.new("Could not find attribute #{idx.range_key} for gsi #{idx.name} rkey")
200
+ next
201
+ end
202
+ end
203
+
204
+ idx
205
+ rescue ArgumentError => e
206
+ @parse_errors << e
207
+ next
208
+ end
209
+ end
210
+
211
+ @gsis = @gsis.compact
212
+ end
213
+
214
+ def parse_validations!
215
+ @required_attrs = options['required']
216
+ @required_attrs.each do |val_attr|
217
+ @parse_errors << ArgumentError.new("No such field #{val_attr} in required validations") if !self.attributes.any? { |attr| attr.name == val_attr }
218
+ end
219
+
220
+ @length_validations = options['length_validations'].map do |val_attr, bounds|
221
+ @parse_errors << ArgumentError.new("No such field #{val_attr} in required validations") if !self.attributes.any? { |attr| attr.name == val_attr }
222
+
223
+ bounds = bounds.gsub(/[,.-]/, ':').split(':').reject { |s| s.empty? }
224
+ [val_attr, "#{bounds[0]}..#{bounds[1]}"]
225
+ end
226
+ @length_validations = @length_validations.to_h
227
+ end
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,33 @@
1
+ require 'aws-record'
2
+ <%= "require 'active_model'
3
+ " if has_validations? -%>
4
+
5
+ <% module_namespacing do -%>
6
+ class <%= class_name %>
7
+ include Aws::Record
8
+ <%= ' include ActiveModel::Validations
9
+ ' if has_validations? -%>
10
+ <%= ' disable_mutation_tracking
11
+ ' if mutation_tracking_disabled? -%>
12
+
13
+ <% attributes.each do |attribute| -%>
14
+ <%= attribute.type %> :<%= attribute.name %><% *opts, last_opt = attribute.options.to_a %><%= ', ' if last_opt %><% opts.each do |opt| %><%= opt[0] %>: <%= opt[1] %>, <% end %><% if last_opt %><%= last_opt[0] %>: <%= last_opt[1] %><% end %>
15
+ <% end -%>
16
+ <% gsis.each do |index| %>
17
+ global_secondary_index(
18
+ :<%= index.name %>,
19
+ hash_key: :<%= index.hash_key -%>,<%- if index.range_key %>
20
+ range_key: :<%= index.range_key -%>,<%- end %>
21
+ projection: {
22
+ projection_type: <%= index.projection_type %>
23
+ }
24
+ )
25
+ <% end -%>
26
+ <% if !required_attrs.empty? -%>
27
+ validates_presence_of <% *req, last_req = required_attrs -%><% req.each do |required_validation|-%>:<%= required_validation %>, <% end -%>:<%= last_req %>
28
+ <% end -%>
29
+ <% length_validations.each do |attribute, validation| -%>
30
+ validates_length_of :<%= attribute %>, within: <%= validation %>
31
+ <% end -%>
32
+ end
33
+ <% end -%>
@@ -0,0 +1,18 @@
1
+ require 'aws-record'
2
+
3
+ module ModelTableConfig
4
+ def self.config
5
+ Aws::Record::TableConfig.define do |t|
6
+ t.model_class <%= class_name %>
7
+
8
+ t.read_capacity_units <%= primary_read_units %>
9
+ t.write_capacity_units <%= primary_write_units %>
10
+ <%- gsis.each do |index| %>
11
+ t.global_secondary_index(:<%= index.name %>) do |i|
12
+ i.read_capacity_units <%= gsi_rw_units[index.name][0] %>
13
+ i.write_capacity_units <%= gsi_rw_units[index.name][1] %>
14
+ end
15
+ <%- end -%>
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,110 @@
1
+ # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You may not
4
+ # use this file except in compliance with the License. A copy of the License is
5
+ # located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is distributed on
10
+ # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
+ # or implied. See the License for the specific language governing permissions
12
+ # and limitations under the License.
13
+
14
+ module AwsRecord
15
+ module Generators
16
+ class GeneratedAttribute
17
+
18
+ OPTS = %w(hkey rkey persist_nil db_attr_name ddb_type default_value)
19
+ INVALID_HKEY_TYPES = %i(map_attr list_attr numeric_set_attr string_set_attr)
20
+ attr_reader :name, :type
21
+ attr_accessor :options
22
+
23
+ class << self
24
+
25
+ def parse(field_definition)
26
+ name, type, opts = field_definition.split(':')
27
+ type = "string" if not type
28
+ type, opts = "string", type if OPTS.any? { |opt| type.include? opt }
29
+
30
+ opts = opts.split(',') if opts
31
+ type, opts = parse_type_and_options(name, type, opts)
32
+ validate_opt_combs(name, type, opts)
33
+
34
+ new(name, type, opts)
35
+ end
36
+
37
+ private
38
+
39
+ def validate_opt_combs(name, type, opts)
40
+ if opts
41
+ is_hkey = opts.key?(:hash_key)
42
+ is_rkey = opts.key?(:range_key)
43
+
44
+ raise ArgumentError.new("Field #{name} cannot be a range key and hash key simultaneously") if is_hkey && is_rkey
45
+ raise ArgumentError.new("Field #{name} cannot be a hash key and be of type #{type}") if is_hkey and INVALID_HKEY_TYPES.include? type
46
+ end
47
+ end
48
+
49
+ def parse_type_and_options(name, type, opts)
50
+ opts = [] if not opts
51
+ return parse_type(name, type), opts.map { |opt| parse_option(name, opt) }.to_h
52
+ end
53
+
54
+ def parse_option(name, opt)
55
+ case opt
56
+
57
+ when "hkey"
58
+ return :hash_key, true
59
+ when "rkey"
60
+ return :range_key, true
61
+ when "persist_nil"
62
+ return :persist_nil, true
63
+ when /db_attr_name\{(\w+)\}/
64
+ return :database_attribute_name, '"' + $1 + '"'
65
+ when /ddb_type\{(S|N|B|BOOL|SS|NS|BS|M|L)\}/i
66
+ return :dynamodb_type, '"' + $1.upcase + '"'
67
+ when /default_value\{(.+)\}/
68
+ return :default_value, $1
69
+ else
70
+ raise ArgumentError.new("You provided an invalid option for #{name}: #{opt}")
71
+ end
72
+ end
73
+
74
+ def parse_type(name, type)
75
+ case type.downcase
76
+
77
+ when "bool", "boolean"
78
+ :boolean_attr
79
+ when "date"
80
+ :date_attr
81
+ when "datetime"
82
+ :datetime_attr
83
+ when "float"
84
+ :float_attr
85
+ when "int", "integer"
86
+ :integer_attr
87
+ when "list"
88
+ :list_attr
89
+ when "map"
90
+ :map_attr
91
+ when "num_set", "numeric_set", "nset"
92
+ :numeric_set_attr
93
+ when "string_set", "s_set", "sset"
94
+ :string_set_attr
95
+ when "string"
96
+ :string_attr
97
+ else
98
+ raise ArgumentError.new("Invalid type for #{name}: #{type}")
99
+ end
100
+ end
101
+ end
102
+
103
+ def initialize(name, type = :string_attr, options = {})
104
+ @name = name
105
+ @type = type
106
+ @options = options
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,73 @@
1
+ # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You may not
4
+ # use this file except in compliance with the License. A copy of the License is
5
+ # located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is distributed on
10
+ # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
+ # or implied. See the License for the specific language governing permissions
12
+ # and limitations under the License.
13
+
14
+ module AwsRecord
15
+ module Generators
16
+ class SecondaryIndex
17
+
18
+ PROJ_TYPES = %w(ALL KEYS_ONLY INCLUDE)
19
+ attr_reader :name, :hash_key, :range_key, :projection_type
20
+
21
+ class << self
22
+ def parse(key_definition)
23
+ name, index_options = key_definition.split(':')
24
+ index_options = index_options.split(',') if index_options
25
+ opts = parse_raw_options(index_options)
26
+
27
+ new(name, opts)
28
+ end
29
+
30
+ private
31
+ def parse_raw_options(raw_opts)
32
+ raw_opts = [] if not raw_opts
33
+ raw_opts.map { |opt| get_option_value(opt) }.to_h
34
+ end
35
+
36
+ def get_option_value(raw_option)
37
+ case raw_option
38
+
39
+ when /hkey\{(\w+)\}/
40
+ return :hash_key, $1
41
+ when /rkey\{(\w+)\}/
42
+ return :range_key, $1
43
+ when /proj_type\{(\w+)\}/
44
+ return :projection_type, $1
45
+ else
46
+ raise ArgumentError.new("Invalid option for secondary index #{raw_option}")
47
+ end
48
+ end
49
+ end
50
+
51
+ def initialize(name, opts)
52
+ raise ArgumentError.new("You must provide a name") if not name
53
+ raise ArgumentError.new("You must provide a hash key") if not opts[:hash_key]
54
+
55
+ if opts.key? :projection_type
56
+ raise ArgumentError.new("Invalid projection type #{opts[:projection_type]}") if not PROJ_TYPES.include? opts[:projection_type]
57
+ raise NotImplementedError.new("ALL is the only projection type currently supported") if opts[:projection_type] != "ALL"
58
+ else
59
+ opts[:projection_type] = "ALL"
60
+ end
61
+
62
+ if opts[:hash_key] == opts[:range_key]
63
+ raise ArgumentError.new("#{opts[:hash_key]} cannot be both the rkey and hkey for gsi #{name}")
64
+ end
65
+
66
+ @name = name
67
+ @hash_key = opts[:hash_key]
68
+ @range_key = opts[:range_key]
69
+ @projection_type = '"' + "#{opts[:projection_type]}" + '"'
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,79 @@
1
+ # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You may not
4
+ # use this file except in compliance with the License. A copy of the License is
5
+ # located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is distributed on
10
+ # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
+ # or implied. See the License for the specific language governing permissions
12
+ # and limitations under the License.
13
+
14
+ require 'rails/generators/rails/app/app_generator'
15
+ require "rails/generators/testing/behaviour"
16
+ require "fileutils"
17
+ require "minitest/spec"
18
+
19
+ module AwsRecord
20
+ module Generators
21
+ class GeneratorTestHelper
22
+ include Minitest::Assertions
23
+ attr_accessor :assertions
24
+
25
+ include Rails::Generators::Testing::Behaviour
26
+ include FileUtils
27
+
28
+ def initialize(klass, dest)
29
+ @temp_root = File.expand_path(dest)
30
+
31
+ GeneratorTestHelper.tests klass
32
+ temp_app_dest = File.join(File.expand_path(@temp_root, __dir__), "test_app")
33
+ GeneratorTestHelper.destination temp_app_dest
34
+
35
+ destination_root_is_set?
36
+ prepare_destination
37
+ setup_test_app
38
+ ensure_current_path
39
+
40
+ self.assertions = 0
41
+ end
42
+
43
+ def run_in_test_app(cmd)
44
+ cd destination_root
45
+ a = `rails #{cmd}`
46
+
47
+ ensure_current_path
48
+ end
49
+
50
+ def assert_file(generated_file, actual_file)
51
+ assert File.exist?(generated_file), "Expected file #{generated_file.inspect} to exist, but does not"
52
+ assert File.exist?(actual_file), "Expected file #{actual_file.inspect} to exist, but does not"
53
+ assert identical? generated_file, actual_file
54
+ end
55
+
56
+ def assert_not_file(file_path)
57
+ assert !File.exist?(file_path), "Expected file #{file_path.inspect} to not exist, but does"
58
+ end
59
+
60
+ def cleanup
61
+ rm_rf @temp_root
62
+ end
63
+
64
+ def run_generator(args = default_arguments, config = {})
65
+ capture(:stderr) do
66
+ super
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def setup_test_app
73
+ Rails::Generators::AppGenerator.start [destination_root, '--skip-bundle', '--skip-git', '--skip-spring', '--skip-test', '-d' , '--skip-javascript', '--force', '--quiet']
74
+ `echo 'gem "aws-record-generator", :path => "../../"' >> "#{destination_root}/Gemfile"`
75
+ `bundle install --gemfile "#{destination_root}/Gemfile"`
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,26 @@
1
+ # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You may not
4
+ # use this file except in compliance with the License. A copy of the License is
5
+ # located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is distributed on
10
+ # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
+ # or implied. See the License for the specific language governing permissions
12
+ # and limitations under the License.
13
+
14
+ desc "Run all table configs in table_config folder"
15
+
16
+ namespace :aws_record do
17
+ task migrate: :environment do
18
+ Dir[File.join('db', 'table_config', '**/*.rb')].each do |filename|
19
+ puts "running #{filename}"
20
+ load(filename)
21
+
22
+ table_config = ModelTableConfig.config
23
+ table_config.migrate! unless table_config.compatible?
24
+ end
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aws-record-generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.pre.1
5
+ platform: ruby
6
+ authors:
7
+ - Amazon Web Services
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-06-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-record
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '4.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '4.2'
41
+ description: Rails generators for aws-record models
42
+ email:
43
+ - yasharm@amazon.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - lib/aws-record-generator.rb
49
+ - lib/generators/aws_record/model/USAGE
50
+ - lib/generators/aws_record/model/model_generator.rb
51
+ - lib/generators/aws_record/model/templates/model.rb.tt
52
+ - lib/generators/aws_record/model/templates/table_config.rb.tt
53
+ - lib/generators/generated_attribute.rb
54
+ - lib/generators/secondary_index.rb
55
+ - lib/generators/test_helper.rb
56
+ - lib/tasks/table_config_migrate_task.rake
57
+ homepage: https://github.com/awslabs/aws-record-generator
58
+ licenses:
59
+ - Apache 2.0
60
+ metadata: {}
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">"
73
+ - !ruby/object:Gem::Version
74
+ version: 1.3.1
75
+ requirements: []
76
+ rubyforge_project:
77
+ rubygems_version: 2.6.13
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: Rails generators for aws-record
81
+ test_files: []