nanoc 4.4.4 → 4.4.5

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +9 -8
  4. data/NEWS.md +10 -0
  5. data/lib/nanoc/base.rb +0 -3
  6. data/lib/nanoc/base/contracts_support.rb +55 -2
  7. data/lib/nanoc/base/core_ext/array.rb +0 -2
  8. data/lib/nanoc/base/core_ext/hash.rb +0 -2
  9. data/lib/nanoc/base/entities.rb +1 -0
  10. data/lib/nanoc/base/entities/context.rb +1 -4
  11. data/lib/nanoc/base/entities/directed_graph.rb +0 -10
  12. data/lib/nanoc/base/entities/identifiable_collection.rb +1 -2
  13. data/lib/nanoc/base/entities/identifier.rb +6 -8
  14. data/lib/nanoc/base/entities/item_rep.rb +12 -18
  15. data/lib/nanoc/base/{compilation → entities}/outdatedness_reasons.rb +0 -0
  16. data/lib/nanoc/base/entities/site.rb +3 -19
  17. data/lib/nanoc/base/errors.rb +9 -0
  18. data/lib/nanoc/base/memoization.rb +0 -2
  19. data/lib/nanoc/base/repos/checksum_store.rb +21 -14
  20. data/lib/nanoc/base/repos/compiled_content_cache.rb +11 -15
  21. data/lib/nanoc/base/repos/dependency_store.rb +8 -27
  22. data/lib/nanoc/base/services.rb +3 -0
  23. data/lib/nanoc/base/services/compiler.rb +379 -0
  24. data/lib/nanoc/base/services/compiler_loader.rb +3 -1
  25. data/lib/nanoc/base/services/executor.rb +27 -41
  26. data/lib/nanoc/base/services/item_rep_builder.rb +4 -0
  27. data/lib/nanoc/base/services/item_rep_writer.rb +5 -2
  28. data/lib/nanoc/base/{compilation → services}/outdatedness_checker.rb +1 -1
  29. data/lib/nanoc/base/views/post_compile_item_rep_view.rb +1 -1
  30. data/lib/nanoc/base/views/view_context.rb +3 -3
  31. data/lib/nanoc/checking/check.rb +1 -1
  32. data/lib/nanoc/checking/checks/external_links.rb +1 -1
  33. data/lib/nanoc/cli.rb +0 -4
  34. data/lib/nanoc/cli/commands/compile.rb +2 -2
  35. data/lib/nanoc/cli/commands/shell.rb +1 -1
  36. data/lib/nanoc/data_sources/filesystem.rb +10 -20
  37. data/lib/nanoc/data_sources/filesystem/errors.rb +55 -0
  38. data/lib/nanoc/filters/asciidoc.rb +0 -2
  39. data/lib/nanoc/filters/coffeescript.rb +0 -2
  40. data/lib/nanoc/filters/colorize_syntax.rb +0 -2
  41. data/lib/nanoc/filters/handlebars.rb +0 -2
  42. data/lib/nanoc/filters/mustache.rb +0 -2
  43. data/lib/nanoc/filters/redcarpet.rb +0 -4
  44. data/lib/nanoc/filters/slim.rb +0 -2
  45. data/lib/nanoc/filters/typogruby.rb +0 -2
  46. data/lib/nanoc/filters/xsl.rb +0 -2
  47. data/lib/nanoc/filters/yui_compressor.rb +0 -2
  48. data/lib/nanoc/helpers/capturing.rb +22 -19
  49. data/lib/nanoc/helpers/link_to.rb +3 -7
  50. data/lib/nanoc/helpers/rendering.rb +1 -1
  51. data/lib/nanoc/rule_dsl/action_provider.rb +2 -2
  52. data/lib/nanoc/rule_dsl/compiler_dsl.rb +0 -2
  53. data/lib/nanoc/rule_dsl/recording_executor.rb +6 -6
  54. data/lib/nanoc/rule_dsl/rule.rb +0 -2
  55. data/lib/nanoc/rule_dsl/rule_context.rb +3 -3
  56. data/lib/nanoc/rule_dsl/rule_memory_calculator.rb +5 -5
  57. data/lib/nanoc/spec.rb +1 -1
  58. data/lib/nanoc/version.rb +1 -1
  59. data/test/base/test_compiler.rb +3 -1
  60. data/test/base/test_dependency_tracker.rb +0 -19
  61. data/test/base/test_item_rep.rb +3 -0
  62. data/test/cli/commands/test_create_site.rb +1 -1
  63. data/test/data_sources/test_filesystem.rb +5 -5
  64. data/test/filters/test_coffeescript.rb +2 -0
  65. data/test/filters/test_handlebars.rb +4 -0
  66. data/test/filters/test_uglify_js.rb +4 -0
  67. data/test/filters/test_xsl.rb +1 -1
  68. data/test/helper.rb +6 -0
  69. data/test/helpers/test_capturing.rb +6 -1
  70. data/test/helpers/test_xml_sitemap.rb +1 -1
  71. metadata +6 -6
  72. data/lib/nanoc/base/compilation/compiler.rb +0 -295
  73. data/test/base/test_checksum_store.rb +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a8f94a3171ddf9ebc26963938e4399d7075b1e5a
