fbf72e343c46e69cb3cc655f6a3dca26fc3ac7ba
[packages/precise/mcollective.git] / lib / mcollective / monkey_patches.rb
1 # start_with? was introduced in 1.8.7, we need to support
2 # 1.8.5 and 1.8.6
3 class String
4   def start_with?(str)
5     return self[0 .. (str.length-1)] == str
6   end unless method_defined?("start_with?")
7 end
8
9 # Make arrays of Symbols sortable
10 class Symbol
11   include Comparable
12
13   def <=>(other)
14     self.to_s <=> other.to_s
15   end unless method_defined?("<=>")
16 end
17
18 # This provides an alias for RbConfig to Config for versions of Ruby older then
19 # # version 1.8.5. This allows us to use RbConfig in place of the older Config in
20 # # our code and still be compatible with at least Ruby 1.8.1.
21 # require 'rbconfig'
22 unless defined? ::RbConfig
23   ::RbConfig = ::Config
24 end
25
26 # a method # that walks an array in groups, pass a block to
27 # call the block on each sub array
28 class Array
29   def in_groups_of(chunk_size, padded_with=nil, &block)
30     arr = self.clone
31
32     # how many to add
33     padding = chunk_size - (arr.size % chunk_size)
34
35     # pad at the end
36     arr.concat([padded_with] * padding) unless padding == chunk_size
37
38     # how many chunks we'll make
39     count = arr.size / chunk_size
40
41     # make that many arrays
42     result = []
43     count.times {|s| result <<  arr[s * chunk_size, chunk_size]}
44
45     if block_given?
46       result.each_with_index do |a, i|
47         case block.arity
48           when 1
49             yield(a)
50           when 2
51             yield(a, (i == result.size - 1))
52           else
53             raise "Expected 1 or 2 arguments, got #{block.arity}"
54         end
55       end
56     else
57       result
58     end
59   end unless method_defined?(:in_groups_of)
60 end
61
62 class String
63   def bytes(&block)
64     # This should not be necessary, really ...
65     require 'enumerator'
66     return to_enum(:each_byte) unless block_given?
67     each_byte(&block)
68   end unless method_defined?(:bytes)
69 end
70
71 class Dir
72   def self.mktmpdir(prefix_suffix=nil, tmpdir=nil)
73     case prefix_suffix
74     when nil
75       prefix = "d"
76       suffix = ""
77     when String
78       prefix = prefix_suffix
79       suffix = ""
80     when Array
81       prefix = prefix_suffix[0]
82       suffix = prefix_suffix[1]
83     else
84       raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}"
85     end
86     tmpdir ||= Dir.tmpdir
87     t = Time.now.strftime("%Y%m%d")
88     n = nil
89     begin
90       path = "#{tmpdir}/#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}"
91       path << "-#{n}" if n
92       path << suffix
93       Dir.mkdir(path, 0700)
94     rescue Errno::EEXIST
95       n ||= 0
96       n += 1
97       retry
98     end
99
100     if block_given?
101       begin
102         yield path
103       ensure
104         FileUtils.remove_entry_secure path
105       end
106     else
107       path
108     end
109   end unless method_defined?(:mktmpdir)
110
111   def self.tmpdir
112     tmp = '.'
113     for dir in [ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'], '/tmp']
114       if dir and stat = File.stat(dir) and stat.directory? and stat.writable?
115         tmp = dir
116         break
117       end rescue nil
118     end
119     File.expand_path(tmp)
120   end unless method_defined?(:tmpdir)
121 end