rubycut-babushka 0.10.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. data/Gemfile +8 -0
  2. data/Gemfile.lock +31 -0
  3. data/README.markdown +246 -0
  4. data/Rakefile +26 -0
  5. data/bin/babushka +11 -0
  6. data/deps/babushka.rb +101 -0
  7. data/deps/dev.rb +12 -0
  8. data/deps/fhs.rb +31 -0
  9. data/deps/git.rb +29 -0
  10. data/deps/homebrew.rb +30 -0
  11. data/deps/os_x.rb +33 -0
  12. data/deps/packages.rb +22 -0
  13. data/deps/pkg_managers.rb +110 -0
  14. data/deps/ruby.rb +23 -0
  15. data/deps/rubygems.rb +24 -0
  16. data/deps/system.rb +10 -0
  17. data/deps/templates/app.rb +68 -0
  18. data/deps/templates/external.rb +12 -0
  19. data/deps/templates/installer.rb +31 -0
  20. data/deps/templates/managed.rb +105 -0
  21. data/deps/templates/ppa.rb +24 -0
  22. data/deps/templates/src.rb +42 -0
  23. data/deps/templates/tmbundle.rb +15 -0
  24. data/lib/babushka.rb +28 -0
  25. data/lib/babushka/accepts_block_for.rb +72 -0
  26. data/lib/babushka/accepts_list_for.rb +49 -0
  27. data/lib/babushka/accepts_value_for.rb +24 -0
  28. data/lib/babushka/base.rb +78 -0
  29. data/lib/babushka/bug_reporter.rb +55 -0
  30. data/lib/babushka/cmdline.rb +133 -0
  31. data/lib/babushka/cmdline/handler.rb +41 -0
  32. data/lib/babushka/cmdline/helpers.rb +127 -0
  33. data/lib/babushka/cmdline/parser.rb +69 -0
  34. data/lib/babushka/colorizer.rb +59 -0
  35. data/lib/babushka/core_patches/array.rb +171 -0
  36. data/lib/babushka/core_patches/blank.rb +22 -0
  37. data/lib/babushka/core_patches/bytes.rb +52 -0
  38. data/lib/babushka/core_patches/hash.rb +107 -0
  39. data/lib/babushka/core_patches/hashish.rb +14 -0
  40. data/lib/babushka/core_patches/integer.rb +25 -0
  41. data/lib/babushka/core_patches/io.rb +8 -0
  42. data/lib/babushka/core_patches/numeric.rb +16 -0
  43. data/lib/babushka/core_patches/object.rb +27 -0
  44. data/lib/babushka/core_patches/string.rb +116 -0
  45. data/lib/babushka/core_patches/symbol.rb +12 -0
  46. data/lib/babushka/core_patches/try.rb +15 -0
  47. data/lib/babushka/core_patches/uri.rb +24 -0
  48. data/lib/babushka/dep.rb +470 -0
  49. data/lib/babushka/dep_context.rb +18 -0
  50. data/lib/babushka/dep_definer.rb +115 -0
  51. data/lib/babushka/dep_pool.rb +49 -0
  52. data/lib/babushka/dep_runner.rb +85 -0
  53. data/lib/babushka/dsl.rb +26 -0
  54. data/lib/babushka/git_repo.rb +185 -0
  55. data/lib/babushka/helpers/git_helpers.rb +32 -0
  56. data/lib/babushka/helpers/log_helpers.rb +176 -0
  57. data/lib/babushka/helpers/path_helpers.rb +34 -0
  58. data/lib/babushka/helpers/run_helpers.rb +145 -0
  59. data/lib/babushka/helpers/shell_helpers.rb +229 -0
  60. data/lib/babushka/helpers/suggest_helpers.rb +16 -0
  61. data/lib/babushka/helpers/uri_helpers.rb +36 -0
  62. data/lib/babushka/ip.rb +160 -0
  63. data/lib/babushka/lambda_chooser.rb +40 -0
  64. data/lib/babushka/levenshtein.rb +125 -0
  65. data/lib/babushka/meta_dep.rb +65 -0
  66. data/lib/babushka/meta_dep_context.rb +15 -0
  67. data/lib/babushka/parameter.rb +143 -0
  68. data/lib/babushka/pkg_helper.rb +81 -0
  69. data/lib/babushka/pkg_helpers/apt_helper.rb +61 -0
  70. data/lib/babushka/pkg_helpers/base_helper.rb +19 -0
  71. data/lib/babushka/pkg_helpers/binpkgsrc_helper.rb +48 -0
  72. data/lib/babushka/pkg_helpers/binports_helper.rb +34 -0
  73. data/lib/babushka/pkg_helpers/brew_helper.rb +110 -0
  74. data/lib/babushka/pkg_helpers/gem_helper.rb +120 -0
  75. data/lib/babushka/pkg_helpers/macports_helper.rb +22 -0
  76. data/lib/babushka/pkg_helpers/npm_helper.rb +45 -0
  77. data/lib/babushka/pkg_helpers/pacman_helper.rb +27 -0
  78. data/lib/babushka/pkg_helpers/pip_helper.rb +45 -0
  79. data/lib/babushka/pkg_helpers/src_helper.rb +16 -0
  80. data/lib/babushka/pkg_helpers/yum_helper.rb +25 -0
  81. data/lib/babushka/popen.rb +40 -0
  82. data/lib/babushka/prompt.rb +176 -0
  83. data/lib/babushka/renderable.rb +67 -0
  84. data/lib/babushka/resource.rb +215 -0
  85. data/lib/babushka/run_reporter.rb +60 -0
  86. data/lib/babushka/shell.rb +108 -0
  87. data/lib/babushka/source.rb +216 -0
  88. data/lib/babushka/source_pool.rb +146 -0
  89. data/lib/babushka/system_definitions.rb +97 -0
  90. data/lib/babushka/system_profile.rb +210 -0
  91. data/lib/babushka/task.rb +142 -0
  92. data/lib/babushka/vars.rb +108 -0
  93. data/lib/babushka/version_of.rb +65 -0
  94. data/lib/babushka/version_str.rb +57 -0
  95. data/lib/babushka/xml_string.rb +28 -0
  96. data/lib/components.rb +82 -0
  97. data/lib/fancypath/fancypath.rb +200 -0
  98. data/lib/inkan/inkan.rb +76 -0
  99. data/spec/acceptance/acceptance.rb +43 -0
  100. data/spec/acceptance_helper.rb +113 -0
  101. data/spec/archives/Blah.app.zip +0 -0
  102. data/spec/archives/archive.tar +0 -0
  103. data/spec/archives/archive.tar.bz2 +0 -0
  104. data/spec/archives/archive.tar.gz +0 -0
  105. data/spec/archives/archive.tbz2 +0 -0
  106. data/spec/archives/archive.tgz +0 -0
  107. data/spec/archives/archive.zip +0 -0
  108. data/spec/archives/content.txt +5 -0
  109. data/spec/archives/invalid_archive +5 -0
  110. data/spec/archives/nested archive/content.txt +5 -0
  111. data/spec/archives/nested_archive.tar +0 -0
  112. data/spec/archives/really_a_gzip.zip +0 -0
  113. data/spec/archives/test-0.3.1.tgz +0 -0
  114. data/spec/archives/tgz_archive +0 -0
  115. data/spec/archives/zip_without_extension +0 -0
  116. data/spec/babushka/accepts_for_spec.rb +174 -0
  117. data/spec/babushka/accepts_for_support.rb +72 -0
  118. data/spec/babushka/cmdline/console_spec.rb +11 -0
  119. data/spec/babushka/cmdline/help_spec.rb +61 -0
  120. data/spec/babushka/cmdline/version_spec.rb +10 -0
  121. data/spec/babushka/core_patches_spec.rb +171 -0
  122. data/spec/babushka/dep_context_spec.rb +58 -0
  123. data/spec/babushka/dep_definer_spec.rb +152 -0
  124. data/spec/babushka/dep_definer_support.rb +36 -0
  125. data/spec/babushka/dep_spec.rb +567 -0
  126. data/spec/babushka/dep_support.rb +29 -0
  127. data/spec/babushka/deps_spec.rb +113 -0
  128. data/spec/babushka/gem_helper_spec.rb +90 -0
  129. data/spec/babushka/git_repo_spec.rb +396 -0
  130. data/spec/babushka/ip_spec.rb +131 -0
  131. data/spec/babushka/lambda_chooser_spec.rb +115 -0
  132. data/spec/babushka/meta_dep_definer_spec.rb +127 -0
  133. data/spec/babushka/meta_dep_wrapper_spec.rb +32 -0
  134. data/spec/babushka/parameter_spec.rb +135 -0
  135. data/spec/babushka/path_helpers_spec.rb +102 -0
  136. data/spec/babushka/prompt_spec.rb +188 -0
  137. data/spec/babushka/renderable_spec.rb +100 -0
  138. data/spec/babushka/resource_spec.rb +141 -0
  139. data/spec/babushka/run_helpers_spec.rb +26 -0
  140. data/spec/babushka/shell_helpers_spec.rb +244 -0
  141. data/spec/babushka/shell_spec.rb +19 -0
  142. data/spec/babushka/source_pool_spec.rb +320 -0
  143. data/spec/babushka/source_pool_support.rb +31 -0
  144. data/spec/babushka/source_spec.rb +382 -0
  145. data/spec/babushka/source_support.rb +17 -0
  146. data/spec/babushka/system_profile_spec.rb +61 -0
  147. data/spec/babushka/task_spec.rb +141 -0
  148. data/spec/babushka/uri_spec.rb +13 -0
  149. data/spec/babushka/vars_spec.rb +59 -0
  150. data/spec/babushka/version_of_spec.rb +110 -0
  151. data/spec/babushka/version_str_spec.rb +130 -0
  152. data/spec/babushka/version_str_support.rb +37 -0
  153. data/spec/babushka/xml_string_spec.rb +98 -0
  154. data/spec/deps/bad/broken.rb +7 -0
  155. data/spec/deps/bad/working.rb +3 -0
  156. data/spec/deps/good/meta.rb +14 -0
  157. data/spec/deps/good/test.rb +11 -0
  158. data/spec/deps/outer/deps.rb +19 -0
  159. data/spec/deps/outer/more deps.rb +11 -0
  160. data/spec/deps/params/params.rb +10 -0
  161. data/spec/fancypath/fancypath_spec.rb +272 -0
  162. data/spec/fancypath_support.rb +10 -0
  163. data/spec/inkan/inkan_spec.rb +217 -0
  164. data/spec/renderable/different_example.conf.erb +4 -0
  165. data/spec/renderable/example.conf.erb +3 -0
  166. data/spec/renderable/example.sh +6 -0
  167. data/spec/renderable/with_binding.conf.erb +4 -0
  168. data/spec/renderable/xml_example.conf.erb +8 -0
  169. data/spec/repos/remote.git.tgz +0 -0
  170. data/spec/spec_helper.rb +87 -0
  171. metadata +238 -0
