nanoc 4.3.7 → 4.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +11 -0
  3. data/Gemfile +6 -6
  4. data/Gemfile.lock +32 -18
  5. data/NEWS.md +14 -0
  6. data/Rakefile +30 -1
  7. data/lib/nanoc.rb +3 -0
  8. data/lib/nanoc/base/checksummer.rb +28 -0
  9. data/lib/nanoc/base/compilation/compiler.rb +34 -20
  10. data/lib/nanoc/base/compilation/filter.rb +1 -1
  11. data/lib/nanoc/base/context.rb +5 -0
  12. data/lib/nanoc/base/entities/item_rep.rb +2 -13
  13. data/lib/nanoc/base/services.rb +1 -0
  14. data/lib/nanoc/base/services/compiler_loader.rb +2 -2
  15. data/lib/nanoc/{extra → base/services}/pruner.rb +56 -48
  16. data/lib/nanoc/checking.rb +11 -0
  17. data/lib/nanoc/{extra/checking → checking}/check.rb +3 -3
  18. data/lib/nanoc/checking/checks.rb +20 -0
  19. data/lib/nanoc/{extra/checking → checking}/checks/css.rb +2 -2
  20. data/lib/nanoc/{extra/checking → checking}/checks/external_links.rb +2 -2
  21. data/lib/nanoc/{extra/checking → checking}/checks/html.rb +2 -2
  22. data/lib/nanoc/{extra/checking → checking}/checks/internal_links.rb +2 -2
  23. data/lib/nanoc/{extra/checking → checking}/checks/mixed_content.rb +2 -2
  24. data/lib/nanoc/{extra/checking → checking}/checks/stale.rb +4 -3
  25. data/lib/nanoc/{extra/checking → checking}/checks/w3c_validator.rb +2 -2
  26. data/lib/nanoc/{extra/checking → checking}/dsl.rb +2 -2
  27. data/lib/nanoc/{extra/checking → checking}/issue.rb +1 -1
  28. data/lib/nanoc/{extra/checking → checking}/runner.rb +4 -4
  29. data/lib/nanoc/cli/cleaning_stream.rb +1 -1
  30. data/lib/nanoc/cli/commands/check.rb +1 -1
  31. data/lib/nanoc/cli/commands/compile.rb +62 -56
  32. data/lib/nanoc/cli/commands/deploy.rb +4 -4
  33. data/lib/nanoc/cli/commands/prune.rb +2 -2
  34. data/lib/nanoc/cli/commands/show-plugins.rb +4 -4
  35. data/lib/nanoc/data_sources/filesystem.rb +3 -1
  36. data/lib/nanoc/{extra/filesystem_tools.rb → data_sources/filesystem/tools.rb} +20 -15
  37. data/lib/nanoc/deploying.rb +8 -0
  38. data/lib/nanoc/{extra → deploying}/deployer.rb +2 -2
  39. data/lib/nanoc/deploying/deployers.rb +10 -0
  40. data/lib/nanoc/{extra → deploying}/deployers/fog.rb +3 -3
  41. data/lib/nanoc/{extra → deploying}/deployers/rsync.rb +3 -3
  42. data/lib/nanoc/extra.rb +9 -5
  43. data/lib/nanoc/filters/colorize_syntax.rb +15 -4
  44. data/lib/nanoc/filters/rdoc.rb +0 -5
  45. data/lib/nanoc/helpers/capturing.rb +2 -1
  46. data/lib/nanoc/rule_dsl/recording_executor.rb +7 -1
  47. data/lib/nanoc/spec.rb +10 -34
  48. data/lib/nanoc/version.rb +1 -1
  49. data/nanoc.gemspec +2 -1
  50. data/test/base/test_context.rb +6 -0
  51. data/test/base/test_dependency_tracker.rb +0 -18
  52. data/test/base/test_item_rep.rb +2 -2
  53. data/test/{extra/checking → checking}/checks/test_css.rb +4 -4
  54. data/test/{extra/checking → checking}/checks/test_external_links.rb +8 -8
  55. data/test/{extra/checking → checking}/checks/test_html.rb +3 -3
  56. data/test/{extra/checking → checking}/checks/test_internal_links.rb +9 -9
  57. data/test/{extra/checking → checking}/checks/test_mixed_content.rb +9 -9
  58. data/test/{extra/checking → checking}/checks/test_stale.rb +3 -3
  59. data/test/{extra/checking → checking}/test_check.rb +4 -4
  60. data/test/{extra/checking → checking}/test_dsl.rb +5 -5
  61. data/test/{extra/checking → checking}/test_runner.rb +4 -4
  62. data/test/data_sources/test_filesystem.rb +0 -18
  63. data/test/{extra → data_sources}/test_filesystem_tools.rb +13 -13
  64. data/test/{extra/deployers → deploying}/test_fog.rb +8 -8
  65. data/test/{extra/deployers → deploying}/test_rsync.rb +7 -7
  66. data/test/filters/{test_colorize_syntax.rb → colorize_syntax/test_coderay.rb} +1 -177
  67. data/test/filters/colorize_syntax/test_common.rb +81 -0
  68. data/test/filters/colorize_syntax/test_pygmentize.rb +35 -0
  69. data/test/filters/colorize_syntax/test_pygments.rb +17 -0
  70. data/test/filters/colorize_syntax/test_simon.rb +20 -0
  71. data/test/filters/test_less.rb +0 -55
  72. metadata +55 -43
  73. data/ChangeLog +0 -3
  74. data/doc/yardoc_handlers/identifier.rb +0 -30
  75. data/doc/yardoc_templates/default/layout/html/footer.erb +0 -19
  76. data/lib/nanoc/extra/checking.rb +0 -11
  77. data/lib/nanoc/extra/checking/checks.rb +0 -20
  78. data/lib/nanoc/extra/deployers.rb +0 -10
  79. data/tasks/doc.rake +0 -16
  80. data/tasks/rubocop.rake +0 -6
  81. data/tasks/test.rake +0 -25
  82. data/test/base/temp_filename_factory_spec.rb +0 -66
@@ -6,4 +6,5 @@ require_relative 'services/item_rep_router'
6
6
  require_relative 'services/item_rep_selector'
7
7
  require_relative 'services/item_rep_writer'
8
8
  require_relative 'services/notification_center'
9
+ require_relative 'services/pruner'
9
10
  require_relative 'services/temp_filename_factory'
@@ -1,7 +1,7 @@
1
1
  module Nanoc::Int
2
2
  # @api private
3
3
  class CompilerLoader
4
- def load(site)
4
+ def load(site, action_provider: nil)
5
5
  rule_memory_store = Nanoc::Int::RuleMemoryStore.new(env_name: site.config.env_name)
6
6
 
7
7
  dependency_store =
@@ -12,7 +12,7 @@ module Nanoc::Int
12
12
 
13
13
  item_rep_repo = Nanoc::Int::ItemRepRepo.new
14
14
 
15
- action_provider = Nanoc::Int::ActionProvider.named(:rule_dsl).for(site)
15
+ action_provider ||= Nanoc::Int::ActionProvider.named(:rule_dsl).for(site)
16
16
 
17
17
  outdatedness_checker =
18
18
  Nanoc::Int::OutdatednessChecker.new(
@@ -1,21 +1,23 @@
1
- module Nanoc::Extra
1
+ require 'find'
2
+
3
+ module Nanoc
2
4
  # Responsible for finding and deleting files in the site’s output directory
3
5
  # that are not managed by Nanoc.
4
6
  #
5
7
  # @api private
6
8
  class Pruner
7
- # @return [Nanoc::Int::Site] The site this pruner belongs to
8
- attr_reader :site
9
-
10
- # @param [Nanoc::Int::Site] site The site for which a pruner is created
9
+ # @param [Nanoc::Int::Configuration] config
10
+ #
11
+ # @param [Nanoc::Int::ItemRepRepo] reps
11
12
  #
12
13
  # @param [Boolean] dry_run true if the files to be deleted
13
14
  # should only be printed instead of actually deleted, false if the files
14
15
  # should actually be deleted.
15
16
  #
16
17
  # @param [Enumerable<String>] exclude
17
- def initialize(site, dry_run: false, exclude: [])
18
- @site = site
18
+ def initialize(config, reps, dry_run: false, exclude: [])
19
+ @config = config
20
+ @reps = reps
19
21
  @dry_run = dry_run
20
22
  @exclude = Set.new(exclude)
21
23
  end
@@ -24,19 +26,49 @@ module Nanoc::Extra
24
26
  #
25
27
  # @return [void]
26
28
  def run
27
- require 'find'
29
+ return unless File.directory?(@config[:output_dir])
30
+
31
+ compiled_files = @reps.flat_map { |r| r.raw_paths.values }.compact
32
+ present_files, present_dirs = files_and_dirs_in(@config[:output_dir] + '/')
28
33
 
29
- return unless File.directory?(site.config[:output_dir])
34
+ remove_stray_files(present_files, compiled_files)
35
+ remove_empty_directories(present_dirs)
36
+ end
37
+
38
+ def exclude?(component)
39
+ @exclude.include?(component)
40
+ end
30
41
 
31
- # Get compiled files
32
- # FIXME: requires #build_reps to have been called
33
- all_raw_paths = site.compiler.reps.flat_map { |r| r.raw_paths.values }
34
- compiled_files = all_raw_paths.flatten.compact.select { |f| File.file?(f) }
42
+ # @param [String] filename The filename to check
43
+ #
44
+ # @return [Boolean] true if the given file is excluded, false otherwise
45
+ def filename_excluded?(filename)
46
+ pathname = Pathname.new(filename)
47
+ @exclude.any? { |e| pathname.__nanoc_include_component?(e) }
48
+ end
49
+
50
+ # @api private
51
+ def remove_stray_files(present_files, compiled_files)
52
+ (present_files - compiled_files).each do |f|
53
+ delete_file(f) unless exclude?(f)
54
+ end
55
+ end
56
+
57
+ # @api private
58
+ def remove_empty_directories(present_dirs)
59
+ present_dirs.reverse_each do |dir|
60
+ next if Dir.foreach(dir) { |n| break true if n !~ /\A\.\.?\z/ }
61
+ next if exclude?(dir)
62
+ delete_dir(dir)
63
+ end
64
+ end
35
65
 
36
- # Get present files and dirs
66
+ # @api private
67
+ def files_and_dirs_in(dir)
37
68
  present_files = []
38
69
  present_dirs = []
39
- Find.find(site.config[:output_dir] + '/') do |f|
70
+
71
+ Find.find(dir) do |f|
40
72
  basename = File.basename(f)
41
73
 
42
74
  case File.ftype(f)
@@ -53,49 +85,25 @@ module Nanoc::Extra
53
85
  end
54
86
  end
55
87
 
56
- # Remove stray files
57
- stray_files = (present_files - compiled_files)
58
- stray_files.each do |f|
59
- delete_file(f) unless exclude?(f)
60
- end
61
-
62
- # Remove empty directories
63
- present_dirs.reverse_each do |dir|
64
- next if Dir.foreach(dir) { |n| break true if n !~ /\A\.\.?\z/ }
65
- next if exclude?(dir)
66
- delete_dir(dir)
67
- end
68
- end
69
-
70
- def exclude?(component)
71
- @exclude.include?(component)
72
- end
73
-
74
- # @param [String] filename The filename to check
75
- #
76
- # @return [Boolean] true if the given file is excluded, false otherwise
77
- def filename_excluded?(filename)
78
- pathname = Pathname.new(filename)
79
- @exclude.any? { |e| pathname.__nanoc_include_component?(e) }
88
+ [present_files, present_dirs]
80
89
  end
81
90
 
82
91
  protected
83
92
 
84
93
  def delete_file(file)
85
- if @dry_run
86
- puts file
87
- else
88
- Nanoc::CLI::Logger.instance.file(:high, :delete, file)
89
- FileUtils.rm(file)
90
- end
94
+ log_delete_and_run(file) { FileUtils.rm(file) }
91
95
  end
92
96
 
93
97
  def delete_dir(dir)
98
+ log_delete_and_run(dir) { Dir.rmdir(dir) }
99
+ end
100
+
101
+ def log_delete_and_run(thing)
94
102
  if @dry_run
95
- puts dir
103
+ puts thing
96
104
  else
97
- Nanoc::CLI::Logger.instance.file(:high, :delete, dir)
98
- Dir.rmdir(dir)
105
+ Nanoc::CLI::Logger.instance.file(:high, :delete, thing)
106
+ yield
99
107
  end
100
108
  end
101
109
  end
@@ -0,0 +1,11 @@
1
+ module Nanoc
2
+ # @api private
3
+ module Checking
4
+ autoload 'Check', 'nanoc/checking/check'
5
+ autoload 'DSL', 'nanoc/checking/dsl'
6
+ autoload 'Runner', 'nanoc/checking/runner.rb'
7
+ autoload 'Issue', 'nanoc/checking/issue'
8
+ end
9
+ end
10
+
11
+ require 'nanoc/checking/checks'
@@ -1,4 +1,4 @@
1
- module Nanoc::Extra::Checking
1
+ module Nanoc::Checking
2
2
  # @api private
3
3
  class OutputDirNotFoundError < Nanoc::Int::Errors::Generic
4
4
  def initialize(directory_path)
@@ -15,7 +15,7 @@ module Nanoc::Extra::Checking
15
15
  def self.create(site)
16
16
  output_dir = site.config[:output_dir]
17
17
  unless File.exist?(output_dir)
18
- raise Nanoc::Extra::Checking::OutputDirNotFoundError.new(output_dir)
18
+ raise Nanoc::Checking::OutputDirNotFoundError.new(output_dir)
19
19
  end
20
20
  output_filenames = Dir[output_dir + '/**/*'].select { |f| File.file?(f) }
21
21
 
@@ -39,7 +39,7 @@ module Nanoc::Extra::Checking
39
39
  end
40
40
 
41
41
  def run
42
- raise NotImplementedError.new('Nanoc::Extra::Checking::Check subclasses must implement #run')
42
+ raise NotImplementedError.new('Nanoc::Checking::Check subclasses must implement #run')
43
43
  end
44
44
 
45
45
  def add_issue(desc, subject: nil)
@@ -0,0 +1,20 @@
1
+ require_relative 'checks/w3c_validator'
2
+
3
+ # @api private
4
+ module Nanoc::Checking::Checks
5
+ autoload 'CSS', 'nanoc/checking/checks/css'
6
+ autoload 'ExternalLinks', 'nanoc/checking/checks/external_links'
7
+ autoload 'HTML', 'nanoc/checking/checks/html'
8
+ autoload 'InternalLinks', 'nanoc/checking/checks/internal_links'
9
+ autoload 'Stale', 'nanoc/checking/checks/stale'
10
+ autoload 'MixedContent', 'nanoc/checking/checks/mixed_content'
11
+
12
+ Nanoc::Checking::Check.register '::Nanoc::Checking::Checks::CSS', :css
13
+ Nanoc::Checking::Check.register '::Nanoc::Checking::Checks::ExternalLinks', :external_links
14
+ Nanoc::Checking::Check.register '::Nanoc::Checking::Checks::ExternalLinks', :elinks
15
+ Nanoc::Checking::Check.register '::Nanoc::Checking::Checks::HTML', :html
16
+ Nanoc::Checking::Check.register '::Nanoc::Checking::Checks::InternalLinks', :internal_links
17
+ Nanoc::Checking::Check.register '::Nanoc::Checking::Checks::InternalLinks', :ilinks
18
+ Nanoc::Checking::Check.register '::Nanoc::Checking::Checks::Stale', :stale
19
+ Nanoc::Checking::Check.register '::Nanoc::Checking::Checks::MixedContent', :mixed_content
20
+ end
@@ -1,6 +1,6 @@
1
- module ::Nanoc::Extra::Checking::Checks
1
+ module ::Nanoc::Checking::Checks
2
2
  # @api private
3
- class CSS < ::Nanoc::Extra::Checking::Checks::W3CValidator
3
+ class CSS < ::Nanoc::Checking::Checks::W3CValidator
4
4
  identifier :css
5
5
 
6
6
  def extension
@@ -4,11 +4,11 @@ require 'nokogiri'
4
4
  require 'timeout'
5
5
  require 'uri'
6
6
 
7
- module ::Nanoc::Extra::Checking::Checks
7
+ module ::Nanoc::Checking::Checks
8
8
  # A validator that verifies that all external links point to a location that exists.
9
9
  #
10
10
  # @api private
11
- class ExternalLinks < ::Nanoc::Extra::Checking::Check
11
+ class ExternalLinks < ::Nanoc::Checking::Check
12
12
  identifiers :external_links, :elinks
13
13
 
14
14
  def run
@@ -1,6 +1,6 @@
1
- module ::Nanoc::Extra::Checking::Checks
1
+ module ::Nanoc::Checking::Checks
2
2
  # @api private
3
- class HTML < ::Nanoc::Extra::Checking::Checks::W3CValidator
3
+ class HTML < ::Nanoc::Checking::Checks::W3CValidator
4
4
  identifier :html
5
5
 
6
6
  def extension
@@ -1,10 +1,10 @@
1
1
  require 'uri'
2
2
 
3
- module Nanoc::Extra::Checking::Checks
3
+ module Nanoc::Checking::Checks
4
4
  # A check that verifies that all internal links point to a location that exists.
5
5
  #
6
6
  # @api private
7
- class InternalLinks < ::Nanoc::Extra::Checking::Check
7
+ class InternalLinks < ::Nanoc::Checking::Check
8
8
  # Starts the validator. The results will be printed to stdout.
9
9
  #
10
10
  # Internal links that match a regexp pattern in `@config[:checks][:internal_links][:exclude]` will
@@ -1,9 +1,9 @@
1
- module Nanoc::Extra::Checking::Checks
1
+ module Nanoc::Checking::Checks
2
2
  # A check that verifies HTML files do not reference external resources with
3
3
  # URLs that would trigger "mixed content" warnings.
4
4
  #
5
5
  # @api private
6
- class MixedContent < ::Nanoc::Extra::Checking::Check
6
+ class MixedContent < ::Nanoc::Checking::Check
7
7
  PROTOCOL_PATTERN = /^(\w+):\/\//
8
8
 
9
9
  def run
@@ -1,6 +1,6 @@
1
- module Nanoc::Extra::Checking::Checks
1
+ module Nanoc::Checking::Checks
2
2
  # @api private
3
- class Stale < ::Nanoc::Extra::Checking::Check
3
+ class Stale < ::Nanoc::Checking::Check
4
4
  def run
5
5
  require 'set'
6
6
 
@@ -30,7 +30,8 @@ module Nanoc::Extra::Checking::Checks
30
30
 
31
31
  def pruner
32
32
  exclude_config = @config.fetch(:prune, {}).fetch(:exclude, [])
33
- @pruner ||= Nanoc::Extra::Pruner.new(@site, exclude: exclude_config)
33
+ # FIXME: reps=nil is icky
34
+ @pruner ||= Nanoc::Pruner.new(@config, nil, exclude: exclude_config)
34
35
  end
35
36
  end
36
37
  end
@@ -1,6 +1,6 @@
1
- module ::Nanoc::Extra::Checking::Checks
1
+ module ::Nanoc::Checking::Checks
2
2
  # @api private
3
- class W3CValidator < ::Nanoc::Extra::Checking::Check
3
+ class W3CValidator < ::Nanoc::Checking::Check
4
4
  def run
5
5
  require 'w3c_validators'
6
6
 
@@ -1,4 +1,4 @@
1
- module Nanoc::Extra::Checking
1
+ module Nanoc::Checking
2
2
  # @api private
3
3
  class DSL
4
4
  attr_reader :deploy_checks
@@ -15,7 +15,7 @@ module Nanoc::Extra::Checking
15
15
  end
16
16
 
17
17
  def check(identifier, &block)
18
- klass = Class.new(::Nanoc::Extra::Checking::Check)
18
+ klass = Class.new(::Nanoc::Checking::Check)
19
19
  klass.send(:define_method, :run, &block)
20
20
  klass.send(:identifier, identifier)
21
21
  end
@@ -1,4 +1,4 @@
1
- module Nanoc::Extra::Checking
1
+ module Nanoc::Checking
2
2
  # @api private
3
3
  class Issue
4
4
  attr_reader :description
@@ -1,4 +1,4 @@
1
- module Nanoc::Extra::Checking
1
+ module Nanoc::Checking
2
2
  # Runner is reponsible for running issue checks.
3
3
  #
4
4
  # @api private
@@ -67,7 +67,7 @@ module Nanoc::Extra::Checking
67
67
  unless @dsl_loaded
68
68
  @dsl =
69
69
  if dsl_present?
70
- Nanoc::Extra::Checking::DSL.from_file(checks_filename)
70
+ Nanoc::Checking::DSL.from_file(checks_filename)
71
71
  else
72
72
  nil
73
73
  end
@@ -93,12 +93,12 @@ module Nanoc::Extra::Checking
93
93
  end
94
94
 
95
95
  def all_check_classes
96
- Nanoc::Extra::Checking::Check.all.map(&:last).uniq
96
+ Nanoc::Checking::Check.all.map(&:last).uniq
97
97
  end
98
98
 
99
99
  def check_classes_named(n)
100
100
  n.map do |a|
101
- klass = Nanoc::Extra::Checking::Check.named(a)
101
+ klass = Nanoc::Checking::Check.named(a)
102
102
  raise Nanoc::Int::Errors::GenericTrivial, "Unknown check: #{a}" if klass.nil?
103
103
  klass
104
104
  end
@@ -145,7 +145,7 @@ module Nanoc::CLI
145
145
  protected
146
146
 
147
147
  def _nanoc_clean(s)
148
- @stream_cleaners.reduce(s.to_s) { |a, e| e.clean(a) }
148
+ @stream_cleaners.reduce(s.to_s) { |acc, elem| elem.clean(acc) }
149
149
  end
150
150
 
151
151
  def _nanoc_swallow_broken_pipe_errors_while
@@ -14,7 +14,7 @@ module Nanoc::CLI::Commands
14
14
  validate_options_and_arguments
15
15
  load_site(preprocess: true)
16
16
 
17
- runner = Nanoc::Extra::Checking::Runner.new(site)
17
+ runner = Nanoc::Checking::Runner.new(site)
18
18
 
19
19
  if options[:list]
20
20
  runner.list_checks
@@ -164,19 +164,55 @@ module Nanoc::CLI::Commands
164
164
 
165
165
  # @param [Enumerable<Nanoc::Int::ItemRep>] reps
166
166
  def initialize(reps:)
167
- @times = {}
167
+ # rep ->
168
+ # filter_name ->
169
+ # accum -> 0.0
170
+ # last_start -> nil
171
+ @times_per_rep = {}
168
172
 
169
173
  @reps = reps
170
174
  end
171
175
 
172
176
  # @see Listener#start
173
177
  def start
174
- Nanoc::Int::NotificationCenter.on(:filtering_started) do |_rep, filter_name|
175
- @times[filter_name] ||= []
176
- @times[filter_name] << { start: Time.now }
178
+ Nanoc::Int::NotificationCenter.on(:filtering_started) do |rep, filter_name|
179
+ @times_per_rep[rep] ||= {}
180
+ @times_per_rep[rep][filter_name] ||= {}
181
+
182
+ @times_per_rep[rep][filter_name][:last_start] = Time.now
183
+ @times_per_rep[rep][filter_name][:accum] ||= []
184
+ @times_per_rep[rep][filter_name][:suspended] = false
185
+ end
186
+
187
+ Nanoc::Int::NotificationCenter.on(:filtering_ended) do |rep, filter_name|
188
+ times = @times_per_rep[rep][filter_name]
189
+ last_start = @times_per_rep[rep][filter_name][:last_start]
190
+
191
+ times[:accum] << (Time.now - last_start)
192
+ @times_per_rep[rep][filter_name].delete(:last_start)
193
+ end
194
+
195
+ Nanoc::Int::NotificationCenter.on(:compilation_suspended) do |rep, _exception|
196
+ @times_per_rep.fetch(rep, {}).each do |_filter_name, times|
197
+ if times[:last_start]
198
+ times[:accum] << (Time.now - times[:last_start])
199
+ times.delete(:last_start)
200
+ times[:suspended] = true
201
+
202
+ break
203
+ end
204
+ end
177
205
  end
178
- Nanoc::Int::NotificationCenter.on(:filtering_ended) do |_rep, filter_name|
179
- @times[filter_name].last[:stop] = Time.now
206
+
207
+ Nanoc::Int::NotificationCenter.on(:compilation_started) do |rep|
208
+ @times_per_rep.fetch(rep, {}).each do |filter_name, times|
209
+ if times[:suspended]
210
+ @times_per_rep[rep][filter_name][:last_start] = Time.now
211
+ times[:suspended] = false
212
+
213
+ break
214
+ end
215
+ end
180
216
  end
181
217
  end
182
218
 
@@ -217,7 +253,7 @@ module Nanoc::CLI::Commands
217
253
  # Calculate stats
218
254
  count = samples.size
219
255
  min = samples.min
220
- tot = samples.reduce(0) { |a, e| a + e }
256
+ tot = samples.reduce(0) { |acc, elem| acc + elem }
221
257
  avg = tot / count
222
258
  max = samples.max
223
259
 
@@ -236,55 +272,17 @@ module Nanoc::CLI::Commands
236
272
  def durations_per_filter
237
273
  @_durations_per_filter ||= begin
238
274
  result = {}
239
- @times.keys.each do |filter_name|
240
- durations = durations_for_filter(filter_name)
241
- if durations
242
- result[filter_name] = durations
243
- end
244
- end
245
- result
246
- end
247
- end
248
275
 
249
- def durations_for_filter(filter_name)
250
- result = []
251
- @times[filter_name].each do |sample|
252
- if sample[:start] && sample[:stop]
253
- result << sample[:stop] - sample[:start]
276
+ @times_per_rep.each do |_rep, times_per_filter|
277
+ times_per_filter.each do |filter_name, data|
278
+ result[filter_name] ||= []
279
+ result[filter_name].concat(data[:accum])
280
+ end
254
281
  end
255
- end
256
- result
257
- end
258
- end
259
-
260
- # Controls garbage collection so that it only occurs once every 20 items
261
- class GCController < Listener
262
- # @see Listener#enable_for?
263
- def self.enable_for?(_command_runner)
264
- !ENV.key?('TRAVIS')
265
- end
266
282
 
267
- def initialize(*)
268
- @gc_count = 0
269
- end
270
-
271
- # @see Listener#start
272
- def start
273
- Nanoc::Int::NotificationCenter.on(:compilation_started) do |_rep|
274
- if (@gc_count % 20).zero?
275
- GC.enable
276
- GC.start
277
- GC.disable
278
- end
279
- @gc_count += 1
283
+ result
280
284
  end
281
285
  end
282
-
283
- # @see Listener#stop
284
- def stop
285
- super
286
- GC.enable
287
- end
288
286
  end
289
287
 
290
288
  # Prints debug information (compilation started/ended, filtering started/ended, …)
@@ -303,7 +301,7 @@ module Nanoc::CLI::Commands
303
301
  puts "*** Ended compilation of #{rep.inspect}"
304
302
  puts
305
303
  end
306
- Nanoc::Int::NotificationCenter.on(:compilation_failed) do |rep, e|
304
+ Nanoc::Int::NotificationCenter.on(:compilation_suspended) do |rep, e|
307
305
  puts "*** Suspended compilation of #{rep.inspect}: #{e.message}"
308
306
  end
309
307
  Nanoc::Int::NotificationCenter.on(:cached_content_used) do |rep|
@@ -325,6 +323,7 @@ module Nanoc::CLI::Commands
325
323
  class FileActionPrinter < Listener
326
324
  def initialize(reps:)
327
325
  @start_times = {}
326
+ @acc_durations = {}
328
327
 
329
328
  @reps = reps
330
329
  end
@@ -332,10 +331,18 @@ module Nanoc::CLI::Commands
332
331
  # @see Listener#start
333
332
  def start
334
333
  Nanoc::Int::NotificationCenter.on(:compilation_started) do |rep|
335
- @start_times[rep.raw_path] = Time.now
334
+ @start_times[rep] = Time.now
335
+ @acc_durations[rep] ||= 0.0
336
+ end
337
+
338
+ Nanoc::Int::NotificationCenter.on(:compilation_suspended) do |rep|
339
+ @acc_durations[rep] += Time.now - @start_times[rep]
336
340
  end
337
- Nanoc::Int::NotificationCenter.on(:rep_written) do |_rep, path, is_created, is_modified|
338
- duration = path && @start_times[path] ? Time.now - @start_times[path] : nil
341
+
342
+ Nanoc::Int::NotificationCenter.on(:rep_written) do |rep, path, is_created, is_modified|
343
+ @acc_durations[rep] += Time.now - @start_times[rep]
344
+ duration = @acc_durations[rep]
345
+
339
346
  action =
340
347
  if is_created then :create
341
348
  elsif is_modified then :update
@@ -418,7 +425,6 @@ module Nanoc::CLI::Commands
418
425
  Nanoc::CLI::Commands::Compile::DiffGenerator,
419
426
  Nanoc::CLI::Commands::Compile::DebugPrinter,
420
427
  Nanoc::CLI::Commands::Compile::TimingRecorder,
421
- Nanoc::CLI::Commands::Compile::GCController,
422
428
  Nanoc::CLI::Commands::Compile::FileActionPrinter,
423
429
  Nanoc::CLI::Commands::Compile::StackProfProfiler,
424
430
  ]