Generic related files check
This commit is contained in:
parent
a546e0f523
commit
16b997498b
|
@ -61,3 +61,5 @@ Style/ParallelAssignment:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
Style/BlockDelimiters:
|
Style/BlockDelimiters:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
Style/MultilineBlockChain:
|
||||||
|
Enabled: false
|
||||||
|
|
1
Gemfile
1
Gemfile
|
@ -7,6 +7,7 @@ gem 'yard', '~> 0.8', require: false
|
||||||
# Test tools
|
# Test tools
|
||||||
gem 'pry', '~> 0.10', group: :development, require: false
|
gem 'pry', '~> 0.10', group: :development, require: false
|
||||||
gem 'pry-byebug'
|
gem 'pry-byebug'
|
||||||
|
gem 'pry-stack_explorer'
|
||||||
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
|
||||||
|
|
0
middleman-core/fixtures/related-files-app/config.rb
Normal file
0
middleman-core/fixtures/related-files-app/config.rb
Normal file
|
@ -180,7 +180,7 @@ module Middleman
|
||||||
Contract String => String
|
Contract String => String
|
||||||
def extensionless_path(file)
|
def extensionless_path(file)
|
||||||
path = file.dup
|
path = file.dup
|
||||||
remove_templating_extensions(path)
|
::Middleman::Util.remove_templating_extensions(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Actually update the resource list, assuming anything has called
|
# Actually update the resource list, assuming anything has called
|
||||||
|
@ -224,16 +224,6 @@ module Middleman
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Removes the templating extensions, while keeping the others
|
|
||||||
# @param [String] path
|
|
||||||
# @return [String]
|
|
||||||
Contract String => String
|
|
||||||
def remove_templating_extensions(path)
|
|
||||||
# Strip templating extensions as long as Tilt knows them
|
|
||||||
path = path.sub(/#{::Regexp.escape(File.extname(path))}$/, '') while ::Tilt[path]
|
|
||||||
path
|
|
||||||
end
|
|
||||||
|
|
||||||
# Remove the locale token from the end of the path
|
# Remove the locale token from the end of the path
|
||||||
# @param [String] path
|
# @param [String] path
|
||||||
# @return [String]
|
# @return [String]
|
||||||
|
|
|
@ -225,15 +225,23 @@ module Middleman
|
||||||
# @return [void]
|
# @return [void]
|
||||||
Contract ArrayOf[Pathname], ArrayOf[Pathname] => Any
|
Contract ArrayOf[Pathname], ArrayOf[Pathname] => Any
|
||||||
def update(updated_paths, removed_paths)
|
def update(updated_paths, removed_paths)
|
||||||
valid_updates = (updated_paths | find_related_files(updated_paths + removed_paths))
|
valid_updates = updated_paths
|
||||||
.lazy
|
.map { |p| ::Middleman::Util.path_to_source_file(p, @directory, @type) }
|
||||||
.map(&method(:path_to_source_file))
|
|
||||||
.select(&method(:valid?))
|
.select(&method(:valid?))
|
||||||
.to_a
|
|
||||||
.each do |f|
|
valid_updates.each do |f|
|
||||||
add_file_to_cache(f)
|
add_file_to_cache(f)
|
||||||
logger.debug "== Change (#{f[:types].inspect}): #{f[:relative_path]}"
|
logger.debug "== Change (#{f[:types].inspect}): #{f[:relative_path]}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
related_updates = ::Middleman::Util.find_related_files(app, (updated_paths + removed_paths)).select(&method(:valid?))
|
||||||
|
|
||||||
|
related_updates.each do |f|
|
||||||
|
add_file_to_cache(f)
|
||||||
|
logger.debug "== Possible Change (#{f[:types].inspect}): #{f[:relative_path]}"
|
||||||
|
end
|
||||||
|
|
||||||
|
valid_updates |= related_updates
|
||||||
|
|
||||||
valid_removes = removed_paths
|
valid_removes = removed_paths
|
||||||
.lazy
|
.lazy
|
||||||
|
@ -283,35 +291,5 @@ module Middleman
|
||||||
@only.any? { |reg| reg.match(file[:relative_path].to_s) }
|
@only.any? { |reg| reg.match(file[:relative_path].to_s) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Convert a path to a file resprentation.
|
|
||||||
#
|
|
||||||
# @param [Pathname] path The path.
|
|
||||||
# @return [Middleman::SourceFile]
|
|
||||||
Contract Pathname => IsA['Middleman::SourceFile']
|
|
||||||
def path_to_source_file(path)
|
|
||||||
types = Set.new([@type])
|
|
||||||
|
|
||||||
relative_path = path.relative_path_from(@directory)
|
|
||||||
destination_dir = @options.fetch(:destination_dir, false)
|
|
||||||
relative_path = File.join(destination_dir, relative_path) if destination_dir
|
|
||||||
|
|
||||||
::Middleman::SourceFile.new(Pathname(relative_path), path, @directory, types)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Finds files which should also be considered to be dirty when
|
|
||||||
# the given file(s) are touched.
|
|
||||||
#
|
|
||||||
# @param [Pathname] files The original touched file paths.
|
|
||||||
# @return [Pathname] All related file paths, not including the source file paths.
|
|
||||||
Contract ArrayOf[Pathname] => ArrayOf[Pathname]
|
|
||||||
def find_related_files(files)
|
|
||||||
files.flat_map do |file|
|
|
||||||
# If any partial file changes, reload all non-partials
|
|
||||||
if File.basename(file).start_with?('_')
|
|
||||||
Dir[File.join(@directory, app.config[:source], "**/[^_]*.#{File.extname(file)}")].map { |p| Pathname(p) }
|
|
||||||
end
|
|
||||||
end.compact.uniq - files
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -430,6 +430,95 @@ module Middleman
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Contract String => String
|
||||||
|
def step_through_extensions(path)
|
||||||
|
while ::Tilt[path]
|
||||||
|
yield File.extname(path) if block_given?
|
||||||
|
|
||||||
|
# Strip templating extensions as long as Tilt knows them
|
||||||
|
path = path.sub(/#{::Regexp.escape(File.extname(path))}$/, '')
|
||||||
|
end
|
||||||
|
|
||||||
|
yield File.extname(path) if block_given?
|
||||||
|
|
||||||
|
path
|
||||||
|
end
|
||||||
|
|
||||||
|
# Removes the templating extensions, while keeping the others
|
||||||
|
# @param [String] path
|
||||||
|
# @return [String]
|
||||||
|
Contract String => String
|
||||||
|
def remove_templating_extensions(path)
|
||||||
|
step_through_extensions(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Removes the templating extensions, while keeping the others
|
||||||
|
# @param [String] path
|
||||||
|
# @return [String]
|
||||||
|
Contract String => ArrayOf[String]
|
||||||
|
def collect_extensions(path)
|
||||||
|
result = []
|
||||||
|
|
||||||
|
step_through_extensions(path) { |e| result << e }
|
||||||
|
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
# Convert a path to a file resprentation.
|
||||||
|
#
|
||||||
|
# @param [Pathname] path The path.
|
||||||
|
# @return [Middleman::SourceFile]
|
||||||
|
Contract Pathname, Pathname, Symbol => IsA['Middleman::SourceFile']
|
||||||
|
def path_to_source_file(path, directory, type)
|
||||||
|
types = Set.new([type])
|
||||||
|
|
||||||
|
relative_path = path.relative_path_from(directory)
|
||||||
|
# destination_dir = @options.fetch(:destination_dir, false)
|
||||||
|
# relative_path = File.join(destination_dir, relative_path) if destination_dir
|
||||||
|
|
||||||
|
::Middleman::SourceFile.new(Pathname(relative_path), path, directory, types)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Finds files which should also be considered to be dirty when
|
||||||
|
# the given file(s) are touched.
|
||||||
|
#
|
||||||
|
# @param [Middleman::Application] app The app.
|
||||||
|
# @param [Pathname] files The original touched file paths.
|
||||||
|
# @return [Middleman::SourceFile] All related file paths, not including the source file paths.
|
||||||
|
Contract IsA['Middleman::Application'], ArrayOf[Pathname] => ArrayOf[IsA['Middleman::SourceFile']]
|
||||||
|
def find_related_files(app, files)
|
||||||
|
all_extensions = files.flat_map { |f| collect_extensions(f.to_s) }
|
||||||
|
|
||||||
|
sass_type_aliasing = ['.scss', '.sass']
|
||||||
|
erb_type_aliasing = ['.erb', '.haml', '.slim']
|
||||||
|
|
||||||
|
if (all_extensions & sass_type_aliasing).length > 0
|
||||||
|
all_extensions |= sass_type_aliasing
|
||||||
|
end
|
||||||
|
|
||||||
|
if (all_extensions & erb_type_aliasing).length > 0
|
||||||
|
all_extensions |= erb_type_aliasing
|
||||||
|
end
|
||||||
|
|
||||||
|
all_extensions.uniq!
|
||||||
|
|
||||||
|
app.sitemap.resources.select { |r|
|
||||||
|
local_extensions = collect_extensions(r.file_descriptor[:relative_path].to_s)
|
||||||
|
|
||||||
|
if (local_extensions & sass_type_aliasing).length > 0
|
||||||
|
local_extensions |= sass_type_aliasing
|
||||||
|
end
|
||||||
|
|
||||||
|
if (local_extensions & erb_type_aliasing).length > 0
|
||||||
|
local_extensions |= erb_type_aliasing
|
||||||
|
end
|
||||||
|
|
||||||
|
local_extensions.uniq!
|
||||||
|
|
||||||
|
((all_extensions & local_extensions).length > 0) && files.none? { |f| f == r.file_descriptor[:full_path] }
|
||||||
|
}.map(&:file_descriptor)
|
||||||
|
end
|
||||||
|
|
||||||
# Handy methods for dealing with URI templates. Mix into whatever class.
|
# Handy methods for dealing with URI templates. Mix into whatever class.
|
||||||
module UriTemplates
|
module UriTemplates
|
||||||
module_function
|
module_function
|
||||||
|
|
|
@ -141,4 +141,44 @@ describe Middleman::Util do
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "::find_related_files" do
|
||||||
|
after(:each) do
|
||||||
|
Given.cleanup!
|
||||||
|
end
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
Given.fixture 'related-files-app'
|
||||||
|
@mm = Middleman::Application.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def source_file(path)
|
||||||
|
Pathname(File.expand_path("source/#{path}"))
|
||||||
|
end
|
||||||
|
|
||||||
|
it "Finds partials possibly related to ERb files" do
|
||||||
|
related = Middleman::Util.find_related_files(@mm, [source_file('partials/_test.erb')]).map { |f| f[:full_path].to_s }
|
||||||
|
expect(related).to include File.expand_path("source/index.html.erb")
|
||||||
|
|
||||||
|
related = Middleman::Util.find_related_files(@mm, [source_file('partials/_test2.haml')]).map { |f| f[:full_path].to_s }
|
||||||
|
expect(related).to include File.expand_path("source/index.html.erb")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "Finds partials possible related to Scss files" do
|
||||||
|
related = Middleman::Util.find_related_files(@mm, [source_file('stylesheets/_include4.scss')]).map { |f| f[:full_path].to_s }
|
||||||
|
expect(related).to include File.expand_path("source/stylesheets/site.css.scss")
|
||||||
|
expect(related).to include File.expand_path("source/stylesheets/include2.css.scss")
|
||||||
|
|
||||||
|
related = Middleman::Util.find_related_files(@mm, [source_file('stylesheets/include2.css.scss')]).map { |f| f[:full_path].to_s }
|
||||||
|
expect(related).to include File.expand_path("source/stylesheets/site.css.scss")
|
||||||
|
expect(related).not_to include File.expand_path("source/stylesheets/include2.css.scss")
|
||||||
|
|
||||||
|
related = Middleman::Util.find_related_files(@mm, [source_file('stylesheets/include1.css')]).map { |f| f[:full_path].to_s }
|
||||||
|
expect(related).to include File.expand_path("source/stylesheets/site.css.scss")
|
||||||
|
expect(related).to include File.expand_path("source/stylesheets/include2.css.scss")
|
||||||
|
|
||||||
|
related = Middleman::Util.find_related_files(@mm, [source_file('stylesheets/_include3.sass')]).map { |f| f[:full_path].to_s }
|
||||||
|
expect(related).to include File.expand_path("source/stylesheets/site.css.scss")
|
||||||
|
expect(related).to include File.expand_path("source/stylesheets/include2.css.scss")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue