nando 1.0.6
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/.env +2 -0
- data/.gitignore +19 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +47 -0
- data/LICENSE +201 -0
- data/README.md +49 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/nando +83 -0
- data/lib/nando/baseline_templates/migration.rb +9 -0
- data/lib/nando/errors.rb +13 -0
- data/lib/nando/generator.rb +86 -0
- data/lib/nando/interface.rb +87 -0
- data/lib/nando/logger.rb +30 -0
- data/lib/nando/migration.rb +347 -0
- data/lib/nando/migrator.rb +369 -0
- data/lib/nando/parser.rb +68 -0
- data/lib/nando/parser_templates/migration.rb +13 -0
- data/lib/nando/schema_diff.rb +805 -0
- data/lib/nando/templates/migration.rb +9 -0
- data/lib/nando/templates/migration_without_transaction.rb +9 -0
- data/lib/nando/updater.rb +372 -0
- data/lib/nando/utils.rb +22 -0
- data/lib/nando/version.rb +3 -0
- data/lib/nando.rb +12 -0
- data/nando.gemspec +44 -0
- data/notes.txt +128 -0
- metadata +200 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
module MigrationUpdater
|
|
2
|
+
|
|
3
|
+
def self.update_migration (migration_file_path, working_directory, functions_to_add)
|
|
4
|
+
|
|
5
|
+
if !File.file?(migration_file_path)
|
|
6
|
+
raise Nando::GenericError.new("No file '#{migration_file_path}' was found")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
@working_directory = working_directory
|
|
10
|
+
@lines = File.readlines(migration_file_path)
|
|
11
|
+
up_keyword = 'NANDO'
|
|
12
|
+
@up_annotation_trigger = "(\s*)(?:#\s(?:#{up_keyword}:)(?:\s)?)(.*)" # match 1 is the space to indent, and match 2 is the file being linked
|
|
13
|
+
@last_scanned_index = 0
|
|
14
|
+
|
|
15
|
+
@changed_file = false
|
|
16
|
+
@source_files_copied = []
|
|
17
|
+
|
|
18
|
+
if !functions_to_add.nil?
|
|
19
|
+
add_new_annotations_to_file_lines(functions_to_add)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
@curr_migration_version, _ = NandoUtils.get_migration_version_and_name_from_file_path(migration_file_path)
|
|
23
|
+
find_and_update()
|
|
24
|
+
|
|
25
|
+
if @changed_file
|
|
26
|
+
File.write(migration_file_path, @lines.join(''))
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# iterates the file, finds annotations and updates them
|
|
31
|
+
def self.find_and_update
|
|
32
|
+
do_another_loop = false
|
|
33
|
+
prepend_append_execute = false
|
|
34
|
+
|
|
35
|
+
starting_sql_index = ending_sql_index = nil
|
|
36
|
+
|
|
37
|
+
line_match = nil
|
|
38
|
+
|
|
39
|
+
execute_match = nil
|
|
40
|
+
ending_execute_match = nil
|
|
41
|
+
|
|
42
|
+
annotation_file = nil
|
|
43
|
+
duplicate_annotation = false
|
|
44
|
+
|
|
45
|
+
@lines.each_with_index do |line, line_index|
|
|
46
|
+
line_match = line.match(@up_annotation_trigger)
|
|
47
|
+
|
|
48
|
+
# found a annotation that has not been updated
|
|
49
|
+
if !line_match.nil? && line_index > @last_scanned_index
|
|
50
|
+
@last_scanned_index = line_index
|
|
51
|
+
do_another_loop = true
|
|
52
|
+
annotation_file = line_match[2]
|
|
53
|
+
|
|
54
|
+
if @source_files_copied.include?(annotation_file)
|
|
55
|
+
_warn "The file '#{annotation_file}' has already been updated in the current migration, remove the duplicate annotation! Skipping!"
|
|
56
|
+
duplicate_annotation = true
|
|
57
|
+
break
|
|
58
|
+
else
|
|
59
|
+
@source_files_copied.push(annotation_file)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# find beginning of block
|
|
63
|
+
if execute_match = @lines[line_index+1].match("(.*)update_function(.*)SQL(.*)\n")
|
|
64
|
+
starting_sql_index = line_index + 1
|
|
65
|
+
ending_trigger = execute_match[1] + 'SQL' + "\n"
|
|
66
|
+
|
|
67
|
+
# find ending of block
|
|
68
|
+
for ending_block_index in line_index+2..@lines.length-1 do
|
|
69
|
+
if ending_execute_match = @lines[ending_block_index].match(ending_trigger)
|
|
70
|
+
ending_sql_index = ending_block_index
|
|
71
|
+
break
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
# we need to create an update_function block, since one does not exist
|
|
75
|
+
else
|
|
76
|
+
starting_sql_index = line_index + 1
|
|
77
|
+
ending_sql_index = starting_sql_index - 1
|
|
78
|
+
prepend_append_execute = true
|
|
79
|
+
end
|
|
80
|
+
break
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
if do_another_loop
|
|
85
|
+
# update the block for the current annotation (if not a duplicate)
|
|
86
|
+
if !(starting_sql_index.nil? && ending_sql_index.nil?) && !duplicate_annotation
|
|
87
|
+
curr_source_file = "#{@working_directory}/#{annotation_file}"
|
|
88
|
+
|
|
89
|
+
if File.file?(curr_source_file)
|
|
90
|
+
# delete from array lines for current update_function block (if there is any)
|
|
91
|
+
@lines.slice!(starting_sql_index, (ending_sql_index - starting_sql_index) + 1)
|
|
92
|
+
# insert into array new update_function block
|
|
93
|
+
curr_file_lines = File.readlines(curr_source_file)
|
|
94
|
+
# create execute block
|
|
95
|
+
if prepend_append_execute
|
|
96
|
+
curr_file_lines.map! { |line| line == "\n" ? line : (" " + line_match[1] + line) }
|
|
97
|
+
curr_file_lines[curr_file_lines.length - 1].rstrip!
|
|
98
|
+
curr_file_lines.insert(0, line_match[1] + "update_function <<-'SQL'\n")
|
|
99
|
+
curr_file_lines.push("\n" + line_match[1] + "SQL\n")
|
|
100
|
+
else
|
|
101
|
+
curr_file_lines.map! { |line| line == "\n" ? line : (" " + execute_match[1] + line) }
|
|
102
|
+
curr_file_lines[curr_file_lines.length - 1].rstrip!
|
|
103
|
+
curr_file_lines.insert(0, execute_match[0])
|
|
104
|
+
curr_file_lines.push("\n" + ending_execute_match[0])
|
|
105
|
+
end
|
|
106
|
+
@lines.insert(starting_sql_index, *curr_file_lines)
|
|
107
|
+
|
|
108
|
+
find_and_update_respective_down_directive(annotation_file, curr_source_file, line_match[1])
|
|
109
|
+
|
|
110
|
+
@last_scanned_index = starting_sql_index + curr_file_lines.length - 1
|
|
111
|
+
@changed_file = true
|
|
112
|
+
_success "Updated content for #{curr_source_file}"
|
|
113
|
+
else
|
|
114
|
+
_warn "Couldn't find file: '#{curr_source_file}'! Skipping that one!"
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
find_and_update()
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def self.find_and_update_respective_down_directive (source_file, source_file_full_path, indent_space)
|
|
123
|
+
# if a NANDO directive is being updated, then we need to find the respetive down (X)
|
|
124
|
+
# start from the top of the file, try and find the directive (may try to optmize this later, to start at "def down") (X)
|
|
125
|
+
# if the directive is found, update it.
|
|
126
|
+
# if not, create one at the bottom of the file and update it
|
|
127
|
+
# matching is done using the source_file, but the code to fill the down comes from previous migrations (NOT THE FILE)
|
|
128
|
+
|
|
129
|
+
down_keyword = 'NANDO_DOWN'
|
|
130
|
+
down_annotation_index = nil
|
|
131
|
+
down_annotation_trigger = "(\s*)(?:#\s(?:#{down_keyword}:)(?:\s)?)(?:#{source_file})" # match 1 is the space to indent
|
|
132
|
+
|
|
133
|
+
down_method_index = nil
|
|
134
|
+
down_method_trigger = "(\s*)def(?:\s*)down(.*)"
|
|
135
|
+
down_method_end_trigger = nil # to find respective "end"
|
|
136
|
+
|
|
137
|
+
line_match = nil
|
|
138
|
+
|
|
139
|
+
# find down annotation
|
|
140
|
+
@lines.each_with_index do |line, line_index|
|
|
141
|
+
# find start of down method (ignore before that)
|
|
142
|
+
if down_method_index.nil?
|
|
143
|
+
line_match = line.match(down_method_trigger)
|
|
144
|
+
if !line_match.nil?
|
|
145
|
+
# _debug 'Found beginning of down method'
|
|
146
|
+
down_method_index = line_index
|
|
147
|
+
down_method_indent = line_match[1]
|
|
148
|
+
down_method_end_trigger = "^(?:#{line_match[1]}end).*"
|
|
149
|
+
end
|
|
150
|
+
next
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# start looking for an annotation
|
|
154
|
+
line_match = line.match(down_annotation_trigger)
|
|
155
|
+
|
|
156
|
+
# found a annotation that has not been updated
|
|
157
|
+
if !line_match.nil?
|
|
158
|
+
# _debug "Found matching annotation for: '#{source_file}'"
|
|
159
|
+
down_annotation_index = line_index
|
|
160
|
+
break
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# no annotation found, create one
|
|
165
|
+
if down_annotation_index.nil?
|
|
166
|
+
# _debug "Did not find respective down annotation for: '#{source_file}'"
|
|
167
|
+
|
|
168
|
+
@lines.each_with_index do |line, line_index|
|
|
169
|
+
# ignore before "def down"
|
|
170
|
+
if line_index <= down_method_index
|
|
171
|
+
next
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# look for the "end" of "def down"
|
|
175
|
+
line_match = line.match(down_method_end_trigger)
|
|
176
|
+
if !line_match.nil?
|
|
177
|
+
# _debug "Found the end of 'def down' at index: #{line_index}"
|
|
178
|
+
@lines.insert(line_index, "\n") # insert empty line to keep annotations 1 line apart
|
|
179
|
+
@lines.insert(line_index, indent_space + "# #{down_keyword}: #{source_file}\n")
|
|
180
|
+
down_annotation_index = line_index
|
|
181
|
+
break
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# update annotation
|
|
187
|
+
source_file_text = File.readlines(source_file_full_path).join(' ')
|
|
188
|
+
# all capture groups are non-greedy, and include any character since names may have '.' for example
|
|
189
|
+
function_info_match = /CREATE (?:OR REPLACE)? FUNCTION (.*?)\((.*?)\) RETURNS (.*?) AS \$\w*\$/im.match(source_file_text) # case insenstive and multi-line
|
|
190
|
+
|
|
191
|
+
if function_info_match.nil?
|
|
192
|
+
raise Nando::GenericError.new("No function definition was found in '#{source_file_full_path}'")
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
function_name = function_info_match[1].strip
|
|
196
|
+
# function_args = function_info_match[2].strip
|
|
197
|
+
# function_return = function_info_match[3].strip
|
|
198
|
+
|
|
199
|
+
file_regex = "CREATE \\(OR REPLACE\\)\\? FUNCTION #{function_name}"
|
|
200
|
+
|
|
201
|
+
files_with_function = %x[grep -irl -e "#{file_regex}" #{NandoMigrator.instance.working_dir}/#{NandoMigrator.instance.migration_dir}].split("\n").sort().reverse()
|
|
202
|
+
|
|
203
|
+
function_previous_block = nil
|
|
204
|
+
|
|
205
|
+
for curr_file_path in files_with_function do
|
|
206
|
+
# _debug curr_file_path
|
|
207
|
+
|
|
208
|
+
if curr_file_path.include?(@curr_migration_version)
|
|
209
|
+
_debug 'Ignore self while updating'
|
|
210
|
+
next
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
curr_file_version, _ = NandoUtils.get_migration_version_and_name_from_file_path(curr_file_path)
|
|
214
|
+
if curr_file_version.to_i > @curr_migration_version.to_i
|
|
215
|
+
_debug 'Skipping migrations more recent than the current one'
|
|
216
|
+
next
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
up_line_index = nil
|
|
220
|
+
down_line_index = nil
|
|
221
|
+
function_line_index = nil
|
|
222
|
+
|
|
223
|
+
curr_file_lines = File.readlines(curr_file_path)
|
|
224
|
+
|
|
225
|
+
# find up, down and line with definition
|
|
226
|
+
curr_file_lines.each_with_index do |line, line_index|
|
|
227
|
+
if up_line_index.nil? && line.match(/(?:\s*)def(?:\s*)up/) then up_line_index = line_index; end
|
|
228
|
+
if down_line_index.nil? && line.match(/(?:\s*)def(?:\s*)down/) then down_line_index = line_index; end
|
|
229
|
+
if function_line_index.nil? && line.match(/CREATE (?:OR REPLACE)? FUNCTION #{function_name}/i) then function_line_index = line_index; end
|
|
230
|
+
|
|
231
|
+
if !up_line_index.nil? && !down_line_index.nil? && !function_line_index.nil?
|
|
232
|
+
# _debug "Found all 3 lines"
|
|
233
|
+
break
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# TODO: only catch definition between up and down indexes
|
|
238
|
+
|
|
239
|
+
# _debug "up: #{up_line_index} | down: #{down_line_index} | function: #{function_line_index}"
|
|
240
|
+
|
|
241
|
+
# TODO: add some validations over current block
|
|
242
|
+
# TODO: match function with correct parameters/return value
|
|
243
|
+
# TODO: isolate into function that extracts block
|
|
244
|
+
|
|
245
|
+
block_indent = nil
|
|
246
|
+
block_start_index = nil
|
|
247
|
+
block_end_index = nil
|
|
248
|
+
|
|
249
|
+
# get block around function
|
|
250
|
+
for block_line_index in (0..function_line_index).to_a.reverse() do
|
|
251
|
+
block_line = curr_file_lines[block_line_index]
|
|
252
|
+
if block_match = block_line.match("(.*)update_function(?:.*)SQL(?:.*)\n")
|
|
253
|
+
block_indent = block_match[1]
|
|
254
|
+
block_start_index = block_line_index
|
|
255
|
+
break
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
for block_line_index in function_line_index..curr_file_lines.length do
|
|
260
|
+
block_line = curr_file_lines[block_line_index]
|
|
261
|
+
if block_match = block_line.match("^#{block_indent}SQL(?:.*)\n")
|
|
262
|
+
block_end_index = block_line_index
|
|
263
|
+
break
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
function_block = []
|
|
268
|
+
for block_line_index in block_start_index..block_end_index do
|
|
269
|
+
function_block.push(curr_file_lines[block_line_index])
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
function_previous_block = function_block.join('')
|
|
273
|
+
break
|
|
274
|
+
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
if function_previous_block.nil?
|
|
278
|
+
# TODO: decide if I need to do anything more when I don't find a previous definition (like add a DROP)
|
|
279
|
+
_warn "No previous definition was found for function '#{function_name}'"
|
|
280
|
+
return
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
# erase previous block (if one exists)
|
|
284
|
+
# TODO: there is similar logic above, maybe resolve to a single function
|
|
285
|
+
if curr_down_block_start = @lines[down_annotation_index+1].match("(.*)update_function(.*)SQL(.*)\n")
|
|
286
|
+
ending_trigger = curr_down_block_start[1] + 'SQL' + "\n"
|
|
287
|
+
starting_sql_index = down_annotation_index + 1
|
|
288
|
+
ending_sql_index = nil
|
|
289
|
+
|
|
290
|
+
# find ending of block
|
|
291
|
+
for ending_down_block_index in down_annotation_index+2..@lines.length-1 do
|
|
292
|
+
if ending_execute_match = @lines[ending_down_block_index].match(ending_trigger)
|
|
293
|
+
ending_sql_index = ending_down_block_index
|
|
294
|
+
break
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
# TODO: add protections here if it does not find the end of the block
|
|
299
|
+
# delete from array lines for current update_function block
|
|
300
|
+
@lines.slice!(starting_sql_index, (ending_sql_index - starting_sql_index) + 1)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
@lines.insert(down_annotation_index + 1, function_previous_block)
|
|
304
|
+
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
## adds new annotations to bottom of "up" method
|
|
308
|
+
def self.add_new_annotations_to_file_lines (functions_to_add)
|
|
309
|
+
migration_file_lines = @lines
|
|
310
|
+
_, up_end_index, _, _ = get_migration_file_up_and_down_limits(migration_file_lines)
|
|
311
|
+
|
|
312
|
+
# insert annotations at the bottom of the "up" method
|
|
313
|
+
functions_to_add.each do |curr_function_path|
|
|
314
|
+
_debug curr_function_path
|
|
315
|
+
annotation = NandoUtils.get_annotation_from_file_path(curr_function_path)
|
|
316
|
+
migration_file_lines.insert(up_end_index, annotation)
|
|
317
|
+
migration_file_lines.insert(up_end_index, "\n") # insert empty line to separate annotations
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
@lines = migration_file_lines
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
def self.get_migration_file_up_and_down_limits (file_lines)
|
|
324
|
+
up_start_index = nil
|
|
325
|
+
up_end_index = nil
|
|
326
|
+
down_start_index = nil
|
|
327
|
+
down_end_index = nil
|
|
328
|
+
|
|
329
|
+
curr_state = nil
|
|
330
|
+
def_indent = nil
|
|
331
|
+
|
|
332
|
+
# find up, down (beggining and end of functions are done by finding an "end" with the same indentation)
|
|
333
|
+
file_lines.each_with_index do |line, line_index|
|
|
334
|
+
case curr_state
|
|
335
|
+
when 'up', 'down'
|
|
336
|
+
# look for end of up/down
|
|
337
|
+
if line_match = line.match(/^#{def_indent}end$/)
|
|
338
|
+
if curr_state == 'up'
|
|
339
|
+
up_end_index = line_index
|
|
340
|
+
else
|
|
341
|
+
down_end_index = line_index
|
|
342
|
+
end
|
|
343
|
+
curr_state = nil
|
|
344
|
+
def_indent = nil
|
|
345
|
+
end
|
|
346
|
+
else
|
|
347
|
+
# read line trying to find beggining of "up" or "down"
|
|
348
|
+
if line_match = line.match(/(\s*)def(?:\s*)up/) then
|
|
349
|
+
curr_state = 'up'
|
|
350
|
+
def_indent = line_match[1]
|
|
351
|
+
up_start_index = line_index
|
|
352
|
+
next
|
|
353
|
+
end
|
|
354
|
+
if line_match = line.match(/(\s*)def(?:\s*)down/) then
|
|
355
|
+
curr_state = 'down'
|
|
356
|
+
def_indent = line_match[1]
|
|
357
|
+
down_start_index = line_index
|
|
358
|
+
next
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
if !up_end_index.nil? && !down_end_index.nil?
|
|
363
|
+
# _debug "Found up and down"
|
|
364
|
+
break
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
# TODO: might add some checks if the index values don't make sense
|
|
369
|
+
return up_start_index, up_end_index, down_start_index, down_end_index
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
end
|
data/lib/nando/utils.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module NandoUtils
|
|
2
|
+
|
|
3
|
+
def self.get_annotation_from_file_path (file_path)
|
|
4
|
+
return " # NANDO: #{file_path}\n"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
# accepts either a path or a file name
|
|
8
|
+
def self.get_migration_version_and_name_from_file_path (file_path)
|
|
9
|
+
file_name = file_path.split('/')[-1] # get last part of the file path
|
|
10
|
+
match = /^(\d+)\_(.*)\.rb$/.match(file_name)
|
|
11
|
+
if match.nil?
|
|
12
|
+
raise Nando::GenericError.new("'#{file_name}' is not a valid file name")
|
|
13
|
+
end
|
|
14
|
+
migration_version = match[1] # by this point, the file name has already been validated, so I don't need to double check
|
|
15
|
+
migration_name = match[2]
|
|
16
|
+
return migration_version, migration_name
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# TODO: move helper methods here, to not fill the main files
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
|
data/lib/nando.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'nando'
|
|
2
|
+
require 'nando/errors'
|
|
3
|
+
require 'nando/version'
|
|
4
|
+
require 'nando/migrator'
|
|
5
|
+
require 'nando/logger'
|
|
6
|
+
require 'nando/migration'
|
|
7
|
+
require 'nando/generator'
|
|
8
|
+
require 'nando/parser'
|
|
9
|
+
require 'nando/updater'
|
|
10
|
+
require 'nando/interface'
|
|
11
|
+
require 'nando/schema_diff'
|
|
12
|
+
require 'nando/utils'
|
data/nando.gemspec
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
|
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require "nando/version"
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "nando"
|
|
8
|
+
spec.version = Nando::VERSION
|
|
9
|
+
spec.authors = ["Fernando Alves"]
|
|
10
|
+
spec.email = ["fernando.alves@cldware.com"]
|
|
11
|
+
|
|
12
|
+
spec.summary = %q{Nando AdmiNs Database Objects}
|
|
13
|
+
spec.description = %q{NANDO - Nando AdmiNs Database Objects}
|
|
14
|
+
|
|
15
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
16
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
17
|
+
if spec.respond_to?(:metadata)
|
|
18
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
|
19
|
+
else
|
|
20
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
|
21
|
+
"public gem pushes."
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Specify which files should be added to the gem when it is released.
|
|
25
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
26
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
|
27
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
28
|
+
end
|
|
29
|
+
spec.bindir = "exe"
|
|
30
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
31
|
+
spec.require_paths = ["lib"]
|
|
32
|
+
|
|
33
|
+
spec.add_development_dependency "bundler", "~> 1.17.3"
|
|
34
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
|
35
|
+
spec.add_development_dependency "rspec", "~> 3.2"
|
|
36
|
+
spec.add_development_dependency "byebug"
|
|
37
|
+
# dependencies
|
|
38
|
+
# TODO: review versions
|
|
39
|
+
spec.add_dependency "pg", "~> 1.2.3"
|
|
40
|
+
spec.add_dependency "optparse", "~> 0.1.0"
|
|
41
|
+
spec.add_dependency "dotenv", "~> 2.7.6"
|
|
42
|
+
spec.add_dependency "colorize", "~> 0.8.1"
|
|
43
|
+
spec.add_dependency "awesome_print", "~> 1.8.0"
|
|
44
|
+
end
|