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

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.



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/sunshine/package_managers/dependency.rb', line 75

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.



73
74
75
# File 'lib/sunshine/package_managers/dependency.rb', line 73

def children
  @children
end

#nameObject (readonly)

Returns the value of attribute name.



73
74
75
# File 'lib/sunshine/package_managers/dependency.rb', line 73

def name
  @name
end

#parentsObject (readonly)

Returns the value of attribute parents.



73
74
75
# File 'lib/sunshine/package_managers/dependency.rb', line 73

def parents
  @parents
end

#pkgObject (readonly)

Returns the value of attribute pkg.



73
74
75
# File 'lib/sunshine/package_managers/dependency.rb', line 73

def pkg
  @pkg
end

Class Method Details

.sudoObject

Check if sudo should be used



49
50
51
# File 'lib/sunshine/package_managers/dependency.rb', line 49

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.



59
60
61
# File 'lib/sunshine/package_managers/dependency.rb', line 59

def self.sudo= value
  @sudo = value
end

.system_manager?(shell = nil) ⇒ Boolean

Checks if dependency type is valid for a given shell. Defaults to false. Override in subclass.

Returns:

  • (Boolean)


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

def self.system_manager? shell=nil
  false
end

Instance Method Details

#add_child(name) ⇒ Object

Append a child dependency



100
101
102
# File 'lib/sunshine/package_managers/dependency.rb', line 100

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'"


119
120
121
# File 'lib/sunshine/package_managers/dependency.rb', line 119

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"


129
130
131
# File 'lib/sunshine/package_managers/dependency.rb', line 129

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

#child_dependenciesObject

Get direct child dependencies



108
109
110
# File 'lib/sunshine/package_managers/dependency.rb', line 108

def child_dependencies
  @children
end

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

Define the install command for the dependency:

dep.install "yum install depname"


139
140
141
# File 'lib/sunshine/package_managers/dependency.rb', line 139

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:



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/sunshine/package_managers/dependency.rb', line 153

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


180
181
182
183
184
185
186
# File 'lib/sunshine/package_managers/dependency.rb', line 180

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)


197
198
199
200
201
# File 'lib/sunshine/package_managers/dependency.rb', line 197

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

#missing_parents?(options = {}) ⇒ Boolean

Returns:

  • (Boolean)


213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/sunshine/package_managers/dependency.rb', line 213

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



232
233
234
# File 'lib/sunshine/package_managers/dependency.rb', line 232

def parent_dependencies
  @parents
end

#requires(*deps) ⇒ Object

Define which dependencies this dependency relies on:

dep.requires 'rubygems', 'rdoc'


242
243
244
245
246
247
248
249
# File 'lib/sunshine/package_managers/dependency.rb', line 242

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



305
306
307
# File 'lib/sunshine/package_managers/dependency.rb', line 305

def to_s
  @name
end

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

Define the uninstall command for the dependency:

dep.uninstall "yum remove depname"


257
258
259
# File 'lib/sunshine/package_managers/dependency.rb', line 257

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:



270
271
272
273
274
275
276
277
# File 'lib/sunshine/package_managers/dependency.rb', line 270

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



288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/sunshine/package_managers/dependency.rb', line 288

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