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,15 @@
|
|
1
|
+
module Babushka
|
2
|
+
class MetaDepContext < DepContext
|
3
|
+
|
4
|
+
def self.template &block
|
5
|
+
@template = block unless block.nil?
|
6
|
+
@template
|
7
|
+
end
|
8
|
+
|
9
|
+
def define!
|
10
|
+
instance_eval(&self.class.template) unless self.class.template.nil?
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module Babushka
|
2
|
+
class Parameter
|
3
|
+
attr_reader :name
|
4
|
+
|
5
|
+
def self.for name, value = nil
|
6
|
+
value.is_a?(Parameter) ? value : Parameter.new(name, value)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(name, value = nil)
|
10
|
+
@name = name
|
11
|
+
@value = value
|
12
|
+
end
|
13
|
+
|
14
|
+
# If #default! is set, the parameter's value will default to it lazily when
|
15
|
+
# it's requested, without prompting. If the parameter is set, though (i.e.
|
16
|
+
# if an explicit value was supplied, say on the command line), it will
|
17
|
+
# override the #default! value.
|
18
|
+
#
|
19
|
+
# This is useful for setting parameters that have a "standard" value of some
|
20
|
+
# kind that won't usually need to be customised.
|
21
|
+
#
|
22
|
+
# For example, the deps that install babushka itself use a :branch parameter
|
23
|
+
# that has #default! set to 'master'. This means that the installation
|
24
|
+
# process will install the 'master' branch without asking the user to choose
|
25
|
+
# a branch, but a custom branch can still be specified by passing an
|
26
|
+
# explicit value, for example by passing 'branch=next' on the command line.
|
27
|
+
def default! value
|
28
|
+
tap { @default_bang = value }
|
29
|
+
end
|
30
|
+
|
31
|
+
# If #default is set, then when this parameter lazily prompts for a value,
|
32
|
+
# it will pass #default to Prompt as the default. That is, Prompt will
|
33
|
+
# return #default's value if the user just hits 'enter', if '--defaults' was
|
34
|
+
# passed on the commandline, or if babushka is running on a non-terminal
|
35
|
+
# STDIN.
|
36
|
+
#
|
37
|
+
# This is useful for setting parameters that should be customised, or maybe
|
38
|
+
# just confirmed by the user, each time the dep is run.
|
39
|
+
#
|
40
|
+
# For example, the deps that install babushka itself use a :path parameter
|
41
|
+
# that has #default set to '/usr/local/babushka' (unless babushka is already
|
42
|
+
# in the path, in which case it's a non-prompting default). This means that
|
43
|
+
# babushka will ask for a path when it's installed, providing
|
44
|
+
# '/usr/local/babushka' as the "just-hit-enter" default.
|
45
|
+
def default value
|
46
|
+
tap { @default = value }
|
47
|
+
end
|
48
|
+
|
49
|
+
# If #ask is set, then when this parameter lazily prompts for a value, it
|
50
|
+
# will pass #ask to Prompt as the message. That is, Prompt will use this
|
51
|
+
# string, ending it with a question mark, as the question it shows to the
|
52
|
+
# user to give them information about the value it's requesting.
|
53
|
+
#
|
54
|
+
# For example, the deps that install babushka itself use a :path parameter.
|
55
|
+
# if #ask wasn't specified, it would prompt the user with just 'path?',
|
56
|
+
# which isn't very clear. Instead, #ask is set to 'Where would you like
|
57
|
+
# babushka installed', which, along with the default value, makes it clear
|
58
|
+
# to the user what they're being asked for.
|
59
|
+
def ask value
|
60
|
+
tap { @ask = value }
|
61
|
+
end
|
62
|
+
|
63
|
+
# If #choose is set, then when this parameter lazily prompts for a value, it
|
64
|
+
# will only accept a value that is in #choose's list.
|
65
|
+
#
|
66
|
+
# You can pass either an array or a hash to #choose. If you pass an array of
|
67
|
+
# values, Prompt will only accept a value that's included in the array. If
|
68
|
+
# you pass a hash of {value => description}, Prompt will only accept a value
|
69
|
+
# that's included in the hash's keys, printing a list of the corresponding
|
70
|
+
# descriptions before asking for the value.
|
71
|
+
def choose *value
|
72
|
+
tap {
|
73
|
+
@choose = if [[Hash], [Array]].include?(value.map(&:class))
|
74
|
+
value.first
|
75
|
+
else
|
76
|
+
value
|
77
|
+
end
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
def set?
|
82
|
+
!!@value
|
83
|
+
end
|
84
|
+
|
85
|
+
def == other
|
86
|
+
value == other
|
87
|
+
end
|
88
|
+
|
89
|
+
def / other
|
90
|
+
value / other
|
91
|
+
end
|
92
|
+
|
93
|
+
def [] other
|
94
|
+
value[other]
|
95
|
+
end
|
96
|
+
|
97
|
+
def p
|
98
|
+
value.p
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_s
|
102
|
+
value.to_s
|
103
|
+
end
|
104
|
+
|
105
|
+
def to_str
|
106
|
+
if !value.respond_to?(:to_str)
|
107
|
+
raise TypeError, "Can't coerce #{value}:#{value.class.name} into a String"
|
108
|
+
else
|
109
|
+
value.to_str
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def inspect
|
114
|
+
"#<Babushka::Parameter:#{object_id} #{description}>"
|
115
|
+
end
|
116
|
+
|
117
|
+
def description
|
118
|
+
if @value
|
119
|
+
"#{name}: #{@value.inspect}"
|
120
|
+
elsif @default_bang
|
121
|
+
"#{name}: [default!: #{@default_bang.inspect}]"
|
122
|
+
elsif @default
|
123
|
+
"#{name}: [default: #{@default.inspect}]"
|
124
|
+
else
|
125
|
+
"#{name}: [unset]"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def value
|
132
|
+
@value ||= @default_bang || Prompt.get_value((@ask || name).to_s, prompt_opts)
|
133
|
+
end
|
134
|
+
|
135
|
+
def prompt_opts
|
136
|
+
{}.tap {|hsh|
|
137
|
+
hsh[:default] = @default unless @default.nil?
|
138
|
+
hsh[:choices] = @choose if @choose.is_a?(Array)
|
139
|
+
hsh[:choice_descriptions] = @choose if @choose.is_a?(Hash)
|
140
|
+
}
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Babushka
|
2
|
+
class PkgHelper
|
3
|
+
class << self
|
4
|
+
include LogHelpers
|
5
|
+
include ShellHelpers
|
6
|
+
include VersionOf::Helpers
|
7
|
+
|
8
|
+
def pkg_binary; pkg_cmd end
|
9
|
+
|
10
|
+
def all_manager_keys
|
11
|
+
[:apt, :brew, :macports, :yum, :binpkgsrc, :binports]
|
12
|
+
end
|
13
|
+
|
14
|
+
def manager_dep
|
15
|
+
manager_key.to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
def has? pkg, opts = {}
|
19
|
+
pkg = VersionOf(pkg)
|
20
|
+
_has?(pkg).tap {|matching_version|
|
21
|
+
matching_pkg = VersionOf(pkg.name, (matching_version if matching_version.is_a?(VersionStr)))
|
22
|
+
unless opts[:log] == false
|
23
|
+
log "system #{matching_version ? "has" : "doesn't have"} #{matching_pkg} #{pkg_type}", :as => (:ok if matching_version)
|
24
|
+
end
|
25
|
+
}
|
26
|
+
end
|
27
|
+
def install! pkgs, opts = nil
|
28
|
+
_install! [*pkgs].map {|pkg| VersionOf(pkg) }, opts
|
29
|
+
end
|
30
|
+
def _install! pkgs, opts
|
31
|
+
log_shell "Installing #{pkgs.to_list} via #{manager_key}", "#{pkg_cmd} -y install #{pkgs.join(' ')} #{opts}", :sudo => should_sudo?
|
32
|
+
end
|
33
|
+
def prefix
|
34
|
+
cmd_dir(pkg_binary).p.dir
|
35
|
+
end
|
36
|
+
def bin_path
|
37
|
+
prefix / 'bin'
|
38
|
+
end
|
39
|
+
def present?
|
40
|
+
which pkg_binary
|
41
|
+
end
|
42
|
+
def cmd_in_path? cmd_name
|
43
|
+
if (_cmd_dir = cmd_dir(cmd_name)).nil?
|
44
|
+
log_error "The '#{cmd_name}' command is not available. You probably need to add #{bin_path} to your PATH."
|
45
|
+
else
|
46
|
+
_cmd_dir.starts_with?(prefix)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
def should_sudo?
|
50
|
+
!File.writable?(bin_path)
|
51
|
+
end
|
52
|
+
|
53
|
+
def update_pkg_lists_if_required
|
54
|
+
if pkg_update_timeout.nil?
|
55
|
+
true # not required
|
56
|
+
else
|
57
|
+
list_age = Time.now - pkg_list_dir.mtime
|
58
|
+
if list_age > pkg_update_timeout
|
59
|
+
update_pkg_lists "#{manager_dep.capitalize} package lists are #{list_age.round.xsecs} old. Updating"
|
60
|
+
else
|
61
|
+
debug "#{manager_dep.capitalize} package lists are #{list_age.round.xsecs} old (up to date)."
|
62
|
+
true # up to date
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
def update_pkg_lists message = "Updating #{manager_dep.capitalize} package lists"
|
67
|
+
log_shell message, pkg_update_command, :sudo => should_sudo?
|
68
|
+
end
|
69
|
+
def pkg_update_timeout
|
70
|
+
nil # not required by default
|
71
|
+
end
|
72
|
+
def pkg_update_command
|
73
|
+
"#{pkg_cmd} update"
|
74
|
+
end
|
75
|
+
|
76
|
+
def cmdline_spec_for pkg
|
77
|
+
"#{pkg.name}#{" --version '#{pkg.version}'" unless pkg.version.nil?}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Babushka
|
2
|
+
class AptHelper < PkgHelper
|
3
|
+
class << self
|
4
|
+
def pkg_type; :deb end
|
5
|
+
def pkg_cmd; "env DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND='noninteractive' #{pkg_binary}" end
|
6
|
+
def pkg_binary
|
7
|
+
@_cached_pkg_binary ||= which('aptitude') ? 'aptitude' : 'apt-get'
|
8
|
+
end
|
9
|
+
def manager_key; :apt end
|
10
|
+
|
11
|
+
def _install! pkgs, opts
|
12
|
+
wait_for_dpkg
|
13
|
+
log_shell "Downloading", "#{pkg_cmd} -y -d install #{pkgs.join(' ')}", :sudo => should_sudo?
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def update_pkg_lists_if_required
|
18
|
+
wait_for_dpkg
|
19
|
+
if !File.exists? '/var/lib/apt/lists/lock'
|
20
|
+
update_pkg_lists "Looks like apt hasn't been used on this system yet. Updating"
|
21
|
+
else
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def source_for_system
|
27
|
+
{
|
28
|
+
:debian => 'http://archive.debian.org/debian',
|
29
|
+
:ubuntu => 'http://archive.ubuntu.com/ubuntu'
|
30
|
+
}[Base.host.flavour]
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def _has? pkg_name
|
35
|
+
wait_for_dpkg
|
36
|
+
status = raw_shell("dpkg -s #{pkg_name}").stdout.val_for('Status')
|
37
|
+
status && status.split(' ').include?('installed')
|
38
|
+
end
|
39
|
+
|
40
|
+
def pkg_update_timeout
|
41
|
+
3600 * 24 # 1 day
|
42
|
+
end
|
43
|
+
def pkg_list_dir
|
44
|
+
'/var/lib/apt/lists'.p
|
45
|
+
end
|
46
|
+
|
47
|
+
def wait_for_dpkg
|
48
|
+
if dpkg_locked?
|
49
|
+
log_block "Looks like dpkg is already in use - waiting" do
|
50
|
+
sleep 1 while dpkg_locked?
|
51
|
+
true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def dpkg_locked?
|
57
|
+
which('fuser') and raw_shell('fuser -v /var/lib/dpkg/lock').stderr[/\bF..../]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Babushka
|
2
|
+
class BaseHelper < PkgHelper
|
3
|
+
class << self
|
4
|
+
def pkg_type; :unknown end
|
5
|
+
def manager_key; :unknown end
|
6
|
+
def manager_dep; nil end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def _install! pkgs, opts
|
11
|
+
raise DepDefiner::UnmeetableDep, "I don't know how to use the package manager on this system."
|
12
|
+
end
|
13
|
+
|
14
|
+
def _has? pkg
|
15
|
+
raise DepDefiner::UnmeetableDep, "I don't know how to use the package manager on this system."
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Babushka
|
2
|
+
class BinPkgSrcHelper < PkgHelper
|
3
|
+
class << self
|
4
|
+
def existing_packages
|
5
|
+
shell("pkg_info -a").lines.to_a.map {|i| i.split(/\s+/)[0] }
|
6
|
+
end
|
7
|
+
|
8
|
+
# Note that with pkg_radd it is possible to override the default
|
9
|
+
# repository using PKG_PATH environment variable. See man 1 pkg_add.
|
10
|
+
|
11
|
+
def pkg_binary; 'pkg_radd' end
|
12
|
+
def pkg_cmd; pkg_binary end
|
13
|
+
def pkg_type; :pkg end
|
14
|
+
def manager_key; :binpkgsrc end
|
15
|
+
|
16
|
+
def update_pkg_lists_if_required
|
17
|
+
if !File.exists? pkg_list_dir
|
18
|
+
update_pkg_lists "Looks like pkg summary hasn't been fetched on this system yet. Updating"
|
19
|
+
else
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def pkg_update_timeout
|
25
|
+
3600 * 24 * 14 # 2 weeks
|
26
|
+
end
|
27
|
+
|
28
|
+
def pkg_list_dir
|
29
|
+
'/usr/pkgsrc/pkg_summary'.p
|
30
|
+
end
|
31
|
+
|
32
|
+
def pkg_update_command
|
33
|
+
"pkg_search -d"
|
34
|
+
end
|
35
|
+
|
36
|
+
def _install! pkgs, opts
|
37
|
+
log_shell "Installing #{pkgs.join(', ')}", "pkg_radd #{pkgs.join(' ')}", :sudo => should_sudo?
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def _has? pkg
|
43
|
+
existing_packages.any? {|i| i.match(/#{pkg}/)}
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Babushka
|
2
|
+
class BinPortsHelper < PkgHelper
|
3
|
+
class << self
|
4
|
+
def existing_packages
|
5
|
+
shell("pkg_info").lines.to_a.map {|i| i.split(/\s+/)[0] }
|
6
|
+
end
|
7
|
+
|
8
|
+
# Regarding FreeBSD binary packages the following should be noted:
|
9
|
+
# pkg_add uses PACKAGESITE and PACKAGEROOT environment variables
|
10
|
+
# to calculate the URL to download packages from.
|
11
|
+
#
|
12
|
+
# If you're using outdated FreeBSD RELEASE branch (like 6.2-release)
|
13
|
+
# that does not have anymore it's public package repository, please
|
14
|
+
# either consider to move to the STABLE one (like 6-release)
|
15
|
+
# or set PACKAGESITE var to point to appropriate package repository.
|
16
|
+
|
17
|
+
def pkg_binary; 'pkg_add' end
|
18
|
+
def pkg_cmd; "#{pkg_binary} -r" end
|
19
|
+
def pkg_type; :tbz end
|
20
|
+
def manager_key; :binports end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def _install! pkgs, opts
|
25
|
+
log_shell "Installing #{pkgs.join(', ')}", "#{pkg_cmd} #{pkgs.join(' ')}", :sudo => should_sudo?
|
26
|
+
end
|
27
|
+
|
28
|
+
def _has? pkg
|
29
|
+
existing_packages.any? {|i| i.match(/#{pkg}/)}
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module Babushka
|
2
|
+
class BrewHelper < PkgHelper
|
3
|
+
class << self
|
4
|
+
def pkg_type; :brew end
|
5
|
+
def pkg_cmd; 'brew' end
|
6
|
+
def manager_key; :brew end
|
7
|
+
def manager_dep; 'homebrew' end
|
8
|
+
|
9
|
+
def _install! pkgs, opts
|
10
|
+
check_for_formulas(pkgs) && pkgs.all? {|pkg|
|
11
|
+
log "Installing #{pkg} via #{manager_key}" do
|
12
|
+
shell(
|
13
|
+
"#{pkg_cmd} install #{cmdline_spec_for pkg} #{opts}",
|
14
|
+
:sudo => should_sudo?,
|
15
|
+
:log => true,
|
16
|
+
:closing_status => :status_only
|
17
|
+
)
|
18
|
+
end
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_pkg_lists_if_required
|
23
|
+
super.tap {|result|
|
24
|
+
pkg_list_dir.touch if result
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def brew_path_for pkg_name
|
29
|
+
if active_version = active_version_of(pkg_name)
|
30
|
+
installed_pkgs_path / pkg_name / active_version
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def should_sudo?
|
35
|
+
super || !installed_pkgs_path.hypothetically_writable?
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
class LibraryDep
|
42
|
+
attr_reader :names
|
43
|
+
def initialize *names
|
44
|
+
@names = names
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def _has? pkg
|
49
|
+
versions_of(pkg).sort.reverse.detect {|version| pkg.matches? version }
|
50
|
+
end
|
51
|
+
|
52
|
+
def check_for_formulas pkgs
|
53
|
+
pkgs.all? {|pkg|
|
54
|
+
has_formula_for?(pkg).tap {|result|
|
55
|
+
log_error "There is no formula for '#{pkg}' in #{formulas_path}." unless result
|
56
|
+
}
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def has_formula_for? pkg
|
61
|
+
existing_formulas.include? pkg.name
|
62
|
+
end
|
63
|
+
|
64
|
+
def existing_formulas
|
65
|
+
Dir[formulas_path / '*.rb'].map {|i| File.basename i, '.rb' }
|
66
|
+
end
|
67
|
+
|
68
|
+
def active_version_of pkg_name
|
69
|
+
shell("brew info #{pkg_name}").split("\n\n", 2).first.split("\n").map {|i|
|
70
|
+
i.scan(/^#{Regexp.escape(installed_pkgs_path.to_s.end_with('/'))}([^\s]+)/)
|
71
|
+
}.flatten.select {|i|
|
72
|
+
i[/\d/] # For it to be a version, it has to have at least 1 digit.
|
73
|
+
}.map {|i|
|
74
|
+
VersionOf i.split('/', 2)
|
75
|
+
}.max.version
|
76
|
+
end
|
77
|
+
|
78
|
+
def versions_of pkg
|
79
|
+
pkg_name = pkg.respond_to?(:name) ? pkg.name : pkg
|
80
|
+
Dir[
|
81
|
+
installed_pkgs_path / pkg_name / '*'
|
82
|
+
].map {|i|
|
83
|
+
File.basename i.chomp('/')
|
84
|
+
}.reject {|i|
|
85
|
+
i[/\d|HEAD/].nil? # reject paths that aren't versions, like 'bin' etc
|
86
|
+
}.map(&:to_version)
|
87
|
+
end
|
88
|
+
|
89
|
+
def pkg_update_timeout
|
90
|
+
3600 # 1 hour
|
91
|
+
end
|
92
|
+
def pkg_list_dir
|
93
|
+
prefix
|
94
|
+
end
|
95
|
+
|
96
|
+
def installed_pkgs_path
|
97
|
+
prefix / 'Cellar'
|
98
|
+
end
|
99
|
+
def formulas_path
|
100
|
+
prefix / 'Library/Formula'
|
101
|
+
end
|
102
|
+
def formula_path_for pkg
|
103
|
+
formulas_path / pkg.to_s.end_with('.rb')
|
104
|
+
end
|
105
|
+
def homebrew_lib_path
|
106
|
+
prefix / 'Library/Homebrew'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|