dyna 0.1.9 → 0.2.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
- SHA1:
3
- metadata.gz: bf7e0af4635d19cc04464734c752ec8f68032ea3
4
- data.tar.gz: 68e76221165d0268c622001e07190ca753894c81
2
+ SHA256:
3
+ metadata.gz: e4c57e85bcc9f5bce4b084da7b9c6c7338529d1b83512b1549bc31f47d48bc1e
4
+ data.tar.gz: 5a14ba531ff8a96bb56ccd09af7db82d8c9e6a3024f3051be520203a890d382e
5
5
  SHA512:
6
- metadata.gz: 9940c92ee88b999d0a9a5a8ba7f745b4d9afd900773fdd7b512c85d289318dbbd81877c4217e569a7ee2b697dabcb0c61d9ac2be45c67cc3ff464dc01def0914
7
- data.tar.gz: 0a2aee89b5f14f22171dfd4a43b9235d9143af4b39b44e66023b0137b53037874b57d89975d70ec9f7864c74ed440f17d5108dbc706c023d5e02b2924a055e0b
6
+ metadata.gz: cf9547e5373b6b690623732de1c70a2efce0128863f53a92a1cbffcc7539ca5294299a993ecf587af339a1fce3fd7ef3f549e5f4313e3b3283003ccb9a54f28c
7
+ data.tar.gz: cbefd166bad5e80202ef3d0f9e5f73da90642fbb0dbce0e6a1c406e85143cae539fc0f7464c0240c88d6c31a21c1f1f6c3c6d4d2d654e069342243c14c7a0d67
data/dyna.gemspec CHANGED
@@ -20,7 +20,8 @@ Gem::Specification.new do |spec|
20
20
  spec.bindir = "bin"
21
21
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ["lib"]
23
- spec.add_dependency 'aws-sdk', '~> 2'
23
+ spec.add_dependency 'aws-sdk-dynamodb', '~> 1.18'
24
+ spec.add_dependency 'aws-sdk-applicationautoscaling', '~> 1.16'
24
25
  spec.add_dependency 'term-ansicolor', '~> 1.4'
25
26
  spec.add_dependency 'diffy', '~> 3.1'
26
27
  spec.add_dependency 'hashie', '~> 3.4'
data/lib/dyna.rb CHANGED
@@ -6,7 +6,8 @@ require 'hashie'
6
6
  require 'singleton'
7
7
  require 'pp'
8
8
 
9
- require 'aws-sdk'
9
+ require 'aws-sdk-applicationautoscaling'
10
+ require 'aws-sdk-dynamodb'
10
11
 
11
12
  require 'dyna/version'
12
13
  require 'dyna/logger'
data/lib/dyna/client.rb CHANGED
@@ -15,6 +15,8 @@ module Dyna
15
15
  )
16
16
  else
17
17
  @options.ddb = Aws::DynamoDB::Client.new
18
+ @options.aas = Aws::ApplicationAutoScaling::Client.new
19
+ Exporter.aas(@options.aas)
18
20
  end
19
21
  end
20
22
 
@@ -35,41 +35,42 @@ end
35
35
  stream_specification = ''
36
36
  if table[:local_secondary_indexes]
37
37
  local_secondary_indexes_tmpl = <<-EOS.chomp
38
- <% table[:local_secondary_indexes].each do |index| %>
38
+ <% table[:local_secondary_indexes].each do |index| -%>
39
39
  local_secondary_index <%= index[:index_name].inspect %> do
40
40
  key_schema hash: <%= index[:key_schema][0][:attribute_name].inspect %>, range: <%= index[:key_schema][1][:attribute_name].inspect %><% if index[:projection] %>
41
41
  projection projection_type: <%= index[:projection][:projection_type].inspect %><% end %>
42
42
  end
43
- <% end %>
43
+ <%- end %>
44
44
  EOS
45
- local_secondary_indexes = ERB.new(local_secondary_indexes_tmpl).result(binding)
45
+ local_secondary_indexes = ERB.new(local_secondary_indexes_tmpl, nil, '-').result(binding)
46
46
  end
47
47
 
