Some immutability tweaks

This commit is contained in:
Thomas Reynolds 2015-05-03 17:11:49 -07:00
parent e64954fbff
commit 69e66b04df
6 changed files with 42 additions and 41 deletions

View file

@ -1,5 +1,6 @@
if ENV['TEST'] || ENV['CONTRACTS'] == 'true'
require 'contracts'
require 'hamster'
module Contracts
class IsA
@ -27,21 +28,7 @@ if ENV['TEST'] || ENV['CONTRACTS'] == 'true'
end
end
# class MethodDefined
# def self.[](val)
# @lookup ||= {}
# @lookup[val] ||= new(val)
# end
# def initialize(val)
# @val = val
# end
# def valid?(val)
# val.method_defined? @val
# end
# end
VectorOf = Contracts::CollectionOf::Factory.new(::Hamster::Vector)
ResourceList = Contracts::ArrayOf[IsA['Middleman::Sitemap::Resource']]
end
else
@ -125,8 +112,8 @@ else
class Frozen < Callable
end
# class MethodDefined < Callable
# end
class VectorOf < Callable
end
end
end

View file

@ -1,3 +1,5 @@
require 'hamster'
module Middleman
module CoreExtensions
module Collections
@ -9,13 +11,13 @@ module Middleman
attr_reader :descriptors
def initialize
@descriptors = []
@descriptors = ::Hamster.set
end
def method_missing(name, *args, &block)
internal = :"_internal_#{name}"
if respond_to?(internal)
@descriptors << send(internal, *args, &block)
@descriptors = @descriptors.add(send(internal, *args, &block))
else
super
end

View file

@ -12,7 +12,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension
def initialize(*)
super
require 'i18n'
# Don't fail on invalid locale, that's not what our current

View file

