Class: Loadable::VendorLoader

Inherits:
Object
  • Object
show all
Includes:
Loadable
Defined in:
lib/loadable/loaders/vendor_loader.rb

Overview

Add vendored projects to load path. For example:

Loadable.vendor(project_root_directoy, 'vendor')

Then any projects in the vendor directory will be accessible via require and load. This method looks for a .gemspec or .ruby file in the project to determine it’s proper load paths, baring either of these it falls back to using ‘lib/`.

Constant Summary

Constants included from Loadable

RB_EXTS

Instance Method Summary collapse

Methods included from Loadable

call, #default_file_extensions, each, #lookup, #name, #raise_load_error, register, search, #traverse, vendor

Constructor Details

#initialize(*directory) ⇒ VendorLoader

Returns a new instance of VendorLoader.

Raises:

  • (ArgumentError)


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/loadable/loaders/vendor_loader.rb', line 21

def initialize(*directory)
  raise ArgumentError if directory.empty?

  @_yaml_loaded ||= !(require 'yaml').nil?

  settings  = (Hash === directory.last ? directory.pop : {})
  directory = File.expand_path(File.join(*directory))

  @load_path = []

  if settings[:direct]
    @load_path.concat(Dir.glob(directory))
  else
    Dir.glob(directory).each do |dir|
      next unless File.directory?(dir)
      build_loadpath(dir)
    end
  end

  if @load_path.empty?
    # TODO: if load_path empty should we fallback to direct path ?
  end
end

Instance Method Details

#build_loadpath(dir) ⇒ Object (private)

Build up load_path given a directory to check. Looks for a ‘.ruby` or `.gemspec` file to get project’s local load paths, otherwise if looks for a ‘lib` directory.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/loadable/loaders/vendor_loader.rb', line 70

def build_loadpath(dir)
  if dotruby_file = Dir.glob(File.join(dir, '.ruby')).first
    @load_path.concat(loadpath_dotruby(dotruby_file, dir))

  elsif defined?(::Gem) && gemspec = Dir.glob(File.join(dir, '{*,}.gemspec')).first
    @load_path.concat(loadpath_gemspec(gemspec_file, dir))

  elsif path = Dir.glob(File.join(dir, 'lib')).first
    @load_path << path

  else
    # TODO: is this an error, just ignore, or add dir directly ?
  end

  return @load_path
end

#call(fname, options = {}) ⇒ Object

Load script from vendored locations.



47
48
49
50
51
52
53
# File 'lib/loadable/loaders/vendor_loader.rb', line 47

def call(fname, options={})
  @load_path.each do |path|
    file = lookup(path, fname, options)
    return super(file, options) if file
  end
  raise_load_error(fname)
end

#each(options = {}, &block) ⇒ Object

Iterate over each loadable file in vendored locations.



57
58
59
60
61
62
# File 'lib/loadable/loaders/vendor_loader.rb', line 57

def each(options={}, &block)
  @load_path.uniq.each do |path|
    path = File.expand_path(path)
    traverse(path, &block)
  end
end

#loadpath_dotruby(dotruby_file, dir) ⇒ Object (private)

Build the load_path given a ‘.ruby` file.



89
90
91
92
93
94
95
# File 'lib/loadable/loaders/vendor_loader.rb', line 89

def loadpath_dotruby(dotruby_file, dir)
  data = YAML.load(dotruby_file)
  path = data['load_path'] || ['lib']
  path.map do |lp|
    File.join(dir, lp)
  end
end

#loadpath_gemspec(gemspec_file, dir) ⇒ Object (private)

Build the load_path given a ‘.gemspec` file.



99
100
101
102
103
104
105
# File 'lib/loadable/loaders/vendor_loader.rb', line 99

def loadpath_gemspec(gemspec_file, dir)
  # TODO: handle YAML gemspecs
  spec = Gem::Specification.load(gemspec_file)
  spec.require_paths.map do |rp|
    File.join(dir, rp)
  end
end