48
48
  if table[:global_secondary_indexes]
49
49
  global_secondary_indexes_tmpl = <<-EOS.chomp
50
- <% table[:global_secondary_indexes].each do |index| %>
50
+ <% table[:global_secondary_indexes].each do |index| -%>
51
51
  global_secondary_index <%= index[:index_name].inspect %> do
52
52
  key_schema hash: <%= index[:key_schema][0][:attribute_name].inspect %><% if index[:key_schema].size == 2 %>, range: <%= index[:key_schema][1][:attribute_name].inspect %><% end %><% if index[:projection] %>
53
53
  projection projection_type: <%= index[:projection][:projection_type].inspect %><% end %>
54
54
  provisioned_throughput read_capacity_units: <%= index[:provisioned_throughput][:read_capacity_units] %>, write_capacity_units: <%= index[:provisioned_throughput][:read_capacity_units] %>
55
55
  end
56
- <% end %>
56
+ <%- end %>
57
57
  EOS
58
- global_secondary_indexes = ERB.new(global_secondary_indexes_tmpl).result(binding)
58
+ global_secondary_indexes = ERB.new(global_secondary_indexes_tmpl, nil, '-').result(binding)
59
59
  end
60
60
 
61
61
  attribute_definitions_tmpl = <<-EOS.chomp
62
- <% table[:attribute_definitions].each do |attr| %>
62
+ <% table[:attribute_definitions].each do |attr| -%>
63
+
63
64
  attribute_definition(
64
65
  attribute_name: <%= attr[:attribute_name].inspect %>,
65
66
  attribute_type: <%= attr[:attribute_type].inspect %>,
66
67
  )
67
- <% end %>
68
+ <%- end %>
68
69
  EOS
69
- attribute_definitions = ERB.new(attribute_definitions_tmpl).result(binding)
70
+ attribute_definitions = ERB.new(attribute_definitions_tmpl, nil, '-').result(binding)
70
71
 
71
72
  if table[:stream_specification]
72
- stream_specification_tmpl = <<-EOS.chomp
73
+ stream_specification_tmpl = <<-EOS
73
74
 
74
75
  stream_specification(
75
76
  stream_enabled: <%= table[:stream_specification][:stream_enabled] %>,
@@ -79,6 +80,35 @@ EOS
79
80
  stream_specification = ERB.new(stream_specification_tmpl).result(binding)
80
81
  end
81
82
 
83
+ if table[:scalable_targets]
84
+ scalable_targets_tmpl = <<-EOS.chomp
85
+ <% table[:scalable_targets].each do |target| -%>
86
+
87
+ scalable_target(
88
+ scalable_dimension: <%= target[:scalable_dimension].inspect %>,
89
+ min_capacity: <%= target[:min_capacity] %>,
90
+ max_capacity: <%= target[:max_capacity] %>,
91
+ )
92
+ <%- end %>
93
+ EOS
94
+ scalable_targets = ERB.new(scalable_targets_tmpl, nil, '-').result(binding)
95
+ end
96
+
97
+ if table[:scaling_policies]
98
+ scaling_policies_tmpl = <<-EOS.chomp
99
+ <% table[:scaling_policies].each do |policy| -%>
100
+
101
+ scaling_policy(
102
+ scalable_dimension: <%= policy[:scalable_dimension].inspect %>,
103
+ target_tracking_scaling_policy_configuration: {
104
+ target_value: <%= policy[:target_tracking_scaling_policy_configuration][:target_value] %>,
105
+ },
106
+ )
107
+ <%- end %>
108
+ EOS
109
+ scaling_policies = ERB.new(scaling_policies_tmpl, nil, '-').result(binding)
110
+ end
111
+
82
112
  <<-EOS
83
113
  table "#{name}" do
84
114
  key_schema(
@@ -90,7 +120,9 @@ EOS
90
120
  read_capacity_units: #{table[:provisioned_throughput][:read_capacity_units]},
91
121
  write_capacity_units: #{table[:provisioned_throughput][:write_capacity_units]},
92
122
  )
93
- #{local_secondary_indexes}#{global_secondary_indexes}#{stream_specification}
123
+
124
+ billing_mode #{table[:billing_mode].inspect}
125
+ #{local_secondary_indexes}#{global_secondary_indexes}#{stream_specification}#{scalable_targets}#{scaling_policies}
94
126
  end
95
127
  EOS
96
128
  end
@@ -11,6 +11,8 @@ module Dyna
11
11
 
12
12
  @result = Hashie::Mash.new({
13
13
  :table_name => table_name,
14
+ :scalable_targets => [],
15
+ :scaling_policies => [],
14
16
  })
15
17
  instance_eval(&block)
16
18
  end
@@ -69,6 +71,35 @@ module Dyna
69
71
  }.merge(index.result.symbolize_keys)
