Class: Jsus::Pool

Inherits:
Object
  • Object
show all
Defined in:
lib/jsus/pool.rb

Overview

Pool class is designed for three purposes:

  • Maintain connections between SourceFiles and/or Packages
  • Resolve dependencies
  • Look up extensions

Instance Method Summary collapse

Constructor Details

#initialize(dir_or_dirs = nil) ⇒ Pool

Basic constructor.

Parameters:

  • dir_or_dirs (Array, String, nil) (defaults to: nil)

    directory or list of directories to load source packages from.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/jsus/pool.rb', line 18

def initialize(dir_or_dirs = nil)
  if dir_or_dirs
    directories = Array(dir_or_dirs)
    directories.each do |dir|
      # '**{,/*/**}' thingie is to resolve problem with not following symlinks
      # one level of symlinks
      # See also: http://stackoverflow.com/questions/357754/can-i-traverse-symlinked-directories-in-ruby-with-a-glob
      Dir[File.join(dir, '**{,/*/**}', 'package.{yml,json}')].uniq.each do |package_path|
        Package.new(File.dirname(package_path), :pool => self)
      end
    end
  end
  flush_cache!
end

Instance Method Details

#<<(source_or_sources_or_package) ⇒ self

Pushes an item into a pool.

Parameters:

Returns:

  • (self)


105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/jsus/pool.rb', line 105

def <<(source_or_sources_or_package)
  case
  when source_or_sources_or_package.kind_of?(SourceFile)
    source = source_or_sources_or_package
    add_source_to_trees(source)
    sources << source
    if source.extends
      extensions_map[source.extends] ||= []
      extensions_map[source.extends] << source
    else
      source.provides.each do |p|
        if provides_map[p] && provides_map[p] != source && provides_map[p].filename != source.filename
          Jsus.logger.warn "Redeclared #{p.to_s} in #{source.filename} (previously declared in #{provides_map[p].filename})"
        end
        provides_map[p] = source
      end

      replacement_map[source.replaces] = source if source.replaces if source.replaces
    end
  when source_or_sources_or_package.kind_of?(Package)
    package = source_or_sources_or_package
    packages << package
    package.source_files.each {|s| s.pool = self }
    package.extensions.each {|e| e.pool = self }
  when source_or_sources_or_package.kind_of?(Array) || source_or_sources_or_package.kind_of?(Container)
    sources = source_or_sources_or_package
    sources.each {|s| self << s}
  end
  self
end

#add_source_to_trees(source) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Registers the source in both trees

Parameters:



193
194
195
196
197
198
199
200
201
202
# File 'lib/jsus/pool.rb', line 193

def add_source_to_trees(source)
  if source.package
    source_tree.insert("/" + source.package.name + "/" + File.basename(source.filename), source)
  else
    source_tree.insert("/" + File.basename(source.filename), source)
  end
  source.provides.each do |tag|
    provides_tree.insert("/" + tag.to_s, tag)
  end
end

#flush_cache!Object

Drops any cached info



139
140
141
# File 'lib/jsus/pool.rb', line 139

def flush_cache!
  @cached_dependencies = {}
end

#lookup(source_or_key) ⇒ Jsus::SourceFile

Looks up for a file replacing or providing given tag or tag key. Replacement file gets priority.

If given a source file, returns the input.

Parameters:

Returns:



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/jsus/pool.rb', line 55

def lookup(source_or_key)
  case source_or_key
    when String
      lookup(Tag[source_or_key])
    when Tag
      replacement_map[source_or_key] || provides_map[source_or_key]
    when SourceFile
      source_or_key
    else
      raise "Illegal lookup query. Expected String, Tag or SourceFile, " <<
            "given #{source_or_key.inspect}, an instance of #{source_or_key.class.name}."
  end
end

#lookup_dependencies(source_or_source_key) ⇒ Jsus::Container

Looks up for dependencies for given file recursively.

Parameters:

Returns:



76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/jsus/pool.rb', line 76

def lookup_dependencies(source_or_source_key)
  source = lookup(source_or_source_key)
  result = Container.new
  looked_up = []
  if source
    dependencies = lookup_direct_dependencies(source)
    while !((dependencies - looked_up).empty?)
      dependencies.each { |d| result << d; looked_up << d }
      dependencies = dependencies.map {|d| lookup_direct_dependencies(d).to_a }.flatten.uniq
    end
  end
  result.sort!
end

#lookup_direct_dependencies(source_or_source_key) ⇒ Array

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Looks up direct dependencies for the given source_file or provides tag. You probably will find yourself using #include_dependencies instead. This method caches results locally, use flush_cache! to drop.

Parameters:

Returns:

  • (Array)

    array of direct dependencies for given entity



154
155
156
157
# File 'lib/jsus/pool.rb', line 154

def lookup_direct_dependencies(source_or_source_key)
  source = lookup(source_or_source_key)
  @cached_dependencies[source] ||= lookup_direct_dependencies!(source)
end

#lookup_direct_dependencies!(source) ⇒ Array

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Performs the actual lookup for #lookup_direct_dependencies

Parameters:

Returns:

  • (Array)

    array of direct dependencies for given entity



165
166
167
168
169
170
171
172
173
174
175
# File 'lib/jsus/pool.rb', line 165

def lookup_direct_dependencies!(source)
  return [] unless source

  source.dependencies.map do |dependency|
    result = provides_tree.glob("/#{dependency}")
    if (!result || (result.is_a?(Array) && result.empty?))
      Jsus.logger.warn "#{source.filename} is missing #{dependency.is_a?(SourceFile) ? dependency.filename : dependency.to_s}"
    end
    result
  end.flatten.map {|tag| lookup(tag) }
end

#lookup_extensions(tag_or_tag_key) ⇒ Array

Returns array with source files with extensions for given tag.

Parameters:

Returns:

  • (Array)

    array with source files with extensions for given tag.



93
94
95
96
# File 'lib/jsus/pool.rb', line 93

def lookup_extensions(tag_or_tag_key)
  tag = Tag[tag_or_tag_key]
  extensions_map[tag]
end

#packagesArray

Returns array containing all the packages in the pool. Unordered.

Returns:

  • (Array)

    array containing all the packages in the pool. Unordered.



36
37
38
# File 'lib/jsus/pool.rb', line 36

def packages
  @packages ||= []
end

#provides_treeJsus::Util::Tree

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns tree containing all the provides tags.

Returns:



185
186
187
# File 'lib/jsus/pool.rb', line 185

def provides_tree
  @provides_tree ||= Util::Tree.new
end

#source_treeJsus::Util::Tree

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns tree containing all the sources.

Returns:



179
180
181
# File 'lib/jsus/pool.rb', line 179

def source_tree
  @source_tree ||= Util::Tree.new
end

#sourcesArray

Returns array with all the sources in the pool. Unordered.

Returns:

  • (Array)

    array with all the sources in the pool. Unordered



42
43
44
# File 'lib/jsus/pool.rb', line 42

def sources
  @sources ||= []
end