rubycut-babushka 0.10.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +8 -0
- data/Gemfile.lock +31 -0
- data/README.markdown +246 -0
- data/Rakefile +26 -0
- data/bin/babushka +11 -0
- data/deps/babushka.rb +101 -0
- data/deps/dev.rb +12 -0
- data/deps/fhs.rb +31 -0
- data/deps/git.rb +29 -0
- data/deps/homebrew.rb +30 -0
- data/deps/os_x.rb +33 -0
- data/deps/packages.rb +22 -0
- data/deps/pkg_managers.rb +110 -0
- data/deps/ruby.rb +23 -0
- data/deps/rubygems.rb +24 -0
- data/deps/system.rb +10 -0
- data/deps/templates/app.rb +68 -0
- data/deps/templates/external.rb +12 -0
- data/deps/templates/installer.rb +31 -0
- data/deps/templates/managed.rb +105 -0
- data/deps/templates/ppa.rb +24 -0
- data/deps/templates/src.rb +42 -0
- data/deps/templates/tmbundle.rb +15 -0
- data/lib/babushka.rb +28 -0
- data/lib/babushka/accepts_block_for.rb +72 -0
- data/lib/babushka/accepts_list_for.rb +49 -0
- data/lib/babushka/accepts_value_for.rb +24 -0
- data/lib/babushka/base.rb +78 -0
- data/lib/babushka/bug_reporter.rb +55 -0
- data/lib/babushka/cmdline.rb +133 -0
- data/lib/babushka/cmdline/handler.rb +41 -0
- data/lib/babushka/cmdline/helpers.rb +127 -0
- data/lib/babushka/cmdline/parser.rb +69 -0
- data/lib/babushka/colorizer.rb +59 -0
- data/lib/babushka/core_patches/array.rb +171 -0
- data/lib/babushka/core_patches/blank.rb +22 -0
- data/lib/babushka/core_patches/bytes.rb +52 -0
- data/lib/babushka/core_patches/hash.rb +107 -0
- data/lib/babushka/core_patches/hashish.rb +14 -0
- data/lib/babushka/core_patches/integer.rb +25 -0
- data/lib/babushka/core_patches/io.rb +8 -0
- data/lib/babushka/core_patches/numeric.rb +16 -0
- data/lib/babushka/core_patches/object.rb +27 -0
- data/lib/babushka/core_patches/string.rb +116 -0
- data/lib/babushka/core_patches/symbol.rb +12 -0
- data/lib/babushka/core_patches/try.rb +15 -0
- data/lib/babushka/core_patches/uri.rb +24 -0
- data/lib/babushka/dep.rb +470 -0
- data/lib/babushka/dep_context.rb +18 -0
- data/lib/babushka/dep_definer.rb +115 -0
- data/lib/babushka/dep_pool.rb +49 -0
- data/lib/babushka/dep_runner.rb +85 -0
- data/lib/babushka/dsl.rb +26 -0
- data/lib/babushka/git_repo.rb +185 -0
- data/lib/babushka/helpers/git_helpers.rb +32 -0
- data/lib/babushka/helpers/log_helpers.rb +176 -0
- data/lib/babushka/helpers/path_helpers.rb +34 -0
- data/lib/babushka/helpers/run_helpers.rb +145 -0
- data/lib/babushka/helpers/shell_helpers.rb +229 -0
- data/lib/babushka/helpers/suggest_helpers.rb +16 -0
- data/lib/babushka/helpers/uri_helpers.rb +36 -0
- data/lib/babushka/ip.rb +160 -0
- data/lib/babushka/lambda_chooser.rb +40 -0
- data/lib/babushka/levenshtein.rb +125 -0
- data/lib/babushka/meta_dep.rb +65 -0
- data/lib/babushka/meta_dep_context.rb +15 -0
- data/lib/babushka/parameter.rb +143 -0
- data/lib/babushka/pkg_helper.rb +81 -0
- data/lib/babushka/pkg_helpers/apt_helper.rb +61 -0
- data/lib/babushka/pkg_helpers/base_helper.rb +19 -0
- data/lib/babushka/pkg_helpers/binpkgsrc_helper.rb +48 -0
- data/lib/babushka/pkg_helpers/binports_helper.rb +34 -0
- data/lib/babushka/pkg_helpers/brew_helper.rb +110 -0
- data/lib/babushka/pkg_helpers/gem_helper.rb +120 -0
- data/lib/babushka/pkg_helpers/macports_helper.rb +22 -0
- data/lib/babushka/pkg_helpers/npm_helper.rb +45 -0
- data/lib/babushka/pkg_helpers/pacman_helper.rb +27 -0
- data/lib/babushka/pkg_helpers/pip_helper.rb +45 -0
- data/lib/babushka/pkg_helpers/src_helper.rb +16 -0
- data/lib/babushka/pkg_helpers/yum_helper.rb +25 -0
- data/lib/babushka/popen.rb +40 -0
- data/lib/babushka/prompt.rb +176 -0
- data/lib/babushka/renderable.rb +67 -0
- data/lib/babushka/resource.rb +215 -0
- data/lib/babushka/run_reporter.rb +60 -0
- data/lib/babushka/shell.rb +108 -0
- data/lib/babushka/source.rb +216 -0
- data/lib/babushka/source_pool.rb +146 -0
- data/lib/babushka/system_definitions.rb +97 -0
- data/lib/babushka/system_profile.rb +210 -0
- data/lib/babushka/task.rb +142 -0
- data/lib/babushka/vars.rb +108 -0
- data/lib/babushka/version_of.rb +65 -0
- data/lib/babushka/version_str.rb +57 -0
- data/lib/babushka/xml_string.rb +28 -0
- data/lib/components.rb +82 -0
- data/lib/fancypath/fancypath.rb +200 -0
- data/lib/inkan/inkan.rb +76 -0
- data/spec/acceptance/acceptance.rb +43 -0
- data/spec/acceptance_helper.rb +113 -0
- data/spec/archives/Blah.app.zip +0 -0
- data/spec/archives/archive.tar +0 -0
- data/spec/archives/archive.tar.bz2 +0 -0
- data/spec/archives/archive.tar.gz +0 -0
- data/spec/archives/archive.tbz2 +0 -0
- data/spec/archives/archive.tgz +0 -0
- data/spec/archives/archive.zip +0 -0
- data/spec/archives/content.txt +5 -0
- data/spec/archives/invalid_archive +5 -0
- data/spec/archives/nested archive/content.txt +5 -0
- data/spec/archives/nested_archive.tar +0 -0
- data/spec/archives/really_a_gzip.zip +0 -0
- data/spec/archives/test-0.3.1.tgz +0 -0
- data/spec/archives/tgz_archive +0 -0
- data/spec/archives/zip_without_extension +0 -0
- data/spec/babushka/accepts_for_spec.rb +174 -0
- data/spec/babushka/accepts_for_support.rb +72 -0
- data/spec/babushka/cmdline/console_spec.rb +11 -0
- data/spec/babushka/cmdline/help_spec.rb +61 -0
- data/spec/babushka/cmdline/version_spec.rb +10 -0
- data/spec/babushka/core_patches_spec.rb +171 -0
- data/spec/babushka/dep_context_spec.rb +58 -0
- data/spec/babushka/dep_definer_spec.rb +152 -0
- data/spec/babushka/dep_definer_support.rb +36 -0
- data/spec/babushka/dep_spec.rb +567 -0
- data/spec/babushka/dep_support.rb +29 -0
- data/spec/babushka/deps_spec.rb +113 -0
- data/spec/babushka/gem_helper_spec.rb +90 -0
- data/spec/babushka/git_repo_spec.rb +396 -0
- data/spec/babushka/ip_spec.rb +131 -0
- data/spec/babushka/lambda_chooser_spec.rb +115 -0
- data/spec/babushka/meta_dep_definer_spec.rb +127 -0
- data/spec/babushka/meta_dep_wrapper_spec.rb +32 -0
- data/spec/babushka/parameter_spec.rb +135 -0
- data/spec/babushka/path_helpers_spec.rb +102 -0
- data/spec/babushka/prompt_spec.rb +188 -0
- data/spec/babushka/renderable_spec.rb +100 -0
- data/spec/babushka/resource_spec.rb +141 -0
- data/spec/babushka/run_helpers_spec.rb +26 -0
- data/spec/babushka/shell_helpers_spec.rb +244 -0
- data/spec/babushka/shell_spec.rb +19 -0
- data/spec/babushka/source_pool_spec.rb +320 -0
- data/spec/babushka/source_pool_support.rb +31 -0
- data/spec/babushka/source_spec.rb +382 -0
- data/spec/babushka/source_support.rb +17 -0
- data/spec/babushka/system_profile_spec.rb +61 -0
- data/spec/babushka/task_spec.rb +141 -0
- data/spec/babushka/uri_spec.rb +13 -0
- data/spec/babushka/vars_spec.rb +59 -0
- data/spec/babushka/version_of_spec.rb +110 -0
- data/spec/babushka/version_str_spec.rb +130 -0
- data/spec/babushka/version_str_support.rb +37 -0
- data/spec/babushka/xml_string_spec.rb +98 -0
- data/spec/deps/bad/broken.rb +7 -0
- data/spec/deps/bad/working.rb +3 -0
- data/spec/deps/good/meta.rb +14 -0
- data/spec/deps/good/test.rb +11 -0
- data/spec/deps/outer/deps.rb +19 -0
- data/spec/deps/outer/more deps.rb +11 -0
- data/spec/deps/params/params.rb +10 -0
- data/spec/fancypath/fancypath_spec.rb +272 -0
- data/spec/fancypath_support.rb +10 -0
- data/spec/inkan/inkan_spec.rb +217 -0
- data/spec/renderable/different_example.conf.erb +4 -0
- data/spec/renderable/example.conf.erb +3 -0
- data/spec/renderable/example.sh +6 -0
- data/spec/renderable/with_binding.conf.erb +4 -0
- data/spec/renderable/xml_example.conf.erb +8 -0
- data/spec/repos/remote.git.tgz +0 -0
- data/spec/spec_helper.rb +87 -0
- 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,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
|