Class: Sunshine::Dependency

Inherits:
Object
  • Object
show all
Defined in:
lib/sunshine/package_managers/dependency.rb

Overview

Dependency objects let you define how to install, check, and remove a described package, including parent dependency lookup and installation.

Dependency.new "ruby", :tree => dependency_lib do
  install    "sudo yum install ruby"
  uninstall  "sudo yum remove ruby"
  check_test "yum list installed ruby | grep -c ruby", "-ge 1"
end

Dependencies are more commonly defined through a Settler class’ constructor methods:

dependency_lib.instance_eval do
  dependency 'custom' do
    requires  'yum', 'ruby'
    install   'sudo yum install custom'
    uninstall 'sudo yum remove custom'
    check     'yum list installed custom'
  end
end

The Dependency class is simple to inherit and use as a built-in part of Settler (see the Yum implementation for more info):

class Yum < Dependency
  def initialize(name, options={}, &block)
    super(dep_lib, name, options) do
      # Define install, check, and uninstall scripts specific to yum
    end
  end
  ...
end

Once a subclass is defined a constructor method is added automatically to the Settler class:

dependency_lib.instance_eval do
  yum "ruby", :version => '1.9'
end

Direct Known Subclasses

Apt, Gem, Yum

Defined Under Namespace

Classes: CmdError, InstallError, UninstallError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, options = {}, &block) ⇒ Dependency

Returns a new instance of Dependency.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/sunshine/package_managers/dependency.rb', line 71

def initialize name, options={}, &block
  @dependency_lib = options[:tree]

  @name    = name.to_s
  @pkg     = options[:pkg] || @name
  @options = options.dup

  @install   = nil
  @uninstall = nil
  @check     = nil

  @parents  = []
  @children = []

  @shell = Sunshine.shell

  requires(*options[:requires]) if options[:requires]

  instance_eval(&block) if block_given?
end

Instance Attribute Details

#childrenObject (readonly)

Returns the value of attribute children.



69
70
71
# File 'lib/sunshine/package_managers/dependency.rb', line 69

def children
  @children
end

#nameObject (readonly)

Returns the value of attribute name.



69
70
71
# File 'lib/sunshine/package_managers/dependency.rb', line 69

def name
  @name
end

#parentsObject (readonly)

Returns the value of attribute parents.



69
70
71
# File 'lib/sunshine/package_managers/dependency.rb', line 69

def parents
  @parents
end

#pkgObject (readonly)

Returns the value of attribute pkg.



69
70
71
# File 'lib/sunshine/package_managers/dependency.rb', line 69

def pkg
  @pkg
end

Class Method Details

.sudoObject

Check if sudo should be used



54
55
56
# File 'lib/sunshine/package_managers/dependency.rb', line 54

def self.sudo
  @sudo ||= nil
end

.sudo=(value) ⇒ Object

Assign a sudo value. A value of nil means ‘don’t assign sudo’, true means sudo, string means sudo -u, false means, explicitely don’t use sudo. Yum and Gem dependency types default to sudo=true.



64
65
66
# File 'lib/sunshine/package_managers/dependency.rb', line 64

def self.sudo= value
  @sudo = value
end

Instance Method Details

#add_child(name) ⇒ Object

Append a child dependency



96
97
98
# File 'lib/sunshine/package_managers/dependency.rb', line 96

def add_child name
  @children << name
end

#check(cmd_str = nil, &block) ⇒ Object

Define the command that checks if the dependency is installed. The check command must have an appropriate exitcode:

dep.check "test -s 'yum list installed depname'"


115
116
117
# File 'lib/sunshine/package_managers/dependency.rb', line 115

def check cmd_str=nil, &block
  @check = cmd_str || block
end

#check_test(cmd_str, condition_str) ⇒ Object

Define checking that the dependency is installed via unix’s ‘test’:

dep.check_test "yum list installed depname | grep -c depname", "-ge 1"


125
126
127
# File 'lib/sunshine/package_managers/dependency.rb', line 125

def check_test cmd_str, condition_str
  check "test \"$(#{cmd_str})\" #{condition_str}"
end

#child_dependenciesObject

Get direct child dependencies



104
105
106
# File 'lib/sunshine/package_managers/dependency.rb', line 104

def child_dependencies
  @children
end

#install(cmd = nil, &block) ⇒ Object

Define the install command for the dependency:

dep.install "yum install depname"


135
136
137
# File 'lib/sunshine/package_managers/dependency.rb', line 135

def install cmd=nil, &block
  @install = cmd || block
end

