nanoc 4.4.4 → 4.4.5

Sign up to get free protection for your applications and to get access to all the features.
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|