70
72
  end
71
73
 
74
+ def billing_mode(billing_mode)
75
+ @result.billing_mode = billing_mode
76
+ end
77
+
78
+ def scalable_target(scalable_dimension:, min_capacity:, max_capacity:)
79
+ @result.scalable_targets << {
80
+ service_namespace: 'dynamodb',
81
+ scalable_dimension: scalable_dimension,
82
+ resource_id: "table/#{@result.table_name}",
83
+ min_capacity: min_capacity,
84
+ max_capacity: max_capacity,
85
+ }
86
+ end
87
+
88
+ def scaling_policy(scalable_dimension:, target_tracking_scaling_policy_configuration:)
89
+ predefined_metric_type = 'DynamoDBWriteCapacityUtilization'
90
+ if scalable_dimension == 'dynamodb:table:ReadCapacityUnits'
91
+ predefined_metric_type = 'DynamoDBReadCapacityUtilization'
92
+ end
93
+ @result.scaling_policies << {
94
+ policy_name: "#{predefined_metric_type}:table/#{@result.table_name}",
95
+ policy_type: 'TargetTrackingScaling',
96
+ resource_id: "table/#{@result.table_name}",
97
+ scalable_dimension: scalable_dimension,
98
+ service_namespace: 'dynamodb',
99
+ target_tracking_scaling_policy_configuration: target_tracking_scaling_policy_configuration.merge(predefined_metric_specification: {predefined_metric_type: predefined_metric_type}),
100
+ }
101
+ end
102
+
72
103
  class LocalSecondaryIndex
73
104
  attr_accessor :result
74
105
 
data/lib/dyna/exporter.rb CHANGED
@@ -15,12 +15,16 @@ module Dyna
15
15
  end
16
16
 
17
17
  def export
18
- @ddb.list_tables.table_names
19
- .reject { |name| should_skip(name) }
20
- .sort
21
- .each_with_object({}) do |table_name, result|
22
- result[table_name] = self.class.export_table(@ddb, table_name)
18
+ result = {}
19
+ @ddb.list_tables.map do |tables|
20
+ tables.table_names
21
+ .reject { |name| should_skip(name) }
22
+ .sort
23
+ .each do |table_name|
24
+ result[table_name] = self.class.export_table(@ddb, table_name)
25
+ end
23
26
  end
27
+ result
24
28
  end
25
29
 
26
30
  def self.table_definition(describe_table)
@@ -28,6 +32,7 @@ module Dyna
28
32
  table_name: describe_table.table_name,
29
33
  key_schema: key_schema(describe_table),
30
34
  attribute_definitions: attribute_definitions(describe_table),
35
+ billing_mode: describe_table.billing_mode_summary&.billing_mode,
31
36
  provisioned_throughput: {
32
37
  read_capacity_units: describe_table.provisioned_throughput.read_capacity_units,
33
38
  write_capacity_units: describe_table.provisioned_throughput.write_capacity_units,
@@ -35,9 +40,15 @@ module Dyna
35
40
  local_secondary_indexes: local_secondary_indexes(describe_table),
36
41
  global_secondary_indexes: global_secondary_indexes(describe_table),
37
42
  stream_specification: stream_specification(describe_table),
43
+ scalable_targets: scalable_targets(describe_table),
44
+ scaling_policies: scaling_policies(describe_table),
38
45
  }
39
46
  end
