lib/nanoc3/base/item_rep.rb in nanoc3-3.1.0a3 vs lib/nanoc3/base/item_rep.rb in nanoc3-3.1.0b1
- old
+ new
@@ -28,10 +28,14 @@
# @return [Boolean] true if this rep is forced to be dirty (e.g. because
# of the `--force` commandline option); false otherwise
attr_accessor :force_outdated
+ # @return [Boolean] true if this rep is currently binary; false otherwise
+ attr_reader :binary
+ alias_method :binary?, :binary
+
# @return [Boolean] true if this rep’s output file has changed since the
# last time it was compiled; false otherwise
attr_accessor :modified
alias_method :modified?, :modified
@@ -68,25 +72,30 @@
# belong.
#
# @param [Symbol] name The unique name for the new item representation.
def initialize(item, name)
# Set primary attributes
- @item = item
- @name = name
+ @item = item
+ @name = name
+ # Set binary
+ @binary = @item.binary?
+
# Initialize content and filenames
- if @item.binary?
+ if self.binary?
@filenames = {
:raw => @item.raw_filename,
:last => @item.raw_filename
}
+ @content = {}
else
@content = {
:raw => @item.raw_content,
:last => @item.raw_content,
:pre => @item.raw_content
}
+ @filenames = {}
end
@old_content = nil
# Reset flags
@compiled = false
@@ -137,11 +146,11 @@
end
# @return [Hash] The assignments that should be available when compiling
# the content.
def assigns
- if item.binary?
+ if self.binary?
content_or_filename_assigns = { :filename => @filenames[:last] }
else
content_or_filename_assigns = { :content => @content[:last] }
end
@@ -163,16 +172,10 @@
# any).
#
# @return [String] The compiled content at the given snapshot (or the
# default snapshot if no snapshot is specified)
def compiled_content(params={})
- # Check whether content can be fetched
- # TODO get proper exception
- if @item.binary?
- raise RuntimeError, "attempted to fetch compiled content from a binary item"
- end
-
# Notify
Nanoc3::NotificationCenter.post(:visit_started, self.item)
Nanoc3::NotificationCenter.post(:visit_ended, self.item)
# Debug
@@ -211,34 +214,44 @@
# @param [Hash] filter_args The filter arguments that should be passed to
# the filter's #run method
#
# @return [void]
def filter(filter_name, filter_args={})
- # Create filter
- klass = Nanoc3::Filter.named(filter_name)
+ # Get filter class
+ klass = filter_named(filter_name)
raise Nanoc3::Errors::UnknownFilter.new(filter_name) if klass.nil?
- filter = klass.new(assigns)
# Check whether filter can be applied
- if klass.binary? && !item.binary?
+ if klass.from_binary? && !self.binary?
raise Nanoc3::Errors::CannotUseBinaryFilter.new(self, klass)
- elsif !klass.binary? && item.binary?
+ elsif !klass.from_binary? && self.binary?
raise Nanoc3::Errors::CannotUseTextualFilter.new(self, klass)
end
+ # Create filter
+ filter = klass.new(assigns)
+
# Run filter
Nanoc3::NotificationCenter.post(:filtering_started, self, filter_name)
- if item.binary?
- filter.run(@filenames[:last], filter_args)
+ source = self.binary? ? @filenames[:last] : @content[:last]
+ result = filter.run(source, filter_args)
+ if klass.to_binary?
@filenames[:last] = filter.output_filename
else
- @content[:last] = filter.run(@content[:last], filter_args)
+ @content[:last] = result
end
+ @binary = klass.to_binary?
Nanoc3::NotificationCenter.post(:filtering_ended, self, filter_name)
+ # Check whether file was written
+ if self.binary? && !File.file?(filter.output_filename)
+ raise RuntimeError,
+ "The #{filter_name.inspect} filter did not write anything to the required output file, #{filter.output_filename}."
+ end
+
# Create snapshot
- snapshot(@content[:post] ? :post : :pre) unless item.binary?
+ snapshot(@content[:post] ? :post : :pre) unless self.binary?
end
# Lays out the item using the given layout. This method will replace the
# content of the `:last` snapshot with the laid out content of the last
# snapshot.
@@ -250,11 +263,11 @@
# should be laid out with
#
# @return [void]
def layout(layout_identifier)
# Check whether item can be laid out
- raise Nanoc3::Errors::CannotLayoutBinaryItem.new(self) if item.binary?
+ raise Nanoc3::Errors::CannotLayoutBinaryItem.new(self) if self.binary?
# Create "pre" snapshot
snapshot(:pre) unless @content[:pre]
# Create filter
@@ -276,11 +289,11 @@
#
# @param [Symbol] snapshot_name The name of the snapshot to create
#
# @return [void]
def snapshot(snapshot_name)
- target = @item.binary? ? @filenames : @content
+ target = self.binary? ? @filenames : @content
target[snapshot_name] = target[:last]
end
# Writes the item rep's compiled content to the rep's output file.
#
@@ -293,11 +306,11 @@
FileUtils.mkdir_p(File.dirname(self.raw_path))
# Check if file will be created
@created = !File.file?(self.raw_path)
- if @item.binary?
+ if self.binary?
# Calculate hash of old content
if File.file?(self.raw_path)
hash_old = hash(self.raw_path)
size_old = File.size(self.raw_path)
end
@@ -333,26 +346,30 @@
# content in `diff(1)` format, or nil if there is no previous compiled
# content
def diff
# Check if content can be diffed
# TODO allow binary diffs
- return nil if @item.binary?
+ return nil if self.binary?
# Check if old content exists
if @old_content.nil? or self.raw_path.nil?
nil
else
diff_strings(@old_content, @content[:last])
end
end
def inspect
- "<#{self.class}:0x#{self.object_id.to_s(16)} name=#{self.name} item.identifier=#{self.item.identifier} item.binary?=#{@item.binary?}>"
+ "<#{self.class}:0x#{self.object_id.to_s(16)} name=#{self.name} binary=#{self.binary?} item.identifier=#{self.item.identifier}>"
end
private
+ def filter_named(name)
+ Nanoc3::Filter.named(name)
+ end
+
def layout_with_identifier(layout_identifier)
layout ||= @item.site.layouts.find { |l| l.identifier == layout_identifier.cleaned_identifier }
raise Nanoc3::Errors::UnknownLayout.new(layout_identifier) if layout.nil?
layout
end
@@ -380,20 +397,21 @@
require 'tempfile'
require 'open3'
# Create files
- old_file = Tempfile.new('old')
- new_file = Tempfile.new('new')
+ Tempfile.open('old') do |old_file|
+ Tempfile.open('new') do |new_file|
+ # Write files
+ old_file.write(a)
+ new_file.write(b)
- # Write files
- old_file.write(a)
- new_file.write(b)
-
- # Diff
- stdin, stdout, stderr = Open3.popen3('diff', '-u', old_file.path, new_file.path)
- result = stdout.read
- result == '' ? nil : result
+ # Diff
+ stdin, stdout, stderr = Open3.popen3('diff', '-u', old_file.path, new_file.path)
+ result = stdout.read
+ result == '' ? nil : result
+ end
+ end
rescue Errno::ENOENT
warn 'Failed to run `diff`, so no diff with the previously compiled ' \
'content will be available.'
nil
end