117 lines
No EOL
3.5 KiB
Ruby
117 lines
No EOL
3.5 KiB
Ruby
module Middleman
|
|
|
|
module Extensions
|
|
|
|
class << self
|
|
def registered
|
|
@_registered ||= {}
|
|
end
|
|
|
|
# Register a new extension. Choose a name which will be
|
|
# used to activate the extension in config.rb, like this:
|
|
#
|
|
# activate :my_extension
|
|
#
|
|
# Provide your extension module either as the namespace
|
|
# parameter, or return it from the block:
|
|
#
|
|
# @param [Symbol] name The name of the extension
|
|
# @param [Module] namespace The extension module
|
|
# @param [String] version A RubyGems-style version string stating
|
|
# the versions of middleman this extension
|
|
# is compatible with.
|
|
# @yield Instead of passing a module in namespace, you can provide
|
|
# a block which returns your extension module. This gives
|
|
# you the ability to require other files only when the
|
|
# extension is activated.
|
|
def register(name, namespace=nil, version=nil, &block)
|
|
# If we've already got a matching extension that passed the
|
|
# version check, bail out.
|
|
return if registered.has_key?(name.to_sym) &&
|
|
!registered[name.to_sym].is_a?(String)
|
|
|
|
if block_given?
|
|
version = namespace
|
|
end
|
|
|
|
passed_version_check = true
|
|
if !version.nil?
|
|
requirement = ::Gem::Requirement.create(version)
|
|
if !requirement.satisfied_by?(Middleman::GEM_VERSION)
|
|
passed_version_check = false
|
|
end
|
|
end
|
|
|
|
registered[name.to_sym] = if !passed_version_check
|
|
"== #{name} failed version check. Requested #{version}, got #{Middleman::VERSION}"
|
|
elsif block_given?
|
|
block
|
|
elsif namespace
|
|
namespace
|
|
end
|
|
end
|
|
|
|
def load(name)
|
|
name = name.to_sym
|
|
return nil unless registered.has_key?(name)
|
|
|
|
extension = registered[name]
|
|
if extension.is_a?(Proc)
|
|
extension = extension.call() || nil
|
|
registered[name] = extension
|
|
end
|
|
|
|
extension
|
|
end
|
|
end
|
|
end
|
|
|
|
# Where to look in gems for extensions to auto-register
|
|
EXTENSION_FILE = File.join("lib", "middleman_extension.rb") unless const_defined?(:EXTENSION_FILE)
|
|
|
|
class << self
|
|
# Automatically load extensions from available RubyGems
|
|
# which contain the EXTENSION_FILE
|
|
#
|
|
# @private
|
|
def load_extensions_in_path
|
|
if defined?(Bundler)
|
|
Bundler.require
|
|
else
|
|
extensions = rubygems_latest_specs.select do |spec|
|
|
spec_has_file?(spec, EXTENSION_FILE)
|
|
end
|
|
|
|
extensions.each do |spec|
|
|
require spec.name
|
|
end
|
|
end
|
|
end
|
|
|
|
# Backwards compatible means of finding all the latest gemspecs
|
|
# available on the system
|
|
#
|
|
# @private
|
|
# @return [Array] Array of latest Gem::Specification
|
|
def rubygems_latest_specs
|
|
# If newer Rubygems
|
|
if ::Gem::Specification.respond_to? :latest_specs
|
|
::Gem::Specification.latest_specs
|
|
else
|
|
::Gem.source_index.latest_specs
|
|
end
|
|
end
|
|
|
|
# Where a given Gem::Specification has a specific file. Used
|
|
# to discover extensions and Sprockets-supporting gems.
|
|
#
|
|
# @private
|
|
# @param [Gem::Specification] spec
|
|
# @param [String] path Path to look for
|
|
# @return [Boolean] Whether the file exists
|
|
def spec_has_file?(spec, path)
|
|
full_path = File.join(spec.full_gem_path, path)
|
|
File.exists?(full_path)
|
|
end
|
|
end
|
|
end |