40
47
 
48
+ def self.aas(aas)
49
+ @aas = aas
50
+ end
51
+
41
52
  private
42
53
  def self.export_table(ddb, table_name)
43
54
  describe_table = ddb.describe_table(table_name: table_name).table
@@ -102,5 +113,43 @@ module Dyna
102
113
  stream_view_type: stream_spec.stream_view_type,
103
114
  }
104
115
  end
116
+
117
+ def self.scalable_targets(table)
118
+ scalable_targets_by_resource_id["table/#{table.table_name}"] || []
119
+ end
120
+
121
+ def self.scalable_targets_by_resource_id
122
+ return @scalable_targets_by_resource_id if @scalable_targets_by_resource_id
123
+
124
+ results = []
125
+ next_token = nil
126
+ begin
127
+ resp = @aas.describe_scalable_targets(service_namespace: 'dynamodb', next_token: next_token)
128
+ resp.scalable_targets.each do |target|
129
+ results.push(target)
130
+ end
131
+ next_token = resp.next_token
132
+ end while next_token
133
+ @scalable_targets_by_resource_id = results.group_by(&:resource_id)
134
+ end
135
+
136
+ def self.scaling_policies(table)
137
+ scaling_policies_by_resource_id["table/#{table.table_name}"] || []
138
+ end
139
+
140
+ def self.scaling_policies_by_resource_id
141
+ return @scaling_policies_by_resource_id if @scaling_policies_by_resource_id
142
+
143
+ results = []
144
+ next_token = nil
145
+ begin
146
+ resp = @aas.describe_scaling_policies(service_namespace: 'dynamodb', next_token: next_token)
147
+ resp.scaling_policies.each do |policy|
148
+ results.push(policy)
149
+ end
150
+ next_token = resp.next_token
151
+ end while next_token
152
+ @scaling_policies_by_resource_id = results.group_by(&:resource_id)
153
+ end
105
154
  end
106
155
  end
data/lib/dyna/utils.rb CHANGED
@@ -1,6 +1,37 @@
1
1
  module Dyna
2
2
  class Utils
3
3
  class << self
4
+ def normalize_hash(hash)
5
+ hash.dup.each do |k, v|
6
+ if v.kind_of?(Array)
7
+ if v.first.kind_of?(Hash)
8
+ hash[k] = v.map { |o| normalize_hash(o) }
9
+ elsif v.first.respond_to?(:to_h)
10
+ hash[k] = v.map { |o| normalize_hash(o.to_h) }
11
+ else
12
+ v.sort!
13
+ end
14
+ elsif v.respond_to?(:to_h)
15
+ hash[k] = normalize_hash(v.to_h)
16
+ end
17
+ end
18
+ sort_keys(hash)
19
+ end
20
+
21
+ def sort_keys(hash)
22
+ hash = Hash[hash.sort]
23
+ hash.each do |k, v|
24
+ if v.kind_of?(Array)
25
+ if v.first.kind_of?(Hash)
26
+ hash[k] = v.map { |h| sort_keys(h) }
27
+ end
28
+ elsif v.kind_of?(Hash)
29
+ hash[k] = sort_keys(v)
30
+ end
31
+ end
32
+ hash
33
+ end
34
+
4
35
  def diff(obj1, obj2, options = {})
