yore 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2009-01-25
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,22 @@
1
+ bin/yore
2
+ History.txt
3
+ lib/ihl_ruby/enum.rb
4
+ lib/ihl_ruby/extend_base_classes.rb
5
+ lib/ihl_ruby/misc_utils.rb
6
+ lib/ihl_ruby/string_utils.rb
7
+ lib/ihl_ruby/xml_utils.rb
8
+ lib/yore.orig.rb
9
+ lib/yore/yore_core.rb
10
+ Manifest.txt
11
+ PostInstall.txt
12
+ Rakefile
13
+ README.rdoc
14
+ script/console
15
+ script/destroy
16
+ script/generate
17
+ spec/rewind_spec.rb
18
+ spec/spec.opts
19
+ spec/spec_helper.rb
20
+ spec/test_job_a.xml
21
+ spec/yore_spec.rb
22
+ tasks/rspec.rake
data/PostInstall.txt ADDED
@@ -0,0 +1,7 @@
1
+
2
+ For more information on yore, see http://yore.rubyforge.org
3
+
4
+ NOTE: Change this information in PostInstall.txt
5
+ You can also delete it if you don't want it.
6
+
7
+
data/README.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ = yore
2
+
3
+ * FIX (url)
4
+
5
+ == DESCRIPTION:
6
+
7
+ FIX (describe your package)
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * FIX (list of features or problems)
12
+
13
+ == SYNOPSIS:
14
+
15
+ FIX (code sample of usage)
16
+
17
+ == REQUIREMENTS:
18
+
19
+ * FIX (list of requirements)
20
+
21
+ == INSTALL:
22
+
23
+ * FIX (sudo gem install, anything else)
24
+
25
+ == LICENSE:
26
+
27
+ (The MIT License)
28
+
29
+ Copyright (c) 2009 FIXME full name
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining
32
+ a copy of this software and associated documentation files (the
33
+ 'Software'), to deal in the Software without restriction, including
34
+ without limitation the rights to use, copy, modify, merge, publish,
35
+ distribute, sublicense, and/or sell copies of the Software, and to
36
+ permit persons to whom the Software is furnished to do so, subject to
37
+ the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be
40
+ included in all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
43
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
45
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
46
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
47
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
48
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'rake/rdoctask'
3
+ require 'rake/testtask'
4
+ require 'spec/rake/spectask'
5
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
6
+ require File.dirname(__FILE__) + '/lib/yore.orig'
7
+
8
+ # built following http://newgem.rubyforge.org/
9
+ # using RSpec option
10
+ # and had to add processor_ids from dr nic :
11
+ # http://groups.google.com/group/new-gem-generator/browse_thread/thread/648f70da782e607a/928ea0fe8319d886?lnk=raot
12
+
13
+ # Generate all the Rake tasks
14
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
15
+ $hoe = Hoe.new('yore', Yore::VERSION) do |p|
16
+ p.developer('Gary McGhee', 'contact@buzz@ware@com@au')
17
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
18
+ #p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
19
+ p.rubyforge_name = 'buzzware' #p.name # TODO this is default value
20
+ p.extra_deps = [
21
+ ['RequirePaths','>= 1.0.1'],
22
+ ['cmdparse', '>= 2.0.2'],
23
+ ['s3sync', '>= 1.2.5']
24
+ ]
25
+ p.extra_dev_deps = [
26
+ ['newgem', ">= #{::Newgem::VERSION}"]
27
+ ]
28
+
29
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
30
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
31
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
32
+ p.rsync_args = '-av --delete --ignore-errors'
33
+ end
34
+
35
+ require 'newgem/tasks' # load /tasks/*.rake
36
+ Dir['tasks/**/*.rake'].each { |t| load t }
37
+
38
+ # TODO - want other tests/tasks run by default? Add them to the list
39
+ # task :default => [:spec, :features]
40
+ # this was generated by netbeans
41
+ # Rake::RDocTask.new do |rdoc|
42
+ # files =['README', 'LICENSE', 'lib/**/*.rb']
43
+ # rdoc.rdoc_files.add(files)
44
+ # rdoc.main = "README" # page to start on
45
+ # rdoc.title = "yore Docs"
46
+ # rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
47
+ # rdoc.options << '--line-numbers'
48
+ # end
49
+ #
50
+ # Rake::TestTask.new do |t|
51
+ # t.test_files = FileList['test/**/*.rb']
52
+ # end
53
+
54
+ Spec::Rake::SpecTask.new do |t|
55
+ t.spec_files = FileList['spec/**/*.rb']
56
+ end
57
+
data/bin/yore ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'fileutils'
4
+
5
+ require 'rubygems'
6
+ gem 'RequirePaths'; require 'require_paths'
7
+ require_paths '.','../../..','/Users/gary/repos/Buzzware/projects_2009/yore/lib'
8
+
9
+ gem 'cmdparse'; require 'cmdparse'
10
+
11
+ require 'ihl_ruby/misc_utils'
12
+ require 'ihl_ruby/xml_utils'
13
+ require 'ihl_ruby/extend_base_classes'
14
+
15
+ require 'yore/yore_core'
16
+
17
+ CMD_OPTIONS = {} # options given on command line
18
+
19
+ # this contains a block that actually creates the controller, yore
20
+ def command(aParser,aController,aAction,aShortDescription=nil,aOptionParser=nil,aOther={})
21
+ c = CmdParse::Command.new( aAction.to_s, false )
22
+ c.short_desc = aShortDescription
23
+ c.description = aOther[:description] if aOther[:description]
24
+ c.options = aOptionParser if aOptionParser
25
+ c.set_execution_block do |args|
26
+ job = args.first
27
+ xmlRoot = XmlUtils.get_file_root(job)
28
+ aController.configure(xmlRoot,CMD_OPTIONS,{:basepath => File.dirname(File.expand_path(job))})
29
+ aController.send(aAction,args)
30
+ end
31
+ aParser.add_command(c)
32
+ end
33
+
34
+ cmd = CmdParse::CommandParser.new( true )
35
+ cmd.program_name = "yore"
36
+ cmd.program_version = [0, 0, 1]
37
+ # Options are given after a command and before arguments on the command line
38
+ # so global options are given first, before the first command
39
+ # ie ruby yore.rb --global_option command --command_option argument1 argument2 argumentn
40
+ cmd.options = CmdParse::OptionParserWrapper.new do |opt|
41
+ opt.separator "Global options:"
42
+ opt.on("--verbose", "Be verbose when outputting info") do |t|
43
+ CMD_OPTIONS[:verbose] = t
44
+ end
45
+ end
46
+ cmd.add_command( CmdParse::HelpCommand.new )
47
+ cmd.add_command( CmdParse::VersionCommand.new )
48
+
49
+ yore = YoreCore::Yore.new # main program object
50
+
51
+ # these options must be given after backup and before arguments
52
+ option_parser = CmdParse::OptionParserWrapper.new do |opt|
53
+ opt.on( '--all', 'Delete all IP addresses' ) do
54
+ CMD_OPTIONS[:deleteAll] = true
55
+ end
56
+ end
57
+
58
+ command(cmd,yore,:backup,"Backup filelist to S3",option_parser)
59
+
60
+ command(cmd,yore,:test_email,"Test email sending\n")
61
+
62
+ command(cmd,yore,:db_dump,"Dump database by name in job\n")
63
+
64
+ cmd.parse
65
+
@@ -0,0 +1,50 @@
1
+ module Kernel
2
+ # simple (sequential) enumerated values
3
+ # usage :
4
+ #
5
+ # module Constants
6
+ # module Gradient
7
+ # enum :B, :A, :C
8
+ # end
9
+ # end
10
+ #
11
+ # then :
12
+ #
13
+ # puts Constants::Gradient::B -> 0
14
+ # puts Constants::Gradient::C -> 2
15
+ # puts Constants::Gradient::MINVALUE -> 0
16
+ # puts Constants::Gradient::MAXVALUE -> 2
17
+ # puts Constants::Gradient::NAMES -> [:B, :A, :C]
18
+ # puts Constants::Gradient[0] -> :B
19
+ # puts Constants::Gradient[1] -> :A
20
+ # puts Constants::Gradient[2] -> :C
21
+
22
+ def enum(*syms)
23
+ syms.each_index { |i|
24
+ const_set(syms[i], i)
25
+ }
26
+ const_set(:NAMES, syms || [])
27
+ const_set(:MINVALUE, syms==nil ? nil : 0)
28
+ const_set(:MAXVALUE, syms==nil ? nil : syms.length-1)
29
+ const_set(:VALUECOUNT, syms==nil ? nil : syms.length)
30
+ const_set(:ALL, syms==nil ? [] : (0..syms.length-1).to_a)
31
+ const_set(:HUMAN_NAMES, syms.map{|n| n.to_s.humanize} || [])
32
+
33
+ # this returns the enum name given the value
34
+ def self.[]( idx )
35
+ (idx.is_a? Integer) ? const_get(:NAMES)[idx] : nil
36
+ end
37
+
38
+ def self.valid?(idx)
39
+ (idx.is_a? Integer) && (idx >= 0) && (idx <= const_get(:MAXVALUE))
40
+ end
41
+
42
+ def self.parse(name,default=nil)
43
+ return default if name.nil? || name.empty?
44
+ return default if not name = name.to_sym
45
+ result = const_get(:NAMES).index(name)
46
+ return result==nil ? default : result
47
+ end
48
+ end
49
+ end
50
+
@@ -0,0 +1,313 @@
1
+ String.class_eval do
2
+ def pad_left(value)
3
+ increase = value-self.length
4
+ return self if increase==0
5
+ if increase > 0
6
+ return self + ' '*increase
7
+ else
8
+ return self[0,value]
9
+ end
10
+ end
11
+
12
+ def pad_right(value)
13
+ increase = value-self.length
14
+ return self if increase==0
15
+ if increase > 0
16
+ return ' '*increase + self
17
+ else
18
+ return self[0,value]
19
+ end
20
+ end
21
+
22
+ # Like chomp! but operates on the leading characters instead.
23
+ # The aString parameter would not normally be used.
24
+ def bite!(aValue=$/,aString=self)
25
+ if aString[0,aValue.length] == aValue
26
+ aString[0,aValue.length] = ''
27
+ return aString
28
+ else
29
+ return aString
30
+ end
31
+ end
32
+
33
+ def bite(aValue=$/)
34
+ bite!(aValue,self.clone)
35
+ end
36
+
37
+ def begins_with?(aString)
38
+ self[0,aString.length]==aString
39
+ end
40
+
41
+ def ends_with?(aString)
42
+ self[-aString.length,aString.length]==aString
43
+ end
44
+
45
+ # for future methods
46
+ # def centre_bar(aChar = '-', indent = 6)
47
+ # (' '*indent) + aChar*(@width-(indent*2)) + (' '*indent)
48
+ # end
49
+ # def replace_string(aString,aCol,aSubString)
50
+ # return aString if aSubString==nil || aSubString==''
51
+ #
52
+ # aSubString = aSubString.to_s
53
+ # start_col = aCol < 0 ? 0 : aCol
54
+ # end_col = aCol+aSubString.length-1
55
+ # end_col = @width-1 if end_col >= @width
56
+ # source_len = end_col-start_col+1
57
+ # return aString if source_len <= 0 || end_col < 0 || start_col >= @width
58
+ # aString += ' '*((end_col+1) - aString.length) if aString.length < end_col+1
59
+ # aString[start_col,source_len] = aSubString[start_col-aCol,end_col-start_col+1]
60
+ # return aString
61
+ # end
62
+
63
+ def to_integer(aDefault=nil)
64
+ t = self.strip
65
+ return aDefault if t.empty? || !t.index(/^-{0,1}[0-9]+$/)
66
+ return t.to_i
67
+ end
68
+
69
+ def is_i?
70
+ self.to_integer(false) and true
71
+ end
72
+
73
+ def to_float(aDefault=nil)
74
+ t = self.strip
75
+ return aDefault if !t =~ /(\+|-)?([0-9]+\.?[0-9]*|\.[0-9]+)([eE](\+|-)?[0-9]+)?/
76
+ return t.to_f
77
+ end
78
+
79
+ def is_f?
80
+ self.to_float(false) and true
81
+ end
82
+
83
+ end
84
+
85
+
86
+ Time.class_eval do
87
+
88
+ if !respond_to?(:change) # no activesupport loaded
89
+ def change(options)
90
+ ::Time.send(
91
+ self.utc? ? :utc : :local,
92
+ options[:year] || self.year,
93
+ options[:month] || self.month,
94
+ options[:day] || self.day,
95
+ options[:hour] || self.hour,
96
+ options[:min] || (options[:hour] ? 0 : self.min),
97
+ options[:sec] || ((options[:hour] || options[:min]) ? 0 : self.sec),
98
+ options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : self.usec)
99
+ )
100
+ end
101
+
102
+ def seconds_since_midnight
103
+ self.to_i - self.change(:hour => 0).to_i + (self.usec/1.0e+6)
104
+ end
105
+
106
+ def beginning_of_day
107
+ (self - self.seconds_since_midnight).change(:usec => 0)
108
+ end
109
+
110
+ alias :midnight :beginning_of_day
111
+ alias :at_midnight :beginning_of_day
112
+ alias :at_beginning_of_day :beginning_of_day
113
+
114
+ end
115
+
116
+ # offset of local machine from UTC, in seconds eg +9.hours
117
+ def self.local_offset
118
+ local(2000).utc_offset
119
+ end
120
+
121
+ def date
122
+ self.at_beginning_of_day
123
+ end
124
+
125
+ # index number of this day, from Time.at(0) + utc_offset
126
+ def day_number
127
+ (self.to_i+self.utc_offset) / 86400
128
+ end
129
+
130
+ # index number of this utc day
131
+ def day_number_utc
132
+ self.to_i / 86400
133
+ end
134
+
135
+ # the last microsecond of the day
136
+ def day_end
137
+ self.at_beginning_of_day + 86399.999999
138
+ end
139
+
140
+ def date_numeric
141
+ self.strftime('%Y%m%d')
142
+ end
143
+
144
+ # create a new Time from eg. "20081231"
145
+ def self.from_date_numeric(aString)
146
+ local(aString[0,4].to_i,aString[4,2].to_i,aString[6,2].to_i)
147
+ end
148
+
149
+ def time_numeric
150
+ self.strftime('%H%M%S')
151
+ end
152
+
153
+ def datetime_numeric
154
+ self.strftime('%Y%m%d-%H%M%S')
155
+ end
156
+
157
+ def to_sql
158
+ self.strftime('%Y-%m-%d %H:%M:%S')
159
+ end
160
+
161
+ def to_w3c
162
+ utc.strftime("%Y-%m-%dT%H:%M:%S+00:00")
163
+ end
164
+ end
165
+
166
+ module HashUtils
167
+ def filter_include!(aKeys,aHash=nil)
168
+ aHash ||= self
169
+
170
+ if aKeys.is_a? Regexp
171
+ return aHash.delete_if {|k,v| not k =~ aKeys }
172
+ else
173
+ aKeys = [aKeys] unless aKeys.is_a? Array
174
+ return aHash.clear if aKeys.empty?
175
+ return aHash.delete_if {|key, value| !((aKeys.include?(key)) || (key.is_a?(Symbol) and aKeys.include?(key.to_s)) || (key.is_a?(String) and aKeys.include?(key.to_sym)))}
176
+ return aHash # last resort
177
+ end
178
+ end
179
+
180
+ def filter_include(aKeys,aHash=nil)
181
+ aHash ||= self
182
+ filter_include!(aKeys,aHash.clone)
183
+ end
184
+
185
+ def filter_exclude!(aKeys,aHash=nil)
186
+ aHash ||= self
187
+
188
+ if aKeys.is_a? Regexp
189
+ return aHash.delete_if {|k,v| k =~ aKeys }
190
+ else
191
+ aKeys = [aKeys] unless aKeys.is_a? Array
192
+ return aHash if aKeys.empty?
193
+ return aHash.delete_if {|key, value| ((aKeys.include?(key)) || (key.is_a?(Symbol) and aKeys.include?(key.to_s)) || (key.is_a?(String) and aKeys.include?(key.to_sym)))}
194
+ end
195
+ end
196
+
197
+ def filter_exclude(aKeys,aHash=nil)
198
+ aHash ||= self
199
+ filter_exclude!(aKeys,aHash.clone)
200
+ end
201
+
202
+ def has_values_for?(aKeys,aHash=nil)
203
+ aHash ||= self
204
+ # check all keys exist in aHash and their values are not nil
205
+ aKeys.all? { |k,v| aHash[k] }
206
+ end
207
+
208
+ # give a block to execute without the given key in this hash
209
+ # It will be replaced after the block (guaranteed by ensure)
210
+ # eg.
211
+ # hash.without_key(:blah) do |aHash|
212
+ # puts aHash.inspect
213
+ # end
214
+ def without_key(aKey)
215
+ temp = nil
216
+ h = self
217
+ begin
218
+ if h.include?(aKey)
219
+ temp = [aKey,h.delete(aKey)]
220
+ end
221
+ result = yield(h)
222
+ ensure
223
+ h[temp[0]] = temp[1] if temp
224
+ end
225
+ return result
226
+ end
227
+
228
+ end
229
+
230
+ Hash.class_eval do
231
+ include HashUtils
232
+ end
233
+
234
+ if defined? HashWithIndifferentAccess
235
+ HashWithIndifferentAccess.class_eval do
236
+ include HashUtils
237
+ end
238
+ end
239
+
240
+ module ArrayUtils
241
+ def filter_include!(aValues,aArray=nil)
242
+ aArray ||= self
243
+ if aValues.is_a? Array
244
+ return aArray if aValues.empty?
245
+ return aArray.delete_if {|v| not aValues.include? v }
246
+ elsif aValues.is_a? Regexp
247
+ return aArray.delete_if {|v| not v =~ aValues }
248
+ else
249
+ return filter_include!([aValues],aArray)
250
+ end
251
+ end
252
+
253
+ def filter_include(aValues,aArray=nil)
254
+ aArray ||= self
255
+ filter_include!(aValues,aArray.clone)
256
+ end
257
+
258
+ def filter_exclude!(aValues,aArray=nil)
259
+ aArray ||= self
260
+ if aValues.is_a? Array
261
+ return aArray if aValues.empty?
262
+ return aArray.delete_if {|v| aValues.include? v }
263
+ elsif aValues.is_a? Regexp
264
+ return aArray.delete_if {|v| v =~ aValues }
265
+ else
266
+ return filter_exclude!([aValues],aArray)
267
+ end
268
+ end
269
+
270
+ def filter_exclude(aValues,aArray=nil)
271
+ aArray ||= self
272
+ filter_exclude!(aValues,aArray.clone)
273
+ end
274
+ end
275
+
276
+ Array.class_eval do
277
+ include ArrayUtils
278
+
279
+ # fixes a memory leak in shift in Ruby 1.8 - should be fixed in 1.9
280
+ # see http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/216055
281
+ def shift()
282
+ delete_at(0)
283
+ end
284
+
285
+ end
286
+
287
+ Kernel.class_eval do
288
+ def is_windows?
289
+ RUBY_PLATFORM =~ /(win|w)32$/ ? true : false
290
+ end
291
+ end
292
+
293
+ if defined? ActiveRecord
294
+ ActiveRecord::Base.class_eval do
295
+
296
+ def self.find_any_id(aId)
297
+ with_exclusive_scope { find(:first, {:conditions => {:id => aId}}) }
298
+ end
299
+
300
+ def self.find_any_all(aOptions={})
301
+ with_exclusive_scope { find(:all, aOptions) }
302
+ end
303
+
304
+ def self.find_ids(aIds)
305
+ find(:all, {:conditions=> ["id in (?)",aIds.join(',')]})
306
+ end
307
+
308
+ def self.find_any_ids(aIds)
309
+ with_exclusive_scope { find(:all, {:conditions=> ["id in (?)",aIds.join(',')]}) }
310
+ end
311
+
312
+ end
313
+ end