4
- data.tar.gz: 81f10a1af119995497a8a11ff564ecc0408c3703
3
+ metadata.gz: 863abf7fed2e1998046a921fe61e76d21bc0d4d3
4
+ data.tar.gz: 03a50e4fc4e75f74e0505c0664c352e5b2821d09
5
5
  SHA512:
6
- metadata.gz: 78b10318c7b1160ce58257201d03f82295db7cd027bf6cb1e5265c0bbcde0cacbf9907ee140166c51d572c1b8ca1a4c53ed93af8dfafdba3ff37f322b4110cf2
7
- data.tar.gz: 67260b141c829d973f341bf469a0fae490232d628265a9e55bc6e89a73a672b8811505702b8c0327694ea6e098db5b8d16462580b920e319ddea141510df3521
6
+ metadata.gz: 5efd6d09aef769a17e8a1d66ee9557ca8b70dbdca303b36e2142e331d133904caf4b902b246d65d9b22ead0cb152746684bf0ae52436ce7c7bfa6de670a537af
7
+ data.tar.gz: 62b27f158e7d10f8faf730df0ce02bb931fc15d665e5ad4960ca006c2f917333dcc74ff8cd49532245b47f65648313095819c4bda84e4657e515585ea20a6686
data/Gemfile CHANGED
@@ -21,6 +21,7 @@ group :devel do
21
21
  gem 'vcr'
22
22
  gem 'webmock'
23
23
  gem 'yard'
24
+ gem 'yard-contracts'
24
25
  end
25
26
 
26
27
  group :plugins do
@@ -1,15 +1,14 @@
1
1
  GIT
2
2
  remote: git://github.com/tmm1/pygments.rb.git
3
- revision: fc7e79ef1a5c215abe5f3e5ac7d5fdd12dd8b73d
3
+ revision: a988d127d3270d21685d2ac2e586060bf43709f3
4
4
  specs:
5
- pygments.rb (1.0.0)
6
- posix-spawn (~> 0.3.6)
7
- yajl-ruby (~> 1.2)
5
+ pygments.rb (1.1.0)
6
+ multi_json (>= 1.0.0)
8
7
 
9
8
  PATH
10
9
  remote: .
11
10
  specs:
12
- nanoc (4.4.4)
11
+ nanoc (4.4.5)
13
12
  cri (~> 2.3)
14
13
  hamster (~> 3.0)
15
14
  parallel (~> 1.9)
@@ -257,7 +256,6 @@ GEM
257
256
  parallel (1.10.0)
258
257
  parser (2.3.3.1)
259
258
  ast (~> 2.2)
260
- posix-spawn (0.3.12)
261
259
  powerpack (0.1.1)
262
260
  pry (0.10.4)
263
261
  coderay (~> 1.1.0)
@@ -304,7 +302,7 @@ GEM
304
302
  ruby_dep (1.5.0)
305
303
  rubypants (0.6.0)
306
304
  safe_yaml (1.0.4)