5
36
  diffy = Diffy::Diff.new(
6
37
  obj1.pretty_inspect,
data/lib/dyna/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Dyna
2
- VERSION = '0.1.9'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -8,17 +8,22 @@ module Dyna
8
8
  end
9
9
 
10
10
  def tables
11
- @ddb.list_tables.table_names.map do |table_name|
12
- describe_table = @ddb.describe_table(table_name: table_name).table
13
- Table.new(@ddb, describe_table, @options)
14
- end
11
+ @ddb.list_tables.map { |tables|
12
+ tables.table_names.map do |table_name|
13
+ describe_table = @ddb.describe_table(table_name: table_name).table
14
+ Table.new(@ddb, describe_table, @options)
15
+ end
16
+ }.flatten
15
17
  end
16
18
 
17
19
  def create(dsl)
18
20
  log(:info, 'Create Table', :cyan, "#{dsl.table_name}")
19
21
 
20
22
  unless @options.dry_run
21
- result = @ddb.create_table(dsl.symbolize_keys)
23
+ params = dsl.symbolize_keys
24
+ params.delete(:scalable_targets)
25
+ params.delete(:scaling_policies)
26
+ result = @ddb.create_table(params)
22
27
  @options.updated = true
23
28
  result
24
29
  end
@@ -20,9 +20,8 @@ module Dyna
20
20
  end
21
21
 
22
22
  def update(dsl)
23
- unless provisioned_throughput_eql?(dsl)
24
- wait_until_table_is_active
25
- update_table(dsl_provisioned_throughput(dsl))
23
+ unless billing_mode_eql?(dsl) && provisioned_throughput_eql?(dsl)
24
+ update_table(dsl)
26
25
  end
27
26
  unless global_secondary_indexes_eql?(dsl)
28
27
  wait_until_table_is_active
@@ -32,6 +31,9 @@ module Dyna
32
31
  wait_until_table_is_active
33
32
  update_stream_specification(dsl_stream_specification(dsl))
34
33
  end
34
+ unless auto_scaling_eql?(dsl)
35
+ update_auto_scaling(dsl)
36
+ end
35
37
  end
36
38
 
37
39
  def delete
@@ -63,14 +65,54 @@ module Dyna
63
65
  end
64
66
 
65
67
  private
68
+ def auto_scaling_eql?(dsl)
69
+ scalable_targets_eql?(dsl) && scaling_policies_eql?(dsl)
70
+ end
71
+
72
+ def scalable_targets_eql?(dsl)
73
+ df = definition[:scalable_targets].map do |target|
74
+ cmp = target.to_h
75
+ cmp.delete(:creation_time)
76
+ cmp.delete(:role_arn)
77
+ Dyna::Utils.normalize_hash(cmp)
78
+ end
79
+ df.sort_by {|s| s[:scalable_dimension] } == dsl[:scalable_targets].map { |target| Dyna::Utils.normalize_hash(target) }.sort_by {|s| s[:scalable_dimension] }
80
+ end
81
+
82
+ def scaling_policies_for_diff
83
+ definition[:scaling_policies].map { |policy|
84
+ #Dyna::Utils.normalize_hash({target_tracking_scaling_policy_configuration: {target_value: policy.target_tracking_scaling_policy_configuration.target_value} })
85
+ cmp = policy.to_h
86
+ cmp.delete(:alarms)
87
+ cmp.delete(:creation_time)
88
+ cmp.delete(:policy_arn)
89
+ Dyna::Utils.normalize_hash(cmp)
90
+ }.sort_by {|s| s[:scalable_dimension] }
91
+ end
92
+
93
+ def scaling_policies_eql?(dsl)
94
+ scaling_policies_for_diff == dsl.scaling_policies.map { |policy| Dyna::Utils.normalize_hash(policy) }.sort_by {|s| s[:scalable_dimension] }
95
+ end
96
+
66
97
  def definition_eql?(dsl)
67
98
  definition == dsl.definition
68
99
  end
69
100
 
70
101
  def provisioned_throughput_eql?(dsl)
102
+ if definition[:billing_mode] == 'PROVISIONED' && billing_mode_eql?(dsl)
103
+ return true
104
+ end
71
105
  self_provisioned_throughput == dsl_provisioned_throughput(dsl)
72
106
  end
73
107
 
108
+ def billing_mode_eql?(dsl)
109
+ if definition[:billing_mode] == dsl[:billing_mode]
110
+ return true
111
+ end
112
+
113
+ definition[:billing_mode].nil? && dsl[:billing_mode].to_s == 'PROVISIONED'
114
+ end
115
+
74
116
  def self_provisioned_throughput
75
117
  definition.select {|k,v| k == :provisioned_throughput}
76
118
  end
@@ -169,11 +211,24 @@ module Dyna
169
211
  end
170
212
 
171
213
  def update_table(dsl)
172
- log(:info, " table: #{@table.table_name}\n".green + Dyna::Utils.diff(self_provisioned_throughput, dsl, :color => @options.color, :indent => ' '), false)
214
+ params = {}
215
+ df_params = {}
216
+ unless billing_mode_eql?(dsl)
217
+ params[:billing_mode] = dsl[:billing_mode]
218
+ df_params[:billing_mode] = definition[:billing_mode]
219
+ end
220
+
221
+ if provisioned_throughput_eql?(dsl) == false && dsl[:scalable_targets].empty?
222
+ params[:provisioned_throughput] = dsl[:provisioned_throughput].symbolize_keys
223
+ df_params[:provisioned_throughput] = self_provisioned_throughput[:provisioned_throughput]
224
+ end
225
+
226
+ return if params.empty?
227
+ log(:info, " table: #{@table.table_name}\n".green + Dyna::Utils.diff(df_params, params, :color => @options.color, :indent => ' '), false)
173
228
  unless @options.dry_run
174
- params = dsl.dup
229
+ wait_until_table_is_active
175
230
  params[:table_name] = @table.table_name
176
- @ddb.update_table(params)
231
+ @ddb.update_table(params.symbolize_keys)
177
232
  @options.updated = true
178
233
  end
179
234
  end
@@ -205,6 +260,48 @@ module Dyna
205
260
  @options.updated = true
206
261
  end
207
262
  end
263
+
264
+ def update_auto_scaling(dsl)
265
+ has_change = false
266
+ unless scalable_targets_eql?(dsl)
267
+ has_change = true
268
+ df_cmp = definition[:scalable_targets].sort_by { |target| target[:scalable_dimension] }.map do |target|
269
+ h = target.to_h
270
+ h.delete(:creation_time)
271
+ h.delete(:role_arn)
272
+ Dyna::Utils.normalize_hash(h)
273
+ end
274
+ dsl_cmp = dsl.scalable_targets.sort_by { |target| target[:scalable_dimension] }.map { |target| Dyna::Utils.normalize_hash(target) }
275
+ log(:info, " table: #{@table.table_name}(update scalable targets)\n".green + Dyna::Utils.diff(df_cmp, dsl_cmp, :color => @options.color, :indent => ' '), false)
276
+ end
277
+
278
+ unless scaling_policies_eql?(dsl)
279
+ has_change = true
280
+ dsl_cmp = dsl.scaling_policies.map { |policy| Dyna::Utils.normalize_hash(policy) }.sort_by {|s| s[:scalable_dimension] }
281
+ log(:info, " table: #{@table.table_name}(update scaling policies)\n".green + Dyna::Utils.diff(scaling_policies_for_diff, dsl_cmp, :color => @options.color, :indent => ' '), false)
282
+ end
283
+
284
+ unless @options.dry_run
285
+ if has_change
286
+ definition[:scalable_targets].each do |target|
287
+ @options.aas.deregister_scalable_target(
288
+ service_namespace: 'dynamodb',
289
+ resource_id: target.resource_id,
290
+ scalable_dimension: target.scalable_dimension,
291
+ )
292
+ end
293
+
294
+ dsl.scalable_targets.each do |target|
295
+ @options.aas.register_scalable_target(target)
296
+ end
297
+
298
+ dsl.scaling_policies.each do |policy|
299
+ @options.aas.put_scaling_policy(policy)
300
+ end
301
+ end
302
+ @options.updated = true
303
+ end
304
+ end
208
305
  end
209
306
  end
210
307
  end
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dyna
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - wata
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-02 00:00:00.000000000 Z
11
+ date: 2019-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: aws-sdk
14
+ name: aws-sdk-dynamodb
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2'
19
+ version: '1.18'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2'
26
+ version: '1.18'
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws-sdk-applicationautoscaling
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.16'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.16'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: term-ansicolor
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -174,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
174
188
  version: '0'
175
189
  requirements: []
176
190
  rubyforge_project:
177
- rubygems_version: 2.5.2
191
+ rubygems_version: 2.7.6
178
192
  signing_key:
179
193
  specification_version: 4
180
194
  summary: Codenize DynamoDB table