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,210 @@
|
|
1
|
+
module Babushka
|
2
|
+
class SystemProfile
|
3
|
+
include ShellHelpers
|
4
|
+
extend ShellHelpers
|
5
|
+
|
6
|
+
def self.for_host
|
7
|
+
{
|
8
|
+
'Linux' => LinuxSystemProfile,
|
9
|
+
'Darwin' => OSXSystemProfile,
|
10
|
+
'DragonFly' => DragonFlySystemProfile,
|
11
|
+
'FreeBSD' => FreeBSDSystemProfile
|
12
|
+
}[shell('uname -s')].try(:for_flavour)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.for_flavour
|
16
|
+
new
|
17
|
+
end
|
18
|
+
|
19
|
+
def version_info
|
20
|
+
@_version_info ||= get_version_info
|
21
|
+
end
|
22
|
+
|
23
|
+
def linux?; false end
|
24
|
+
def osx?; false end
|
25
|
+
def bsd?; false end
|
26
|
+
def pkg_helper; nil end
|
27
|
+
def pkg_helper_key; pkg_helper.try(:manager_key) end
|
28
|
+
def pkg_helper_str; pkg_helper_key.to_s.capitalize end
|
29
|
+
# The extension that dynamic libraries are given on this system. On linux
|
30
|
+
# libraries are named like 'libssl.so'; on OS X, 'libssl.bundle'.
|
31
|
+
def library_ext; 'so' end
|
32
|
+
|
33
|
+
def cpu_type
|
34
|
+
shell('uname -p').tap {|result|
|
35
|
+
result.replace shell('uname -m') if result[/unknown|\s/]
|
36
|
+
# These replacements are taken from PhusionPassenger::PlatformInfo.cpu_architectures
|
37
|
+
result.replace 'x86' if result[/^i.86$/]
|
38
|
+
result.replace 'x86_64' if result == 'amd64'
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def total_memory
|
43
|
+
raise "#{self.class}#total_memory is unimplemented."
|
44
|
+
end
|
45
|
+
|
46
|
+
def description
|
47
|
+
[
|
48
|
+
(flavour_str unless flavour_str == system_str),
|
49
|
+
system_str,
|
50
|
+
version,
|
51
|
+
("(#{name_str})" unless name_str.nil?)
|
52
|
+
].compact.join(' ')
|
53
|
+
end
|
54
|
+
|
55
|
+
def name
|
56
|
+
(SystemDefinitions.names[system][flavour] || {})[release]
|
57
|
+
end
|
58
|
+
def name_str
|
59
|
+
(SystemDefinitions.descriptions[system][flavour] || {})[release]
|
60
|
+
end
|
61
|
+
|
62
|
+
def match_list
|
63
|
+
[name, flavour, pkg_helper_key, system, :all].compact
|
64
|
+
end
|
65
|
+
|
66
|
+
def matches? specs
|
67
|
+
[*specs].any? {|spec| first_nonmatch_for(spec).nil? }
|
68
|
+
end
|
69
|
+
|
70
|
+
def first_nonmatch_for spec
|
71
|
+
if spec == :all
|
72
|
+
nil
|
73
|
+
elsif SystemDefinitions.all_systems.include? spec
|
74
|
+
spec == system ? nil : :system
|
75
|
+
elsif PkgHelper.all_manager_keys.include? spec
|
76
|
+
spec == pkg_helper_key ? nil : :pkg_helper
|
77
|
+
elsif our_flavours.include? spec
|
78
|
+
spec == flavour ? nil : :flavour
|
79
|
+
elsif our_flavour_names.include? spec
|
80
|
+
spec == name ? nil : :name
|
81
|
+
else
|
82
|
+
:system
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def differentiator_for specs
|
87
|
+
nonmatches = [*specs].map {|spec|
|
88
|
+
first_nonmatch_for spec
|
89
|
+
}.sort_by {|spec|
|
90
|
+
[:system, :flavour, :name].index spec
|
91
|
+
}.compact
|
92
|
+
send "#{nonmatches.last}_str" unless nonmatches.empty?
|
93
|
+
end
|
94
|
+
|
95
|
+
def our_flavours
|
96
|
+
SystemDefinitions.names[system].keys
|
97
|
+
end
|
98
|
+
def our_flavour_names
|
99
|
+
SystemDefinitions.names[system][flavour].values
|
100
|
+
end
|
101
|
+
|
102
|
+
def flavour_str_map
|
103
|
+
# Only required for names that can't be auto-capitalized,
|
104
|
+
# e.g. :ubuntu => 'Ubuntu' isn't required.
|
105
|
+
{
|
106
|
+
:linux => {
|
107
|
+
:centos => 'CentOS',
|
108
|
+
:redhat => 'Red Hat'
|
109
|
+
}
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
class OSXSystemProfile < SystemProfile
|
116
|
+
def osx?; true end
|
117
|
+
def library_ext; 'bundle' end
|
118
|
+
def system; :osx end
|
119
|
+
def system_str; 'Mac OS X' end
|
120
|
+
def flavour; system end
|
121
|
+
def flavour_str; system_str end
|
122
|
+
def version; version_info.val_for 'ProductVersion' end
|
123
|
+
def release; version.match(/^\d+\.\d+/).to_s end
|
124
|
+
def get_version_info; shell 'sw_vers' end
|
125
|
+
def pkg_helper; BrewHelper end
|
126
|
+
def total_memory; shell("sysctl -a").val_for("hw.memsize").to_i end
|
127
|
+
end
|
128
|
+
|
129
|
+
class BSDSystemProfile < SystemProfile
|
130
|
+
def bsd?; true end
|
131
|
+
def system; :bsd end
|
132
|
+
def system_str; 'BSD' end
|
133
|
+
def flavour; :unknown end
|
134
|
+
def flavour_str; system_str end
|
135
|
+
def version; shell 'uname -s' end
|
136
|
+
def release; shell 'uname -r' end
|
137
|
+
def get_version_info; shell 'uname -v' end
|
138
|
+
end
|
139
|
+
|
140
|
+
class DragonFlySystemProfile < BSDSystemProfile
|
141
|
+
def system_str; 'DragonFly' end
|
142
|
+
def flavour; :dragonfly end
|
143
|
+
def pkg_helper; BinPkgSrcHelper end
|
144
|
+
def total_memory; shell("sysctl -a").val_for("hw.physmem").to_i end
|
145
|
+
end
|
146
|
+
|
147
|
+
class FreeBSDSystemProfile < BSDSystemProfile
|
148
|
+
def system_str; 'FreeBSD' end
|
149
|
+
def flavour; :freebsd end
|
150
|
+
def pkg_helper; BinPortsHelper end
|
151
|
+
def total_memory; shell("sysctl -a").val_for("hw.realmem").to_i end
|
152
|
+
end
|
153
|
+
|
154
|
+
class LinuxSystemProfile < SystemProfile
|
155
|
+
def linux?; true end
|
156
|
+
def system; :linux end
|
157
|
+
def system_str; 'Linux' end
|
158
|
+
def flavour; :unknown end
|
159
|
+
def flavour_str; flavour_str_map[system][flavour] end
|
160
|
+
def version; 'unknown' end
|
161
|
+
def release; version end
|
162
|
+
|
163
|
+
def self.for_flavour
|
164
|
+
(detect_using_release_file || LinuxSystemProfile).new
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
|
169
|
+
def self.detect_using_release_file
|
170
|
+
{
|
171
|
+
'debian_version' => DebianSystemProfile,
|
172
|
+
'redhat-release' => RedhatSystemProfile,
|
173
|
+
'arch-release' => ArchSystemProfile,
|
174
|
+
# 'gentoo-release' =>
|
175
|
+
# 'SuSE-release' =>
|
176
|
+
}.selekt {|release_file, system_profile|
|
177
|
+
File.exists? "/etc/#{release_file}"
|
178
|
+
}.values.first
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
class DebianSystemProfile < LinuxSystemProfile
|
183
|
+
def flavour; flavour_str.downcase.to_sym end
|
184
|
+
def flavour_str; version_info.val_for 'Distributor ID' end
|
185
|
+
def version; version_info.val_for 'Release' end
|
186
|
+
def name; version_info.val_for('Codename').to_sym end
|
187
|
+
def get_version_info; ensure_lsb_release and shell('lsb_release -a') end
|
188
|
+
def ensure_lsb_release
|
189
|
+
which('lsb_release') or log("Babushka uses `lsb_release` to learn about debian-based systems.") {
|
190
|
+
AptHelper.install!('lsb-release')
|
191
|
+
}
|
192
|
+
end
|
193
|
+
def pkg_helper; AptHelper end
|
194
|
+
def total_memory; shell("free -b").val_for("Mem").scan(/^\d+\b/).first.to_i end
|
195
|
+
end
|
196
|
+
|
197
|
+
class RedhatSystemProfile < LinuxSystemProfile
|
198
|
+
def flavour; version_info[/^Red Hat/i] ? :redhat : version_info[/^\w+/].downcase.to_sym end
|
199
|
+
def version; version_info[/release [\d\.]+ \((\w+)\)/i, 1] || version_info[/release ([\d\.]+)/i, 1] end
|
200
|
+
def get_version_info; File.read '/etc/redhat-release' end
|
201
|
+
def pkg_helper; YumHelper end
|
202
|
+
end
|
203
|
+
|
204
|
+
class ArchSystemProfile < LinuxSystemProfile
|
205
|
+
def get_version_info; 'rolling' end
|
206
|
+
def pkg_helper; PacmanHelper end
|
207
|
+
def flavour; :arch end
|
208
|
+
def version; ''; end
|
209
|
+
end
|
210
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
module Babushka
|
2
|
+
class Task
|
3
|
+
include Singleton
|
4
|
+
include LogHelpers
|
5
|
+
include PathHelpers
|
6
|
+
include ShellHelpers
|
7
|
+
|
8
|
+
attr_reader :opts, :vars, :persistent_log
|
9
|
+
attr_accessor :reportable
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@vars = Vars.new
|
13
|
+
@opts = Base.cmdline.opts.dup
|
14
|
+
@running = false
|
15
|
+
end
|
16
|
+
|
17
|
+
def process dep_names, with_vars = {}
|
18
|
+
raise "A task is already running." if running?
|
19
|
+
@running = true
|
20
|
+
Base.in_thread { RunReporter.post_reports }
|
21
|
+
dep_names.all? {|dep_name| process_dep dep_name, with_vars }
|
22
|
+
ensure
|
23
|
+
@running = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def process_dep dep_name, with_vars
|
27
|
+
Dep.find_or_suggest dep_name do |dep|
|
28
|
+
log_dep(dep) {
|
29
|
+
load_run_info_for dep, with_vars
|
30
|
+
dep.with(task_args_for(dep, with_vars)).process(:top_level => true).tap {|result|
|
31
|
+
save_run_info_for dep, result
|
32
|
+
}
|
33
|
+
}.tap {|result|
|
34
|
+
log "You can view #{opt(:debug) ? 'the' : 'a more detailed'} log at '#{log_path_for(dep)}'." unless result
|
35
|
+
RunReporter.queue dep, result, reportable
|
36
|
+
BugReporter.report dep if reportable
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def task_info dep, result
|
42
|
+
{
|
43
|
+
:version => VERSION,
|
44
|
+
:run_at => Time.now,
|
45
|
+
:system_info => Base.host.description,
|
46
|
+
:dep_name => dep.name,
|
47
|
+
:source_uri => dep.dep_source.uri,
|
48
|
+
:result => result
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def opt name
|
53
|
+
opts[name]
|
54
|
+
end
|
55
|
+
|
56
|
+
def running?
|
57
|
+
@running
|
58
|
+
end
|
59
|
+
|
60
|
+
def callstack
|
61
|
+
@callstack ||= []
|
62
|
+
end
|
63
|
+
|
64
|
+
def log_path_for dep
|
65
|
+
log_prefix / dep.contextual_name
|
66
|
+
end
|
67
|
+
|
68
|
+
def var_path_for dep
|
69
|
+
VarsPrefix.p / dep.contextual_name
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def task_args_for dep, with_vars
|
75
|
+
with_vars.keys.inject({}) {|hsh,k|
|
76
|
+
# The string arg names are sanitized in the 'meet' cmdline handler.
|
77
|
+
hsh[k.to_sym] = with_vars[k]; hsh
|
78
|
+
}.tap {|with_args|
|
79
|
+
if (unexpected = with_args.keys - dep.params).any?
|
80
|
+
log_warn "Ignoring unexpected argument#{'s' if unexpected.length > 1} #{unexpected.map(&:to_s).map(&:inspect).to_list}, which the dep '#{dep.name}' would reject."
|
81
|
+
unexpected.each {|key| with_args.delete(key) }
|
82
|
+
end
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
def log_dep dep
|
87
|
+
log_prefix.mkdir
|
88
|
+
log_path_for(dep).open('w') {|f|
|
89
|
+
f.sync = true
|
90
|
+
@persistent_log = f
|
91
|
+
yield.tap { @persistent_log = nil }
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
def log_prefix
|
96
|
+
LogPrefix.p
|
97
|
+
end
|
98
|
+
|
99
|
+
def load_run_info_for dep, with_vars
|
100
|
+
load_var_log_for(var_path_for(dep)).each_pair {|var_name,var_data|
|
101
|
+
vars.saved_vars[var_name].update var_data
|
102
|
+
}
|
103
|
+
with_vars.each_pair {|var_name,var_value|
|
104
|
+
vars.vars[var_name].update :value => var_value
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
def save_run_info_for dep, result
|
109
|
+
save_var_log_for var_path_for(dep), {
|
110
|
+
:info => task_info(dep, result),
|
111
|
+
:vars => vars.for_save
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
def load_var_log_for path
|
116
|
+
require 'yaml'
|
117
|
+
unless File.exists? path
|
118
|
+
debug "No log to load for '#{path}'."
|
119
|
+
else
|
120
|
+
dep_log = YAML.load_file path
|
121
|
+
unless dep_log.is_a?(Hash) && dep_log[:vars].is_a?(Hash)
|
122
|
+
log_error "Ignoring corrupt var log at #{path}."
|
123
|
+
else
|
124
|
+
dep_log[:vars]
|
125
|
+
end
|
126
|
+
end || {}
|
127
|
+
end
|
128
|
+
|
129
|
+
def save_var_log_for var_path, data
|
130
|
+
cd File.dirname(var_path), :create => true do |path|
|
131
|
+
debug "Saving #{var_path}"
|
132
|
+
dump_yaml_to File.basename(var_path), data
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def dump_yaml_to filename, data
|
137
|
+
require 'yaml'
|
138
|
+
File.open(filename, 'w') {|f| YAML.dump data, f }
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Babushka
|
2
|
+
class Vars
|
3
|
+
include LogHelpers
|
4
|
+
|
5
|
+
attr_reader :vars, :saved_vars
|
6
|
+
|
7
|
+
module Helpers
|
8
|
+
def set(key, value) Base.task.vars.set(key, value) end
|
9
|
+
def merge(key, value) Base.task.vars.merge(key, value) end
|
10
|
+
def var(name, opts = {}) Base.task.vars.var(name, opts) end
|
11
|
+
def define_var(name, opts = {}) Base.task.vars.define_var(name, opts) end
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@vars = Hashish.hash
|
16
|
+
@saved_vars = Hashish.hash
|
17
|
+
end
|
18
|
+
|
19
|
+
def set key, value
|
20
|
+
vars[key.to_s][:value] = value
|
21
|
+
end
|
22
|
+
def merge key, value
|
23
|
+
set key, ((vars[key.to_s] || {})[:value] || {}).merge(value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def var name, opts = {}
|
27
|
+
define_var name, opts
|
28
|
+
if vars[name.to_s].has_key? :value
|
29
|
+
if vars[name.to_s][:value].respond_to? :call
|
30
|
+
vars[name.to_s][:value].call
|
31
|
+
else
|
32
|
+
vars[name.to_s][:value]
|
33
|
+
end
|
34
|
+
elsif opts[:ask] != false
|
35
|
+
ask_for_var name.to_s, opts
|
36
|
+
else
|
37
|
+
default_for name
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def define_var name, opts = {}
|
42
|
+
vars[name.to_s].update opts.slice(:default, :type, :message, :choices, :choice_descriptions)
|
43
|
+
vars[name.to_s][:choices] ||= vars[name.to_s][:choice_descriptions].keys unless vars[name.to_s][:choice_descriptions].nil?
|
44
|
+
vars[name.to_s]
|
45
|
+
end
|
46
|
+
|
47
|
+
def for_save
|
48
|
+
vars.dup.inject(saved_vars.dup) {|vars_to_save,(var,_)|
|
49
|
+
vars_to_save[var].update vars[var]
|
50
|
+
save_referenced_default_for(var, vars_to_save) if vars[var][:default].is_a?(Symbol)
|
51
|
+
vars_to_save
|
52
|
+
}.reject_r {|var,data|
|
53
|
+
![String, Symbol, Hash, Numeric, TrueClass, FalseClass].include?(data.class) ||
|
54
|
+
var.to_s['password']
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def default_for key
|
59
|
+
if vars[key.to_s][:default].respond_to? :call
|
60
|
+
# If the default is a proc, re-evaluate it every time.
|
61
|
+
instance_eval { vars[key.to_s][:default].call }
|
62
|
+
|
63
|
+
elsif saved_vars[key.to_s].has_key? :value
|
64
|
+
# Otherwise, if there's a saved value, use that.
|
65
|
+
saved_vars[key.to_s][:value]
|
66
|
+
|
67
|
+
# Symbol defaults are references to other vars.
|
68
|
+
elsif vars[key.to_s][:default].is_a? Symbol
|
69
|
+
# Look up the current value of the referenced var.
|
70
|
+
referenced_val = var vars[key.to_s][:default], :ask => false
|
71
|
+
# Use the corresponding saved value if there is one, otherwise use the reference.
|
72
|
+
(saved_vars[key.to_s][:values] ||= {})[referenced_val] || referenced_val
|
73
|
+
|
74
|
+
else
|
75
|
+
# Otherwise, use the default.
|
76
|
+
vars[key.to_s][:default]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def ask_for_var key, opts
|
84
|
+
set key, Prompt.send("get_#{vars[key][:type] || 'value'}",
|
85
|
+
message_for(key),
|
86
|
+
vars[key].slice(:choices, :choice_descriptions).merge(
|
87
|
+
opts
|
88
|
+
).merge(
|
89
|
+
:default => default_for(key),
|
90
|
+
:dynamic => vars[key][:default].respond_to?(:call)
|
91
|
+
)
|
92
|
+
)
|
93
|
+
end
|
94
|
+
|
95
|
+
def message_for key
|
96
|
+
printable_key = key.to_s.gsub '_', ' '
|
97
|
+
vars[key][:message] || printable_key
|
98
|
+
end
|
99
|
+
|
100
|
+
def save_referenced_default_for var, vars_to_save
|
101
|
+
vars_to_save[var][:values] ||= {}
|
102
|
+
vars_to_save[var][:values][ # set the saved value of this var
|
103
|
+
vars[vars[var][:default].to_s][:value] # for this var's current default reference
|
104
|
+
] = vars_to_save[var].delete(:value) # to the referenced var's value
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|