nanoc 4.8.16 → 4.8.17
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.
- checksums.yaml +4 -4
- data/NEWS.md +6 -0
- data/lib/nanoc.rb +11 -8
- data/lib/nanoc/base.rb +0 -1
- data/lib/nanoc/base/entities/action_sequence.rb +1 -1
- data/lib/nanoc/base/entities/checksum_collection.rb +0 -1
- data/lib/nanoc/base/entities/identifiable_collection.rb +2 -1
- data/lib/nanoc/base/services/outdatedness_checker.rb +2 -2
- data/lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb +1 -1
- data/lib/nanoc/cli/commands/compile_listeners/timing_recorder.rb +1 -36
- data/lib/nanoc/cli/error_handler.rb +37 -20
- data/lib/nanoc/rule_dsl/action_sequence_calculator.rb +1 -1
- data/lib/nanoc/version.rb +1 -1
- metadata +16 -3
- data/lib/nanoc/base/memoization.rb +0 -80
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b0135cd287173e9725acef9bb921109f8158d9e6453bd8e7ae194e23cdd25ef
|
4
|
+
data.tar.gz: 115b6b3baf84924b26cacac37925023f0aacbb9530721bd093386a74102fbd10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8aa8b0d5005dfbaa7664d08baaeee74bc7e5fb15cd2873d18bb0d4847c4c76203539852a258c4ad7c5187cb6503db1396e0a43752926f51fe89ea66b04dce12
|
7
|
+
data.tar.gz: 19fd6556430be0ffda0d733f0e8546a0ac646e7deb8da0e62df17c9caae4e99c166f4cc6bf8aadfc39376d5a1df44f53c542f104fefbf404686b840b4d18ced0
|
data/NEWS.md
CHANGED
data/lib/nanoc.rb
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Load external dependencies
|
4
|
+
require 'addressable'
|
5
|
+
require 'ddplugin'
|
6
|
+
require 'hamster'
|
7
|
+
require 'ref'
|
8
|
+
require 'slow_enumerator_tools'
|
9
|
+
require 'ddmemoize'
|
10
|
+
require 'ddtelemetry'
|
11
|
+
|
3
12
|
module Nanoc
|
4
13
|
# @return [String] A string containing information about this Nanoc version
|
5
14
|
# and its environment (Ruby engine and version, Rubygems version if any).
|
@@ -16,15 +25,9 @@ module Nanoc
|
|
16
25
|
def self.on_windows?
|
17
26
|
RUBY_PLATFORM =~ /windows|bccwin|cygwin|djgpp|mingw|mswin|wince/i
|
18
27
|
end
|
19
|
-
end
|
20
28
|
|
21
|
-
|
22
|
-
|
23
|
-
require 'ddplugin'
|
24
|
-
require 'hamster'
|
25
|
-
require 'ref'
|
26
|
-
require 'slow_enumerator_tools'
|
27
|
-
require 'ddtelemetry'
|
29
|
+
MEMOIZATION_TELEMETRY = DDTelemetry.new
|
30
|
+
end
|
28
31
|
|
29
32
|
# Load general requirements
|
30
33
|
require 'cgi'
|
data/lib/nanoc/base.rb
CHANGED
@@ -3,10 +3,11 @@
|
|
3
3
|
module Nanoc::Int
|
4
4
|
# @api private
|
5
5
|
class IdentifiableCollection
|
6
|
+
DDMemoize.activate(self, telemetry: Nanoc::MEMOIZATION_TELEMETRY)
|
7
|
+
|
6
8
|
include Nanoc::Int::ContractsSupport
|
7
9
|
include Enumerable
|
8
10
|
|
9
|
-
extend Nanoc::Int::Memoization
|
10
11
|
extend Forwardable
|
11
12
|
|
12
13
|
def_delegator :@objects, :each
|
@@ -6,7 +6,7 @@ module Nanoc::Int
|
|
6
6
|
# @api private
|
7
7
|
class OutdatednessChecker
|
8
8
|
class Basic
|
9
|
-
|
9
|
+
DDMemoize.activate(self, telemetry: Nanoc::MEMOIZATION_TELEMETRY)
|
10
10
|
|
11
11
|
include Nanoc::Int::ContractsSupport
|
12
12
|
|
@@ -97,7 +97,7 @@ module Nanoc::Int
|
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
100
|
-
|
100
|
+
DDMemoize.activate(self, telemetry: Nanoc::MEMOIZATION_TELEMETRY)
|
101
101
|
|
102
102
|
include Nanoc::Int::ContractsSupport
|
103
103
|
|
@@ -100,14 +100,6 @@ module Nanoc::CLI::Commands::CompileListeners
|
|
100
100
|
|
101
101
|
@telemetry.summary(:phases).observe(stopwatch.duration, phase_name)
|
102
102
|
end
|
103
|
-
|
104
|
-
on(:memoization_miss) do |label|
|
105
|
-
@telemetry.counter(:memoization).increment([label, :miss])
|
106
|
-
end
|
107
|
-
|
108
|
-
on(:memoization_hit) do |label|
|
109
|
-
@telemetry.counter(:memoization).increment([label, :hit])
|
110
|
-
end
|
111
103
|
end
|
112
104
|
|
113
105
|
# @see Listener#stop
|
@@ -146,32 +138,12 @@ module Nanoc::CLI::Commands::CompileListeners
|
|
146
138
|
[headers] + rows
|
147
139
|
end
|
148
140
|
|
149
|
-
def table_for_memoization
|
150
|
-
headers = %w[memoization hit miss %]
|
151
|
-
|
152
|
-
rows_raw = @telemetry.counter(:memoization).map do |(name, type), counter|
|
153
|
-
{ name: name, type: type, count: counter.value }
|
154
|
-
end
|
155
|
-
|
156
|
-
rows = rows_raw.group_by { |r| r[:name] }.map do |name, rows_for_name|
|
157
|
-
rows_by_type = rows_for_name.group_by { |r| r[:type] }
|
158
|
-
|
159
|
-
num_hit = rows_by_type.fetch(:hit, []).fetch(0, {}).fetch(:count, 0)
|
160
|
-
num_miss = rows_by_type.fetch(:miss, []).fetch(0, {}).fetch(:count, 0)
|
161
|
-
pct = num_hit.to_f / (num_hit + num_miss).to_f
|
162
|
-
|
163
|
-
[name, num_hit.to_s, num_miss.to_s, "#{format('%3.1f', pct * 100)}%"]
|
164
|
-
end
|
165
|
-
|
166
|
-
[headers] + rows
|
167
|
-
end
|
168
|
-
|
169
141
|
def print_profiling_feedback
|
170
142
|
print_table_for_summary(:filters)
|
171
143
|
print_table_for_summary(:phases) if Nanoc::CLI.verbosity >= 2
|
172
144
|
print_table_for_summary_duration(:stages) if Nanoc::CLI.verbosity >= 2
|
173
145
|
print_table_for_summary(:outdatedness_rules) if Nanoc::CLI.verbosity >= 2
|
174
|
-
|
146
|
+
DDMemoize.print_telemetry(Nanoc::MEMOIZATION_TELEMETRY) if Nanoc::CLI.verbosity >= 2
|
175
147
|
end
|
176
148
|
|
177
149
|
def print_table_for_summary(name)
|
@@ -188,13 +160,6 @@ module Nanoc::CLI::Commands::CompileListeners
|
|
188
160
|
print_table(table_for_summary_durations(name))
|
189
161
|
end
|
190
162
|
|
191
|
-
def print_table_for_memoization
|
192
|
-
return if @telemetry.counter(:memoization).empty?
|
193
|
-
|
194
|
-
puts
|
195
|
-
print_table(table_for_memoization)
|
196
|
-
end
|
197
|
-
|
198
163
|
def print_table(rows)
|
199
164
|
puts DDTelemetry::Table.new(rows).to_s
|
200
165
|
end
|
@@ -58,12 +58,20 @@ module Nanoc::CLI
|
|
58
58
|
rescue Interrupt
|
59
59
|
exit(1)
|
60
60
|
rescue StandardError, ScriptError => e
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
handle_error(e, exit_on_error: exit_on_error)
|
62
|
+
end
|
63
|
+
|
64
|
+
def handle_error(error, exit_on_error:)
|
65
|
+
if trivial?(error)
|
66
|
+
$stderr.puts
|
67
|
+
$stderr.puts "Error: #{error.message}"
|
68
|
+
resolution = resolution_for(error)
|
69
|
+
if resolution
|
70
|
+
$stderr.puts
|
71
|
+
$stderr.puts resolution
|
72
|
+
end
|
65
73
|
else
|
66
|
-
print_error(
|
74
|
+
print_error(error)
|
67
75
|
end
|
68
76
|
exit(1) if exit_on_error
|
69
77
|
end
|
@@ -148,6 +156,18 @@ module Nanoc::CLI
|
|
148
156
|
feature_enabled || ruby_2_5_used
|
149
157
|
end
|
150
158
|
|
159
|
+
# @api private
|
160
|
+
def trivial?(error)
|
161
|
+
case error
|
162
|
+
when Nanoc::Int::Errors::GenericTrivial, Errno::EADDRINUSE
|
163
|
+
true
|
164
|
+
when LoadError
|
165
|
+
GEM_NAMES.keys.include?(gem_name_from_load_error(error))
|
166
|
+
else
|
167
|
+
false
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
151
171
|
protected
|
152
172
|
|
153
173
|
# @return [Hash<String, Array>] A hash containing the gem names as keys and gem versions as value
|
@@ -196,15 +216,6 @@ module Nanoc::CLI
|
|
196
216
|
'w3c_validators' => 'w3c_validators',
|
197
217
|
}.freeze
|
198
218
|
|
199
|
-
def trivial?(error)
|
200
|
-
case error
|
201
|
-
when Nanoc::Int::Errors::GenericTrivial, Errno::EADDRINUSE
|
202
|
-
true
|
203
|
-
else
|
204
|
-
false
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
219
|
# Attempts to find a resolution for the given error, or nil if no
|
209
220
|
# resolution can be automatically obtained.
|
210
221
|
#
|
@@ -216,15 +227,15 @@ module Nanoc::CLI
|
|
216
227
|
|
217
228
|
case error
|
218
229
|
when LoadError
|
219
|
-
|
220
|
-
matches = error.message.match(/(no such file to load|cannot load such file) -- ([^\s]+)/)
|
221
|
-
return nil if matches.nil?
|
222
|
-
gem_name = GEM_NAMES[matches[2]]
|
230
|
+
gem_name = gem_name_from_load_error(error)
|
223
231
|
|
224
|
-
# Build message
|
225
232
|
if gem_name
|
226
233
|
if using_bundler?
|
227
|
-
|
234
|
+
<<~RES
|
235
|
+
1. Add `gem '#{gem_name}'` to your Gemfile
|
236
|
+
2. Run `bundle install`
|
237
|
+
3. Re-run this command
|
238
|
+
RES
|
228
239
|
else
|
229
240
|
"Install the '#{gem_name}' gem using `gem install #{gem_name}`."
|
230
241
|
end
|
@@ -241,6 +252,12 @@ module Nanoc::CLI
|
|
241
252
|
end
|
242
253
|
end
|
243
254
|
|
255
|
+
def gem_name_from_load_error(error)
|
256
|
+
matches = error.message.match(/(no such file to load|cannot load such file) -- ([^\s]+)/)
|
257
|
+
return nil if matches.nil?
|
258
|
+
GEM_NAMES[matches[2]]
|
259
|
+
end
|
260
|
+
|
244
261
|
def using_bundler?
|
245
262
|
defined?(Bundler) && Bundler::SharedHelpers.in_bundle?
|
246
263
|
end
|
data/lib/nanoc/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nanoc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.8.
|
4
|
+
version: 4.8.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Defreyne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-12-
|
11
|
+
date: 2017-12-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '2.8'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ddmemoize
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.0.0a2
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.0.0a2
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: ddplugin
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -162,7 +176,6 @@ files:
|
|
162
176
|
- lib/nanoc/base/error.rb
|
163
177
|
- lib/nanoc/base/errors.rb
|
164
178
|
- lib/nanoc/base/feature.rb
|
165
|
-
- lib/nanoc/base/memoization.rb
|
166
179
|
- lib/nanoc/base/repos.rb
|
167
180
|
- lib/nanoc/base/repos/action_sequence_store.rb
|
168
181
|
- lib/nanoc/base/repos/aggregate_data_source.rb
|
@@ -1,80 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Nanoc::Int
|
4
|
-
# Adds support for memoizing functions.
|
5
|
-
#
|
6
|
-
# @api private
|
7
|
-
module Memoization
|
8
|
-
class Value
|
9
|
-
attr_reader :value
|
10
|
-
|
11
|
-
def initialize(value)
|
12
|
-
@value = value
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
NONE = Object.new
|
17
|
-
|
18
|
-
# Memoizes the method with the given name. The modified method will cache
|
19
|
-
# the results of the original method, so that calling a method twice with
|
20
|
-
# the same arguments will short-circuit and return the cached results
|
21
|
-
# immediately.
|
22
|
-
#
|
23
|
-
# Memoization assumes that the current object as well as the function
|
24
|
-
# arguments are immutable. Mutating the object or the arguments will not
|
25
|
-
# cause memoized methods to recalculate their results. There is no way to
|
26
|
-
# un-memoize a result, and calculation results will remain in memory even
|
27
|
-
# if they are no longer needed.
|
28
|
-
#
|
29
|
-
# @example A fast fib function due to memoization
|
30
|
-
#
|
31
|
-
# class FibFast
|
32
|
-
#
|
33
|
-
# extend Nanoc::Int::Memoization
|
34
|
-
#
|
35
|
-
# def run(n)
|
36
|
-
# if n == 0
|
37
|
-
# 0
|
38
|
-
# elsif n == 1
|
39
|
-
# 1
|
40
|
-
# else
|
41
|
-
# run(n-1) + run(n-2)
|
42
|
-
# end
|
43
|
-
# end
|
44
|
-
# memoize :run
|
45
|
-
#
|
46
|
-
# end
|
47
|
-
#
|
48
|
-
# @param [Symbol, String] method_name The name of the method to memoize
|
49
|
-
#
|
50
|
-
# @return [void]
|
51
|
-
def memoize(method_name)
|
52
|
-
original_method_name = '__nonmemoized_' + method_name.to_s
|
53
|
-
alias_method original_method_name, method_name
|
54
|
-
|
55
|
-
instance_cache = Hash.new { |hash, key| hash[key] = {} }
|
56
|
-
|
57
|
-
define_method(method_name) do |*args|
|
58
|
-
instance_method_cache = instance_cache[self]
|
59
|
-
|
60
|
-
value = NONE
|
61
|
-
if instance_method_cache.key?(args)
|
62
|
-
object = instance_method_cache[args].object
|
63
|
-
value = object ? object.value : NONE
|
64
|
-
end
|
65
|
-
|
66
|
-
counter_label = is_a?(Class) ? "#{self}.#{method_name}" : "#{self.class}##{method_name}"
|
67
|
-
if value.equal?(NONE)
|
68
|
-
Nanoc::Int::NotificationCenter.post(:memoization_miss, counter_label)
|
69
|
-
send(original_method_name, *args).tap do |r|
|
70
|
-
instance_method_cache[args] = Ref::SoftReference.new(Value.new(r))
|
71
|
-
end
|
72
|
-
else
|
73
|
-
Nanoc::Int::NotificationCenter.post(:memoization_hit, counter_label)
|
74
|
-
value
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
alias memoized memoize
|
79
|
-
end
|
80
|
-
end
|