middleman-core 3.0.4 → 3.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/bin/middleman CHANGED
@@ -1,12 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # Add our lib/ directory to the path
4
- libdir = File.expand_path(File.join(File.dirname(File.dirname(__FILE__)), "lib"))
5
- $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
6
-
7
- moredir = File.expand_path(File.join(File.dirname(File.dirname(libdir)), "middleman-more", "lib", "middleman-more"))
8
- $LOAD_PATH.unshift(moredir) unless $LOAD_PATH.include?(moredir)
9
-
10
3
  require 'middleman-core/profiling'
11
4
  if ARGV.include? '--profile'
12
5
  Middleman::Profiling.profiler = Middleman::Profiling::RubyProfProfiler.new
@@ -183,11 +183,7 @@ module Middleman
183
183
  # Evaluate a passed block if given
184
184
  instance_exec(&block) if block_given?
185
185
 
186
- # Build expanded source path once paths have been parsed
187
- path = root.dup
188
- source_path = ENV["MM_SOURCE"] || self.source
189
- path = File.join(root, source_path) unless source_path.empty?
190
- set :source_dir, path
186
+ set :source, ENV["MM_SOURCE"] if ENV["MM_SOURCE"]
191
187
 
192
188
  super
193
189
  end
@@ -216,6 +212,13 @@ module Middleman
216
212
  self
217
213
  end
218
214
 
215
+ # The full path to the source directory
216
+ #
217
+ # @return [String]
218
+ def source_dir
219
+ File.join(root, source)
220
+ end
221
+
219
222
  delegate :logger, :instrument, :to => ::Middleman::Util
220
223
 
221
224
  # Work around this bug: http://bugs.ruby-lang.org/issues/4521
@@ -232,12 +235,18 @@ module Middleman
232
235
  # @param [String] path Request path
233
236
  # @return [String] Path with index file if necessary
234
237
  def full_path(path)
235
- cache.fetch(:full_path, path) do
236
- parts = path ? path.split('/') : []
237
- if parts.last.nil? || parts.last.split('.').length == 1
238
- path = File.join(path, index_file)
239
- end
240
- "/" + path.sub(%r{^/}, '')
238
+ resource = sitemap.find_resource_by_destination_path(path)
239
+
240
+ if !resource
241
+ # Try it with /index.html at the end
242
+ indexed_path = File.join(path.sub(%r{/$}, ''), index_file)
243
+ resource = sitemap.find_resource_by_destination_path(indexed_path)
244
+ end
245
+
246
+ if resource
247
+ '/' + resource.destination_path
248
+ else
249
+ '/' + Middleman::Util.normalize_path(path)
241
250
  end
242
251
  end
243
252
 
@@ -99,10 +99,7 @@ module Middleman::Cli
99
99
  #
100
100
  # @return [Rack::Test::Session]
101
101
  def shared_rack
102
- @_shared_rack ||= begin
103
- mock = ::Rack::MockSession.new(shared_server.to_rack_app)
104
- ::Rack::Test::Session.new(mock)
105
- end
102
+ @_shared_rack ||= ::Rack::Test::Session.new(shared_server.to_rack_app)
106
103
  end
107
104
 
108
105
  # Set the root path to the Middleman::Application's root
@@ -242,6 +239,7 @@ module Middleman::Cli
242
239
 
243
240
  # Double-check for compass sprites
244
241
  @app.files.find_new_files((Pathname(@app.source_dir) + @app.images_dir).relative_path_from(@app.root_path))
242
+ @app.sitemap.ensure_resource_list_updated!
245
243
 
246
244
  # Sort paths to be built by the above order. This is primarily so Compass can
247
245
  # find files in the build folder when it needs to generate sprites for the
@@ -28,10 +28,18 @@ module Middleman::Cli
28
28
  :type => :boolean,
29
29
  :default => false,
30
30
  :desc => 'Include a config.ru file'
31
- method_option "bundler",
31
+ method_option "skip-gemfile",
32
32
  :type => :boolean,
33
33
  :default => false,
34
- :desc => 'Create a Gemfile and use Bundler to manage gems'
34
+ :desc => "Don't create a Gemfile"
35
+ method_option "skip-bundle",
36
+ :type => :boolean,
37
+ :default => false,
38
+ :desc => "Don't run bundle install"
39
+ method_option "skip-git",
40
+ :type => :boolean,
41
+ :default => false,
42
+ :desc => 'Skip Git ignores and keeps'
35
43
  # The init task
