Class: Juicer::Install::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/juicer/install/base.rb

Overview

Installer skeleton. Provides basic functionality like figuring out where to install, create base directories, remove unneeded directories and more housekeeping.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(install_dir = Juicer.home) ⇒ Base

Create new installer



19
20
21
22
23
24
25
# File 'lib/juicer/install/base.rb', line 19

def initialize(install_dir = Juicer.home)
  @install_dir = install_dir
  @path = nil
  @bin_path = nil
  @name = nil
  @dependencies = {}
end

Instance Attribute Details

#install_dirObject (readonly)

Returns the value of attribute install_dir.



14
15
16
# File 'lib/juicer/install/base.rb', line 14

def install_dir
  @install_dir
end

Instance Method Details

#bin_pathObject

Returns the path to search for binaries from



44
45
46
47
# File 'lib/juicer/install/base.rb', line 44

def bin_path
  return @bin_path if @bin_path
  @bin_path = File.join(path, "bin")
end

#dependencies(&block) ⇒ Object

Yields depencies one at a time: class and version and returns an array of arrays: [dependency, version] where dependency is an instance and version a string.



166
167
168
169
170
171
172
173
# File 'lib/juicer/install/base.rb', line 166

def dependencies(&block)
  @dependencies.collect do |name, dependency|
    version = dependency[1]
    dependency = dependency[0].new(@install_dir)
    block.call(dependency, version) if block
    [dependency, version]
  end
end

#dependency(dependency, version = nil) ⇒ Object

Add a dependency. Dependency should be a Juicer::Install::Base installer class (not instance) OR a symbol/string like :rhino/“rhino” (which will be expanded unto Juicer::Install::RhinoInstaller). Version is optional and defaults to latest and greatest.



155
156
157
158
159
# File 'lib/juicer/install/base.rb', line 155

def dependency(dependency, version = nil)
  dependency = Juicer::Install.get(dependency) if [String, Symbol].include?(dependency.class)

  @dependencies[dependency.to_s + (version || "")] = [dependency, version]
end

#download(url, force = false) ⇒ Object

Download a file to Juicer temporary directory. The file will be kept until #purge is called to wipe it. If the installer receives a request to download the same file again, the disk cache will be used unless the force argument is true (default false)



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/juicer/install/base.rb', line 126

def download(url, force = false)
  filename = File.join(@install_dir, "download", path.sub("lib/", ""), File.basename(url).split("?").first)
  return filename if File.exists?(filename) && !force
  FileUtils.mkdir_p(File.dirname(filename))
  File.delete(filename) if File.exists?(filename) && force

  log "Downloading #{url}"
  File.open(filename, "wb") do |file|
    webpage = open(url)
    file.write(webpage.read)
    webpage.close
  end

  filename
end

#install(version = nil) ⇒ Object

Install the component. Creates basic directory structure.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/juicer/install/base.rb', line 72

def install(version = nil)
  raise "#{name} #{version} is already installed in #{File.join(@install_dir, path)}" if installed?(version)
  version ||= latest
  log "Installing #{name} #{version} in #{File.join(@install_dir, path)}"

  if @dependencies.length > 0
    log "Installing dependencies"
    dependencies { |dependency, ver| dependency.install(ver) unless dependency.installed?(ver) }
  end

  # Create directories
  FileUtils.mkdir_p(File.join(@install_dir, path, "bin"))
  FileUtils.mkdir_p(File.join(@install_dir, path, version))

  # Return resolved version for subclass to use
  version
end

#installed?(version = nil) ⇒ Boolean

Checks if the component is currently installed.

If no version is provided the most recent version is assumed.

Returns:

  • (Boolean)


63
64
65
66
67
# File 'lib/juicer/install/base.rb', line 63

def installed?(version = nil)
  installed = File.exists?(File.join(@install_dir, path, "#{version || latest}"))
  deps = @dependencies.length == 0 || dependencies.all? { |d, v| d.installed?(v) }
  installed && deps
end

#latestObject

Returns the latest available version number. Must be implemented in subclasses. Raises an exception when called directly.

Raises:

  • (NotImplementedError)


31
32
33
# File 'lib/juicer/install/base.rb', line 31

def latest
  raise NotImplementedError.new("Implement in subclasses")
end

#log(str) ⇒ Object

Display a message to the user through Juicer::LOGGER



145
146
147
# File 'lib/juicer/install/base.rb', line 145

def log(str)
  Juicer::LOGGER.info str
end

#nameObject

Returns name of component. Default implementation returns class name with “Installer” removed



53
54
55
56
# File 'lib/juicer/install/base.rb', line 53

def name
  return @name if @name
  @name = File.basename(path).split("_").inject("") { |str, word| (str + " #{word.capitalize}").strip }
end

#pathObject

Returns the path relative to installation path this installer will install to



37
38
39
40
# File 'lib/juicer/install/base.rb', line 37

def path
  return @path if @path
  @path = "lib/" + self.class.to_s.split("::").pop.sub(/Installer$/, "").underscore
end

#uninstall(version = nil) {|File.join(@install_dir, path), version| ... } ⇒ Object

Uninstalls the given version of the component.

If no version is provided the most recent version is assumed.

If there are no more files left in INSTALLATION_PATH/<path>, the whole directory is removed.

This method takes a block and can be used from subclasses like so:

def self.uninstall(install_dir = nil, version = nil)
  super do |home_dir, version|
    # Custom uninstall logic
  end
end

Yields:



107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/juicer/install/base.rb', line 107

def uninstall(version = nil)
  version ||= self.latest
  install_dir = File.join(@install_dir, path, version)
  raise "#{name} #{version} is not installed" if !File.exists?(install_dir)

  FileUtils.rm_rf(install_dir)

  yield(File.join(@install_dir, path), version) if block_given?

  files = Dir.glob(File.join(@install_dir, path, "**", "*")).find_all { |f| File.file?(f) }
  FileUtils.rm_rf(File.join(@install_dir, path)) if files.length == 0
end