Class: Sunshine::DependencyLib

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

Overview

DependencyLib is a simple class for building and handling depenedencies. A dependency tree can be defined by inheriting the DependencyLib class, and dependencies can be defined through dependency instantiation methods:

dependency_lib.instance_eval do

  yum 'ruby', :pkg => 'ruby-devel'

  yum 'rubygems', :requires => 'ruby'

  gem 'rdoc', :requires => 'rubygems'

  gem 'ri', :requires => 'rubygems'

end

Calling the install for rdoc will then check and install all of its parent dependencies as well:

dependency_lib.install 'rdoc', 'ri'

Dependencies may also be generic and/or have custom bash scripts for installs, uninstalls, and presence checks:

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

See the Dependency class for more information.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDependencyLib

Returns a new instance of DependencyLib.



78
79
80
# File 'lib/sunshine/dependency_lib.rb', line 78

def initialize
  @dependencies = Hash.new
end

Instance Attribute Details

#dependenciesObject (readonly)

Returns the value of attribute dependencies.



76
77
78
# File 'lib/sunshine/dependency_lib.rb', line 76

def dependencies
  @dependencies
end

Class Method Details

.dependency_typesObject

Array of all dependency classes. Appended to automatically when DependencyLib::Dependency is inherited.



43
44
45
# File 'lib/sunshine/dependency_lib.rb', line 43

def self.dependency_types
  @dependency_types ||= []
end

.register_type(dep_class) ⇒ Object

Registers a new dependency class, creates its constructor method (DependencyLib#).



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/sunshine/dependency_lib.rb', line 52

def self.register_type dep_class
  class_eval <<-STR, __FILE__, __LINE__ + 1

    def #{dep_class.short_name}(name, options={}, &block)
      dep = #{dep_class}.new(name, options.merge(:tree => self), &block)
      self.add dep
      dep
    end
  STR

  dependency_types << dep_class
end

.sudo=(value) ⇒ Object

Define if sudo should be used



69
70
71
72
73
# File 'lib/sunshine/dependency_lib.rb', line 69

def self.sudo= value
  dependency_types.each do |dep_class|
    dep_class.sudo = value
  end
end

Instance Method Details

#[](key) ⇒ Object

Returns a dependency hash by type:

DependencyLib['name'] #=> {:yum => <Yum...>, :apt => <Apt...>, ...}


87
88
89
# File 'lib/sunshine/dependency_lib.rb', line 87

def [](key)
  @dependencies[key]
end

#add(dep) ⇒ Object

Add a dependency to the dependencies hash.



95
96
97
# File 'lib/sunshine/dependency_lib.rb', line 95

def add dep
  (@dependencies[dep.name] ||= []).unshift dep
end

#exist?(key) ⇒ Boolean

Checks for the existance of a dependency by name

Returns:

  • (Boolean)


103
104
105
# File 'lib/sunshine/dependency_lib.rb', line 103

def exist? key
  @dependencies.has_key? key
end

#get(name, options = {}) ⇒ Object

Get a dependency object by name. Supports passing :type => :pkg_manager if dependencies with the same name but different package managers exist:

dependencies.get 'daemon', :type => Gem
#=> <Gem @name="daemon"...>

For an ‘nginx’ dependency defined for both apt and yum, where the yum dependency object was added to the tree last. Returns nil if no matching dependency type is found:

dependencies.get 'nginx'
#=> <Yum @name="nginx"...>

dependencies.get 'nginx', :type => Apt
#=> <Apt @name="nginx"...>

Use the :prefer option if a certain dependency type is prefered but will fall back to whatever first dependency is available:

dependencies.yum 'my_dep'
dependencies.get 'my_dep', :prefer => Apt
#=> <Yum @name="my_dep"...>

Both the :type and the :prefer options support passing arrays to search from best to least acceptable candidate:

dependencies.yum 'my_dep'
dependencies.apt 'my_dep'
dependencies.get 'my_dep', :type => [Tpkg, Yum]
#=> <Yum @name="my_dep"...>


136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/sunshine/dependency_lib.rb', line 136

def get name, options={}
  return unless exist? name

  deps      = @dependencies[name]
  dep_types = [*(options[:type] || options[:prefer])].compact

  return deps.first if dep_types.empty?

  dep_types.each do |dep_type|
    deps.each do |dep|
      return dep if dep_type === dep
    end
  end

  return deps.first unless options[:type]
end

#install(*deps) ⇒ Object

Install one or more dependencies:

dependencies.install 'dep1', 'dep2', options_hash

See DependencyLib#get and Dependency#install! for supported options.

Note: If a Dependency object is passed and the :type option is set, DependencyLib will attempt to find and install a dependency of class :type with the same name as the passed Dependency object:

my_dep = dependencies.yum "my_dep_yum_only"
dependencies.install my_dep, :type => Apt
#=> "No dependency 'my_dep' [Sunshine::Apt]"


168
169
170
# File 'lib/sunshine/dependency_lib.rb', line 168

def install(*deps)
  send_each(:install!, *deps)
end

#send_each(method, *deps) ⇒ Object

Get and call method on each dependency passed



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/sunshine/dependency_lib.rb', line 188

def send_each(method, *deps)
  options = Hash === deps.last ? deps.delete_at(-1).dup : {}

  #if options[:call].respond_to? :pkg_manager
  #  options[:prefer] ||= options[:call].pkg_manager
  #end

  deps.each do |dep_name|
    dep = if Dependency === dep_name
            if options[:type] && !(options[:type] === dep_name)
              get(dep_name.name, options)
            else
              dep_name
            end
          else
            get(dep_name, options)
          end

    raise MissingDependency,
      "No dependency '#{dep_name}' [#{options[:type] || "any"}]" if !dep

    # Remove :type so dependencies of other types than dep can be installed
    options.delete(:type)

    dep.send method, options
  end
end

#uninstall(*deps) ⇒ Object

Uninstall one or more dependencies:

dependencies.uninstall 'dep1', 'dep2', options_hash

See DependencyLib#get and Dependency#uninstall! for supported options.



180
181
182
# File 'lib/sunshine/dependency_lib.rb', line 180

def uninstall(*deps)
  send_each(:uninstall!, *deps)
end