307
- sass (3.4.22)
305
+ sass (3.4.23)
308
306
  shellany (0.0.1)
309
307
  simplecov (0.12.0)
310
308
  docile (~> 1.1.0)
@@ -340,8 +338,10 @@ GEM
340
338
  crack (>= 0.3.2)
341
339
  hashdiff
342
340
  xml-simple (1.1.5)
343
- yajl-ruby (1.3.0)
344
341
  yard (0.9.5)
342
+ yard-contracts (0.1.5)
343
+ contracts (~> 0.7)
344
+ yard (~> 0.8)
345
345
  yuicompressor (1.3.3)
346
346
 
347
347
  PLATFORMS
@@ -402,6 +402,7 @@ DEPENDENCIES
402
402
  w3c_validators
403
403
  webmock
404
404
  yard
405
+ yard-contracts
405
406
  yuicompressor
406
407
 
407
408
  BUNDLED WITH
data/NEWS.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Nanoc news
2
2
 
3
+ ## 4.4.5 (2016-12-24)
4
+
5
+ Fixes:
6
+
7
+ * Prevented stale data from making it into the checksum store and thereby blowing up in memory (#1004, #1027)
8
+ * Fixed slow recompile after adding many items to a site (#1028)
9
+ * Fixed wrong capturing helper output when the output field separator (`$,`) is set
10
+ * Fixed issue that could cause items with multiple reps not to be recompiled when needed (#1031, #1032)
11
+ * Fixed error when fetching textual content of item whose `:last` snapshot is binary (#1035, #1036)
12
+
3
13
  ## 4.4.4 (2016-12-19)
4
14
 
5
15
  Enhancements:
@@ -1,8 +1,5 @@
1
1
  # @api private
2
2
  module Nanoc::Int
3
- autoload 'Compiler', 'nanoc/base/compilation/compiler'
4
- autoload 'OutdatednessChecker', 'nanoc/base/compilation/outdatedness_checker'
5
- autoload 'OutdatednessReasons', 'nanoc/base/compilation/outdatedness_reasons'
6
3
  end
7
4
 
8
5
  require_relative 'base/core_ext'
@@ -29,17 +29,58 @@ module Nanoc::Int
29
29
  Or = Ignorer.instance
30
30
  Func = Ignorer.instance
31
31
  RespondTo = Ignorer.instance
32
+ Named = Ignorer.instance
33
+ IterOf = Ignorer.instance
34
+ HashOf = Ignorer.instance
32
35
 
33
36
  def contract(*args); end
34
37
  end
35
38
 
36
39
  module EnabledContracts
40
+ class AbstractContract
41
+ def self.[](*vals)
42
+ new(*vals)
43
+ end
44
+ end
45
+
46
+ class Named < AbstractContract
47
+ def initialize(name)
48
+ @name = name
49
+ end
50
+
51
+ def valid?(val)
52
+ val.is_a?(Kernel.const_get(@name))
53
+ end
54
+
55
+ def inspect
56
+ "#{self.class}(#{@name})"
57
+ end
58
+ end
59
+
60
+ class IterOf < AbstractContract
61
+ def initialize(contract)
62
+ @contract = contract
63
+ end
64
+
65
+ def valid?(val)
66
+ val.respond_to?(:each) && val.all? { |v| Contract.valid?(v, @contract) }
67
+ end
68
+
69
+ def inspect
70
+ "#{self.class}(#{@contract})"
71
+ end
72
+ end
73
+
37
74
  def contract(*args)
38
75
  Contract(*args)
39
76
  end
40
77
  end
41
78
 
42
- def self.included(base)
79
+ def self.setup_once
80
+ @_contracts_support__setup ||= false
81
+ return @_contracts_support__should_enable if @_contracts_support__setup
82
+ @_contracts_support__setup = true
83
+
43
84
  contracts_loadable =
44
85
  begin
45
86
  require 'contracts'
@@ -48,7 +89,19 @@ module Nanoc::Int
48
89
  false
49
90
  end
50
91
 
51
- should_enable = contracts_loadable && !ENV.key?('DISABLE_CONTRACTS')
92
+ @_contracts_support__should_enable = contracts_loadable && !ENV.key?('DISABLE_CONTRACTS')
93
+
94
+ if @_contracts_support__should_enable
95
+ # FIXME: ugly
96
+ ::Contracts.const_set('Named', EnabledContracts::Named)
97
+ ::Contracts.const_set('IterOf', EnabledContracts::IterOf)
98
+ end
99
+
100
+ @_contracts_support__should_enable
101
+ end
102
+
103
+ def self.included(base)
104
+ should_enable = setup_once
52
105
 
53
106
  if should_enable
54
107
  unless base.include?(::Contracts::Core)
@@ -20,8 +20,6 @@ module Nanoc::ArrayExtensions
20
20
  # @see Hash#__nanoc_freeze_recursively
21
21
  #
22
22
  # @return [void]
23
- #
24
- # @since 3.2.0
25
23
  def __nanoc_freeze_recursively
26
24
  return if frozen?
27
25
  freeze
@@ -22,8 +22,6 @@ module Nanoc::HashExtensions
22
22
  # @see Array#__nanoc_freeze_recursively
23
23
  #
24
24
  # @return [void]
25
- #
26
- # @since 3.2.0
27
25
  def __nanoc_freeze_recursively
28
26
  return if frozen?
29
27
  freeze
@@ -21,4 +21,5 @@ require_relative 'entities/site'
21
21
  require_relative 'entities/snapshot_def'
22
22
 
23
23
  require_relative 'entities/outdatedness_status'
24
+ require_relative 'entities/outdatedness_reasons'
24
25
  require_relative 'entities/dependency'
@@ -24,12 +24,9 @@ module Nanoc::Int
24
24
  # end
25
25
  # # => "I am Max Payne and I am hiding in a cheap motel."
26
26
  def initialize(hash)
27
+ metaclass = class << self; self; end
27
28
  hash.each_pair do |key, value|
28
- # Build instance variable
29
29
  instance_variable_set('@' + key.to_s, value)
30
-
31
- # Define method
32
- metaclass = (class << self; self; end)
33
30
  metaclass.send(:define_method, key) { value }
34
31
  end
35
32
  end
@@ -84,8 +84,6 @@ module Nanoc::Int
84
84
  # @param to End vertex of the edge
85
85
  #
86
86
  # @return [void]
87
- #
88
- # @since 3.2.0
89
87
  def delete_edge(from, to)
90
88
  @from_graph[from] ||= Set.new
91
89
  @from_graph[from].delete(to)
@@ -105,8 +103,6 @@ module Nanoc::Int
105
103
  # @param v The vertex to add to the graph
106
104
  #
107
105
  # @return [void]
108
- #
109
- # @since 3.2.0
110
106
  def add_vertex(v)
111
107
  return if @vertices.key?(v)
112
108
 
@@ -120,8 +116,6 @@ module Nanoc::Int
120
116
  # @param from Vertex from which all edges should be removed
121
117
  #
122
118
  # @return [void]
123
- #
124
- # @since 3.2.0
125
119
  def delete_edges_from(from)
126
120
  return if @from_graph[from].nil?
127
121
 
@@ -154,8 +148,6 @@ module Nanoc::Int
154
148
  # @param v Vertex to remove from the graph
155
149
  #
156
150
  # @return [void]
157
- #
158
- # @since 3.2.0
159
151
  def delete_vertex(v)
160
152
  delete_edges_to(v)
161
153
  delete_edges_from(v)
@@ -232,8 +224,6 @@ module Nanoc::Int
232
224
  # Returns all root vertices, i.e. vertices where no edge points to.
233
225
  #
234
226
  # @return [Set] The set of all root vertices in this graph.
235
- #
236
- # @since 3.2.0
237
227
  def roots
238
228
  @roots
239
229
  end
@@ -11,8 +11,7 @@ module Nanoc::Int
11
11
  def_delegator :@objects, :<<
12
12
  def_delegator :@objects, :concat
13
13
 
14
- # FIXME: use Nanoc::Int::Configuration
15
- contract C::Any => C::Any
14
+ contract C::Or[Hash, C::Named['Nanoc::Int::Configuration']] => C::Any
16
15
  def initialize(config)
17
16
  @config = config
18
17
 
@@ -98,15 +98,13 @@ module Nanoc
98
98
  end
99
99
 
100
100
  contract C::None => C::Bool
101
- # @return [Boolean] True if this is a full-type identifier (i.e. includes
102
- # the extension), false otherwise
101
+ # Whether or not this is a full identifier (i.e.includes the extension).
103
102
  def full?
104
103
  @type == :full
105
104
  end
106
105
 
107
106
  contract C::None => C::Bool
108
- # @return [Boolean] True if this is a legacy identifier (i.e. does not
109
- # include the extension), false otherwise
107
+ # Whether or not this is a legacy identifier (i.e. does not include the extension).
110
108
  def legacy?
111
109
  @type == :legacy
112
110
  end
@@ -133,7 +131,7 @@ module Nanoc
133
131
  end
134
132
 
135
133
  contract C::None => String
136
- # @return [String]
134
+ # The identifier, as string, with the last extension removed
137
135
  def without_ext
138
136
  unless full?
139
137
  raise UnsupportedLegacyOperationError
@@ -149,7 +147,7 @@ module Nanoc
149
147
  end
150
148
 
151
149
  contract C::None => C::Maybe[String]
152
- # @return [String, nil] The extension, without a leading dot.
150
+ # The extension, without a leading dot
153
151
  def ext
154
152
  unless full?
155
153
  raise UnsupportedLegacyOperationError
@@ -160,7 +158,7 @@ module Nanoc
160
158
  end
161
159
 
162
160
  contract C::None => String
163
- # @return [String]
161
+ # The identifier, as string, with all extensions removed
164
162
  def without_exts
165
163
  extname = exts.join('.')
166
164
  if !extname.empty?
@@ -171,7 +169,7 @@ module Nanoc
171
169
  end
172
170
 
173
171
  contract C::None => C::ArrayOf[String]
174
- # @return [Array] List of extensions, without a leading dot.
172
+ # The list of extensions, without a leading dot
175
173
  def exts
176
174
  unless full?
177
175
  raise UnsupportedLegacyOperationError
@@ -42,7 +42,7 @@ module Nanoc::Int
42
42
  @raw_paths = {}
43
43
  @paths = {}
44
44
  @snapshot_defs = []
45
- initialize_content
45
+ @snapshot_contents = { last: @item.content }
46
46
 
47
47
  # Reset flags
48
48
  @compiled = false
@@ -64,18 +64,14 @@ module Nanoc::Int
64
64
  # @return [String] The compiled content at the given snapshot (or the
65
65
  # default snapshot if no snapshot is specified)
66
66
  def compiled_content(snapshot: nil)
67
- # Make sure we're not binary
68
- if binary?
69
- raise Nanoc::Int::Errors::CannotGetCompiledContentOfBinaryItem.new(self)
70
- end
71
-
72
67
  # Get name of last pre-layout snapshot
73
68
  snapshot_name = snapshot || (@snapshot_contents[:pre] ? :pre : :last)
74
- is_moving = [:pre, :post, :last].include?(snapshot_name)
69
+ is_movable = [:pre, :post, :last].include?(snapshot_name)
75
70
 
76
71
  # Check existance of snapshot
77
72
  snapshot_def = snapshot_defs.reverse.find { |sd| sd.name == snapshot_name }
78
- if !is_moving && (snapshot_def.nil? || !snapshot_def.final?)
73
+ is_final = snapshot_def && snapshot_def.final?
74
+ if !is_movable && !is_final
79
75
  raise Nanoc::Int::Errors::NoSuchSnapshot.new(self, snapshot_name)
80
76
  end
81
77
 
@@ -85,7 +81,7 @@ module Nanoc::Int
85
81
  when :post, :last
86
82
  true
87
83
  when :pre
88
- snapshot_def.nil? || !snapshot_def.final?
84
+ !is_final
89
85
  end
90
86
  is_usable_snapshot = @snapshot_contents[snapshot_name] && (compiled? || !is_still_moving)
91
87
  unless is_usable_snapshot
@@ -93,7 +89,13 @@ module Nanoc::Int
93
89
  return compiled_content(snapshot: snapshot)
94
90
  end
95
91
 
96
- @snapshot_contents[snapshot_name].string
92
+ # Verify snapshot is not binary
93
+ snapshot_content = @snapshot_contents[snapshot_name]
94
+ if snapshot_content.binary?
95
+ raise Nanoc::Int::Errors::CannotGetCompiledContentOfBinaryItem.new(self)
96
+ end
97
+
98
+ snapshot_content.string
97
99
  end
98
100
 
99
101
  contract Symbol => C::Bool
@@ -101,8 +103,6 @@ module Nanoc::Int
101
103
  #
102
104
  # @return [Boolean] True if content exists for the snapshot with the
103
105
  # given name, false otherwise
104
- #
105
- # @since 3.2.0
106
106
  def snapshot?(snapshot_name)
107
107
  !@snapshot_contents[snapshot_name].nil?
108
108
  end
@@ -146,11 +146,5 @@ module Nanoc::Int
146
146
  def inspect
147
147
  "<#{self.class} name=\"#{name}\" binary=#{binary?} raw_path=\"#{raw_path}\" item.identifier=\"#{item.identifier}\">"
148
148
  end
149
-
150
- private
151
-
152
- def initialize_content
153
- @snapshot_contents = { last: @item.content }
154
- end
155
149
  end
156
150
  end
@@ -5,11 +5,7 @@ module Nanoc::Int
5
5
 
6
6
  attr_accessor :compiler
7
7
 
8
- contract C::KeywordArgs[config: Nanoc::Int::Configuration, code_snippets: C::RespondTo[:each], items: C::RespondTo[:each], layouts: C::RespondTo[:each]] => C::Any
9
- # @param [Nanoc::Int::Configuration] config
10
- # @param [Enumerable<Nanoc::Int::CodeSnippet>] code_snippets
11
- # @param [Enumerable<Nanoc::Int::Item>] items
12
- # @param [Enumerable<Nanoc::Int::Layout>] layouts
8
+ contract C::KeywordArgs[config: Nanoc::Int::Configuration, code_snippets: C::IterOf[Nanoc::Int::CodeSnippet], items: C::IterOf[Nanoc::Int::Item], layouts: C::IterOf[Nanoc::Int::Layout]] => C::Any
13
9
  def initialize(config:, code_snippets:, items:, layouts:)
14
10
  @config = config
15
11
  @code_snippets = code_snippets
@@ -21,21 +17,12 @@ module Nanoc::Int
21
17
  end
22
18
 
23
19
  contract C::None => self
24
- # Compiles the site.
25
- #
26
- # @return [void]
27
- #
28
- # @since 3.2.0
29
20
  def compile
30
21
  compiler.run_all
31
22
  self
32
23
  end
33
24
 
34
- contract C::None => Nanoc::Int::Compiler
35
- # Returns the compiler for this site. Will create a new compiler if none
36
- # exists yet.
37
- #
38
- # @return [Nanoc::Int::Compiler] The compiler for this site
25
+ contract C::None => C::Named['Nanoc::Int::Compiler']
39
26
  def compiler
40
27
  @compiler ||= Nanoc::Int::CompilerLoader.new.load(self)
41
28
  end
@@ -46,9 +33,6 @@ module Nanoc::Int
46
33
  attr_reader :layouts
47
34
 
48
35
  contract C::None => self
49
- # Prevents all further modifications to itself, its items, its layouts etc.
50
- #
51
- # @return [void]
52
36
  def freeze
53
37
  config.freeze
54
38
  items.freeze
@@ -57,7 +41,7 @@ module Nanoc::Int
57
41
  self
58
42
  end
59
43
 
60
- contract C::RespondTo[:each], String => self
44
+ contract C::IterOf[C::Or[Nanoc::Int::Item, Nanoc::Int::Layout]], String => self
61
45
  def ensure_identifier_uniqueness(objects, type)
62
46
  seen = Set.new
63
47
  objects.each do |obj|