middleman-core 4.0.0.beta.1 → 4.0.0.beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/middleman-core/application.rb +126 -112
- data/lib/middleman-core/builder.rb +7 -17
- data/lib/middleman-core/callback_manager.rb +61 -0
- data/lib/middleman-core/cli/server.rb +10 -0
- data/lib/middleman-core/config_context.rb +6 -46
- data/lib/middleman-core/contracts.rb +4 -17
- data/lib/middleman-core/core_extensions/collections/step_context.rb +4 -2
- data/lib/middleman-core/core_extensions/i18n.rb +19 -0
- data/lib/middleman-core/core_extensions/show_exceptions.rb +1 -1
- data/lib/middleman-core/extension.rb +1 -0
- data/lib/middleman-core/extension_manager.rb +11 -0
- data/lib/middleman-core/file_renderer.rb +5 -15
- data/lib/middleman-core/preview_server.rb +31 -2
- data/lib/middleman-core/rack.rb +1 -1
- data/lib/middleman-core/renderers/coffee_script.rb +1 -3
- data/lib/middleman-core/sitemap/extensions/ignores.rb +1 -1
- data/lib/middleman-core/sitemap/extensions/on_disk.rb +9 -10
- data/lib/middleman-core/sitemap/store.rb +20 -9
- data/lib/middleman-core/sources.rb +10 -9
- data/lib/middleman-core/sources/source_watcher.rb +7 -27
- data/lib/middleman-core/version.rb +1 -1
- data/middleman-core.gemspec +0 -1
- data/spec/middleman-core/callbacks_spec.rb +132 -0
- metadata +4 -16
@@ -1,6 +1,7 @@
|
|
1
1
|
# Used for merging results of metadata callbacks
|
2
2
|
require 'active_support/core_ext/hash/deep_merge'
|
3
3
|
require 'monitor'
|
4
|
+
require 'hamster'
|
4
5
|
|
5
6
|
# Ignores
|
6
7
|
Middleman::Extensions.register :sitemap_ignore, auto_activate: :before_configuration do
|
@@ -37,6 +38,8 @@ require 'middleman-core/contracts'
|
|
37
38
|
module Middleman
|
38
39
|
# Sitemap namespace
|
39
40
|
module Sitemap
|
41
|
+
ManipulatorDescriptor = Struct.new :name, :manipulator, :priority, :custom_name
|
42
|
+
|
40
43
|
# The Store class
|
41
44
|
#
|
42
45
|
# The Store manages a collection of Resource objects, which represent
|
@@ -46,20 +49,21 @@ module Middleman
|
|
46
49
|
class Store
|
47
50
|
include Contracts
|
48
51
|
|
49
|
-
|
52
|
+
Contract IsA['Middleman::Application']
|
50
53
|
attr_reader :app
|
51
54
|
|
55
|
+
Contract Num
|
52
56
|
attr_reader :update_count
|
53
57
|
|
54
58
|
# Initialize with parent app
|
55
59
|
# @param [Middleman::Application] app
|
60
|
+
Contract IsA['Middleman::Application'] => Any
|
56
61
|
def initialize(app)
|
57
62
|
@app = app
|
58
63
|
@resources = []
|
59
64
|
@update_count = 0
|
60
65
|
|
61
|
-
|
62
|
-
@resource_list_manipulators = []
|
66
|
+
@resource_list_manipulators = ::Hamster.vector
|
63
67
|
@needs_sitemap_rebuild = true
|
64
68
|
|
65
69
|
@lock = Monitor.new
|
@@ -76,24 +80,29 @@ module Middleman
|
|
76
80
|
# @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.
|
77
81
|
# @param [Symbol] custom_name The method name to execute.
|
78
82
|
# @return [void]
|
79
|
-
Contract Symbol, RespondTo[
|
83
|
+
Contract Symbol, RespondTo[:manipulate_resource_list], Maybe[Num], Maybe[Symbol] => Any
|
80
84
|
def register_resource_list_manipulator(name, manipulator, priority=50, custom_name=nil)
|
81
85
|
# The third argument used to be a boolean - handle those who still pass one
|
82
86
|
priority = 50 unless priority.is_a? Numeric
|
83
|
-
@resource_list_manipulators
|
87
|
+
@resource_list_manipulators = @resource_list_manipulators.push(
|
88
|
+
ManipulatorDescriptor.new(name, manipulator, priority, custom_name)
|
89
|
+
)
|
90
|
+
|
84
91
|
# The index trick is used so that the sort is stable - manipulators with the same priority
|
85
92
|
# will always be ordered in the same order as they were registered.
|
86
93
|
n = 0
|
87
94
|
@resource_list_manipulators = @resource_list_manipulators.sort_by do |m|
|
88
95
|
n += 1
|
89
|
-
[m[
|
96
|
+
[m[:priority], n]
|
90
97
|
end
|
98
|
+
|
91
99
|
rebuild_resource_list!(:registered_new)
|
92
100
|
end
|
93
101
|
|
94
102
|
# Rebuild the list of resources from scratch, using registed manipulators
|
95
103
|
# @return [void]
|
96
|
-
|
104
|
+
Contract Maybe[Symbol] => Any
|
105
|
+
def rebuild_resource_list!(_name=nil)
|
97
106
|
@lock.synchronize do
|
98
107
|
@needs_sitemap_rebuild = true
|
99
108
|
end
|
@@ -178,11 +187,13 @@ module Middleman
|
|
178
187
|
|
179
188
|
@app.logger.debug '== Rebuilding resource list'
|
180
189
|
|
181
|
-
@resources = @resource_list_manipulators.reduce([]) do |result,
|
182
|
-
newres = manipulator.send(custom_name || :manipulate_resource_list, result)
|
190
|
+
@resources = @resource_list_manipulators.reduce([]) do |result, m|
|
191
|
+
newres = m[:manipulator].send(m[:custom_name] || :manipulate_resource_list, result)
|
183
192
|
|
184
193
|
# Reset lookup cache
|
185
194
|
reset_lookup_cache!
|
195
|
+
|
196
|
+
# Rebuild cache
|
186
197
|
newres.each do |resource|
|
187
198
|
@_lookup_by_path[resource.path] = resource
|
188
199
|
@_lookup_by_destination_path[resource.destination_path] = resource
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'hamster'
|
1
2
|
require 'middleman-core/contracts'
|
2
3
|
require 'backports/2.0.0/enumerable/lazy'
|
3
4
|
|
@@ -47,10 +48,10 @@ module Middleman
|
|
47
48
|
@options = options
|
48
49
|
|
49
50
|
# Set of procs wanting to be notified of changes
|
50
|
-
@on_change_callbacks =
|
51
|
+
@on_change_callbacks = ::Hamster.vector
|
51
52
|
|
52
53
|
# Global ignores
|
53
|
-
@ignores =
|
54
|
+
@ignores = ::Hamster.hash
|
54
55
|
|
55
56
|
# Whether we're "running", which means we're in a stable
|
56
57
|
# watch state after all initialization and config.
|
@@ -72,7 +73,8 @@ module Middleman
|
|
72
73
|
# @return [void]
|
73
74
|
Contract Symbol, Symbol, Or[Regexp, Proc] => Any
|
74
75
|
def ignore(name, type, regex=nil, &block)
|
75
|
-
@ignores
|
76
|
+
@ignores = @ignores.put(name, type: type,
|
77
|
+
validator: (block_given? ? block : regex))
|
76
78
|
|
77
79
|
bump_count
|
78
80
|
find_new_files! if @running
|
@@ -238,11 +240,10 @@ module Middleman
|
|
238
240
|
# Add callback to be run on file change or deletion
|
239
241
|
#
|
240
242
|
# @param [Symbol] type The change type.
|
241
|
-
# @return [
|
242
|
-
Contract Symbol, Proc =>
|
243
|
+
# @return [void]
|
244
|
+
Contract Symbol, Proc => Any
|
243
245
|
def on_change(type, &block)
|
244
|
-
@on_change_callbacks
|
245
|
-
@on_change_callbacks
|
246
|
+
@on_change_callbacks = @on_change_callbacks.push(CallbackDescriptor.new(type, block))
|
246
247
|
end
|
247
248
|
|
248
249
|
# Backwards compatible change handler.
|
@@ -328,7 +329,7 @@ module Middleman
|
|
328
329
|
# @param [Set] callback_descriptors The registered callbacks.
|
329
330
|
# @param [Array<Middleman::SourceFile>] files The files that were changed.
|
330
331
|
# @return [void]
|
331
|
-
Contract
|
332
|
+
Contract VectorOf[CallbackDescriptor], ArrayOf[SourceFile], ArrayOf[SourceFile] => Any
|
332
333
|
def run_callbacks(callback_descriptors, updated_files, removed_files)
|
333
334
|
callback_descriptors.each do |callback|
|
334
335
|
if callback[:type] == :all
|
@@ -345,4 +346,4 @@ module Middleman
|
|
345
346
|
end
|
346
347
|
|
347
348
|
# And, require the actual default implementation for a watcher.
|
348
|
-
require 'middleman-core/sources/source_watcher
|
349
|
+
require 'middleman-core/sources/source_watcher'
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# Watcher Library
|
2
2
|
require 'listen'
|
3
3
|
require 'middleman-core/contracts'
|
4
|
+
require 'middleman-core/contracts'
|
4
5
|
require 'backports/2.0.0/enumerable/lazy'
|
5
6
|
|
6
7
|
module Middleman
|
@@ -55,7 +56,8 @@ module Middleman
|
|
55
56
|
|
56
57
|
@listener = nil
|
57
58
|
|
58
|
-
@
|
59
|
+
@callbacks = ::Middleman::CallbackManager.new
|
60
|
+
@callbacks.install_methods!(self, [:on_change])
|
59
61
|
|
60
62
|
@waiting_for_existence = !@directory.exist?
|
61
63
|
end
|
@@ -174,16 +176,6 @@ module Middleman
|
|
174
176
|
listen!
|
175
177
|
end
|
176
178
|
|
177
|
-
# Add callback to be run on file change
|
178
|
-
#
|
179
|
-
# @param [Proc] matcher A Regexp to match the change path against
|
180
|
-
# @return [Set<Proc>]
|
181
|
-
Contract Proc => SetOf[Proc]
|
182
|
-
def on_change(&block)
|
183
|
-
@on_change_callbacks << block
|
184
|
-
@on_change_callbacks
|
185
|
-
end
|
186
|
-
|
187
179
|
# Work around this bug: http://bugs.ruby-lang.org/issues/4521
|
188
180
|
# where Ruby will call to_s/inspect while printing exception
|
189
181
|
# messages, which can take a long time (minutes at full CPU)
|
@@ -237,11 +229,11 @@ module Middleman
|
|
237
229
|
logger.debug "== Deletion (#{f[:types].inspect}): #{f[:relative_path]}"
|
238
230
|
end
|
239
231
|
|
240
|
-
|
241
|
-
@on_change_callbacks,
|
232
|
+
execute_callbacks(:on_change, [
|
242
233
|
valid_updates,
|
243
|
-
valid_removes
|
244
|
-
|
234
|
+
valid_removes,
|
235
|
+
self
|
236
|
+
]) unless valid_updates.empty? && valid_removes.empty?
|
245
237
|
end
|
246
238
|
|
247
239
|
def add_file_to_cache(f)
|
@@ -289,17 +281,5 @@ module Middleman
|
|
289
281
|
|
290
282
|
::Middleman::SourceFile.new(Pathname(relative_path), path, @directory, types)
|
291
283
|
end
|
292
|
-
|
293
|
-
# Notify callbacks for a file given an array of callbacks
|
294
|
-
#
|
295
|
-
# @param [Pathname] path The file that was changed
|
296
|
-
# @param [Symbol] callbacks_name The name of the callbacks method
|
297
|
-
# @return [void]
|
298
|
-
Contract Set, ArrayOf[IsA['Middleman::SourceFile']], ArrayOf[IsA['Middleman::SourceFile']] => Any
|
299
|
-
def run_callbacks(callbacks, updated_files, removed_files)
|
300
|
-
callbacks.each do |callback|
|
301
|
-
callback.call(updated_files, removed_files, self)
|
302
|
-
end
|
303
|
-
end
|
304
284
|
end
|
305
285
|
end
|
data/middleman-core.gemspec
CHANGED
@@ -0,0 +1,132 @@
|
|
1
|
+
# require 'spec_helper'
|
2
|
+
require 'middleman-core/callback_manager'
|
3
|
+
|
4
|
+
describe ::Middleman::CallbackManager do
|
5
|
+
it "adds a simple key" do
|
6
|
+
counters = {
|
7
|
+
test1: 0,
|
8
|
+
test2: 0,
|
9
|
+
test3: 0
|
10
|
+
}
|
11
|
+
|
12
|
+
m = ::Middleman::CallbackManager.new
|
13
|
+
m.add(:test3) { counters[:test3] += 1 }
|
14
|
+
m.add(:test1) { counters[:test1] += 1 }
|
15
|
+
m.add(:test2) { counters[:test2] += 1 }
|
16
|
+
m.add(:test1) { counters[:test1] += 1 }
|
17
|
+
m.add(:test2) { counters[:test2] += 1 }
|
18
|
+
m.add(:test1) { counters[:test1] += 1 }
|
19
|
+
m.add(:test3) { counters[:test3] += 1 }
|
20
|
+
|
21
|
+
m.execute(:test1)
|
22
|
+
m.execute(:test2)
|
23
|
+
|
24
|
+
expect(counters[:test1]).to eq 3
|
25
|
+
expect(counters[:test2]).to eq 2
|
26
|
+
expect(counters[:test3]).to eq 0
|
27
|
+
end
|
28
|
+
|
29
|
+
it "callbacks run in order" do
|
30
|
+
result = []
|
31
|
+
|
32
|
+
m = ::Middleman::CallbackManager.new
|
33
|
+
m.add(:test) { result.push(1) }
|
34
|
+
m.add(:test) { result.push(2) }
|
35
|
+
m.add(:test) { result.push(3) }
|
36
|
+
|
37
|
+
m.execute(:test)
|
38
|
+
|
39
|
+
expect(result.join('')).to eq '123'
|
40
|
+
end
|
41
|
+
|
42
|
+
it "adds a nested key" do
|
43
|
+
counters = {
|
44
|
+
test1: 0,
|
45
|
+
test1a: 0
|
46
|
+
}
|
47
|
+
|
48
|
+
m = ::Middleman::CallbackManager.new
|
49
|
+
m.add([:test1, :a]) { |n| counters[:test1a] += n }
|
50
|
+
m.add(:test1) { counters[:test1] += 1 }
|
51
|
+
|
52
|
+
m.execute([:test1, :a], [2])
|
53
|
+
m.execute([:test1, :b], [5])
|
54
|
+
|
55
|
+
expect(counters[:test1]).to eq 0
|
56
|
+
expect(counters[:test1a]).to eq 2
|
57
|
+
end
|
58
|
+
|
59
|
+
it "works in isolation" do
|
60
|
+
m1 = ::Middleman::CallbackManager.new
|
61
|
+
m2 = ::Middleman::CallbackManager.new
|
62
|
+
|
63
|
+
counters = {
|
64
|
+
test1: 0,
|
65
|
+
test2: 0
|
66
|
+
}
|
67
|
+
|
68
|
+
m1.add(:test1) { |n| counters[:test1] += n }
|
69
|
+
m2.add(:test1) { |n| counters[:test2] += n }
|
70
|
+
|
71
|
+
m1.execute(:test1, [2])
|
72
|
+
m2.execute(:test1, [5])
|
73
|
+
m1.execute(:test2, [20])
|
74
|
+
m2.execute(:test2, [50])
|
75
|
+
|
76
|
+
expect(counters[:test1]).to eq 2
|
77
|
+
expect(counters[:test2]).to eq 5
|
78
|
+
end
|
79
|
+
|
80
|
+
it "installs to arbitrary instances" do
|
81
|
+
instance = Class.new(Object).new
|
82
|
+
|
83
|
+
m = ::Middleman::CallbackManager.new
|
84
|
+
m.install_methods!(instance, [:ready])
|
85
|
+
|
86
|
+
counter = 0
|
87
|
+
instance.ready { |n| counter += n }
|
88
|
+
instance.execute_callbacks(:ready, [2])
|
89
|
+
instance.execute_callbacks(:ready2, [10])
|
90
|
+
instance.execute_callbacks([:ready], [20])
|
91
|
+
instance.execute_callbacks([:ready, :two], [20])
|
92
|
+
expect(counter).to eq 2
|
93
|
+
end
|
94
|
+
|
95
|
+
it "executes in default scope" do
|
96
|
+
instance = Class.new(Object).new
|
97
|
+
m = ::Middleman::CallbackManager.new
|
98
|
+
m.install_methods!(instance, [:ready])
|
99
|
+
|
100
|
+
internal_self = nil
|
101
|
+
instance.ready do
|
102
|
+
internal_self = self
|
103
|
+
end
|
104
|
+
|
105
|
+
instance.execute_callbacks(:ready)
|
106
|
+
|
107
|
+
expect(internal_self) === instance
|
108
|
+
end
|
109
|
+
|
110
|
+
it "executes in custom scope" do
|
111
|
+
instance = Class.new(Object).new
|
112
|
+
m = ::Middleman::CallbackManager.new
|
113
|
+
m.install_methods!(instance, [:ready])
|
114
|
+
|
115
|
+
external_class = Struct.new(:counter, :scope) do
|
116
|
+
def when_ready(n)
|
117
|
+
self[:scope] = self
|
118
|
+
self[:counter] += n
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
external_instance = external_class.new(0, nil)
|
123
|
+
|
124
|
+
instance.ready(&external_instance.method(:when_ready))
|
125
|
+
|
126
|
+
instance.execute_callbacks(:ready, [5])
|
127
|
+
|
128
|
+
expect(external_instance[:scope]).to eq external_instance
|
129
|
+
expect(external_instance[:counter]).to eq 5
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: middleman-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.0.beta.
|
4
|
+
version: 4.0.0.beta.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Reynolds
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-05-
|
13
|
+
date: 2015-05-04 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -88,20 +88,6 @@ dependencies:
|
|
88
88
|
- - ">="
|
89
89
|
- !ruby/object:Gem::Version
|
90
90
|
version: '0'
|
91
|
-
- !ruby/object:Gem::Dependency
|
92
|
-
name: hooks
|
93
|
-
requirement: !ruby/object:Gem::Requirement
|
94
|
-
requirements:
|
95
|
-
- - "~>"
|
96
|
-
- !ruby/object:Gem::Version
|
97
|
-
version: '0.3'
|
98
|
-
type: :runtime
|
99
|
-
prerelease: false
|
100
|
-
version_requirements: !ruby/object:Gem::Requirement
|
101
|
-
requirements:
|
102
|
-
- - "~>"
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
version: '0.3'
|
105
91
|
- !ruby/object:Gem::Dependency
|
106
92
|
name: activesupport
|
107
93
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1129,6 +1115,7 @@ files:
|
|
1129
1115
|
- lib/middleman-core.rb
|
1130
1116
|
- lib/middleman-core/application.rb
|
1131
1117
|
- lib/middleman-core/builder.rb
|
1118
|
+
- lib/middleman-core/callback_manager.rb
|
1132
1119
|
- lib/middleman-core/cli/server.rb
|
1133
1120
|
- lib/middleman-core/config_context.rb
|
1134
1121
|
- lib/middleman-core/configuration.rb
|
@@ -1222,6 +1209,7 @@ files:
|
|
1222
1209
|
- spec/middleman-core/binary_spec/stars.svgz
|
1223
1210
|
- spec/middleman-core/binary_spec/unicode
|
1224
1211
|
- spec/middleman-core/binary_spec/unicode.txt
|
1212
|
+
- spec/middleman-core/callbacks_spec.rb
|
1225
1213
|
- spec/middleman-core/core_extensions/data_spec.rb
|
1226
1214
|
- spec/middleman-core/util_spec.rb
|
1227
1215
|
- spec/spec_helper.rb
|