@ -179,15 +179,15 @@ module Middleman
http_opts[:SSLEnable] = true
if ssl_certificate || ssl_private_key
raise "You must provide both :ssl_certificate and :ssl_private_key" unless ssl_private_key && ssl_certificate
raise 'You must provide both :ssl_certificate and :ssl_private_key' unless ssl_private_key && ssl_certificate
http_opts[:SSLCertificate] = OpenSSL::X509::Certificate.new File.read ssl_certificate
http_opts[:SSLPrivateKey] = OpenSSL::PKey::RSA.new File.read ssl_private_key
else
# use a generated self-signed cert
http_opts[:SSLCertName] = [
%w(CN localhost),
%w(CN #{host})
].uniq
%w(CN localhost),
%w(CN #{host})
].uniq
end
end

View file

@ -1,6 +1,7 @@
# Used for merging results of metadata callbacks
require 'active_support/core_ext/hash/deep_merge'
require 'monitor'
require 'hamster'
# Ignores
Middleman::Extensions.register :sitemap_ignore, auto_activate: :before_configuration do
@ -37,6 +38,8 @@ require 'middleman-core/contracts'
module Middleman
# Sitemap namespace
module Sitemap
ManipulatorDescriptor = Struct.new :name, :manipulator, :priority, :custom_name
# The Store class
#
# The Store manages a collection of Resource objects, which represent
@ -46,20 +49,21 @@ module Middleman
class Store
include Contracts
# @return [Middleman::Application]
Contract IsA['Middleman::Application']
attr_reader :app
Contract Num
attr_reader :update_count
# Initialize with parent app
# @param [Middleman::Application] app
Contract IsA['Middleman::Application'] => Any
def initialize(app)
@app = app
@resources = []
@update_count = 0
# TODO: Should this be a set or hash?
@resource_list_manipulators = []
@resource_list_manipulators = ::Hamster.vector
@needs_sitemap_rebuild = true
@lock = Monitor.new
@ -76,24 +80,29 @@ module Middleman
# @param [Numeric] priority Sets the order of this resource list manipulator relative to the rest. By default this is 50, and manipulators run in the order they are registered, but if a priority is provided then this will run ahead of or behind other manipulators.
# @param [Symbol] custom_name The method name to execute.
# @return [void]
Contract Symbol, RespondTo['manipulate_resource_list'], Maybe[Num], Maybe[Symbol] => Any
Contract Symbol, RespondTo[:manipulate_resource_list], Maybe[Num], Maybe[Symbol] => Any
def register_resource_list_manipulator(name, manipulator, priority=50, custom_name=nil)
# The third argument used to be a boolean - handle those who still pass one
priority = 50 unless priority.is_a? Numeric
@resource_list_manipulators << [name, manipulator, priority, custom_name]
@resource_list_manipulators = @resource_list_manipulators.push(
ManipulatorDescriptor.new(name, manipulator, priority, custom_name)
)
# The index trick is used so that the sort is stable - manipulators with the same priority
# will always be ordered in the same order as they were registered.
n = 0
@resource_list_manipulators = @resource_list_manipulators.sort_by do |m|
n += 1
[m[2], n]
[m[:priority], n]
end
rebuild_resource_list!(:registered_new)
end
# Rebuild the list of resources from scratch, using registed manipulators
# @return [void]
def rebuild_resource_list!(_=nil)
Contract Maybe[Symbol] => Any
def rebuild_resource_list!(_name=nil)
@lock.synchronize do
@needs_sitemap_rebuild = true
end
@ -178,11 +187,13 @@ module Middleman
@app.logger.debug '== Rebuilding resource list'
@resources = @resource_list_manipulators.reduce([]) do |result, (_, manipulator, _, custom_name)|
newres = manipulator.send(custom_name || :manipulate_resource_list, result)
@resources = @resource_list_manipulators.reduce([]) do |result, m|
newres = m[:manipulator].send(m[:custom_name] || :manipulate_resource_list, result)
# Reset lookup cache
reset_lookup_cache!
# Rebuild cache
newres.each do |resource|
@_lookup_by_path[resource.path] = resource
@_lookup_by_destination_path[resource.destination_path] = resource

View file

@ -1,3 +1,4 @@
require 'hamster'
require 'middleman-core/contracts'
require 'backports/2.0.0/enumerable/lazy'
@ -47,10 +48,10 @@ module Middleman
@options = options
# Set of procs wanting to be notified of changes
@on_change_callbacks = []
@on_change_callbacks = ::Hamster.vector
# Global ignores
@ignores = {}
@ignores = ::Hamster.hash
# Whether we're "running", which means we're in a stable
# watch state after all initialization and config.
@ -72,7 +73,8 @@ module Middleman
# @return [void]
Contract Symbol, Symbol, Or[Regexp, Proc] => Any
def ignore(name, type, regex=nil, &block)
@ignores[name] = { type: type, validator: (block_given? ? block : regex) }
@ignores = @ignores.put(name, type: type,
validator: (block_given? ? block : regex))
bump_count
find_new_files! if @running
@ -238,11 +240,10 @@ module Middleman
# Add callback to be run on file change or deletion
#
# @param [Symbol] type The change type.
# @return [Set<CallbackDescriptor>]
Contract Symbol, Proc => ArrayOf[CallbackDescriptor]
# @return [void]
Contract Symbol, Proc => Any
def on_change(type, &block)
@on_change_callbacks << CallbackDescriptor.new(type, block)
@on_change_callbacks
@on_change_callbacks = @on_change_callbacks.push(CallbackDescriptor.new(type, block))
end
# Backwards compatible change handler.
@ -328,7 +329,7 @@ module Middleman
# @param [Set] callback_descriptors The registered callbacks.
# @param [Array<Middleman::SourceFile>] files The files that were changed.
# @return [void]
Contract ArrayOf[CallbackDescriptor], ArrayOf[SourceFile], ArrayOf[SourceFile] => Any
Contract VectorOf[CallbackDescriptor], ArrayOf[SourceFile], ArrayOf[SourceFile] => Any
def run_callbacks(callback_descriptors, updated_files, removed_files)
callback_descriptors.each do |callback|
if callback[:type] == :all