rubycut-babushka 0.10.6
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/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
|