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.



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|
        self << Package.new(File.dirname(package_path))
      end
    end
  end
  flush_cache!
end

Instance Method Details

#<<(source_or_sources_or_package) ⇒ self

Pushes an item into a pool.



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/jsus/pool.rb', line 114

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
    end
  when source_or_sources_or_package.kind_of?(Package)
    package = source_or_sources_or_package
    packages << package
    package.source_files.each {|s| self << s }
    package.extensions.each   {|e| self << e }
  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



221
222
223
224
225
226
227
228
229
230
# File 'lib/jsus/pool.rb', line 221

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

#compile_package(package) ⇒ Array



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/jsus/pool.rb', line 148

def compile_package(package)
  result = []
  package.source_files.each do |source|
    result << source
    result << lookup_dependencies(source) unless source.extension? || source.replacement?
  end
  result = result.flatten.compact
  extra_files = []
  result.each_with_index do |source, i|
    extra_files << lookup_replacement(source)
    extra_files << lookup_extensions(source)
  end
  result = (result + extra_files).flatten.compact
  Container.new(result)
end

#flush_cache!Object

Drops any cached info



167
168
169
# File 'lib/jsus/pool.rb', line 167

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.



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

def lookup(source_or_key)
  case source_or_key
  when nil
    nil
  when String
    lookup(Tag[source_or_key])
  when Tag
    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.



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

def lookup_dependencies(source_or_source_key)
  source = lookup(source_or_source_key)
  result = []
  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
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.



182
183
184
185
# File 'lib/jsus/pool.rb', line 182

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



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

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(source) ⇒ Array

Returns array with source files with extensions for given source file.



103
104
105
# File 'lib/jsus/pool.rb', line 103

def lookup_extensions(source)
  source.provides.map {|tag| extensions_map[tag] }.flatten.compact
end

#lookup_replacement(source) ⇒ Jsus::SourceFile?

Returns replacement for given source file.



96
97
98
# File 'lib/jsus/pool.rb', line 96

def lookup_replacement(source)
  source.provides.map {|tag| replacement_map[tag] }.compact[0]
end

#packagesArray

Returns 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.



213
214
215
# File 'lib/jsus/pool.rb', line 213

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.



207
208
209
# File 'lib/jsus/pool.rb', line 207

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

#sourcesArray

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



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

def sources
  @sources ||= []
end