#install!(options = {}) ⇒ Object

Run the install command for the dependency Allows options:

:call

obj - an object that responds to call will be passed the bash cmd

:skip_parents

true - install regardless of missing parent dependencies

runner = lambda{|str| system(str)}
dep.install! :call => runner

Raises:



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/sunshine/package_managers/dependency.rb', line 149

def install! options={}
  return if installed?(options)

  if options[:skip_parents]
    missing = missing_parents?
    if missing
      raise(InstallError, "Could not install #{@name}. "+
        "Missing dependencies #{missing.join(", ")}")
    end
  else
    install_parents!(options)
  end

  run_command(@install, options)
  raise(InstallError, "Failed installing #{@name}") unless
    installed?(options)
end

#install_parents!(options = {}) ⇒ Object

Call install on direct parent dependencies Allows options:

:call

obj - an object that responds to call will be passed the bash cmd

runner = lambda{|str| system(str)}
dep.install_parents! :call => runner


176
177
178
179
180
181
182
# File 'lib/sunshine/package_managers/dependency.rb', line 176

def install_parents! options={}
  return unless @dependency_lib

  @parents.each do |dep|
    @dependency_lib.get(dep, options).install!(options)
  end
end

#installed?(options = {}) ⇒ Boolean

Run the check command to verify that the dependency is installed Allows options:

:call

obj - an object that responds to call will be passed the bash cmd

runner = lambda{|str| system(str)}
dep.installed? :call => runner

Returns:

  • (Boolean)


193
194
195
196
197
# File 'lib/sunshine/package_managers/dependency.rb', line 193

def installed? options={}
  run_command @check, options
rescue => e
  false
end

#missing_parents?(options = {}) ⇒ Boolean

Returns:

  • (Boolean)


209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/sunshine/package_managers/dependency.rb', line 209

def missing_parents? options={}
  return unless @dependency_lib

  missing = []
  @parents.each do |dep|
    parent_dep = @dependency_lib.get dep, options

    missing << dep unless parent_dep.installed?(options)

    return missing if options[:limit] && options[:limit] == missing.length
  end

  missing.empty? ? nil : missing
end

#parent_dependenciesObject

Get direct parent dependencies



228
229
230
# File 'lib/sunshine/package_managers/dependency.rb', line 228

def parent_dependencies
  @parents
end

#requires(*deps) ⇒ Object

Define which dependencies this dependency relies on:

dep.requires 'rubygems', 'rdoc'


238
239
240
241
242
243
244
245
# File 'lib/sunshine/package_managers/dependency.rb', line 238

def requires *deps
  return unless @dependency_lib

  @parents.concat(deps).uniq!
  deps.each do |dep|
    @dependency_lib.dependencies[dep].each{|d| d.add_child(@name) }
  end
end

#to_sObject

Alias for name



301
302
303
# File 'lib/sunshine/package_managers/dependency.rb', line 301

def to_s
  @name
end

#uninstall(cmd = nil, &block) ⇒ Object

Define the uninstall command for the dependency:

dep.uninstall "yum remove depname"


253
254
255
# File 'lib/sunshine/package_managers/dependency.rb', line 253

def uninstall cmd=nil, &block
  @uninstall = cmd || block
end

#uninstall!(options = {}) ⇒ Object

Run the uninstall command for the dependency Allows options:

:call

obj - an object that responds to call will be passed the bash cmd

:force

true - uninstalls regardless of child dependencies

:remove_children

true - removes direct child dependencies

:remove_children

:recursive - removes children recursively

Raises:



266
267
268
269
270
271
272
273
# File 'lib/sunshine/package_managers/dependency.rb', line 266

def uninstall! options={}
  if !options[:remove_children] && !options[:force]
    raise UninstallError, "The #{@name} has child dependencies."
  end
  uninstall_children!(options) if options[:remove_children]
  run_command(@uninstall, options)
  raise(UninstallError, "Failed removing #{@name}") if installed?(options)
end

#uninstall_children!(options = {}) ⇒ Object

Removes child dependencies Allows options:

:call

obj - an object that responds to call will be passed the bash cmd

:force

true - uninstalls regardless of child dependencies

:remove_children

true - removes direct child dependencies

:remove_children

:recursive - removes children recursively



284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/sunshine/package_managers/dependency.rb', line 284

def uninstall_children! options={}
  return unless @dependency_lib

  options = options.dup

  @children.each do |dep|
    options.delete(:remove_children) unless
      options[:remove_children] == :recursive

    @dependency_lib.get(dep, options).uninstall!(options)
  end
end