@@ -0,0 +1,22 @@
1
+ # #blank? means (nil? or empty?). Instead of defining it on all objects and
2
+ # checking if they respond to the #empty? method when #blank? is called, we
3
+ # define it only on the classes where it has meaning. That means we also
4
+ # have to define it on nil, since it is also considered 'blank'.
5
+
6
+ module Enumerable
7
+ def blank?
8
+ empty?
9
+ end
10
+ end
11
+
12
+ class String
13
+ def blank?
14
+ empty?
15
+ end
16
+ end
17
+
18
+ class NilClass
19
+ def blank?
20
+ true
21
+ end
22
+ end
@@ -0,0 +1,52 @@
1
+ # Lifted from activesupport-3.0.5/lib/active_support/core_ext/numeric/bytes.rb
2
+ class Numeric
3
+ KILOBYTE = 1024
4
+ MEGABYTE = KILOBYTE * 1024
5
+ GIGABYTE = MEGABYTE * 1024
6
+ TERABYTE = GIGABYTE * 1024
7
+ PETABYTE = TERABYTE * 1024
8
+ EXABYTE = PETABYTE * 1024
9
+
10
+ # Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
11
+ def bytes
12
+ self
13
+ end
14
+ alias :byte :bytes
15
+
16
+ def kilobytes
17
+ self * KILOBYTE
18
+ end
19
+ alias :kilobyte :kilobytes
20
+
21
+ def megabytes
22
+ self * MEGABYTE
23
+ end
24
+ alias :megabyte :megabytes
25
+
26
+ def gigabytes
27
+ self * GIGABYTE
28
+ end
29
+ alias :gigabyte :gigabytes
30
+
31
+ def terabytes
32
+ self * TERABYTE
33
+ end
34
+ alias :terabyte :terabytes
35
+
36
+ def petabytes
37
+ self * PETABYTE
38
+ end
39
+ alias :petabyte :petabytes
40
+
41
+ def exabytes
42
+ self * EXABYTE
43
+ end
44
+ alias :exabyte :exabytes
45
+
46
+ alias :kb :kilobytes
47
+ alias :mb :megabytes
48
+ alias :gb :gigabytes
49
+ alias :tb :terabytes
50
+ alias :pb :petabytes
51
+ alias :eb :exabytes
52
+ end
@@ -0,0 +1,107 @@
1
+ class Hash
2
+ # Return a new hash filtered to exclude any key-value pairs whose keys appear
3
+ # in +keys+.
4
+ def discard *keys
5
+ dup.discard!(*keys)
6
+ end
7
+
8
+ # Filter this hash in-place so any key-value pairs whose keys appear in
9
+ # +keys+ are removed.
10
+ def discard! *keys
11
+ keys.each {|k| delete k }
12
+ self
13
+ end
14
+
15
+ # Return a new hash filtered to contain only the key-value pairs whose keys
16
+ # appear in +keys+.
17
+ def slice *keys
18
+ dup.slice!(*keys)
19
+ end
20
+
21
+ # Filter this hash in-place so it contains only the key-value pairs whose
22
+ # keys appear in +keys+.
23
+ def slice! *keys
24
+ keys.inject({}) {|acc,key|
25
+ acc[key] = self.delete(key) if self.has_key?(key)
26
+ acc
27
+ }
28
+ end
29
+
30
+ # Reverse-merge +other+ into this hash in-place; that is, merge all
31
+ # key-value pairs in +other+ whose keys are not already present in self.
32
+ def defaults! other
33
+ replace other.merge(self)
34
+ end
35
+
36
+ # Return a new hash consisting of +other+ reverse-merged into this hash;
37
+ # that is, equal to +other.merge(self)+.
38
+ def defaults other
39
+ dup.defaults! other
40
+ end
41
+
42
+ # Return a new hash with the same keys as this hash, but with values
43
+ # generated by yielding each key-value pair to +block+.
44
+ def map_values &block
45
+ dup.map_values!(&block)
46
+ end
47
+
48
+ # Update this hash in-place by replacing each value with the result of
49
+ # yielding the corresponding key-value pair to the block.
50
+ def map_values! &block
51
+ keys.each {|k|
52
+ self[k] = yield k, self[k]
53
+ }
54
+ self
55
+ end
56
+
57
+ # Return a new hash filtered to contain just the key-value pairs for which
58
+ # the block returns true. That is, like Hash#select, but returning a hash
59
+ # instead of an array of tuples.
60
+ def selekt &block
61
+ hsh = {}
62
+ each_pair {|k,v|
63
+ hsh[k] = v if yield(k,v)
64
+ }
65
+ hsh
66
+ end
67
+
68
+ # Return a new hash recursively filtered to remove all key-value pairs for
69
+ # which the block returned true. That is, like Hash#reject, except sub-hashes
70
+ # are also filtered.
71
+ def reject_r &block
72
+ dup.reject_r!(&block)
73
+ end
74
+
75
+ # Recursively filter this hash in-place to remove all key-value pairs for
76
+ # which the block returned true. That is, like Hash#reject!, except
77
+ # sub-hashes are also filtered.
78
+ def reject_r! &block
79
+ each_pair {|k,v|
80
+ if yield k, v
81
+ self.delete k
82
+ elsif v.is_a? Hash
83
+ self[k] = v.reject_r(&block)
84
+ end
85
+ }
86
+ end
87
+
88
+ # Converts this hash to a string that can be submitted as HTTP parameters.
89
+ # The keys and values are encoded, so the string is safe to submit exactly as
90
+ # it is returned.
91
+ #
92
+ # This isn't a recursive implementation, because I didn't need it to be :)
93
+ #
94
+ # Example:
95
+ # {'name' => 'Sigur Rós', 'album' => 'Takk...'}.to_http_params
96
+ # #=> "name=Sigur%20R%C3%B3s&album=Takk..."
97
+ def to_http_params
98
+ require 'uri'
99
+
100
+ keys.map {|key|
101
+ [
102
+ URI.escape(key.to_s),
103
+ URI.escape(fetch(key).to_s)
104
+ ].join('=')
105
+ }.join( '&')
106
+ end
107
+ end
@@ -0,0 +1,14 @@
1
+ class Hashish
2
+ # Return a new hash whose default value is an empty array; i.e. querying any
3
+ # un-assigned key will assign and return an empty array to that key.
4
+ def self.array
5
+ Hash.new {|hsh,k| hsh[k] = [] }
6
+ end
7
+
8
+ # Return a new hash whose default value is an empty hash; i.e. querying any
9
+ # un-assigned key will assign and return an empty hash to that key. Note that
10
+ # the empty hash is a regular hash and doesn't have any default keys of its own.
11
+ def self.hash
12
+ Hash.new {|hsh,k| hsh[k] = {} }
13
+ end
14
+ end
@@ -0,0 +1,25 @@
1
+ class Integer
2
+ # Return a string describing this integer as a human-readable, approximated
3
+ # duration, assuming it is a number of seconds. The description will be
4
+ # either 'now', 'less than a minute', or a value in minutes, hours or days.
5
+ # Some examples:
6
+ # 12.xsecs #=> "less than a minute"
7
+ # 80.xsecs #=> "1 minute"
8
+ # 1337.xsecs #=> "22 minutes"
9
+ # 1234567.xsecs #=> "14 days"
10
+ def xsecs
11
+ value = self.abs
12
+ past = (self < 0)
13
+
14
+ case value
15
+ when 0; return 'now'
16
+ when 1...60; return "less than a minute#{' ago' if past}"
17
+ when 61...3600; value /= 60; unit = 'minute'
18
+ when 3600...(3600*24); value /= 3600; unit = 'hour'
19
+ else value /= (3600*24); unit = 'day'
20
+ end
21
+
22
+ value = 1 if value == 0
23
+ "#{value.commas} #{unit}#{'s' unless value == 1}#{' ago' if past}"
24
+ end
25
+ end
@@ -0,0 +1,8 @@
1
+ class IO
2
+ # Return true iff reading from this IO object would return data immediately,
3
+ # and not block while waiting for data.
4
+ def ready_for_read?
5
+ result = IO.select([self], [], [], 0)
6
+ result && (result.first.first == self)
7
+ end
8
+ end
@@ -0,0 +1,16 @@
1
+ class Numeric
2
+ # Return a string representation of this value with commas between the
3
+ # thousands groupings.
4
+ # Some examples:
5
+ # 3.commas #=> "3"
6
+ # 314.commas #=> "314"
7
+ # 31459.commas #=> "31,459"
8
+ def commas
9
+ if self < 1000
10
+ to_s
11
+ else
12
+ whole, fract = self.to_s.split('.')
13
+ [ whole.reverse.scan(/\d{1,3}/).join(',').reverse, fract ].squash.join('.')
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ alias :L :proc
2
+
3
+ class Object
4
+ # Return this object's metaclass; i.e. the value of self within a
5
+ # 'class << self' block.
6
+ def metaclass
7
+ class << self; self end
8
+ end
9
+
10
+ # Return this object after yielding it to the block. This is useful for
11
+ # neatly working with an object in some way before returning it:
12
+ # def valmorphanize
13
+ # process.tap {|result|
14
+ # log "Oops!" unless result
15
+ # }
16
+ # end
17
+ def tap &block
18
+ yield self
19
+ self
20
+ end unless Object.respond_to?(:tap)
21
+
22
+ # Return self unmodified after logging the output of #inspect, along with
23
+ # the point at which +tapp+ was called.
24
+ def tapp
25
+ tap { puts "#{File.basename caller[2]}: #{self.inspect}" }
26
+ end
27
+ end
@@ -0,0 +1,116 @@
1
+ class String
2
+ # Return a Dep::Requirement that specifies the dep that should later be
3
+ # called, and the arguments that should be passed. This allows requiring
4
+ # deps with a less noisy syntax, and the lookup is lazy (it happens at
5
+ # the point the dep is invoked, from its parent dep in Dep#process_deps).
6
+ #
7
+ # dep 'user has a password', :username do
8
+ # requires 'user exists'.with(username)
9
+ # end
10
+ def with *args
11
+ Babushka::Dep::Requirement.new(self, args)
12
+ end
13
+
14
+ # Returns true iff +other+ appears exactly at the start of +self+.
15
+ def starts_with? other
16
+ self[0, other.length] == other
17
+ end
18
+
19
+ # Returns true iff +other+ appears exactly at the end of +self+.
20
+ def ends_with? other
21
+ self[-other.length, other.length] == other
22
+ end
23
+
24
+ # Return a duplicate of +self+, with +other+ prepended to it if it doesn't already start with +other+.
25
+ def start_with other
26
+ starts_with?(other) ? self : other + self
27
+ end
28
+
29
+ # Return a duplicate of +self+, with +other+ appended to it if it doesn't already end with +other+.
30
+ def end_with other
31
+ ends_with?(other) ? self : self + other
32
+ end
33
+
34
+ # Extracts specified values from arbitrary, multiline strings. Most common
35
+ # formats are handled. When there are multiple matches across a multi-line
36
+ # string, the first is returned. If there is no match, the empty string is
37
+ # returned.
38
+ #
39
+ # With a simple key/value format:
40
+ # 'key: value'.val_for('key') #=> 'value'
41
+ # 'key = value'.val_for('key') #=> 'value'
42
+ # 'key value'.val_for('key') #=> 'value'
43
+ #
44
+ # Whitespace is handled correctly:
45
+ # ' key: value '.val_for('key') #=> 'value'
46
+ # ' key value '.val_for('key') #=> 'value'
47
+ #
48
+ # Leading non-word characters form part of the key:
49
+ # '*key: value'.val_for('*key') #=> 'value'
50
+ # '-key: value'.val_for('-key') #=> 'value'
51
+ # '-key: value'.val_for('key') #=> nil
52
+ #
53
+ # But not if they're separated from the key:
54
+ # '* key: value'.val_for('key') #=> 'value'
55
+ #
56
+ # Spaces within the key are handled properly:
57
+ # 'key with spaces: value'.val_for('key with spaces') #=> 'value'
58
+ # '- key with spaces: value'.val_for('key with spaces') #=> 'value'
59
+ # ' -- key with spaces: value'.val_for('key with spaces') #=> 'value'
60
+ # 'space-separated key: value'.val_for('space-separated key') #=> 'value'
61
+ #
62
+ # As are values containing spaces:
63
+ # 'key: space-separated value'.val_for('key') #=> 'space-separated value'
64
+ # 'key with spaces: space-separated value'.val_for('key with spaces') #=> 'space-separated value'
65
+ def val_for key
66
+ split("\n").grep(
67
+ # The key we're after, maybe preceded by non-word chars and spaces, and
68
+ # followed either by a word/non-word boundary or whitespace.
69
+ key.is_a?(Regexp) ? key : /(^|^[^\w]*\s+)#{Regexp.escape(key)}(\b|(?=\s))/
70
+ ).map {|l|
71
+ l.sub(/^[^\w]*\s+/, '').
72
+ sub(key.is_a?(Regexp) ? key : /^#{Regexp.escape(key)}(\b|(?=\s))\s*[:=]?/, '').
73
+ sub(/[;,]\s*$/, '').
74
+ strip
75
+ }.first
76
+ end
77
+
78
+ def / other
79
+ (empty? ? other.p : (p / other))
80
+ end
81
+
82
+ # Create a VersionStr from this string.
83
+ def to_version
84
+ Babushka::VersionStr.new self
85
+ end
86
+
87
+ # Return a new string with the contents of this string surrounded in escape
88
+ # sequences such that it will render as described in +description+.
89
+ # Some examples:
90
+ # 'Hello world!'.colorize('green') #=> "\e[0;32;29mHello world!\e[0m"
91
+ # 'Hello world!'.colorize('on red') #=> "\e[0;29;41mHello world!\e[0m"
92
+ # 'Hello world!'.colorize('reverse') #=> "\e[0;29;7mHello world!\e[0m"
93
+ def colorize description = '', start_at = nil
94
+ if start_at.nil? || (cut_point = index(start_at)).nil?
95
+ Colorizer.instance.colorize self, description
96
+ else
97
+ self[0...cut_point] + Colorizer.instance.colorize(self[cut_point..-1], description)
98
+ end
99
+ end
100
+
101
+ # As +colorize+, but modify this string in-place instead of returning a new one.
102
+ def colorize! description = nil, start_at = nil
103
+ replace colorize(description, start_at) unless description.nil?
104
+ end
105
+
106
+ # Return a new string with all color-related escape sequences removed.
107
+ def decolorize
108
+ dup.decolorize!
109
+ end
110
+
111
+ # Remove all color-related escape sequences from this string in-place.
112
+ def decolorize!
113
+ gsub!(/\e\[\d+[;\d]*m/, '')
114
+ self
115
+ end
116
+ end
@@ -0,0 +1,12 @@
1
+ unless :to_proc.respond_to? :to_proc
2
+ class Symbol
3
+ # Returns a Proc object which responds to a method whose name is this
4
+ # symbol.
5
+ #
6
+ # This is a fallback implementation for older rubies that don't have
7
+ # a built-in Symbol#to_proc.
8
+ def to_proc
9
+ L{|*args| args.shift.__send__ self, *args }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ # The implementation of #try as found in activesupport:
2
+ # lib/active_support/core_ext/object/try.rb
3
+ #
4
+ # Try is just a nil-swallowing send, which means return nil when called on
5
+ # nil and just send like normal when called on any other object.
6
+
7
+ class Object
8
+ alias_method :try, :__send__
9
+ end
10
+
11
+ class NilClass
12
+ def try *args
13
+ nil
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ require 'uri'
2
+ module URI
3
+ module Escape
4
+ alias_method :original_escape, :escape
5
+
6
+ # Patch URI.escape to prevent multiple escapes, by unescaping the input
7
+ # before escaping it.
8
+ #
9
+ # For example, URI.escape normally behaves like this:
10
+ # URI.escape "path with spaces" #=> "path%20with%20spaces"
11
+ # URI.escape "/path%20with%20spaces" #=> "/path%2520with%2520spaces"
12
+ #
13
+ # This patched version behaves like this:
14
+ # URI.escape "/path with spaces" #=> "/path%20with%20spaces"
15
+ # URI.escape "/path%20with%20spaces" #=> "/path%20with%20spaces"
16
+ #
17
+ # This is pretty cheeky, but as far as I can see it won't cause any
18
+ # problems - I can't see any situation where a doubly-escaped entity is a
19
+ # good thing.
20
+ def escape str, unsafe = URI::UNSAFE
21
+ URI.original_escape URI.unescape(str), unsafe
22
+ end
23
+ end
24
+ end