Compare commits
20 commits
Author | SHA1 | Date | |
---|---|---|---|
b6167b1369 | |||
30217d2c04 | |||
073f273fe4 | |||
e30f413376 | |||
a680fb30c5 | |||
42e31c8c5e | |||
046d15cfa5 | |||
5adea781c9 | |||
97082d5fc4 | |||
604c0e2b5d | |||
7c968b9572 | |||
197093b36c | |||
ea2115f3f8 | |||
07651c63a6 | |||
65462cbc43 | |||
c264b05906 | |||
dcd36a4f99 | |||
7027b4933a | |||
cbad571338 | |||
ffef14deb4 |
|
@ -67,3 +67,5 @@ Style/MultilineBlockChain:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
Style/SpecialGlobalVars:
|
Style/SpecialGlobalVars:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
Style/FrozenStringLiteralComment:
|
||||||
|
Enabled: false
|
||||||
|
|
|
@ -7,8 +7,6 @@ rvm:
|
||||||
- ruby-head
|
- ruby-head
|
||||||
- 2.3.1
|
- 2.3.1
|
||||||
- 2.2.4
|
- 2.2.4
|
||||||
- 2.1
|
|
||||||
- 2.0
|
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
# - osx
|
# - osx
|
||||||
|
|
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,6 +1,18 @@
|
||||||
master
|
master
|
||||||
===
|
===
|
||||||
|
|
||||||
|
# 4.1.13
|
||||||
|
|
||||||
|
* Change how config options are passed to Thor. Removes new Thor warnings from #2017
|
||||||
|
|
||||||
|
# 4.1.12
|
||||||
|
|
||||||
|
* Fix broken `ignore { |p| true }` form.
|
||||||
|
|
||||||
|
# 4.1.11
|
||||||
|
|
||||||
|
* Upgrade to Rack 2.
|
||||||
|
|
||||||
# 4.1.10
|
# 4.1.10
|
||||||
|
|
||||||
* Fix unicode issues in URL deeplinks.
|
* Fix unicode issues in URL deeplinks.
|
||||||
|
|
10
Gemfile
10
Gemfile
|
@ -9,6 +9,12 @@ gem 'byebug'
|
||||||
gem 'aruba', '~> 0.7.4', require: false
|
gem 'aruba', '~> 0.7.4', require: false
|
||||||
gem 'rspec', '~> 3.0', require: false
|
gem 'rspec', '~> 3.0', require: false
|
||||||
gem 'cucumber', '~> 2.0', require: false
|
gem 'cucumber', '~> 2.0', require: false
|
||||||
|
gem 'addressable', '~> 2.4.0', require: false
|
||||||
|
|
||||||
|
# Pry tools
|
||||||
|
gem 'pry'
|
||||||
|
gem 'pry-stack_explorer'
|
||||||
|
gem 'pry-rescue'
|
||||||
|
|
||||||
# Optional middleman dependencies, included for tests
|
# Optional middleman dependencies, included for tests
|
||||||
gem 'haml', '>= 4.0.5', require: false
|
gem 'haml', '>= 4.0.5', require: false
|
||||||
|
@ -18,7 +24,7 @@ gem 'kramdown', '~> 1.2', require: false
|
||||||
gem 'slim', '>= 2.0', require: false
|
gem 'slim', '>= 2.0', require: false
|
||||||
gem 'liquid', '>= 2.6', require: false
|
gem 'liquid', '>= 2.6', require: false
|
||||||
gem 'stylus', '>= 1.0', require: false
|
gem 'stylus', '>= 1.0', require: false
|
||||||
gem 'sinatra', '>= 1.4', require: false
|
gem 'sinatra', '>= 2.0.0.beta2', require: false
|
||||||
gem 'redcarpet', '>= 3.1', require: false
|
gem 'redcarpet', '>= 3.1', require: false
|
||||||
|
|
||||||
# Dns server to test preview server
|
# Dns server to test preview server
|
||||||
|
@ -26,7 +32,7 @@ gem 'rubydns', '~> 1.0.1', require: false
|
||||||
|
|
||||||
# To test javascript
|
# To test javascript
|
||||||
gem 'poltergeist', '~> 1.8', require: false
|
gem 'poltergeist', '~> 1.8', require: false
|
||||||
gem 'phantomjs', '~> 1.9.8.0', require: false
|
gem 'phantomjs', '~> 2.1.1.0', require: false
|
||||||
|
|
||||||
# For less, note there is no compatible JS runtime for windows
|
# For less, note there is no compatible JS runtime for windows
|
||||||
gem 'therubyrhino', '>= 2.0', platforms: :jruby
|
gem 'therubyrhino', '>= 2.0', platforms: :jruby
|
||||||
|
|
9
ISSUE_TEMPLATE.md
Normal file
9
ISSUE_TEMPLATE.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
## Expected behavior and actual behavior
|
||||||
|
|
||||||
|
## Steps to reproduce the problem (from a clean middleman installation)
|
||||||
|
|
||||||
|
## Additional information
|
||||||
|
|
||||||
|
- Ruby version:
|
||||||
|
- Middleman version:
|
||||||
|
- OS version:
|
|
@ -25,12 +25,10 @@ module Middleman::Cli
|
||||||
if setting.default.is_a?(String) || setting.default.is_a?(NilClass)
|
if setting.default.is_a?(String) || setting.default.is_a?(NilClass)
|
||||||
base.class_option setting.key,
|
base.class_option setting.key,
|
||||||
type: :string,
|
type: :string,
|
||||||
default: :undefined,
|
|
||||||
desc: setting.description
|
desc: setting.description
|
||||||
elsif setting.default.is_a?(TrueClass) || setting.default.is_a?(FalseClass)
|
elsif setting.default.is_a?(TrueClass) || setting.default.is_a?(FalseClass)
|
||||||
base.class_option setting.key,
|
base.class_option setting.key,
|
||||||
type: :boolean,
|
type: :boolean,
|
||||||
default: :undefined,
|
|
||||||
desc: setting.description
|
desc: setting.description
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,7 +29,7 @@ module Middleman::Cli
|
||||||
default: false,
|
default: false,
|
||||||
desc: 'Print debug messages'
|
desc: 'Print debug messages'
|
||||||
class_option :instrument,
|
class_option :instrument,
|
||||||
type: :string,
|
type: :boolean,
|
||||||
default: false,
|
default: false,
|
||||||
desc: 'Print instrument messages'
|
desc: 'Print instrument messages'
|
||||||
class_option :profile,
|
class_option :profile,
|
||||||
|
@ -64,7 +64,7 @@ module Middleman::Cli
|
||||||
config[:mode] = :build
|
config[:mode] = :build
|
||||||
config[:show_exceptions] = false
|
config[:show_exceptions] = false
|
||||||
config[:cli_options] = cli_options.each_with_object({}) do |(k, v), sum|
|
config[:cli_options] = cli_options.each_with_object({}) do |(k, v), sum|
|
||||||
sum[k] = v unless v == :undefined
|
sum[k] = v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ module Middleman::Cli
|
||||||
default: false,
|
default: false,
|
||||||
desc: 'Print debug messages'
|
desc: 'Print debug messages'
|
||||||
class_option :instrument,
|
class_option :instrument,
|
||||||
type: :string,
|
type: :boolean,
|
||||||
default: false,
|
default: false,
|
||||||
desc: 'Print instrument messages'
|
desc: 'Print instrument messages'
|
||||||
class_option :profile,
|
class_option :profile,
|
||||||
|
|
|
@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
||||||
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0")
|
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0")
|
||||||
s.executable = 'middleman'
|
s.executable = 'middleman'
|
||||||
s.require_path = 'lib'
|
s.require_path = 'lib'
|
||||||
s.required_ruby_version = '>= 2.0.0'
|
s.required_ruby_version = '>= 2.2.0'
|
||||||
|
|
||||||
# CLI
|
# CLI
|
||||||
s.add_dependency('thor', ['>= 0.17.0', '< 2.0'])
|
s.add_dependency('thor', ['>= 0.17.0', '< 2.0'])
|
||||||
|
|
|
@ -25,7 +25,8 @@ Feature: Alternate between multiple asset hosts
|
||||||
And a file named "config.rb" with:
|
And a file named "config.rb" with:
|
||||||
"""
|
"""
|
||||||
activate :asset_host, host: Proc.new { |asset|
|
activate :asset_host, host: Proc.new { |asset|
|
||||||
"http://assets%d.example.com" % (asset.hash % 4)
|
hash = Digest::MD5.digest(asset).bytes.map!(&:ord).reduce(&:+)
|
||||||
|
"http://assets%d.example.com" % (hash % 4)
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
And the Server is running
|
And the Server is running
|
||||||
|
|
|
@ -3,14 +3,60 @@ Feature: Page IDs
|
||||||
Scenario: link_to works with blocks (erb)
|
Scenario: link_to works with blocks (erb)
|
||||||
Given the Server is running at "page-id-app"
|
Given the Server is running at "page-id-app"
|
||||||
When I go to "/index.html"
|
When I go to "/index.html"
|
||||||
Then I should see "I am: index.html"
|
Then I should see "I am: index"
|
||||||
And I should see "URL1: /fm.html"
|
And I should see "URL1: /fm.html"
|
||||||
And I should see "URL2: /2.html"
|
And I should see "URL2: /2.html"
|
||||||
And I should see 'URL3: <a href="/3.html">Hi</a>'
|
And I should see 'URL3: <a href="/3.html">Hi</a>'
|
||||||
And I should see 'URL4: <a href="/overwrites/from-default.html">Sym</a>'
|
And I should see 'URL4: <a href="/overwrites/from-default.html">Sym</a>'
|
||||||
|
And I should see 'URL5: <a href="/implicit.html">Imp</a>'
|
||||||
|
And I should see 'URL6: <a href="/folder/foldern.html">Foldern</a>'
|
||||||
|
And I should see 'URL7: <a href="/feed.xml">Feed</a>'
|
||||||
|
|
||||||
When I go to "/fm.html"
|
When I go to "/fm.html"
|
||||||
Then I should see "I am: frontmatter"
|
Then I should see "I am: frontmatter"
|
||||||
|
When I go to "/implicit.html"
|
||||||
|
Then I should see "I am: implicit"
|
||||||
|
When I go to "/feed.xml"
|
||||||
|
Then I should see "I am: feed.xml"
|
||||||
|
When I go to "/folder/foldern.html"
|
||||||
|
Then I should see "I am: folder/foldern"
|
||||||
|
|
||||||
|
When I go to "/1.html"
|
||||||
|
Then I should see "I am: page1"
|
||||||
|
When I go to "/2.html"
|
||||||
|
Then I should see "I am: page2"
|
||||||
|
When I go to "/3.html"
|
||||||
|
Then I should see "I am: page3"
|
||||||
|
|
||||||
|
When I go to "/overwrites/from-default.html"
|
||||||
|
Then I should see "I am: something-else"
|
||||||
|
|
||||||
|
When I go to "/overwrites/from-frontmatter.html"
|
||||||
|
Then I should see "I am: from_frontmatter"
|
||||||
|
|
||||||
|
Scenario: Override page ID derivation with a proc
|
||||||
|
Given a fixture app "page-id-app"
|
||||||
|
And app "page-id-app" is using config "proc"
|
||||||
|
And the Server is running at "page-id-app"
|
||||||
|
|
||||||
|
When I go to "/index.html"
|
||||||
|
Then I should see "I am: index.html-foo"
|
||||||
|
And I should see "URL1: /fm.html"
|
||||||
|
And I should see "URL2: /2.html"
|
||||||
|
And I should see 'URL3: <a href="/3.html">Hi</a>'
|
||||||
|
And I should see 'URL4: <a href="/overwrites/from-default.html">Sym</a>'
|
||||||
|
And I should see 'URL8: <a href="/implicit.html">Imp</a>'
|
||||||
|
And I should see 'URL9: <a href="/folder/foldern.html">Foldern</a>'
|
||||||
|
And I should see 'URL10: <a href="/feed.xml">Feed</a>'
|
||||||
|
|
||||||
|
When I go to "/fm.html"
|
||||||
|
Then I should see "I am: frontmatter"
|
||||||
|
When I go to "/implicit.html"
|
||||||
|
Then I should see "I am: implicit.html-foo"
|
||||||
|
When I go to "/feed.xml"
|
||||||
|
Then I should see "I am: feed.xml-foo"
|
||||||
|
When I go to "/folder/foldern.html"
|
||||||
|
Then I should see "I am: folder/foldern.html-foo"
|
||||||
|
|
||||||
When I go to "/1.html"
|
When I go to "/1.html"
|
||||||
Then I should see "I am: page1"
|
Then I should see "I am: page1"
|
||||||
|
|
7
middleman-core/fixtures/page-id-app/config-proc.rb
Normal file
7
middleman-core/fixtures/page-id-app/config-proc.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
%w(1 2 3).each do |n|
|
||||||
|
proxy "/#{n}.html", "/index.html", id: "page#{n}"
|
||||||
|
end
|
||||||
|
|
||||||
|
page "/overwrites/*", id: :"something-else"
|
||||||
|
|
||||||
|
config[:page_id_generator] = ->(path){ path + "-foo" }
|
1
middleman-core/fixtures/page-id-app/source/feed.xml.erb
Normal file
1
middleman-core/fixtures/page-id-app/source/feed.xml.erb
Normal file
|
@ -0,0 +1 @@
|
||||||
|
I am: <%= current_resource.page_id %>
|
|
@ -0,0 +1 @@
|
||||||
|
I am: <%= current_resource.page_id %>
|
|
@ -0,0 +1 @@
|
||||||
|
I am: <%= current_resource.page_id %>
|
|
@ -4,3 +4,11 @@ URL1: <%= url_for "frontmatter" %>
|
||||||
URL2: <%= url_for "page2" %>
|
URL2: <%= url_for "page2" %>
|
||||||
URL3: <%= link_to "Hi", "page3" %>
|
URL3: <%= link_to "Hi", "page3" %>
|
||||||
URL4: <%= link_to "Sym", :"something-else" %>
|
URL4: <%= link_to "Sym", :"something-else" %>
|
||||||
|
URL5: <%= link_to "Imp", :implicit %>
|
||||||
|
URL6: <%= link_to "Foldern", "folder/foldern" %>
|
||||||
|
URL7: <%= link_to "Feed", "feed.xml" %>
|
||||||
|
|
||||||
|
<%# If custom proc %>
|
||||||
|
URL8: <%= link_to "Imp", "implicit.html-foo" %>
|
||||||
|
URL9: <%= link_to "Foldern", "folder/foldern.html-foo" %>
|
||||||
|
URL10: <%= link_to "Feed", "feed.xml-foo" %>
|
||||||
|
|
|
@ -203,6 +203,7 @@ module Middleman
|
||||||
define_setting :watcher_disable, false, 'If the Listen watcher should not run'
|
define_setting :watcher_disable, false, 'If the Listen watcher should not run'
|
||||||
define_setting :watcher_force_polling, false, 'If the Listen watcher should run in polling mode'
|
define_setting :watcher_force_polling, false, 'If the Listen watcher should run in polling mode'
|
||||||
define_setting :watcher_latency, nil, 'The Listen watcher latency'
|
define_setting :watcher_latency, nil, 'The Listen watcher latency'
|
||||||
|
define_setting :watcher_wait_for_delay, 0.5, 'The Listen watcher delay between calls when changes exist'
|
||||||
|
|
||||||
# Delegate convenience methods off to their implementations
|
# Delegate convenience methods off to their implementations
|
||||||
def_delegator :"::Middleman::Logger", :singleton, :logger
|
def_delegator :"::Middleman::Logger", :singleton, :logger
|
||||||
|
@ -344,11 +345,11 @@ module Middleman
|
||||||
|
|
||||||
# Clean up missing Tilt exts
|
# Clean up missing Tilt exts
|
||||||
def prune_tilt_templates!
|
def prune_tilt_templates!
|
||||||
::Tilt.mappings.each_key do |key|
|
::Tilt.default_mapping.lazy_map.each_key do |key|
|
||||||
begin
|
begin
|
||||||
::Tilt[".#{key}"]
|
::Tilt[".#{key}"]
|
||||||
rescue LoadError, NameError
|
rescue LoadError, NameError
|
||||||
::Tilt.mappings.delete(key)
|
::Tilt.default_mapping.lazy_map.delete(key)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,10 +28,7 @@ module Middleman
|
||||||
super
|
super
|
||||||
|
|
||||||
# Setup source collection.
|
# Setup source collection.
|
||||||
@sources = ::Middleman::Sources.new(app,
|
@sources = ::Middleman::Sources.new(app)
|
||||||
disable_watcher: app.config[:watcher_disable],
|
|
||||||
force_polling: app.config[:watcher_force_polling],
|
|
||||||
latency: app.config[:watcher_latency])
|
|
||||||
|
|
||||||
# Add default ignores.
|
# Add default ignores.
|
||||||
IGNORES.each do |key, value|
|
IGNORES.each do |key, value|
|
||||||
|
@ -55,6 +52,13 @@ module Middleman
|
||||||
# @return [void]
|
# @return [void]
|
||||||
Contract Any
|
Contract Any
|
||||||
def after_configuration
|
def after_configuration
|
||||||
|
@watcher.update_config(
|
||||||
|
disable_watcher: app.config[:watcher_disable],
|
||||||
|
force_polling: app.config[:watcher_force_polling],
|
||||||
|
latency: app.config[:watcher_latency],
|
||||||
|
wait_for_delay: app.config[:watcher_wait_for_delay]
|
||||||
|
)
|
||||||
|
|
||||||
if @original_source_dir != app.config[:source]
|
if @original_source_dir != app.config[:source]
|
||||||
@watcher.update_path(app.config[:source])
|
@watcher.update_path(app.config[:source])
|
||||||
end
|
end
|
||||||
|
|
|
@ -72,7 +72,7 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
|
||||||
end
|
end
|
||||||
|
|
||||||
if minified
|
if minified
|
||||||
headers['Content-Length'] = ::Rack::Utils.bytesize(minified).to_s
|
headers['Content-Length'] = minified.bytesize.to_s
|
||||||
response = [minified]
|
response = [minified]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension
|
||||||
end
|
end
|
||||||
|
|
||||||
if minified
|
if minified
|
||||||
headers['Content-Length'] = ::Rack::Utils.bytesize(minified).to_s
|
headers['Content-Length'] = minified.bytesize.to_s
|
||||||
response = [minified]
|
response = [minified]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@ require 'active_support/core_ext/string/output_safety'
|
||||||
require 'active_support/core_ext/module/delegation'
|
require 'active_support/core_ext/module/delegation'
|
||||||
require 'middleman-core/contracts'
|
require 'middleman-core/contracts'
|
||||||
|
|
||||||
::Tilt.mappings.delete('html') # WTF, Tilt?
|
::Tilt.default_mapping.lazy_map.delete('html')
|
||||||
::Tilt.mappings.delete('csv')
|
::Tilt.default_mapping.lazy_map.delete('csv')
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
class FileRenderer
|
class FileRenderer
|
||||||
|
@ -123,8 +123,8 @@ module Middleman
|
||||||
# Find all the engines which handle this extension in tilt. Look for
|
# Find all the engines which handle this extension in tilt. Look for
|
||||||
# config variables of that name and merge it
|
# config variables of that name and merge it
|
||||||
extension_class = ::Middleman::Util.tilt_class(ext)
|
extension_class = ::Middleman::Util.tilt_class(ext)
|
||||||
::Tilt.mappings.each do |mapping_ext, engines|
|
|
||||||
next unless engines.include? extension_class
|
::Tilt.default_mapping.extensions_for(extension_class).each do |mapping_ext|
|
||||||
engine_options = @app.config[mapping_ext.to_sym] || {}
|
engine_options = @app.config[mapping_ext.to_sym] || {}
|
||||||
options.merge!(engine_options)
|
options.merge!(engine_options)
|
||||||
end
|
end
|
||||||
|
|
|
@ -143,7 +143,7 @@ module Middleman
|
||||||
|
|
||||||
app = ::Middleman::Application.new do
|
app = ::Middleman::Application.new do
|
||||||
config[:cli_options] = cli_options.each_with_object({}) do |(k, v), sum|
|
config[:cli_options] = cli_options.each_with_object({}) do |(k, v), sum|
|
||||||
sum[k] = v unless v == :undefined
|
sum[k] = v
|
||||||
end
|
end
|
||||||
|
|
||||||
ready do
|
ready do
|
||||||
|
@ -160,6 +160,9 @@ module Middleman
|
||||||
path: root,
|
path: root,
|
||||||
only: match_against
|
only: match_against
|
||||||
|
|
||||||
|
# Hack around bower_components in root.
|
||||||
|
watcher.listener.ignore(/^bower_components/)
|
||||||
|
|
||||||
# Hack around node_modules in root.
|
# Hack around node_modules in root.
|
||||||
watcher.listener.ignore(/^node_modules/)
|
watcher.listener.ignore(/^node_modules/)
|
||||||
|
|
||||||
|
@ -204,7 +207,7 @@ module Middleman
|
||||||
end
|
end
|
||||||
|
|
||||||
def possible_from_cli(key, config)
|
def possible_from_cli(key, config)
|
||||||
if @cli_options[key] && @cli_options[key] != :undefined
|
if @cli_options[key]
|
||||||
@cli_options[key]
|
@cli_options[key]
|
||||||
else
|
else
|
||||||
config[key]
|
config[key]
|
||||||
|
|
|
@ -134,8 +134,14 @@ module Middleman
|
||||||
# Immediately send static file
|
# Immediately send static file
|
||||||
def send_file(resource, env)
|
def send_file(resource, env)
|
||||||
file = ::Rack::File.new nil
|
file = ::Rack::File.new nil
|
||||||
file.path = resource.file_descriptor[:full_path]
|
path = resource.file_descriptor[:full_path]
|
||||||
|
if !file.respond_to?(:path=)
|
||||||
|
request = ::Rack::Request.new(env)
|
||||||
|
response = file.serving(request, path)
|
||||||
|
else
|
||||||
|
file.path = path
|
||||||
response = file.serving(env)
|
response = file.serving(env)
|
||||||
|
end
|
||||||
status = response[0]
|
status = response[0]
|
||||||
response[1]['Content-Encoding'] = 'gzip' if %w(.svgz .gz).include?(resource.ext)
|
response[1]['Content-Encoding'] = 'gzip' if %w(.svgz .gz).include?(resource.ext)
|
||||||
# Do not set Content-Type if status is 1xx, 204, 205 or 304, otherwise
|
# Do not set Content-Type if status is 1xx, 204, 205 or 304, otherwise
|
||||||
|
|
|
@ -3,7 +3,7 @@ require 'active_support/core_ext/module/attribute_accessors'
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
module Renderers
|
module Renderers
|
||||||
class RedcarpetTemplate < ::Tilt::RedcarpetTemplate::Redcarpet2
|
class RedcarpetTemplate < ::Tilt::RedcarpetTemplate
|
||||||
# because tilt has decided to convert these
|
# because tilt has decided to convert these
|
||||||
# in the wrong direction
|
# in the wrong direction
|
||||||
ALIASES = {
|
ALIASES = {
|
||||||
|
|
|
@ -14,16 +14,31 @@ module Middleman
|
||||||
Contract Or[String, Regexp, Proc] => RespondTo[:execute_descriptor]
|
Contract Or[String, Regexp, Proc] => RespondTo[:execute_descriptor]
|
||||||
def ignore(path=nil, &block)
|
def ignore(path=nil, &block)
|
||||||
@app.sitemap.invalidate_resources_not_ignored_cache!
|
@app.sitemap.invalidate_resources_not_ignored_cache!
|
||||||
|
|
||||||
|
if path.is_a? Regexp
|
||||||
|
RegexpIgnoreDescriptor.new(path)
|
||||||
|
elsif path.is_a? String
|
||||||
|
path_clean = ::Middleman::Util.normalize_path(path)
|
||||||
|
|
||||||
|
if path_clean.include?('*') # It's a glob
|
||||||
|
GlobIgnoreDescriptor.new(path_clean)
|
||||||
|
else
|
||||||
|
StringIgnoreDescriptor.new(path_clean)
|
||||||
|
end
|
||||||
|
elsif block
|
||||||
|
BlockIgnoreDescriptor.new(nil, block)
|
||||||
|
else
|
||||||
IgnoreDescriptor.new(path, block)
|
IgnoreDescriptor.new(path, block)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
IgnoreDescriptor = Struct.new(:path, :block) do
|
IgnoreDescriptor = Struct.new(:path, :block) do
|
||||||
def execute_descriptor(_app, resources)
|
def execute_descriptor(_app, resources)
|
||||||
resources.map do |r|
|
resources.map do |r|
|
||||||
# Ignore based on the source path (without template extensions)
|
# Ignore based on the source path (without template extensions)
|
||||||
if ignored?(r.path)
|
if ignored?(r.normalized_path)
|
||||||
r.ignore!
|
r.ignore!
|
||||||
elsif !r.is_a?(ProxyResource) && r.file_descriptor && ignored?(r.file_descriptor[:relative_path].to_s)
|
elsif !r.is_a?(ProxyResource) && r.file_descriptor && ignored?(r.file_descriptor.normalized_relative_path)
|
||||||
# This allows files to be ignored by their source file name (with template extensions)
|
# This allows files to be ignored by their source file name (with template extensions)
|
||||||
r.ignore!
|
r.ignore!
|
||||||
end
|
end
|
||||||
|
@ -33,27 +48,38 @@ module Middleman
|
||||||
end
|
end
|
||||||
|
|
||||||
def ignored?(match_path)
|
def ignored?(match_path)
|
||||||
match_path = ::Middleman::Util.normalize_path(match_path)
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if path.is_a? Regexp
|
class RegexpIgnoreDescriptor < IgnoreDescriptor
|
||||||
|
def ignored?(match_path)
|
||||||
match_path =~ path
|
match_path =~ path
|
||||||
elsif path.is_a? String
|
end
|
||||||
path_clean = ::Middleman::Util.normalize_path(path)
|
end
|
||||||
|
|
||||||
if path_clean.include?('*') # It's a glob
|
class GlobIgnoreDescriptor < IgnoreDescriptor
|
||||||
|
def ignored?(match_path)
|
||||||
if defined?(::File::FNM_EXTGLOB)
|
if defined?(::File::FNM_EXTGLOB)
|
||||||
::File.fnmatch(path_clean, match_path, ::File::FNM_EXTGLOB)
|
::File.fnmatch(path, match_path, ::File::FNM_EXTGLOB)
|
||||||
else
|
else
|
||||||
::File.fnmatch(path_clean, match_path)
|
::File.fnmatch(path, match_path)
|
||||||
end
|
end
|
||||||
else
|
|
||||||
match_path == path_clean
|
|
||||||
end
|
end
|
||||||
elsif block
|
end
|
||||||
|
|
||||||
|
class StringIgnoreDescriptor < IgnoreDescriptor
|
||||||
|
def ignored?(match_path)
|
||||||
|
match_path == path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class BlockIgnoreDescriptor < IgnoreDescriptor
|
||||||
|
def ignored?(match_path)
|
||||||
block.call(match_path)
|
block.call(match_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -47,7 +47,7 @@ module Middleman
|
||||||
)
|
)
|
||||||
|
|
||||||
if should_ignore
|
if should_ignore
|
||||||
d = ::Middleman::Sitemap::Extensions::Ignores::IgnoreDescriptor.new(target)
|
d = ::Middleman::Sitemap::Extensions::Ignores::StringIgnoreDescriptor.new(target)
|
||||||
d.execute_descriptor(app, resources)
|
d.execute_descriptor(app, resources)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ module Middleman
|
||||||
|
|
||||||
Contract Or[Symbol, String, Fixnum]
|
Contract Or[Symbol, String, Fixnum]
|
||||||
def page_id
|
def page_id
|
||||||
metadata[:page][:id] || destination_path
|
metadata[:page][:id] || make_implicit_page_id(destination_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Merge in new metadata specific to this resource.
|
# Merge in new metadata specific to this resource.
|
||||||
|
@ -197,10 +197,41 @@ module Middleman
|
||||||
options[:content_type] || ::Rack::Mime.mime_type(ext, nil)
|
options[:content_type] || ::Rack::Mime.mime_type(ext, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The normalized source path of this resource (relative to the source directory,
|
||||||
|
# without template extensions)
|
||||||
|
# @return [String]
|
||||||
|
def normalized_path
|
||||||
|
@normalized_path ||= ::Middleman::Util.normalize_path @path
|
||||||
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
"#<#{self.class} path=#{@path}>"
|
"#<#{self.class} path=#{@path}>"
|
||||||
end
|
end
|
||||||
alias inspect to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s
|
alias inspect to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
# Makes a page id based on path (when not otherwise given)
|
||||||
|
#
|
||||||
|
# Removes .html extension and potential leading slashes or dots
|
||||||
|
# eg. "foo/bar/baz.foo.html" => "foo/bar/baz.foo"
|
||||||
|
Contract String => String
|
||||||
|
def make_implicit_page_id(path)
|
||||||
|
@id ||= begin
|
||||||
|
if prok = @app.config[:page_id_generator]
|
||||||
|
return prok.call(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
basename = if ext == ".html"
|
||||||
|
File.basename(path, ext)
|
||||||
|
else
|
||||||
|
File.basename(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Remove leading dot or slash if present
|
||||||
|
File.join(File.dirname(path), basename).gsub(/^\.?\//, '')
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class StringResource < Resource
|
class StringResource < Resource
|
||||||
|
|
|
@ -8,6 +8,10 @@ module Middleman
|
||||||
::Middleman::Sources.file_cache[full_path] ||= {}
|
::Middleman::Sources.file_cache[full_path] ||= {}
|
||||||
::Middleman::Sources.file_cache[full_path][version] ||= ::File.read(full_path)
|
::Middleman::Sources.file_cache[full_path][version] ||= ::File.read(full_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def normalized_relative_path
|
||||||
|
@normalized_relative_path ||= ::Middleman::Util.normalize_path relative_path.to_s
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sources handle multiple on-disk collections of files which make up
|
# Sources handle multiple on-disk collections of files which make up
|
||||||
|
@ -52,15 +56,13 @@ module Middleman
|
||||||
# @param [Hash] options Global options.
|
# @param [Hash] options Global options.
|
||||||
# @param [Array] watchers Default watchers.
|
# @param [Array] watchers Default watchers.
|
||||||
Contract IsA['Middleman::Application'], Maybe[Hash], Maybe[Array] => Any
|
Contract IsA['Middleman::Application'], Maybe[Hash], Maybe[Array] => Any
|
||||||
def initialize(app, options={}, watchers=[])
|
def initialize(app, _options={}, watchers=[])
|
||||||
@app = app
|
@app = app
|
||||||
@watchers = watchers
|
@watchers = watchers
|
||||||
@sorted_watchers = @watchers.dup.freeze
|
@sorted_watchers = @watchers.dup.freeze
|
||||||
|
|
||||||
::Middleman::Sources.file_cache = {}
|
::Middleman::Sources.file_cache = {}
|
||||||
|
|
||||||
@options = options
|
|
||||||
|
|
||||||
# Set of procs wanting to be notified of changes
|
# Set of procs wanting to be notified of changes
|
||||||
@on_change_callbacks = ::Hamster::Vector.empty
|
@on_change_callbacks = ::Hamster::Vector.empty
|
||||||
|
|
||||||
|
@ -168,7 +170,7 @@ module Middleman
|
||||||
# @return [Middleman::Sources]
|
# @return [Middleman::Sources]
|
||||||
Contract Symbol => ::Middleman::Sources
|
Contract Symbol => ::Middleman::Sources
|
||||||
def by_type(type)
|
def by_type(type)
|
||||||
self.class.new @app, @options, watchers.select { |d| d.type == type }
|
self.class.new @app, nil, watchers.select { |d| d.type == type }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get all files for this collection of watchers.
|
# Get all files for this collection of watchers.
|
||||||
|
|
|
@ -75,9 +75,10 @@ module Middleman
|
||||||
@ignored = options.fetch(:ignored, proc { false })
|
@ignored = options.fetch(:ignored, proc { false })
|
||||||
@only = Array(options.fetch(:only, []))
|
@only = Array(options.fetch(:only, []))
|
||||||
|
|
||||||
@disable_watcher = app.build? || @parent.options.fetch(:disable_watcher, false)
|
@disable_watcher = app.build?
|
||||||
@force_polling = @parent.options.fetch(:force_polling, false)
|
@force_polling = false
|
||||||
@latency = @parent.options.fetch(:latency, nil)
|
@latency = nil
|
||||||
|
@wait_for_delay = nil
|
||||||
|
|
||||||
@listener = nil
|
@listener = nil
|
||||||
|
|
||||||
|
@ -95,13 +96,20 @@ module Middleman
|
||||||
def update_path(directory)
|
def update_path(directory)
|
||||||
@directory = Pathname(File.expand_path(directory, app.root))
|
@directory = Pathname(File.expand_path(directory, app.root))
|
||||||
|
|
||||||
stop_listener! if @listener
|
without_listener_running do
|
||||||
|
|
||||||
update([], @files.values.map { |source_file| source_file[:full_path] })
|
update([], @files.values.map { |source_file| source_file[:full_path] })
|
||||||
|
end
|
||||||
|
|
||||||
poll_once!
|
poll_once!
|
||||||
|
end
|
||||||
|
|
||||||
listen! unless @disable_watcher
|
def update_config(options={})
|
||||||
|
without_listener_running do
|
||||||
|
@disable_watcher = options.fetch(:disable_watcher, false)
|
||||||
|
@force_polling = options.fetch(:force_polling, false)
|
||||||
|
@latency = options.fetch(:latency, nil)
|
||||||
|
@wait_for_delay = options.fetch(:wait_for_delay, nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Stop watching.
|
# Stop watching.
|
||||||
|
@ -160,10 +168,10 @@ module Middleman
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
force_polling: @force_polling,
|
force_polling: @force_polling,
|
||||||
wait_for_delay: 0.5
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config[:latency] = @latency.to_i if @latency
|
config[:wait_for_delay] = @wait_for_delay.try(:to_f) || 0.5
|
||||||
|
config[:latency] = @latency.to_f if @latency
|
||||||
|
|
||||||
@listener = ::Listen.to(@directory.to_s, config, &method(:on_listener_change))
|
@listener = ::Listen.to(@directory.to_s, config, &method(:on_listener_change))
|
||||||
|
|
||||||
|
@ -199,7 +207,7 @@ module Middleman
|
||||||
Contract ArrayOf[Pathname]
|
Contract ArrayOf[Pathname]
|
||||||
def poll_once!
|
def poll_once!
|
||||||
updated = ::Middleman::Util.all_files_under(@directory.to_s, &method(:should_not_recurse?))
|
updated = ::Middleman::Util.all_files_under(@directory.to_s, &method(:should_not_recurse?))
|
||||||
removed = @files.keys.reject { |p| updated.include?(p) }
|
removed = @files.keys - updated
|
||||||
|
|
||||||
result = update(updated, removed)
|
result = update(updated, removed)
|
||||||
|
|
||||||
|
@ -343,5 +351,20 @@ module Middleman
|
||||||
@only.any? { |reg| file[:relative_path].to_s =~ reg }
|
@only.any? { |reg| file[:relative_path].to_s =~ reg }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def without_listener_running
|
||||||
|
listener_running = @listener && @listener.processing?
|
||||||
|
|
||||||
|
stop_listener! if listener_running
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
if listener_running
|
||||||
|
poll_once!
|
||||||
|
listen!
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -64,9 +64,7 @@ module Middleman
|
||||||
extension_class = ::Middleman::Util.tilt_class(options[:preferred_engine])
|
extension_class = ::Middleman::Util.tilt_class(options[:preferred_engine])
|
||||||
|
|
||||||
# Get a list of extensions for a preferred engine
|
# Get a list of extensions for a preferred engine
|
||||||
preferred_engines += ::Tilt.mappings.select do |_, engines|
|
preferred_engines += ::Tilt.default_mapping.extensions_for(extension_class)
|
||||||
engines.include? extension_class
|
|
||||||
end.keys
|
|
||||||
end
|
end
|
||||||
|
|
||||||
preferred_engines << '*'
|
preferred_engines << '*'
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# Core Pathname library used for traversal
|
# Core Pathname library used for traversal
|
||||||
require 'pathname'
|
require 'pathname'
|
||||||
require 'uri'
|
require 'uri'
|
||||||
require 'addressable'
|
require 'addressable/uri'
|
||||||
require 'memoist'
|
require 'memoist'
|
||||||
require 'tilt'
|
require 'tilt'
|
||||||
|
|
||||||
|
@ -152,7 +152,8 @@ module Middleman
|
||||||
def url_for(app, path_or_resource, options={})
|
def url_for(app, path_or_resource, options={})
|
||||||
if path_or_resource.is_a?(String) || path_or_resource.is_a?(Symbol)
|
if path_or_resource.is_a?(String) || path_or_resource.is_a?(Symbol)
|
||||||
r = app.sitemap.find_resource_by_page_id(path_or_resource)
|
r = app.sitemap.find_resource_by_page_id(path_or_resource)
|
||||||
path_or_resource = r if r
|
|
||||||
|
path_or_resource = r ? r : path_or_resource.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
# Handle Resources and other things which define their own url method
|
# Handle Resources and other things which define their own url method
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module Middleman
|
module Middleman
|
||||||
# Current Version
|
# Current Version
|
||||||
# @return [String]
|
# @return [String]
|
||||||
VERSION = '4.1.10'.freeze unless const_defined?(:VERSION)
|
VERSION = '4.1.14'.freeze unless const_defined?(:VERSION)
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,12 +16,12 @@ Gem::Specification.new do |s|
|
||||||
s.files = `git ls-files -z`.split("\0")
|
s.files = `git ls-files -z`.split("\0")
|
||||||
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0")
|
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0")
|
||||||
s.require_path = 'lib'
|
s.require_path = 'lib'
|
||||||
s.required_ruby_version = '>= 2.0.0'
|
s.required_ruby_version = '>= 2.2.0'
|
||||||
|
|
||||||
# Core
|
# Core
|
||||||
s.add_dependency('bundler', ['~> 1.1'])
|
s.add_dependency('bundler', ['~> 1.1'])
|
||||||
s.add_dependency('rack', ['>= 1.4.5', '< 2.0'])
|
s.add_dependency('rack', ['>= 1.4.5', '< 3'])
|
||||||
s.add_dependency('tilt', ['~> 1.4.1'])
|
s.add_dependency('tilt', ['~> 2.0'])
|
||||||
s.add_dependency('erubis')
|
s.add_dependency('erubis')
|
||||||
s.add_dependency('fast_blank')
|
s.add_dependency('fast_blank')
|
||||||
s.add_dependency('parallel')
|
s.add_dependency('parallel')
|
||||||
|
@ -29,7 +29,7 @@ Gem::Specification.new do |s|
|
||||||
s.add_dependency('dotenv')
|
s.add_dependency('dotenv')
|
||||||
|
|
||||||
# Helpers
|
# Helpers
|
||||||
s.add_dependency('activesupport', ['~> 4.2'])
|
s.add_dependency('activesupport', ['>= 4.2', '< 5.1'])
|
||||||
s.add_dependency('padrino-helpers', ['~> 0.13.0'])
|
s.add_dependency('padrino-helpers', ['~> 0.13.0'])
|
||||||
s.add_dependency("addressable", ["~> 2.3"])
|
s.add_dependency("addressable", ["~> 2.3"])
|
||||||
s.add_dependency('memoist', ['~> 0.14'])
|
s.add_dependency('memoist', ['~> 0.14'])
|
||||||
|
|
|
@ -220,7 +220,7 @@ describe Middleman::Util do
|
||||||
|
|
||||||
it "does not loop infinitely when file name is a possible templating engine" do
|
it "does not loop infinitely when file name is a possible templating engine" do
|
||||||
expect do
|
expect do
|
||||||
Timeout::timeout(0.5) do
|
Timeout::timeout(3.0) do
|
||||||
result = Middleman::Util.step_through_extensions("markdown.scss")
|
result = Middleman::Util.step_through_extensions("markdown.scss")
|
||||||
expect(result).to eq "markdown"
|
expect(result).to eq "markdown"
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,7 +16,7 @@ Gem::Specification.new do |s|
|
||||||
s.files = `git ls-files -z`.split("\0")
|
s.files = `git ls-files -z`.split("\0")
|
||||||
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0")
|
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0")
|
||||||
s.require_path = 'lib'
|
s.require_path = 'lib'
|
||||||
s.required_ruby_version = '>= 2.0.0'
|
s.required_ruby_version = '>= 2.2.0'
|
||||||
|
|
||||||
s.add_dependency('middleman-core', Middleman::VERSION)
|
s.add_dependency('middleman-core', Middleman::VERSION)
|
||||||
s.add_dependency('middleman-cli', Middleman::VERSION)
|
s.add_dependency('middleman-cli', Middleman::VERSION)
|
||||||
|
|
Loading…
Reference in a new issue