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