yore 0.0.1
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.
- data/History.txt +4 -0
- data/Manifest.txt +22 -0
- data/PostInstall.txt +7 -0
- data/README.rdoc +48 -0
- data/Rakefile +57 -0
- data/bin/yore +65 -0
- data/lib/ihl_ruby/enum.rb +50 -0
- data/lib/ihl_ruby/extend_base_classes.rb +313 -0
- data/lib/ihl_ruby/misc_utils.rb +454 -0
- data/lib/ihl_ruby/string_utils.rb +53 -0
- data/lib/ihl_ruby/xml_utils.rb +163 -0
- data/lib/yore/yore_core.rb +491 -0
- data/lib/yore.orig.rb +6 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/rewind_spec.rb +187 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/test_job_a.xml +19 -0
- data/spec/yore_spec.rb +199 -0
- data/tasks/rspec.rake +21 -0
- metadata +128 -0
@@ -0,0 +1,491 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'RequirePaths'; require 'require_paths'
|
3
|
+
require_paths '.','..'
|
4
|
+
|
5
|
+
require 'fileutils'
|
6
|
+
require 'net/smtp'
|
7
|
+
|
8
|
+
require 'ihl_ruby/misc_utils'
|
9
|
+
require 'ihl_ruby/string_utils'
|
10
|
+
require 'ihl_ruby/xml_utils'
|
11
|
+
require 'ihl_ruby/extend_base_classes'
|
12
|
+
|
13
|
+
THIS_FILE = __FILE__
|
14
|
+
THIS_DIR = File.dirname(THIS_FILE)
|
15
|
+
|
16
|
+
module YoreCore
|
17
|
+
|
18
|
+
class KeepDaily
|
19
|
+
|
20
|
+
attr_reader :keep_age
|
21
|
+
|
22
|
+
def initialize(aKeepAge=14)
|
23
|
+
@keep_age = aKeepAge
|
24
|
+
end
|
25
|
+
|
26
|
+
def is?
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
def age(aDate)
|
31
|
+
|
32
|
+
end
|
33
|
+
def keep?(aDate)
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class KeepWeekly
|
39
|
+
|
40
|
+
attr_reader :keep_age
|
41
|
+
|
42
|
+
def initialize(aKeepAge=14)
|
43
|
+
@keep_age = aKeepAge
|
44
|
+
end
|
45
|
+
|
46
|
+
def is?
|
47
|
+
|
48
|
+
end
|
49
|
+
def age(aDate)
|
50
|
+
|
51
|
+
end
|
52
|
+
def keep?(aDate)
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class KeepMonthly
|
58
|
+
|
59
|
+
attr_reader :keep_age
|
60
|
+
|
61
|
+
def initialize(aKeepAge=14)
|
62
|
+
@keep_age = aKeepAge
|
63
|
+
end
|
64
|
+
|
65
|
+
def is?
|
66
|
+
|
67
|
+
end
|
68
|
+
def age(aDate)
|
69
|
+
|
70
|
+
end
|
71
|
+
def keep?(aDate)
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
class ConfigClass < Hash
|
78
|
+
|
79
|
+
def initialize(aDefaultHash=nil)
|
80
|
+
self.merge!(aDefaultHash) if aDefaultHash
|
81
|
+
end
|
82
|
+
|
83
|
+
def set_int(aKey,aValue)
|
84
|
+
case aValue
|
85
|
+
when String then self[aKey] = aValue.to_integer(self[aKey]);
|
86
|
+
when Fixnum then self[aKey] = aValue;
|
87
|
+
when Float then self[aKey] = aValue.to_i;
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def set_float(aKey,aValue)
|
92
|
+
case aValue
|
93
|
+
when String then self[aKey] = aValue.to_float(self[aKey]);
|
94
|
+
when Fixnum then self[aKey] = aValue.to_f;
|
95
|
+
when Float then self[aKey] = aValue;
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def set_boolean(aKey,aValue)
|
100
|
+
case aValue
|
101
|
+
when TrueClass,FalseClass then self[aKey] = aValue;
|
102
|
+
when String then self[aKey] = (['1','yes','y','true','on'].include?(aValue.downcase))
|
103
|
+
else
|
104
|
+
default set_boolean(aKey,aValue.to_s)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def set_symbol(aKey,aValue)
|
109
|
+
case aValue
|
110
|
+
when String then self[aKey] = (aValue.to_sym rescue nil);
|
111
|
+
when Symbol then self[aKey] = aValue;
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def copy_item(aHash,aKey)
|
116
|
+
case self[aKey]
|
117
|
+
when NilClass then ;
|
118
|
+
when String then self[aKey] = aHash[aKey].to_s unless aHash[aKey].nil?
|
119
|
+
when Float then set_float(aKey,aHash[aKey]);
|
120
|
+
when Fixnum then set_int(aKey,aHash[aKey]);
|
121
|
+
when TrueClass, FalseClass then set_boolean(aKey,aHash[aKey]);
|
122
|
+
when Symbol then self[aKey] = (aHash[aKey].to_sym rescue nil)
|
123
|
+
else
|
124
|
+
raise Error.new('unsupported type')
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def copy_strings(aHash,*aKeys)
|
129
|
+
aKeys.each do |k|
|
130
|
+
self[k] = aHash[k].to_s unless aHash[k].nil?
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def copy_ints(*aDb)
|
135
|
+
aHash = aDb.shift
|
136
|
+
aKeys = aDb
|
137
|
+
aKeys.each do |k|
|
138
|
+
set_int(k,aHash[k])
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def copy_floats(aHash,*aKeys)
|
143
|
+
aKeys.each do |k|
|
144
|
+
set_float(k,aHash[k])
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def copy_booleans(aHash,*aKeys)
|
149
|
+
aKeys.each do |k|
|
150
|
+
set_boolean(k,aHash[k])
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def to_hash
|
155
|
+
{}.merge(self)
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
class Yore
|
161
|
+
|
162
|
+
DEFAULT_CONFIG = {
|
163
|
+
:keep_daily => 14,
|
164
|
+
:keep_weekly => 12,
|
165
|
+
:keep_monthly => 12,
|
166
|
+
:crypto_iv => "3A63775C1E3F291B0925578165EB917E",
|
167
|
+
:crypto_key => "07692FC8656F04AE5518B80D38681E038A3C12050DF6CC97CEEC33D800D5E2FE",
|
168
|
+
:first_hour => 4,
|
169
|
+
:prefix => 'backup',
|
170
|
+
:log_level => 'DEBUG',
|
171
|
+
:bucket => '',
|
172
|
+
:email_report => false,
|
173
|
+
:mail_host => '',
|
174
|
+
:mail_port => 25,
|
175
|
+
:mail_helodomain => '',
|
176
|
+
:mail_user => '',
|
177
|
+
:mail_password => '',
|
178
|
+
:mail_from => '',
|
179
|
+
:mail_from_alias => '',
|
180
|
+
:mail_to => '',
|
181
|
+
:mail_to_alias => '',
|
182
|
+
:mail_auth => :plain,
|
183
|
+
:mysqldump => 'mysqldump'
|
184
|
+
}
|
185
|
+
|
186
|
+
attr_reader :config
|
187
|
+
attr_reader :logger
|
188
|
+
attr_reader :reporter
|
189
|
+
attr_reader :keepers
|
190
|
+
attr_reader :basepath
|
191
|
+
|
192
|
+
def initialize(aConfig=nil)
|
193
|
+
DEFAULT_CONFIG[:email_report] = true # fixes some bug where this was nil
|
194
|
+
configure(aConfig || DEFAULT_CONFIG)
|
195
|
+
end
|
196
|
+
|
197
|
+
def self.clean_config(aConfig)
|
198
|
+
result = ConfigClass.new(DEFAULT_CONFIG)
|
199
|
+
DEFAULT_CONFIG.each do |k,v|
|
200
|
+
result.copy_item(aConfig,k) if aConfig[k]
|
201
|
+
end
|
202
|
+
#result.copy_ints(aConfig,:keep_daily,:keep_weekly,:keep_monthly)
|
203
|
+
#result.copy_strings(aConfig,:crypto_iv,:crypto_key,:prefix,:bucket,:log_level,:basepath)
|
204
|
+
result.to_hash
|
205
|
+
end
|
206
|
+
|
207
|
+
# read the config however its given and return a hash with values in their correct type, and either valid or nil
|
208
|
+
# keys must be :symbols for aOptions. aConfig and aCmdOptions can be strings
|
209
|
+
def configure(aConfig,aCmdOptions = nil,aOptions = nil)
|
210
|
+
config_h = nil
|
211
|
+
case aConfig
|
212
|
+
when Hash then config_h = aConfig
|
213
|
+
when REXML::Element then config_h = XmlUtils.read_simple_items(aConfig,'/Yore/SimpleItems')
|
214
|
+
else
|
215
|
+
raise Error.new('unsupported type')
|
216
|
+
end
|
217
|
+
config_i = {}
|
218
|
+
config_h.each{|n,v| config_i[n.to_sym] = v} if config_h
|
219
|
+
aCmdOptions.each{|k,v| config_i[k.to_sym] = v} if aCmdOptions
|
220
|
+
config_i.merge!(aOptions) if aOptions
|
221
|
+
@config = Yore.clean_config(config_i)
|
222
|
+
@keepers = Array.new
|
223
|
+
@keepers << KeepDaily.new(config[:keep_daily])
|
224
|
+
@keepers << KeepWeekly.new(config[:keep_weekly])
|
225
|
+
@keepers << KeepMonthly.new(config[:keep_monthly])
|
226
|
+
|
227
|
+
@log_file = MiscUtils::temp_file()
|
228
|
+
|
229
|
+
@logger = LogUtils::create_logger_from_config({
|
230
|
+
'destination' => 'STDOUT',
|
231
|
+
'level' => config[:log_level]
|
232
|
+
# 'destination' => 'FILE',
|
233
|
+
# 'filename' => @log_file,
|
234
|
+
# 'level' => config[:log_level]
|
235
|
+
})
|
236
|
+
report_file = MiscUtils::temp_file
|
237
|
+
logger.info "report file: #{report_file}"
|
238
|
+
@reporter = LogUtils::create_reporter(report_file)
|
239
|
+
@basepath = config_h[:basepath]
|
240
|
+
#sources = aConfig
|
241
|
+
#
|
242
|
+
#@filelist =
|
243
|
+
end
|
244
|
+
|
245
|
+
def shell(aCommandline)
|
246
|
+
reporter.debug aCommandline
|
247
|
+
reporter.debug response = `#{aCommandline}`
|
248
|
+
response
|
249
|
+
end
|
250
|
+
|
251
|
+
def get_log
|
252
|
+
logger.close
|
253
|
+
# read in log and return
|
254
|
+
end
|
255
|
+
|
256
|
+
def get_report
|
257
|
+
MiscUtils::string_from_file(reporter.logdev.filename)
|
258
|
+
end
|
259
|
+
|
260
|
+
def self.filemap_from_filelist(aFiles)
|
261
|
+
ancestor_path = MiscUtils.file_list_ancestor(aFiles)
|
262
|
+
filemap = {}
|
263
|
+
aFiles.each do |fp|
|
264
|
+
filemap[fp] = MiscUtils.path_debase(fp,ancestor_path)
|
265
|
+
end
|
266
|
+
filemap
|
267
|
+
end
|
268
|
+
|
269
|
+
def keep_file?(aFile)
|
270
|
+
|
271
|
+
end
|
272
|
+
|
273
|
+
# By default, GNU tar suppresses a leading slash on absolute pathnames while creating or reading a tar archive. (You can suppress this with the -p option.)
|
274
|
+
# tar : http://my.safaribooksonline.com/0596102461/I_0596102461_CHP_3_SECT_9#snippet
|
275
|
+
|
276
|
+
# get files from wherever they are into a single file
|
277
|
+
def collect(aSourceFiles,aDestFile,aParentDir=nil)
|
278
|
+
filelist = filemap = nil
|
279
|
+
if aSourceFiles.is_a?(Hash)
|
280
|
+
filelist = aSourceFiles.keys
|
281
|
+
filemap = aSourceFiles
|
282
|
+
else # assume array
|
283
|
+
filelist = aSourceFiles
|
284
|
+
filemap = Yore.filemap_from_filelist(aSourceFiles)
|
285
|
+
end
|
286
|
+
aParentDir ||= MiscUtils.file_list_ancestor(filelist)
|
287
|
+
listfile = File.join(aParentDir,'.contents')
|
288
|
+
MiscUtils.string_to_file(
|
289
|
+
filelist.sort.map{|p| MiscUtils.path_debase(p, aParentDir)}.join("\n"),
|
290
|
+
listfile
|
291
|
+
)
|
292
|
+
tarfile = MiscUtils.file_change_ext(aDestFile, 'tar')
|
293
|
+
shell("tar cv --directory=#{aParentDir} --file=#{tarfile} --files-from=#{listfile}")
|
294
|
+
shell("tar --append --directory=#{aParentDir} --file=#{tarfile} .contents")
|
295
|
+
shell("bzip2 #{tarfile}; mv #{tarfile}.bz2 #{aDestFile}")
|
296
|
+
end
|
297
|
+
|
298
|
+
def pack(aFileIn,aFileOut)
|
299
|
+
shell "openssl enc -aes-256-cbc -K #{config[:crypto_key]} -iv #{config[:crypto_iv]} -in #{aFileIn} -out #{aFileOut}"
|
300
|
+
end
|
301
|
+
|
302
|
+
def unpack(aFileIn,aFileOut)
|
303
|
+
shell "openssl enc -d -aes-256-cbc -K #{config[:crypto_key]} -iv #{config[:crypto_iv]} -in #{aFileIn} -out #{aFileOut}"
|
304
|
+
end
|
305
|
+
|
306
|
+
# uploads the given file to the current bucket as its basename
|
307
|
+
def upload(aFile)
|
308
|
+
shell "s3cmd put #{config[:bucket]}:#{File.basename(aFile)} #{aFile}"
|
309
|
+
end
|
310
|
+
|
311
|
+
# downloads the given file from the current bucket as its basename
|
312
|
+
def download(aFile)
|
313
|
+
shell "s3cmd get #{config[:bucket]}:#{File.basename(aFile)} #{aFile}"
|
314
|
+
end
|
315
|
+
|
316
|
+
# calculate the date (with no time component) based on :day_begins_hour and the local time
|
317
|
+
def backup_date(aTime)
|
318
|
+
(aTime.localtime - (config[:first_hour]*3600)).date
|
319
|
+
end
|
320
|
+
|
321
|
+
# generates filename based on date and config
|
322
|
+
# config :
|
323
|
+
# :first_hour
|
324
|
+
# :
|
325
|
+
def encode_file_name(aTimeNow=Time.now)
|
326
|
+
"#{config[:prefix]}-#{backup_date(aTimeNow).date_numeric}.rew"
|
327
|
+
end
|
328
|
+
|
329
|
+
# return date based on filename
|
330
|
+
def decode_file_name(aFilename)
|
331
|
+
prefix,date,ext = aFilename.scan(/(.*?)\-(.*?)\.(.*)/).flatten
|
332
|
+
return Time.from_date_numeric(date)
|
333
|
+
end
|
334
|
+
|
335
|
+
#def set_file_name(aFile,aNewName)#
|
336
|
+
#
|
337
|
+
#end
|
338
|
+
|
339
|
+
def backup_process(aSourceFiles,aTimeNow=Time.now,aTempDir=nil)
|
340
|
+
aTempDir ||= MiscUtils.make_temp_dir('yore_')
|
341
|
+
temp_file = File.expand_path('backup.tar',aTempDir)
|
342
|
+
collect(aSourceFiles,temp_file)
|
343
|
+
backup_file = File.expand_path(encode_file_name(aTimeNow),aTempDir)
|
344
|
+
pack(temp_file,backup_file)
|
345
|
+
upload(backup_file)
|
346
|
+
end
|
347
|
+
|
348
|
+
# aDb : Hash containing :db_host,db_user,db_password,db_name,
|
349
|
+
def db_to_file(aDb,aFile)
|
350
|
+
shell "#{config[:mysqldump]} --host=#{aDb[:db_host]} --user=#{aDb[:db_user]} --password=#{aDb[:db_password]} --databases --skip-extended-insert --add-drop-database #{aDb[:db_name]} > #{aFile}"
|
351
|
+
end
|
352
|
+
|
353
|
+
def file_to_db(aFile,aDatabase)
|
354
|
+
#run "mysql --user=root --password=prot123ection </root/joomla_db_snapshot/joomla_db.sql"
|
355
|
+
end
|
356
|
+
|
357
|
+
#
|
358
|
+
#
|
359
|
+
# COMMANDLINE COMMANDS
|
360
|
+
#
|
361
|
+
#
|
362
|
+
|
363
|
+
|
364
|
+
|
365
|
+
def clean
|
366
|
+
|
367
|
+
end
|
368
|
+
|
369
|
+
# "/usr/bin/env" sets normal vars
|
370
|
+
# eg. 30 14 * * * /usr/bin/env ruby /Users/kip/svn/thewall/script/runner /Users/kip/svn/thewall/app/delete_old_posts.rb
|
371
|
+
# http://www.ameravant.com/posts/recurring-tasks-in-ruby-on-rails-using-runner-and-cron-jobs
|
372
|
+
|
373
|
+
# install gems
|
374
|
+
# make folder with correct folder structure
|
375
|
+
# copy in files
|
376
|
+
# add to crontab, with just email sending, then call backup
|
377
|
+
|
378
|
+
def report
|
379
|
+
return unless config[:email_report]
|
380
|
+
msg = get_report()
|
381
|
+
MiscUtils::send_email(
|
382
|
+
:host => config[:mail_host],
|
383
|
+
:port => config[:mail_port],
|
384
|
+
:helodomain => config[:mail_helodomain],
|
385
|
+
:user => config[:mail_user],
|
386
|
+
:password => config[:mail_password],
|
387
|
+
:from => config[:mail_from],
|
388
|
+
:from_alias => config[:mail_from_alias],
|
389
|
+
:to => config[:mail_to],
|
390
|
+
:to_alias => config[:mail_to_alias],
|
391
|
+
:auth => config[:mail_auth],
|
392
|
+
:subject => 'backup report',
|
393
|
+
:message => msg
|
394
|
+
)
|
395
|
+
end
|
396
|
+
|
397
|
+
def self.database_from_xml(aDatabaseNode)
|
398
|
+
return {
|
399
|
+
:db_host => aDatabaseNode.attributes['Host'],
|
400
|
+
:db_user => aDatabaseNode.attributes['User'],
|
401
|
+
:db_password => aDatabaseNode.attributes['Password'],
|
402
|
+
:db_name => aDatabaseNode.attributes['Name'],
|
403
|
+
:file => XmlUtils::peek_node_value(aDatabaseNode, "ToFile")
|
404
|
+
}
|
405
|
+
end
|
406
|
+
|
407
|
+
def backup(aJobFiles)
|
408
|
+
#require 'ruby-debug'; debugger
|
409
|
+
return unless job = aJobFiles.is_a?(Array) ? aJobFiles.first : aJobFiles # just use first job
|
410
|
+
|
411
|
+
xmlRoot = XmlUtils.get_file_root(job)
|
412
|
+
|
413
|
+
filelist = []
|
414
|
+
|
415
|
+
REXML::XPath.each(xmlRoot, '/Yore/Sources/Source') do |xmlSource|
|
416
|
+
case xmlSource['Type']
|
417
|
+
when 'File' then
|
418
|
+
REXML::XPath.each(xmlSource, 'IncludePath') do |xmlPath|
|
419
|
+
filelist += MiscUtils::recursive_file_list(File.expand_path(xmlPath.text,config[:basepath]))
|
420
|
+
end
|
421
|
+
when 'MySql' then
|
422
|
+
#<Source Type="MySql" >
|
423
|
+
# <Database Host="" Name="" User="" Password="">
|
424
|
+
# <ToFile>~/dbdump.sql</ToFile>
|
425
|
+
# </Database>
|
426
|
+
#</Source>
|
427
|
+
REXML::XPath.each(xmlSource, 'Database') do |xmlDb|
|
428
|
+
args = Yore::database_from_xml(xmlDb)
|
429
|
+
file = args.delete(:file)
|
430
|
+
unless args[:db_host] && args[:db_user] && args[:db_password] && args[:db_name] && file
|
431
|
+
raise Error.new("Invalid or missing parameter")
|
432
|
+
end
|
433
|
+
db_to_file(args,file)
|
434
|
+
filelist += file
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
filelist.uniq!
|
440
|
+
filelist.sort!
|
441
|
+
|
442
|
+
tempdir = MiscUtils.make_temp_dir('yore')
|
443
|
+
time = Time.now
|
444
|
+
|
445
|
+
backup_process(filelist,time,tempdir)
|
446
|
+
#clean
|
447
|
+
report
|
448
|
+
end
|
449
|
+
|
450
|
+
def test_email(*aDb)
|
451
|
+
args = {
|
452
|
+
:host => config[:mail_host],
|
453
|
+
:port => config[:mail_port],
|
454
|
+
:helodomain => config[:mail_helodomain],
|
455
|
+
:user => config[:mail_user],
|
456
|
+
:password => config[:mail_password],
|
457
|
+
:from => config[:mail_from],
|
458
|
+
:from_alias => config[:mail_from_alias],
|
459
|
+
:to => config[:mail_to],
|
460
|
+
:to_alias => config[:mail_to_alias],
|
461
|
+
:auth => config[:mail_auth],
|
462
|
+
:subject => 'email test',
|
463
|
+
:message => 'Just testing email sending'
|
464
|
+
}
|
465
|
+
logger.debug args.inspect
|
466
|
+
MiscUtils::send_email(args)
|
467
|
+
end
|
468
|
+
|
469
|
+
def db_dump(aArgs)
|
470
|
+
return nil unless aArgs
|
471
|
+
return nil unless job = aArgs[0]
|
472
|
+
|
473
|
+
xmlRoot = XmlUtils.get_file_root(job)
|
474
|
+
xmlDb = nil
|
475
|
+
if db_name = aArgs[1]
|
476
|
+
xmlDb = XmlUtils::single_node(xmlRoot,"/Yore/Sources/Source[@Type='MySql']/Database[@Name='#{db_name}']")
|
477
|
+
else
|
478
|
+
xmlDb = XmlUtils::single_node(xmlRoot,"/Yore/Sources/Source[@Type='MySql']/Database")
|
479
|
+
end
|
480
|
+
raise Error.new("No database") unless xmlDb
|
481
|
+
args = Yore.database_from_xml(xmlDb)
|
482
|
+
file = args.delete(:file)
|
483
|
+
unless args[:db_host] && args[:db_user] && args[:db_password] && args[:db_name] && file
|
484
|
+
raise Error.new("Invalid or missing parameter")
|
485
|
+
end
|
486
|
+
db_to_file(args,file)
|
487
|
+
end
|
488
|
+
|
489
|
+
end
|
490
|
+
|
491
|
+
end
|
data/lib/yore.orig.rb
ADDED
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/yore.rb'}"
|
9
|
+
puts "Loading yore gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|