36
44
  # @param [String] name
37
45
  def init(name)
@@ -11,7 +11,7 @@ module Middleman
11
11
  /^\.sass-cache\//,
12
12
  /^\.git\//,
13
13
  /^\.gitignore$/,
14
- /^\.DS_Store$/,
14
+ /\.DS_Store/,
15
15
  /^build\//,
16
16
  /^\.rbenv-.*$/,
17
17
  /^Gemfile$/,
@@ -116,17 +116,14 @@ module Middleman
116
116
  path = Pathname(path)
117
117
  return unless path.exist?
118
118
 
119
- glob = (path + "**/*").to_s
119
+ glob = (path + "**").to_s
120
120
  subset = @known_paths.select { |p| p.fnmatch(glob) }
121
121
 
122
122
  ::Middleman::Util.all_files_under(path).each do |filepath|
123
- if only_new
124
- next if subset.include?(filepath)
125
- else
126
- subset.delete(filepath)
127
- end
123
+ next if only_new && subset.include?(filepath)
128
124
 
129
- self.did_change(filepath)
125
+ subset.delete(filepath)
126
+ did_change(filepath)
130
127
  end
131
128
 
132
129
  subset.each(&method(:did_delete)) unless only_new
@@ -37,7 +37,6 @@ module Middleman
37
37
  # @private
38
38
  def reset!
39
39
  @app = nil
40
- @prototype = nil
41
40
  end
42
41
 
43
42
  # The shared Rack instance being build
@@ -94,7 +93,8 @@ module Middleman
94
93
  # @private
95
94
  # @return [Rack::Builder]
96
95
  def prototype
97
- @prototype ||= to_rack_app
96
+ reset!
97
+ to_rack_app
98
98
  end
99
99
 
100
100
  # Call prototype, use in config.ru
@@ -227,32 +227,26 @@ module Middleman
227
227
  start_time = Time.now
228
228
  @current_path = nil
229
229
 
230
- # Normalize the path and add index if we're looking at a directory
231
- original_path = URI.decode(env["PATH_INFO"].dup)
232
- if original_path.respond_to? :force_encoding
233
- original_path.force_encoding('UTF-8')
230
+ request_path = URI.decode(env["PATH_INFO"].dup)
231
+ if request_path.respond_to? :force_encoding
232
+ request_path.force_encoding('UTF-8')
234
233
  end
235
- request_path = full_path(original_path)
234
+ request_path = full_path(request_path)
236
235
 
237
236
  # Run before callbacks
238
237
  run_hook :before
239
238
 
240
- if original_path != request_path
241
- # Get the resource object for this path
242
- resource = sitemap.find_resource_by_destination_path(original_path)
243
- end
244
-
245
- # Get the resource object for this full path
246
- resource ||= sitemap.find_resource_by_destination_path(request_path)
239
+ # Get the resource object for this path
240
+ resource = sitemap.find_resource_by_destination_path(request_path)
247
241
 
248
242
  # Return 404 if not in sitemap
249
- return not_found(res) unless resource && !resource.ignored?
243
+ return not_found(res, request_path) unless resource && !resource.ignored?
244
+
245
+ current_path = resource.destination_path
250
246
 
251
247
  # If this path is a static file, send it immediately
252
248
  return send_file(resource.source_file, env, res) unless resource.template?
253
249
 
254
- current_path = request_path.dup
255
-
256
250
  # Set a HTTP content type based on the request's extensions
257
251
  content_type(res, resource.mime_type)
258
252
 
@@ -272,7 +266,7 @@ module Middleman
272
266
  end
273
267
 
274
268
  # End the request
275
- logger.debug "== Finishing Request: #{request_path} (#{(Time.now - start_time).round(2)}s)"
269
+ logger.debug "== Finishing Request: #{current_path} (#{(Time.now - start_time).round(2)}s)"
276
270
  halt res.finish
277
271
  end
278
272
 
@@ -289,9 +283,9 @@ module Middleman
289
283
  end
290
284
 
291
285
  # Halt request and return 404
