Skip to content

Commit

Permalink
Merge pull request #301 from ddfreyne/bug-teardown-listeners-after-co…
Browse files Browse the repository at this point in the history
…mpile

Teardown listeners after compile
  • Loading branch information
bobthecow committed Apr 7, 2013
2 parents aaa3fff + 7d82b14 commit 112401c
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 26 deletions.
4 changes: 2 additions & 2 deletions lib/nanoc/cli/command_runner.rb
Expand Up @@ -64,15 +64,15 @@ def load_site
puts "done"
end

protected

# @return [Boolean] true if debug output is enabled, false if not
#
# @see Nanoc::CLI.debug?
def debug?
Nanoc::CLI.debug?
end

protected

# Sets the data source's VCS to the VCS with the given name. Does nothing
# when the site's data source does not support VCSes (i.e. does not
# implement #vcs=).
Expand Down
89 changes: 66 additions & 23 deletions lib/nanoc/cli/commands/compile.rb
Expand Up @@ -33,6 +33,18 @@ class Compile < ::Nanoc::CLI::CommandRunner
# @abstract Subclasses must override {#start} and may override {#stop}.
class Listener

def initialize(params={})
end

# @param [Nanoc::CLI::CommandRunner] command_runner The command runner for this listener
#
# @return [Boolean] true if this listener should be enabled for the given command runner, false otherwise
#
# @abstract Returns `true` by default, but subclasses may override this.
def self.enable_for?(command_runner)
true
end

# Starts the listener. Subclasses should override this method and set up listener notifications.
#
# @return [void]
Expand All @@ -53,6 +65,11 @@ def stop
# Generates diffs for every output file written
class DiffGenerator < Listener

# @see Listener#enable_for?
def self.enable_for?(command_runner)
command_runner.site.config[:enable_output_diff]
end

# @see Listener#start
def start
require 'tempfile'
Expand Down Expand Up @@ -138,6 +155,11 @@ def diff_strings(a, b)
# Records the time spent per filter and per item representation
class TimingRecorder < Listener

# @see Listener#enable_for?
def self.enable_for?(command_runner)
command_runner.options.fetch(:verbose, false)
end

# @option params [Array<Nanoc::ItemRep>] :reps The list of item representations in the site
def initialize(params={})
@filter_times = {}
Expand Down Expand Up @@ -205,7 +227,7 @@ def print_row(row)
tot = format('%5.2f', tot)

# Output stats
filter_name = format("%#{max_filter_name_length}s", filter_name)
filter_name = format("%#{max}s", filter_name)
puts "#{filter_name} | #{count} #{min}s #{avg}s #{max}s #{tot}s"
end

Expand All @@ -214,7 +236,12 @@ def print_row(row)
# Controls garbage collection so that it only occurs once every 20 items
class GCController < Listener

def initialize
# @see Listener#enable_for?
def self.enable_for?(command_runner)
! ENV.has_key?('TRAVIS')
end

def initialize(params={})
@gc_count = 0
end

Expand All @@ -241,6 +268,11 @@ def stop
# Prints debug information (compilation started/ended, filtering started/ended, …)
class DebugPrinter < Listener

# @see Listener#enable_for?
def self.enable_for?(command_runner)
command_runner.debug?
end

# @see Listener#start
def start
Nanoc::NotificationCenter.on(:compilation_started) do |rep|
Expand Down Expand Up @@ -315,15 +347,21 @@ def stop

end

def initialize(options, arguments, command, params={})
super(options, arguments, command)
@listener_classes = params.fetch(:listener_classes, self.default_listener_classes)
end

def run
self.load_site
self.check_for_deprecated_usage
self.setup_listeners

puts "Compiling site…"
time_before = Time.now
self.site.compile
self.prune
self.run_listeners_while do
self.site.compile
self.prune
end
time_after = Time.now
puts
puts "Site compiled in #{format('%.2f', time_after - time_before)}s."
Expand All @@ -337,28 +375,33 @@ def prune
end
end

def setup_listeners
@listeners = []

if self.site.config[:enable_output_diff]
@listeners << Nanoc::CLI::Commands::Compile::DiffGenerator.new
end

if self.debug?
@listeners << Nanoc::CLI::Commands::Compile::DebugPrinter.new
end
def default_listener_classes
[
Nanoc::CLI::Commands::Compile::DiffGenerator,
Nanoc::CLI::Commands::Compile::DebugPrinter,
Nanoc::CLI::Commands::Compile::TimingRecorder,
Nanoc::CLI::Commands::Compile::GCController,
Nanoc::CLI::Commands::Compile::FileActionPrinter
]
end

if options.fetch(:verbose, false)
@listeners << Nanoc::CLI::Commands::Compile::TimingRecorder.new(:reps => self.reps)
end
def setup_listeners
@listeners = @listener_classes.
select { |klass| klass.enable_for?(self) }.
map { |klass| klass.new(:reps => self.reps) }

unless ENV.has_key?('TRAVIS')
@listeners << Nanoc::CLI::Commands::Compile::GCController.new
end
@listeners.each { |s| s.start }
end

@listeners << Nanoc::CLI::Commands::Compile::FileActionPrinter.new(:reps => self.reps)
def listeners
@listeners
end

@listeners.each { |s| s.start }
def run_listeners_while
self.setup_listeners
yield
ensure
self.teardown_listeners
end

def teardown_listeners
Expand Down
28 changes: 27 additions & 1 deletion test/cli/commands/test_compile.rb
Expand Up @@ -111,7 +111,33 @@ def test_auto_prune_with_exclude
Nanoc::CLI.run %w( compile )
refute File.file?('output/stray.html')
assert File.directory?('output/excluded_dir'),
'excluded_dir should still be there'
'excluded_dir should still be there'
end
end

def test_setup_and_teardown_listeners
with_site do
test_listener_class = Class.new(::Nanoc::CLI::Commands::Compile::Listener) do
def start ; @started = true ; end
def stop ; @stopped = true ; end
def started? ; @started ; end
def stopped? ; @stopped ; end
end

options = {}
arguments = []
cmd = nil
listener_classes = [ test_listener_class ]
cmd_runner = Nanoc::CLI::Commands::Compile.new(
options, arguments, cmd, :listener_classes => listener_classes)

cmd_runner.run

listeners = cmd_runner.send(:listeners)
assert listeners.size == 1
assert listeners.first.started?
assert listeners.first.stopped?
end
end

end

0 comments on commit 112401c

Please sign in to comment.