nanoc3 3.1.9 → 3.2.0a1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/NEWS.md +0 -50
- data/README.md +3 -15
- data/bin/nanoc3 +2 -0
- data/lib/nanoc3/base/checksummer.rb +40 -0
- data/lib/nanoc3/base/code_snippet.rb +30 -12
- data/lib/nanoc3/base/compiled_content_cache.rb +86 -0
- data/lib/nanoc3/base/compiler.rb +134 -95
- data/lib/nanoc3/base/compiler_dsl.rb +12 -11
- data/lib/nanoc3/base/core_ext/string.rb +2 -2
- data/lib/nanoc3/base/data_source.rb +17 -16
- data/lib/nanoc3/base/dependency_tracker.rb +102 -121
- data/lib/nanoc3/base/directed_graph.rb +65 -3
- data/lib/nanoc3/base/errors.rb +20 -16
- data/lib/nanoc3/base/item.rb +58 -50
- data/lib/nanoc3/base/item_rep.rb +177 -150
- data/lib/nanoc3/base/layout.rb +51 -18
- data/lib/nanoc3/base/notification_center.rb +8 -8
- data/lib/nanoc3/base/plugin_registry.rb +9 -9
- data/lib/nanoc3/base/rule.rb +18 -9
- data/lib/nanoc3/base/rule_context.rb +5 -5
- data/lib/nanoc3/base/site.rb +135 -47
- data/lib/nanoc3/base.rb +21 -19
- data/lib/nanoc3/cli/base.rb +51 -74
- data/lib/nanoc3/cli/commands/autocompile.rb +3 -0
- data/lib/nanoc3/cli/commands/compile.rb +35 -74
- data/lib/nanoc3/cli/commands/create_site.rb +17 -5
- data/lib/nanoc3/cli/commands/debug.rb +11 -4
- data/lib/nanoc3/cli/commands/view.rb +0 -1
- data/lib/nanoc3/cli/commands/watch.rb +148 -0
- data/lib/nanoc3/cli/commands.rb +1 -0
- data/lib/nanoc3/cli/logger.rb +15 -21
- data/lib/nanoc3/data_sources/deprecated/twitter.rb +0 -1
- data/lib/nanoc3/data_sources/filesystem.rb +11 -40
- data/lib/nanoc3/data_sources/filesystem_unified.rb +22 -22
- data/lib/nanoc3/extra/auto_compiler.rb +1 -1
- data/lib/nanoc3/extra/chick.rb +8 -8
- data/lib/nanoc3/extra/deployers/rsync.rb +2 -3
- data/lib/nanoc3/extra/validators/links.rb +32 -51
- data/lib/nanoc3/extra/validators/w3c.rb +2 -2
- data/lib/nanoc3/extra/vcs.rb +1 -1
- data/lib/nanoc3/filters/colorize_syntax.rb +15 -19
- data/lib/nanoc3/filters/erb.rb +1 -5
- data/lib/nanoc3/filters/erubis.rb +1 -5
- data/lib/nanoc3/filters/haml.rb +1 -2
- data/lib/nanoc3/filters/less.rb +2 -51
- data/lib/nanoc3/filters/mustache.rb +21 -0
- data/lib/nanoc3/filters/rdiscount.rb +1 -2
- data/lib/nanoc3/filters/relativize_paths.rb +3 -2
- data/lib/nanoc3/filters/sass.rb +50 -56
- data/lib/nanoc3/filters.rb +2 -0
- data/lib/nanoc3/helpers/blogging.rb +22 -29
- data/lib/nanoc3/helpers/breadcrumbs.rb +1 -1
- data/lib/nanoc3/helpers/capturing.rb +1 -1
- data/lib/nanoc3/helpers/filtering.rb +1 -1
- data/lib/nanoc3/helpers/link_to.rb +10 -21
- data/lib/nanoc3/helpers/rendering.rb +5 -24
- data/lib/nanoc3/helpers/tagging.rb +6 -6
- data/lib/nanoc3/helpers/text.rb +2 -2
- data/lib/nanoc3.rb +1 -1
- metadata +35 -93
- data/.gemtest +0 -0
- data/doc/yardoc_templates/default/layout/html/footer.erb +0 -10
- data/nanoc3.gemspec +0 -41
- data/tasks/clean.rake +0 -11
- data/tasks/doc.rake +0 -14
- data/tasks/gem.rake +0 -13
- data/tasks/test.rake +0 -38
- data/test/base/core_ext/array_spec.rb +0 -23
- data/test/base/core_ext/hash_spec.rb +0 -41
- data/test/base/core_ext/string_spec.rb +0 -27
- data/test/base/test_code_snippet.rb +0 -33
- data/test/base/test_compiler.rb +0 -410
- data/test/base/test_compiler_dsl.rb +0 -121
- data/test/base/test_context.rb +0 -33
- data/test/base/test_data_source.rb +0 -48
- data/test/base/test_dependency_tracker.rb +0 -510
- data/test/base/test_directed_graph.rb +0 -91
- data/test/base/test_filter.rb +0 -85
- data/test/base/test_item.rb +0 -141
- data/test/base/test_item_rep.rb +0 -953
- data/test/base/test_layout.rb +0 -44
- data/test/base/test_notification_center.rb +0 -36
- data/test/base/test_plugin.rb +0 -32
- data/test/base/test_rule.rb +0 -21
- data/test/base/test_rule_context.rb +0 -63
- data/test/base/test_site.rb +0 -366
- data/test/cli/commands/test_compile.rb +0 -12
- data/test/cli/commands/test_create_item.rb +0 -12
- data/test/cli/commands/test_create_layout.rb +0 -28
- data/test/cli/commands/test_create_site.rb +0 -24
- data/test/cli/commands/test_help.rb +0 -12
- data/test/cli/commands/test_info.rb +0 -12
- data/test/cli/commands/test_update.rb +0 -12
- data/test/cli/test_logger.rb +0 -12
- data/test/data_sources/test_filesystem.rb +0 -420
- data/test/data_sources/test_filesystem_unified.rb +0 -538
- data/test/data_sources/test_filesystem_verbose.rb +0 -359
- data/test/extra/core_ext/test_enumerable.rb +0 -32
- data/test/extra/core_ext/test_time.rb +0 -17
- data/test/extra/deployers/test_rsync.rb +0 -234
- data/test/extra/test_auto_compiler.rb +0 -482
- data/test/extra/test_file_proxy.rb +0 -21
- data/test/extra/test_vcs.rb +0 -24
- data/test/extra/validators/test_links.rb +0 -53
- data/test/extra/validators/test_w3c.rb +0 -49
- data/test/filters/test_bluecloth.rb +0 -20
- data/test/filters/test_coderay.rb +0 -46
- data/test/filters/test_colorize_syntax.rb +0 -84
- data/test/filters/test_erb.rb +0 -72
- data/test/filters/test_erubis.rb +0 -72
- data/test/filters/test_haml.rb +0 -98
- data/test/filters/test_kramdown.rb +0 -20
- data/test/filters/test_less.rb +0 -118
- data/test/filters/test_markaby.rb +0 -26
- data/test/filters/test_maruku.rb +0 -20
- data/test/filters/test_rainpress.rb +0 -31
- data/test/filters/test_rdiscount.rb +0 -33
- data/test/filters/test_rdoc.rb +0 -18
- data/test/filters/test_redcloth.rb +0 -20
- data/test/filters/test_relativize_paths.rb +0 -231
- data/test/filters/test_rubypants.rb +0 -20
- data/test/filters/test_sass.rb +0 -235
- data/test/gem_loader.rb +0 -11
- data/test/helper.rb +0 -99
- data/test/helpers/test_blogging.rb +0 -808
- data/test/helpers/test_breadcrumbs.rb +0 -83
- data/test/helpers/test_capturing.rb +0 -42
- data/test/helpers/test_filtering.rb +0 -108
- data/test/helpers/test_html_escape.rb +0 -18
- data/test/helpers/test_link_to.rb +0 -251
- data/test/helpers/test_rendering.rb +0 -109
- data/test/helpers/test_tagging.rb +0 -89
- data/test/helpers/test_text.rb +0 -26
- data/test/helpers/test_xml_sitemap.rb +0 -69
- data/test/tasks/test_clean.rb +0 -71
data/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2007-
|
1
|
+
Copyright (c) 2007-2010 Denis Defreyne and contributors
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
of this software and associated documentation files (the "Software"), to deal
|
data/NEWS.md
CHANGED
@@ -1,55 +1,5 @@
|
|
1
1
|
# nanoc news
|
2
2
|
|
3
|
-
## 3.1.9 (2011-06-30)
|
4
|
-
|
5
|
-
* Really fixed dependency generation between Sass partials this time
|
6
|
-
* Updated Less filter to 2.0
|
7
|
-
* Made colorize_syntax filter throw an error if pygmentize is not available
|
8
|
-
|
9
|
-
## 3.1.8 (2011-06-25)
|
10
|
-
|
11
|
-
* Made link validator accept https: URLs
|
12
|
-
* Fixed erronous handling of layouts with names ending in index
|
13
|
-
* Fixed dependency generation between Sass partials
|
14
|
-
* Fixed errors related to thread requires
|
15
|
-
* Fixed crash while handling load errors
|
16
|
-
* Improved encoding handling while reading files
|
17
|
-
|
18
|
-
## 3.1.7 (2011-05-03)
|
19
|
-
|
20
|
-
* Restored compatibility with Sass 3.1
|
21
|
-
|
22
|
-
## 3.1.6 (2010-11-21)
|
23
|
-
|
24
|
-
* Fixed issues with incompatible encodings
|
25
|
-
|
26
|
-
## 3.1.5 (2010-08-24)
|
27
|
-
|
28
|
-
* Improved `#render` documentation
|
29
|
-
* Improved metadata section check so that e.g. raw diffs are handled properly
|
30
|
-
* Deprecated using `Nanoc3::Site#initialize` with a non-`"."` argument
|
31
|
-
* Added Ruby engine to version string
|
32
|
-
* Allowed the `created_at` and `updated_at` attributes used in the `Blogging`
|
33
|
-
helper to be `Date` instances
|
34
|
-
|
35
|
-
## 3.1.4 (2010-07-25)
|
36
|
-
|
37
|
-
* Made INT and TERM signals always quit the CLI
|
38
|
-
* Allowed relative imports in LESS
|
39
|
-
* Made sure modification times are unchanged for identical recompiled items
|
40
|
-
* Improved link validator error handling
|
41
|
-
* Made pygmentize not output extra divs and pres
|
42
|
-
* Allowed colorizers to be specified using symbols instead of strings
|
43
|
-
* Added scss to the default list of text extensions
|
44
|
-
|
45
|
-
## 3.1.3 (2010-04-25)
|
46
|
-
|
47
|
-
* Removed annoying win32console warning [Eric Sunshine]
|
48
|
-
* Removed color codes when not writing to a terminal, or when writing to
|
49
|
-
Windows’ console when win32console is not installed [Eric Sunshine]
|
50
|
-
* Added .xhtml and .xml to list of text extensions
|
51
|
-
* Improved support for relative Sass @imports [Chris Eppstein]
|
52
|
-
|
53
3
|
## 3.1.2 (2010-04-07)
|
54
4
|
|
55
5
|
* Fixed bug which could cause incorrect output when compilation of an item is
|
data/README.md
CHANGED
@@ -52,38 +52,26 @@ you want to explore nanoc from a technical perspective.
|
|
52
52
|
|
53
53
|
## Dependencies
|
54
54
|
|
55
|
-
nanoc
|
56
|
-
|
57
|
-
you’ll likely need some dependencies:
|
55
|
+
nanoc itself can be used without installing any dependencies. Some
|
56
|
+
components, however, do have dependencies:
|
58
57
|
|
59
|
-
* The **commandline frontend** depends on `cli`.
|
60
58
|
* The **autocompiler** depends on `mime-types` and `rack`.
|
61
|
-
* Filters and helpers likely have dependencies on their own too.
|
62
|
-
|
63
|
-
If you’re developing for nanoc, such as writing custom filters or helpers, you
|
64
|
-
may be interested in the development dependencies:
|
65
|
-
|
66
59
|
* For **documentation generation** you’ll need `yard`.
|
67
60
|
* For **packaging** you’ll need `rubygems` (1.3 or newer).
|
68
|
-
* For **testing** you’ll need `mocha
|
61
|
+
* For **testing** you’ll need `mocha`.
|
69
62
|
|
70
63
|
## Contributors
|
71
64
|
|
72
65
|
(In alphabetical order)
|
73
66
|
|
74
|
-
* Ben Armston
|
75
67
|
* Colin Barrett
|
76
68
|
* Dmitry Bilunov
|
77
69
|
* Brian Candler
|
78
70
|
* Chris Eppstein
|
79
|
-
* Felix Hanley
|
80
71
|
* Starr Horne
|
81
|
-
* Tuomas Kareinen
|
82
72
|
* Nicky Peeters
|
83
73
|
* Christian Plessl
|
84
74
|
* Šime Ramov
|
85
|
-
* Xavier Shay
|
86
|
-
* Arnau Siches
|
87
75
|
* “Soryu”
|
88
76
|
* Eric Sunshine
|
89
77
|
* Dennis Sutch
|
data/bin/nanoc3
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Nanoc3
|
4
|
+
|
5
|
+
# Responsible for creating checksums of files. Such checksums are used to
|
6
|
+
# determine whether files have changed between compilations.
|
7
|
+
class Checksummer
|
8
|
+
|
9
|
+
# Returns a checksum for the specified file. Multiple invocations of this
|
10
|
+
# method with the same filename argument will yield the same result.
|
11
|
+
#
|
12
|
+
# The returned checksum has the property that for two given files with
|
13
|
+
# different content, the returned checksum will be different with a very
|
14
|
+
# high probability. In practice, this boils down to using a secure
|
15
|
+
# cryptographic hash function, such as SHA-1.
|
16
|
+
#
|
17
|
+
# The format of the resulting checksum should not be relied upon. In
|
18
|
+
# future versions of nanoc, this function may use a different method for
|
19
|
+
# generating checksums.
|
20
|
+
#
|
21
|
+
# @param [String] filename The name of the file for which the checksum
|
22
|
+
# should be calculated
|
23
|
+
#
|
24
|
+
# @return [String] The checksum for the given files
|
25
|
+
def self.checksum_for(filename)
|
26
|
+
require 'digest'
|
27
|
+
|
28
|
+
digest = Digest::SHA1.new
|
29
|
+
File.open(filename, 'r') do |io|
|
30
|
+
until io.eof
|
31
|
+
data = io.readpartial(2**10)
|
32
|
+
digest.update(data)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
digest.hexdigest
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -2,9 +2,7 @@
|
|
2
2
|
|
3
3
|
module Nanoc3
|
4
4
|
|
5
|
-
# Nanoc3::CodeSnippet represent a piece of custom code of a nanoc site.
|
6
|
-
# contains the textual source code as well as a mtime, which is used to
|
7
|
-
# speed up site compilation.
|
5
|
+
# Nanoc3::CodeSnippet represent a piece of custom code of a nanoc site.
|
8
6
|
class CodeSnippet
|
9
7
|
|
10
8
|
# The {Nanoc3::Site} this code snippet belongs to.
|
@@ -22,24 +20,38 @@ module Nanoc3
|
|
22
20
|
# @return [String]
|
23
21
|
attr_reader :filename
|
24
22
|
|
25
|
-
# The
|
26
|
-
#
|
27
|
-
|
28
|
-
|
23
|
+
# @return [String] The checksum of this code snippet that was in effect
|
24
|
+
# during the previous site compilation
|
25
|
+
attr_accessor :old_checksum
|
26
|
+
|
27
|
+
# @return [String] The current, up-to-date checksum of this code snippet
|
28
|
+
attr_reader :new_checksum
|
29
29
|
|
30
30
|
# Creates a new code snippet.
|
31
31
|
#
|
32
32
|
# @param [String] data The raw source code which will be executed before
|
33
|
-
#
|
33
|
+
# compilation
|
34
34
|
#
|
35
35
|
# @param [String] filename The filename corresponding to this code snippet
|
36
36
|
#
|
37
|
-
# @param [Time]
|
38
|
-
#
|
39
|
-
|
37
|
+
# @param [Time, Hash] params Extra parameters. For backwards
|
38
|
+
# compatibility, this can be a Time instance indicating the time when
|
39
|
+
# this code snippet was last modified (mtime).
|
40
|
+
#
|
41
|
+
# @option params [Time, nil] :mtime (nil) The time when this code snippet
|
42
|
+
# was last modified
|
43
|
+
#
|
44
|
+
# @option params [String, nil] :checksum (nil) The current, up-to-date
|
45
|
+
# checksum of this code snippet
|
46
|
+
def initialize(data, filename, params=nil)
|
47
|
+
# Get mtime and checksum
|
48
|
+
params ||= {}
|
49
|
+
params = { :mtime => params } if params.is_a?(Time)
|
50
|
+
@new_checksum = params[:checksum]
|
51
|
+
@mtime = params[:mtime]
|
52
|
+
|
40
53
|
@data = data
|
41
54
|
@filename = filename
|
42
|
-
@mtime = mtime
|
43
55
|
end
|
44
56
|
|
45
57
|
# Loads the code by executing it.
|
@@ -49,6 +61,12 @@ module Nanoc3
|
|
49
61
|
eval(@data, TOPLEVEL_BINDING, @filename)
|
50
62
|
end
|
51
63
|
|
64
|
+
# @return [Boolean] true if the code snippet was modified since it was
|
65
|
+
# last compiled, false otherwise
|
66
|
+
def outdated?
|
67
|
+
!self.old_checksum || !self.new_checksum || self.new_checksum != self.old_checksum
|
68
|
+
end
|
69
|
+
|
52
70
|
end
|
53
71
|
|
54
72
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Nanoc3
|
4
|
+
|
5
|
+
# Represents a cache than can be used to store already compiled content,
|
6
|
+
# to prevent it from being needlessly recompiled.
|
7
|
+
#
|
8
|
+
# This class is intended for internal use only. Do not rely on its
|
9
|
+
# presence; future versions of nanoc, even in the 3.x branch, may no
|
10
|
+
# longer contain this class.
|
11
|
+
class CompiledContentCache
|
12
|
+
|
13
|
+
# @return [String] The filename where the cache will be loaded from
|
14
|
+
# and stored to
|
15
|
+
attr_reader :filename
|
16
|
+
|
17
|
+
# Creates a new cache for the given filename.
|
18
|
+
#
|
19
|
+
# @param [String] filename The filename where the cache will be loaded
|
20
|
+
# from and stored to
|
21
|
+
def initialize(filename)
|
22
|
+
require 'pstore'
|
23
|
+
|
24
|
+
@filename = filename
|
25
|
+
end
|
26
|
+
|
27
|
+
# Loads the cache from the filesystem into memory.
|
28
|
+
#
|
29
|
+
# @return [void]
|
30
|
+
def load
|
31
|
+
cache = nil
|
32
|
+
return if !File.file?(filename)
|
33
|
+
pstore.transaction { cache = pstore[:compiled_content] }
|
34
|
+
end
|
35
|
+
|
36
|
+
# Stores the content of the (probably modified) in-memory cache to the
|
37
|
+
# filesystem.
|
38
|
+
#
|
39
|
+
# @return [void]
|
40
|
+
def store
|
41
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
42
|
+
pstore.transaction { pstore[:compiled_content] = cache }
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the cached compiled content for the given item
|
46
|
+
# representation. This cached compiled content is a hash where the keys
|
47
|
+
# are the snapshot names and the values the compiled content at the
|
48
|
+
# given snapshot.
|
49
|
+
#
|
50
|
+
# @param [Nanoc3::ItemRep] rep The item rep to fetch the content for
|
51
|
+
#
|
52
|
+
# @return [Hash<Symbol,String>] A hash containing the cached compiled
|
53
|
+
# content for the given item representation
|
54
|
+
def [](rep)
|
55
|
+
item_cache = cache[rep.item.identifier] || {}
|
56
|
+
item_cache[rep.name]
|
57
|
+
end
|
58
|
+
|
59
|
+
# Sets the compiled content for the given representation.
|
60
|
+
#
|
61
|
+
# @param [Nanoc3::ItemRep] rep The item representation for which to set
|
62
|
+
# the compiled content
|
63
|
+
#
|
64
|
+
# @param [Hash<Symbol,String>] content A hash containing the compiled
|
65
|
+
# content of the given representation
|
66
|
+
#
|
67
|
+
# @return [void]
|
68
|
+
def []=(rep, content)
|
69
|
+
cache[rep.item.identifier] ||= {}
|
70
|
+
cache[rep.item.identifier][rep.name] = content
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def cache
|
76
|
+
@cache ||= {}
|
77
|
+
end
|
78
|
+
|
79
|
+
def pstore
|
80
|
+
require 'pstore'
|
81
|
+
@store ||= PStore.new(@filename)
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
data/lib/nanoc3/base/compiler.rb
CHANGED
@@ -3,8 +3,38 @@
|
|
3
3
|
module Nanoc3
|
4
4
|
|
5
5
|
# Responsible for compiling a site’s item representations.
|
6
|
+
#
|
7
|
+
# The compilation process makes use of notifications (see
|
8
|
+
# {Nanoc3::NotificationCenter}) to track dependencies between items,
|
9
|
+
# layouts, etc. The following notifications are used:
|
10
|
+
#
|
11
|
+
# * `compilation_started` — indicates that the compiler has started
|
12
|
+
# compiling this item representation. Has one argument: the item
|
13
|
+
# representation itself. Only one item can be compiled at a given moment;
|
14
|
+
# therefore, it is not possible to get two consecutive
|
15
|
+
# `compilation_started` notifications without also getting a
|
16
|
+
# `compilation_ended` notification in between them.
|
17
|
+
#
|
18
|
+
# * `compilation_ended` — indicates that the compiler has finished compiling
|
19
|
+
# this item representation (either successfully or with failure). Has one
|
20
|
+
# argument: the item representation itself.
|
21
|
+
#
|
22
|
+
# * `visit_started` — indicates that the compiler requires content or
|
23
|
+
# attributes from the item representation that will be visited. Has one
|
24
|
+
# argument: the visited item identifier. This notification is used to
|
25
|
+
# track dependencies of items on other items; a `visit_started` event
|
26
|
+
# followed by another `visit_started` event indicates that the item
|
27
|
+
# corresponding to the former event will depend on the item from the
|
28
|
+
# latter event.
|
29
|
+
#
|
30
|
+
# * `visit_ended` — indicates that the compiler has finished visiting the
|
31
|
+
# item representation and that the requested attributes or content have
|
32
|
+
# been fetched (either successfully or with failure)
|
6
33
|
class Compiler
|
7
34
|
|
35
|
+
# The name of the file where cached compiled content will be stored
|
36
|
+
COMPILED_CONTENT_CACHE_FILENAME = 'tmp/compiled_content'
|
37
|
+
|
8
38
|
# The compilation stack. When the compiler begins compiling a rep or a
|
9
39
|
# layout, it will be placed on the stack; when it is done compiling the
|
10
40
|
# rep or layout, it will be removed from the stack.
|
@@ -47,34 +77,31 @@ module Nanoc3
|
|
47
77
|
# representations.
|
48
78
|
#
|
49
79
|
# @param [Nanoc3::Item] item The item that should be compiled, along with
|
50
|
-
#
|
80
|
+
# its dependencies. Pass `nil` if the entire site should be compiled.
|
51
81
|
#
|
52
82
|
# @option params [Boolean] :force (false) true if the rep should be
|
53
|
-
#
|
83
|
+
# compiled even if it is not outdated, false if not
|
54
84
|
#
|
55
85
|
# @return [void]
|
56
86
|
def run(item=nil, params={})
|
87
|
+
# Parse params
|
88
|
+
params[:force] = false if !params.has_key?(:force)
|
89
|
+
|
57
90
|
# Create output directory if necessary
|
58
91
|
FileUtils.mkdir_p(@site.config[:output_dir])
|
59
92
|
|
60
|
-
# Load
|
93
|
+
# Load necessary data
|
94
|
+
compiled_content_cache = CompiledContentCache.new(COMPILED_CONTENT_CACHE_FILENAME)
|
95
|
+
compiled_content_cache.load
|
61
96
|
dependency_tracker.load_graph
|
62
97
|
|
63
98
|
# Get items and reps to compile
|
64
|
-
|
65
|
-
items = [ item ] + dependency_tracker.successors_of(item)
|
66
|
-
items.uniq!
|
67
|
-
else
|
68
|
-
items = @site.items
|
69
|
-
end
|
99
|
+
items = item ? ([ item ] + dependency_tracker.successors_of(item)).uniq : @site.items
|
70
100
|
reps = items.map { |i| i.reps }.flatten
|
71
101
|
|
72
|
-
#
|
73
|
-
|
74
|
-
|
75
|
-
else
|
76
|
-
dependency_tracker.propagate_outdatedness
|
77
|
-
end
|
102
|
+
# Determine which reps need to be recompiled
|
103
|
+
reps.each { |r| r.force_outdated = true } if params[:force]
|
104
|
+
dependency_tracker.propagate_outdatedness
|
78
105
|
forget_dependencies_if_outdated(items)
|
79
106
|
|
80
107
|
# Compile reps
|
@@ -82,11 +109,21 @@ module Nanoc3
|
|
82
109
|
compile_reps(reps)
|
83
110
|
dependency_tracker.stop
|
84
111
|
|
112
|
+
# Store necessary data
|
113
|
+
compiled_content_cache.store
|
114
|
+
@site.store_checksums
|
115
|
+
dependency_tracker.store_graph
|
116
|
+
ensure
|
85
117
|
# Cleanup
|
86
118
|
FileUtils.rm_rf(Nanoc3::Filter::TMP_BINARY_ITEMS_DIR)
|
119
|
+
end
|
87
120
|
|
88
|
-
|
89
|
-
|
121
|
+
# Returns the dependency tracker for this site, creating it first if it
|
122
|
+
# does not yet exist.
|
123
|
+
#
|
124
|
+
# @return [Nanoc3::DependencyTracker] The dependency tracker for this site
|
125
|
+
def dependency_tracker
|
126
|
+
@dependency_tracker ||= Nanoc3::DependencyTracker.new(@site.items + @site.layouts)
|
90
127
|
end
|
91
128
|
|
92
129
|
# Finds the first matching compilation rule for the given item
|
@@ -95,7 +132,7 @@ module Nanoc3
|
|
95
132
|
# @param [Nanoc3::ItemRep] rep The item rep for which to fetch the rule
|
96
133
|
#
|
97
134
|
# @return [Nanoc3::Rule, nil] The compilation rule for the given item rep,
|
98
|
-
#
|
135
|
+
# or nil if no rules have been found
|
99
136
|
def compilation_rule_for(rep)
|
100
137
|
@item_compilation_rules.find do |rule|
|
101
138
|
rule.applicable_to?(rep.item) && rule.rep_name == rep.name
|
@@ -107,19 +144,37 @@ module Nanoc3
|
|
107
144
|
# @param [Nanoc3::ItemRep] rep The item rep for which to fetch the rule
|
108
145
|
#
|
109
146
|
# @return [Nanoc3::Rule, nil] The routing rule for the given item rep, or
|
110
|
-
#
|
147
|
+
# nil if no rules have been found
|
111
148
|
def routing_rule_for(rep)
|
112
149
|
@item_routing_rules.find do |rule|
|
113
150
|
rule.applicable_to?(rep.item) && rule.rep_name == rep.name
|
114
151
|
end
|
115
152
|
end
|
116
153
|
|
154
|
+
# Returns the list of routing rules that can be applied to the given item
|
155
|
+
# representation. For each snapshot, the first matching rule will be
|
156
|
+
# returned. The result is a hash containing the corresponding rule for
|
157
|
+
# each snapshot.
|
158
|
+
#
|
159
|
+
# @return [Hash<Symbol, Nanoc3::Rule>] The routing rules for the given rep
|
160
|
+
def routing_rules_for(rep)
|
161
|
+
rules = {}
|
162
|
+
@item_routing_rules.each do |rule|
|
163
|
+
next if !rule.applicable_to?(rep.item)
|
164
|
+
next if rule.rep_name != rep.name
|
165
|
+
next if rules.has_key?(rule.snapshot_name)
|
166
|
+
|
167
|
+
rules[rule.snapshot_name] = rule
|
168
|
+
end
|
169
|
+
rules
|
170
|
+
end
|
171
|
+
|
117
172
|
# Finds the filter name and arguments to use for the given layout.
|
118
173
|
#
|
119
174
|
# @param [Nanoc3::Layout] layout The layout for which to fetch the filter.
|
120
175
|
#
|
121
176
|
# @return [Array, nil] A tuple containing the filter name and the filter
|
122
|
-
#
|
177
|
+
# arguments for the given layout.
|
123
178
|
def filter_for_layout(layout)
|
124
179
|
@layout_filter_mapping.each_pair do |layout_identifier, filter_name_and_args|
|
125
180
|
return filter_name_and_args if layout.identifier =~ layout_identifier
|
@@ -135,69 +190,41 @@ module Nanoc3
|
|
135
190
|
#
|
136
191
|
# @return [void]
|
137
192
|
def compile_reps(reps)
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
# Attempt to compile all active reps
|
148
|
-
until active_reps.empty?
|
149
|
-
@stack.clear
|
150
|
-
begin
|
151
|
-
rep = active_reps.shift
|
152
|
-
puts "*** Attempting to compile #{rep.inspect}" if $DEBUG
|
153
|
-
|
154
|
-
@stack.push(rep)
|
155
|
-
compile_rep(rep)
|
156
|
-
rescue Nanoc3::Errors::UnmetDependency => e
|
157
|
-
puts "*** Attempt failed due to unmet dependency on #{e.rep.inspect}" if $DEBUG
|
158
|
-
|
159
|
-
# Reinitialize rep
|
160
|
-
rep.forget_progress
|
161
|
-
|
162
|
-
# Save rep to compile it later
|
163
|
-
inactive_reps << rep
|
164
|
-
|
165
|
-
# Add dependency to list of items to compile
|
166
|
-
unless active_reps.include?(e.rep) || inactive_reps.include?(e.rep)
|
167
|
-
changed = true
|
168
|
-
skipped_reps.delete(e.rep)
|
169
|
-
inactive_reps.unshift(e.rep)
|
170
|
-
end
|
171
|
-
else
|
172
|
-
puts "*** Attempt succeeded" if $DEBUG
|
173
|
-
|
174
|
-
changed = true
|
175
|
-
compiled_reps << rep
|
176
|
-
end
|
177
|
-
puts if $DEBUG
|
178
|
-
end
|
179
|
-
|
180
|
-
# Retry
|
181
|
-
if inactive_reps.empty?
|
182
|
-
puts "*** Nothing left to compile!" if $DEBUG
|
183
|
-
break
|
184
|
-
else
|
185
|
-
puts "*** No active reps left; activating all (#{inactive_reps.size}) inactive reps" if $DEBUG
|
186
|
-
puts if $DEBUG
|
187
|
-
active_reps = inactive_reps
|
188
|
-
inactive_reps = []
|
189
|
-
end
|
193
|
+
require 'set'
|
194
|
+
|
195
|
+
# Partition in outdated and non-outdated
|
196
|
+
outdated_reps = Set.new
|
197
|
+
skipped_reps = Set.new
|
198
|
+
reps.each do |rep|
|
199
|
+
target = (rep.outdated? || rep.item.outdated_due_to_dependencies?) ? outdated_reps : skipped_reps
|
200
|
+
target.add(rep)
|
190
201
|
end
|
191
202
|
|
192
|
-
#
|
193
|
-
|
194
|
-
|
195
|
-
|
203
|
+
# Build graph for outdated reps
|
204
|
+
content_dependency_graph = Nanoc3::DirectedGraph.new(outdated_reps)
|
205
|
+
|
206
|
+
# Attempt to compile all active reps
|
207
|
+
loop do
|
208
|
+
# Find rep to compile
|
209
|
+
break if content_dependency_graph.roots.empty?
|
210
|
+
rep = content_dependency_graph.roots.each { |e| break e }
|
211
|
+
@stack = [ rep ]
|
212
|
+
|
213
|
+
begin
|
214
|
+
compile_rep(rep)
|
215
|
+
content_dependency_graph.delete_vertex(rep)
|
216
|
+
rescue Nanoc3::Errors::UnmetDependency => e
|
217
|
+
content_dependency_graph.add_edge(e.rep, rep)
|
218
|
+
unless content_dependency_graph.vertices.include?(e.rep)
|
219
|
+
skipped_reps.delete(e.rep)
|
220
|
+
content_dependency_graph.add_vertex(e.rep)
|
221
|
+
end
|
222
|
+
end
|
196
223
|
end
|
197
224
|
|
198
|
-
#
|
199
|
-
if !
|
200
|
-
raise Nanoc3::Errors::RecursiveCompilation.new(
|
225
|
+
# Check whether everything was compiled
|
226
|
+
if !content_dependency_graph.vertices.empty?
|
227
|
+
raise Nanoc3::Errors::RecursiveCompilation.new(content_dependency_graph.vertices)
|
201
228
|
end
|
202
229
|
end
|
203
230
|
|
@@ -211,34 +238,35 @@ module Nanoc3
|
|
211
238
|
#
|
212
239
|
# @return [void]
|
213
240
|
def compile_rep(rep)
|
214
|
-
# Start
|
215
241
|
Nanoc3::NotificationCenter.post(:compilation_started, rep)
|
216
242
|
Nanoc3::NotificationCenter.post(:visit_started, rep.item)
|
217
243
|
|
218
|
-
|
219
|
-
|
220
|
-
|
244
|
+
if !rep.outdated? && !rep.item.outdated_due_to_dependencies && compiled_content_cache[rep]
|
245
|
+
Nanoc3::NotificationCenter.post(:cached_content_used, rep)
|
246
|
+
rep.content = compiled_content_cache[rep]
|
247
|
+
else
|
248
|
+
rep.snapshot(:raw)
|
249
|
+
rep.snapshot(:pre, :final => false)
|
250
|
+
compilation_rule_for(rep).apply_to(rep)
|
251
|
+
rep.snapshot(:post) if rep.has_snapshot?(:post)
|
252
|
+
rep.snapshot(:last)
|
253
|
+
end
|
221
254
|
|
222
|
-
|
223
|
-
rep
|
255
|
+
rep.compiled = true
|
256
|
+
compiled_content_cache[rep] = rep.content
|
257
|
+
rescue => e
|
258
|
+
rep.forget_progress
|
259
|
+
Nanoc3::NotificationCenter.post(:compilation_failed, rep)
|
260
|
+
raise e
|
224
261
|
ensure
|
225
|
-
# Stop
|
226
262
|
Nanoc3::NotificationCenter.post(:visit_ended, rep.item)
|
227
263
|
Nanoc3::NotificationCenter.post(:compilation_ended, rep)
|
228
264
|
end
|
229
265
|
|
230
|
-
# Returns the dependency tracker for this site, creating it first if it
|
231
|
-
# does not yet exist.
|
232
|
-
#
|
233
|
-
# @return [Nanoc3::DependencyTracker] The dependency tracker for this site
|
234
|
-
def dependency_tracker
|
235
|
-
@dependency_tracker ||= Nanoc3::DependencyTracker.new(@site.items)
|
236
|
-
end
|
237
|
-
|
238
266
|
# Clears the list of dependencies for items that will be recompiled.
|
239
267
|
#
|
240
268
|
# @param [Array<Nanoc3::Item>] items The list of items for which to forget
|
241
|
-
#
|
269
|
+
# the dependencies
|
242
270
|
#
|
243
271
|
# @return [void]
|
244
272
|
def forget_dependencies_if_outdated(items)
|
@@ -249,6 +277,17 @@ module Nanoc3
|
|
249
277
|
end
|
250
278
|
end
|
251
279
|
|
280
|
+
# Returns the cache used for storing compiled content.
|
281
|
+
#
|
282
|
+
# @return [CompiledContentCache] The compiled content cache
|
283
|
+
def compiled_content_cache
|
284
|
+
@compiled_content_cache ||= begin
|
285
|
+
cache = Nanoc3::CompiledContentCache.new(COMPILED_CONTENT_CACHE_FILENAME)
|
286
|
+
cache.load
|
287
|
+
cache
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
252
291
|
end
|
253
292
|
|
254
293
|
end
|