292
- def not_found(res)
286
+ def not_found(res, path)
293
287
  res.status == 404
294
- res.write "<html><body><h1>File Not Found</h1><p>#{@request_path}</p></body>"
288
+ res.write "<html><body><h1>File Not Found</h1><p>#{path}</p></body>"
295
289
  res.finish
296
290
  end
297
291
 
@@ -64,7 +64,10 @@ module Middleman
64
64
  end
65
65
 
66
66
  # Normalized path
67
- url = full_path(url)
67
+ url = '/' + Middleman::Util.normalize_path(url)
68
+ if url.end_with?('/') || File.directory?(File.join(source_dir, url))
69
+ url = File.join(url, index_file)
70
+ end
68
71
 
69
72
  # Setup proxy
70
73
  if opts.has_key?(:proxy)
@@ -145,7 +145,6 @@ module Middleman
145
145
  # @param [Middleman::Application] app
146
146
  # @return [void]
147
147
  def mount_instance
148
- @app = new_app
149
148
  @webrick ||= setup_webrick(
150
149
  @options[:host] || "0.0.0.0",
151
150
  @options[:debug] || false
@@ -14,7 +14,6 @@ module Middleman
14
14
  def initialize(sitemap)
15
15
  @sitemap = sitemap
16
16
  @app = @sitemap.app
17
-
18
17
  @file_paths_on_disk = Set.new
19
18
 
20
19
  scoped_self = self
@@ -22,17 +21,18 @@ module Middleman
22
21
 
23
22
  # Register file change callback
24
23
  @app.files.changed do |file|
25
- scoped_self.touch_file(file, !scoped_self.waiting_for_ready)
24
+ scoped_self.touch_file(file)
26
25
  end
27
26
 
28
27
  # Register file delete callback
29
28
  @app.files.deleted do |file|
30
- scoped_self.remove_file(file, !scoped_self.waiting_for_ready)
29
+ scoped_self.remove_file(file)
31
30
  end
32
31
 
33
32
  @app.ready do
34
33
  scoped_self.waiting_for_ready = false
35
- scoped_self.sitemap.rebuild_resource_list!(:on_disk_ready)
34
+ # Make sure the sitemap is ready for the first request
35
+ sitemap.ensure_resource_list_updated!
36
36
  end
37
37
  end
38
38
 
@@ -55,7 +55,13 @@ module Middleman
55
55
  # in case one of the other manipulators
56
56
  # (like asset_hash) cares about the contents of this file,
57
57
  # whether or not it belongs in the sitemap (like a partial)
58
- @sitemap.rebuild_resource_list!(:touched_file) if rebuild
58
+ @sitemap.rebuild_resource_list!(:touched_file)
59
+
60
+ unless waiting_for_ready || @app.build?
61
+ # Force sitemap rebuild so the next request is ready to go.
62
+ # Skip this during build because the builder will control sitemap refresh.
63
+ @sitemap.ensure_resource_list_updated!
64
+ end
59
65
  end
60
66
 
61
67
  # Remove a file from the store
@@ -63,7 +69,12 @@ module Middleman
63
69
  # @return [void]
64
70
  def remove_file(file, rebuild=true)
65
71
  if @file_paths_on_disk.delete?(file)
66
- @sitemap.rebuild_resource_list!(:removed_file) if rebuild
72
+ @sitemap.rebuild_resource_list!(:removed_file)
73
+ unless waiting_for_ready || @app.build?
74
+ # Force sitemap rebuild so the next request is ready to go.
75
+ # Skip this during build because the builder will control sitemap refresh.
76
+ @sitemap.ensure_resource_list_updated!
77
+ end
67
78
  end
68
79
  end
69
80
 
@@ -23,41 +23,32 @@ module Middleman
23
23
  @app = app
24
24
  @resources = []
25
25
  @_cached_metadata = {}
26
- @_lookup_cache = { :path => {}, :destination_path => {} }
27
26
  @resource_list_manipulators = []
27
+ @needs_sitemap_rebuild = true
28
+ reset_lookup_cache!
28
29
 
29
30
  # Register classes which can manipulate the main site map list
30
- register_resource_list_manipulator(:on_disk, Middleman::Sitemap::Extensions::OnDisk.new(self), false)
31
+ register_resource_list_manipulator(:on_disk, Middleman::Sitemap::Extensions::OnDisk.new(self))
31
32
 
32
33
  # Proxies
33
- register_resource_list_manipulator(:proxies, @app.proxy_manager, false)
34
+ register_resource_list_manipulator(:proxies, @app.proxy_manager)
34
35
  end
35
36
 
36
- # Register a klass which can manipulate the main site map list
37
+ # Register a klass which can manipulate the main site map list. Best to register
38
+ # these in a before_configuration or after_configuration hook.
39
+ #
37
40
  # @param [Symbol] name Name of the manipulator for debugging
38
41
  # @param [Class, Module] inst Abstract namespace which can update the resource list
39
- # @param [Boolean] immediately_rebuild Whether the resource list should be immediately recalculated
40
42
  # @return [void]
41
- def register_resource_list_manipulator(name, inst, immediately_rebuild=true)
43
+ def register_resource_list_manipulator(name, inst, unused=true)
42
44
  @resource_list_manipulators << [name, inst]
43
- rebuild_resource_list!(:registered_new) if immediately_rebuild
45
+ rebuild_resource_list!(:registered_new)
44
46
  end
45
47
 
46
48
  # Rebuild the list of resources from scratch, using registed manipulators
47
49
  # @return [void]
48
50
  def rebuild_resource_list!(reason=nil)
49
- @resources = @resource_list_manipulators.inject([]) do |result, (_, inst)|
50
- newres = inst.manipulate_resource_list(result)
51
-
52
- # Reset lookup cache
53
- @_lookup_cache = { :path => {}, :destination_path => {} }
54
- newres.each do |resource|
55
- @_lookup_cache[:path][resource.path] = resource
56
- @_lookup_cache[:destination_path][resource.destination_path] = resource
57
- end
58
-
59
- newres
60
- end
51
+ @needs_sitemap_rebuild = true
61
52
  end
62
53
 
63
54
  # Find a resource given its original path
@@ -65,7 +56,8 @@ module Middleman
65
56
  # @return [Middleman::Sitemap::Resource]
66
57
  def find_resource_by_path(request_path)
67
58
  request_path = ::Middleman::Util.normalize_path(request_path)
68
- @_lookup_cache[:path][request_path]
59
+ ensure_resource_list_updated!
60
+ @_lookup_by_path[request_path]
69
61
  end
70
62
 
71
63
  # Find a resource given its destination path
@@ -73,13 +65,15 @@ module Middleman
73
65
  # @return [Middleman::Sitemap::Resource]
74
66
  def find_resource_by_destination_path(request_path)
75
67
  request_path = ::Middleman::Util.normalize_path(request_path)
76
- @_lookup_cache[:destination_path][request_path]
68
+ ensure_resource_list_updated!
69
+ @_lookup_by_destination_path[request_path]
77
70
  end
78
71
 
79
72
  # Get the array of all resources
80
73
  # @param [Boolean] include_ignored Whether to include ignored resources
81
74
  # @return [Array<Middleman::Sitemap::Resource>]
82
75
  def resources(include_ignored=false)
76
+ ensure_resource_list_updated!
83
77
  if include_ignored
84
78
  @resources
85
79
  else
@@ -214,6 +208,36 @@ module Middleman
214
208
 
215
209
  path
216
210
  end
211
+
212
+ # Actually update the resource list, assuming anything has called
213
+ # rebuild_resource_list! since the last time it was run. This is
214
+ # very expensive!
215
+ def ensure_resource_list_updated!
216
+ return unless @needs_sitemap_rebuild
217
+ @needs_sitemap_rebuild = false
218
+
219
+ @app.logger.debug "== Rebuilding resource list"
220
+
221
+ @resources = @resource_list_manipulators.inject([]) do |result, (_, inst)|
222
+ newres = inst.manipulate_resource_list(result)
223
+
224
+ # Reset lookup cache
225
+ reset_lookup_cache!
226
+ newres.each do |resource|
227
+ @_lookup_by_path[resource.path] = resource
228
+ @_lookup_by_destination_path[resource.destination_path] = resource
229
+ end
230
+
231
+ newres
232
+ end
233
+ end
234
+
235
+ private
236
+
237
+ def reset_lookup_cache!
238
+ @_lookup_by_path = {}
239
+ @_lookup_by_destination_path = {}
240
+ end
217
241
  end
218
242
  end
219
243
  end
@@ -50,23 +50,28 @@ module Middleman::Templates
50
50
  template "shared/config.ru", File.join(location, "config.ru")
51
51
  end
52
52
 
53
+ class_option :'skip-bundle', :type => :boolean, :default => false
54
+ class_option :'skip-gemfile', :type => :boolean, :default => false
55
+
53
56
  # Write a Bundler Gemfile file for project
54
57
  # @return [void]
55
58
  def generate_bundler!
59
+ return if options[:'skip-gemfile']
56
60
  template "shared/Gemfile.tt", File.join(location, "Gemfile")
57
61
 
62
+ return if options[:'skip-bundle']
58
63
  inside(location) do
59
64
  ::Middleman::Cli::Bundle.new.invoke(:bundle)
60
65
  end unless ENV["TEST"]
61
66
  end
62
67
 
63
68
  # Output a .gitignore file
64
- class_option :git, :type => :boolean, :default => true
69
+ class_option :'skip-git', :type => :boolean, :default => false
65
70
 
66
71
  # Write a .gitignore file for project
67
72
  # @return [void]
68
73
  def generate_gitignore!
69
- return unless options[:git]
74
+ return if options[:'skip-git']
70
75
  copy_file "shared/gitignore", File.join(location, ".gitignore")
71
76
  end
72
77
  end
@@ -1,5 +1,5 @@
1
1
  module Middleman
2
2
  # Current Version
3
3
  # @return [String]
4
- VERSION = '3.0.4' unless const_defined?(:VERSION)
4
+ VERSION = '3.0.5' unless const_defined?(:VERSION)
5
5
  end
@@ -33,6 +33,6 @@ Gem::Specification.new do |s|
33
33
  s.add_dependency("activesupport", ["~> 3.2.6"])
34
34
 
35
35
  # Watcher
36
- s.add_dependency("listen", ["~> 0.5.0"])
36
+ s.add_dependency("listen", ["~> 0.5.2"])
37
37
  s.add_dependency("wdm", ["~> 0.0.3"]) # Windows
38
38
  end
@@ -33,7 +33,7 @@ Gem::Specification.new do |s|
33
33
  s.add_dependency("activesupport", ["~> 3.2.6"])
34
34
 
35
35
  # Watcher
36
- s.add_dependency("listen", ["~> 0.5.0"])
36
+ s.add_dependency("listen", ["~> 0.5.2"])
37
37
  s.add_dependency("rb-fsevent", ["~> 0.9.1"]) # Linux
38
38
  s.add_dependency("rb-inotify", ["~> 0.8.8"]) # OS X
39
39
  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: 3.0.4
4
+ version: 3.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-09-13 00:00:00.000000000 Z
13
+ date: 2012-09-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -115,7 +115,7 @@ dependencies:
115
115
  requirements:
116
116
  - - ~>
117
117
  - !ruby/object:Gem::Version
118
- version: 0.5.0
118
+ version: 0.5.2
119
119
  type: :runtime
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
@@ -123,7 +123,7 @@ dependencies:
123
123
  requirements:
124
124
  - - ~>
125
125
  - !ruby/object:Gem::Version
126
- version: 0.5.0
126
+ version: 0.5.2
127
127
  - !ruby/object:Gem::Dependency
128
128
  name: rb-fsevent
129
129
  requirement: !ruby/object:Gem::Requirement
@@ -585,7 +585,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
585
585
  version: '0'
586
586
  segments:
587
587
  - 0
588
- hash: -1143395816558407601
588
+ hash: -2720475402935195824
589
589
  required_rubygems_version: !ruby/object:Gem::Requirement
590
590
  none: false
591
591
  requirements:
@@ -594,10 +594,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
594
594
  version: '0'
595
595
  segments:
596
596
  - 0
597
- hash: -1143395816558407601
597
+ hash: -2720475402935195824
598
598
  requirements: []
599
599
  rubyforge_project:
600
- rubygems_version: 1.8.23
600
+ rubygems_version: 1.8.24
601
601
  signing_key:
602
602
  specification_version: 3
603
603
  summary: Hand-crafted frontend development