nanoc 3.2.4 → 3.3.0
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.
- data/.gemtest +0 -0
- data/ChangeLog +3 -0
- data/Gemfile +32 -0
- data/LICENSE +19 -0
- data/NEWS.md +470 -0
- data/README.md +114 -0
- data/Rakefile +14 -0
- data/bin/nanoc +7 -27
- data/bin/nanoc3 +3 -0
- data/doc/yardoc_templates/default/layout/html/footer.erb +10 -0
- data/lib/nanoc.rb +41 -0
- data/lib/nanoc/base.rb +49 -0
- data/lib/nanoc/base/compilation/checksum_store.rb +57 -0
- data/lib/nanoc/base/compilation/compiled_content_cache.rb +62 -0
- data/lib/nanoc/base/compilation/compiler.rb +458 -0
- data/lib/nanoc/base/compilation/compiler_dsl.rb +214 -0
- data/lib/nanoc/base/compilation/dependency_tracker.rb +200 -0
- data/lib/nanoc/base/compilation/filter.rb +165 -0
- data/lib/nanoc/base/compilation/item_rep_proxy.rb +103 -0
- data/lib/nanoc/base/compilation/item_rep_recorder_proxy.rb +102 -0
- data/lib/nanoc/base/compilation/outdatedness_checker.rb +223 -0
- data/lib/nanoc/base/compilation/outdatedness_reasons.rb +46 -0
- data/lib/nanoc/base/compilation/rule.rb +73 -0
- data/lib/nanoc/base/compilation/rule_context.rb +84 -0
- data/lib/nanoc/base/compilation/rule_memory_calculator.rb +40 -0
- data/lib/nanoc/base/compilation/rule_memory_store.rb +53 -0
- data/lib/nanoc/base/compilation/rules_collection.rb +243 -0
- data/lib/nanoc/base/context.rb +47 -0
- data/lib/nanoc/base/core_ext.rb +6 -0
- data/lib/nanoc/base/core_ext/array.rb +62 -0
- data/lib/nanoc/base/core_ext/hash.rb +63 -0
- data/lib/nanoc/base/core_ext/pathname.rb +26 -0
- data/lib/nanoc/base/core_ext/string.rb +46 -0
- data/lib/nanoc/base/directed_graph.rb +275 -0
- data/lib/nanoc/base/errors.rb +211 -0
- data/lib/nanoc/base/memoization.rb +67 -0
- data/lib/nanoc/base/notification_center.rb +84 -0
- data/lib/nanoc/base/ordered_hash.rb +200 -0
- data/lib/nanoc/base/plugin_registry.rb +181 -0
- data/lib/nanoc/base/result_data/item_rep.rb +492 -0
- data/lib/nanoc/base/source_data/code_snippet.rb +58 -0
- data/lib/nanoc/base/source_data/configuration.rb +24 -0
- data/lib/nanoc/base/source_data/data_source.rb +234 -0
- data/lib/nanoc/base/source_data/item.rb +301 -0
- data/lib/nanoc/base/source_data/layout.rb +130 -0
- data/lib/nanoc/base/source_data/site.rb +361 -0
- data/lib/nanoc/base/store.rb +135 -0
- data/lib/nanoc/cli.rb +137 -0
- data/lib/nanoc/cli/command_runner.rb +104 -0
- data/lib/nanoc/cli/commands/autocompile.rb +58 -0
- data/lib/nanoc/cli/commands/compile.rb +297 -0
- data/lib/nanoc/cli/commands/create_item.rb +60 -0
- data/lib/nanoc/cli/commands/create_layout.rb +73 -0
- data/lib/nanoc/cli/commands/create_site.rb +411 -0
- data/lib/nanoc/cli/commands/debug.rb +117 -0
- data/lib/nanoc/cli/commands/deploy.rb +79 -0
- data/lib/nanoc/cli/commands/info.rb +98 -0
- data/lib/nanoc/cli/commands/nanoc.rb +38 -0
- data/lib/nanoc/cli/commands/prune.rb +50 -0
- data/lib/nanoc/cli/commands/update.rb +70 -0
- data/lib/nanoc/cli/commands/view.rb +82 -0
- data/lib/nanoc/cli/commands/watch.rb +124 -0
- data/lib/nanoc/cli/error_handler.rb +199 -0
- data/lib/nanoc/cli/logger.rb +92 -0
- data/lib/nanoc/data_sources.rb +29 -0
- data/lib/nanoc/data_sources/deprecated/delicious.rb +42 -0
- data/lib/nanoc/data_sources/deprecated/last_fm.rb +87 -0
- data/lib/nanoc/data_sources/deprecated/twitter.rb +38 -0
- data/lib/nanoc/data_sources/filesystem.rb +299 -0
- data/lib/nanoc/data_sources/filesystem_unified.rb +121 -0
- data/lib/nanoc/data_sources/filesystem_verbose.rb +91 -0
- data/lib/nanoc/extra.rb +24 -0
- data/lib/nanoc/extra/auto_compiler.rb +103 -0
- data/lib/nanoc/extra/chick.rb +125 -0
- data/lib/nanoc/extra/core_ext.rb +6 -0
- data/lib/nanoc/extra/core_ext/enumerable.rb +33 -0
- data/lib/nanoc/extra/core_ext/pathname.rb +30 -0
- data/lib/nanoc/extra/core_ext/time.rb +19 -0
- data/lib/nanoc/extra/deployer.rb +47 -0
- data/lib/nanoc/extra/deployers.rb +15 -0
- data/lib/nanoc/extra/deployers/fog.rb +98 -0
- data/lib/nanoc/extra/deployers/rsync.rb +70 -0
- data/lib/nanoc/extra/file_proxy.rb +40 -0
- data/lib/nanoc/extra/pruner.rb +86 -0
- data/lib/nanoc/extra/validators.rb +12 -0
- data/lib/nanoc/extra/validators/links.rb +268 -0
- data/lib/nanoc/extra/validators/w3c.rb +95 -0
- data/lib/nanoc/extra/vcs.rb +66 -0
- data/lib/nanoc/extra/vcses.rb +17 -0
- data/lib/nanoc/extra/vcses/bazaar.rb +25 -0
- data/lib/nanoc/extra/vcses/dummy.rb +24 -0
- data/lib/nanoc/extra/vcses/git.rb +25 -0
- data/lib/nanoc/extra/vcses/mercurial.rb +25 -0
- data/lib/nanoc/extra/vcses/subversion.rb +25 -0
- data/lib/nanoc/filters.rb +59 -0
- data/lib/nanoc/filters/asciidoc.rb +38 -0
- data/lib/nanoc/filters/bluecloth.rb +19 -0
- data/lib/nanoc/filters/coderay.rb +21 -0
- data/lib/nanoc/filters/coffeescript.rb +20 -0
- data/lib/nanoc/filters/colorize_syntax.rb +298 -0
- data/lib/nanoc/filters/erb.rb +38 -0
- data/lib/nanoc/filters/erubis.rb +34 -0
- data/lib/nanoc/filters/haml.rb +27 -0
- data/lib/nanoc/filters/kramdown.rb +20 -0
- data/lib/nanoc/filters/less.rb +53 -0
- data/lib/nanoc/filters/markaby.rb +20 -0
- data/lib/nanoc/filters/maruku.rb +20 -0
- data/lib/nanoc/filters/mustache.rb +24 -0
- data/lib/nanoc/filters/rainpress.rb +19 -0
- data/lib/nanoc/filters/rdiscount.rb +22 -0
- data/lib/nanoc/filters/rdoc.rb +33 -0
- data/lib/nanoc/filters/redcarpet.rb +62 -0
- data/lib/nanoc/filters/redcloth.rb +47 -0
- data/lib/nanoc/filters/relativize_paths.rb +94 -0
- data/lib/nanoc/filters/rubypants.rb +20 -0
- data/lib/nanoc/filters/sass.rb +74 -0
- data/lib/nanoc/filters/slim.rb +25 -0
- data/lib/nanoc/filters/typogruby.rb +23 -0
- data/lib/nanoc/filters/uglify_js.rb +42 -0
- data/lib/nanoc/filters/xsl.rb +46 -0
- data/lib/nanoc/filters/yui_compressor.rb +23 -0
- data/lib/nanoc/helpers.rb +16 -0
- data/lib/nanoc/helpers/blogging.rb +319 -0
- data/lib/nanoc/helpers/breadcrumbs.rb +40 -0
- data/lib/nanoc/helpers/capturing.rb +138 -0
- data/lib/nanoc/helpers/filtering.rb +50 -0
- data/lib/nanoc/helpers/html_escape.rb +55 -0
- data/lib/nanoc/helpers/link_to.rb +151 -0
- data/lib/nanoc/helpers/rendering.rb +140 -0
- data/lib/nanoc/helpers/tagging.rb +71 -0
- data/lib/nanoc/helpers/text.rb +44 -0
- data/lib/nanoc/helpers/xml_sitemap.rb +76 -0
- data/lib/nanoc/tasks.rb +10 -0
- data/lib/nanoc/tasks/clean.rake +16 -0
- data/lib/nanoc/tasks/clean.rb +29 -0
- data/lib/nanoc/tasks/deploy/rsync.rake +16 -0
- data/lib/nanoc/tasks/validate.rake +92 -0
- data/nanoc.gemspec +49 -0
- data/tasks/doc.rake +16 -0
- data/tasks/test.rake +46 -0
- data/test/base/core_ext/array_spec.rb +73 -0
- data/test/base/core_ext/hash_spec.rb +98 -0
- data/test/base/core_ext/pathname_spec.rb +27 -0
- data/test/base/core_ext/string_spec.rb +37 -0
- data/test/base/test_checksum_store.rb +35 -0
- data/test/base/test_code_snippet.rb +31 -0
- data/test/base/test_compiler.rb +403 -0
- data/test/base/test_compiler_dsl.rb +161 -0
- data/test/base/test_context.rb +31 -0
- data/test/base/test_data_source.rb +46 -0
- data/test/base/test_dependency_tracker.rb +262 -0
- data/test/base/test_directed_graph.rb +288 -0
- data/test/base/test_filter.rb +83 -0
- data/test/base/test_item.rb +179 -0
- data/test/base/test_item_rep.rb +579 -0
- data/test/base/test_layout.rb +59 -0
- data/test/base/test_memoization.rb +90 -0
- data/test/base/test_notification_center.rb +34 -0
- data/test/base/test_outdatedness_checker.rb +394 -0
- data/test/base/test_plugin.rb +30 -0
- data/test/base/test_rule.rb +19 -0
- data/test/base/test_rule_context.rb +65 -0
- data/test/base/test_site.rb +190 -0
- data/test/cli/commands/test_compile.rb +33 -0
- data/test/cli/commands/test_create_item.rb +14 -0
- data/test/cli/commands/test_create_layout.rb +28 -0
- data/test/cli/commands/test_create_site.rb +24 -0
- data/test/cli/commands/test_deploy.rb +74 -0
- data/test/cli/commands/test_help.rb +12 -0
- data/test/cli/commands/test_info.rb +11 -0
- data/test/cli/commands/test_prune.rb +98 -0
- data/test/cli/commands/test_update.rb +10 -0
- data/test/cli/test_cli.rb +102 -0
- data/test/cli/test_error_handler.rb +29 -0
- data/test/cli/test_logger.rb +10 -0
- data/test/data_sources/test_filesystem.rb +433 -0
- data/test/data_sources/test_filesystem_unified.rb +536 -0
- data/test/data_sources/test_filesystem_verbose.rb +357 -0
- data/test/extra/core_ext/test_enumerable.rb +30 -0
- data/test/extra/core_ext/test_pathname.rb +17 -0
- data/test/extra/core_ext/test_time.rb +15 -0
- data/test/extra/deployers/test_fog.rb +67 -0
- data/test/extra/deployers/test_rsync.rb +100 -0
- data/test/extra/test_auto_compiler.rb +417 -0
- data/test/extra/test_file_proxy.rb +19 -0
- data/test/extra/test_vcs.rb +22 -0
- data/test/extra/validators/test_links.rb +62 -0
- data/test/extra/validators/test_w3c.rb +47 -0
- data/test/filters/test_asciidoc.rb +22 -0
- data/test/filters/test_bluecloth.rb +18 -0
- data/test/filters/test_coderay.rb +44 -0
- data/test/filters/test_coffeescript.rb +18 -0
- data/test/filters/test_colorize_syntax.rb +379 -0
- data/test/filters/test_erb.rb +105 -0
- data/test/filters/test_erubis.rb +78 -0
- data/test/filters/test_haml.rb +96 -0
- data/test/filters/test_kramdown.rb +18 -0
- data/test/filters/test_less.rb +113 -0
- data/test/filters/test_markaby.rb +24 -0
- data/test/filters/test_maruku.rb +18 -0
- data/test/filters/test_mustache.rb +25 -0
- data/test/filters/test_rainpress.rb +29 -0
- data/test/filters/test_rdiscount.rb +31 -0
- data/test/filters/test_rdoc.rb +18 -0
- data/test/filters/test_redcarpet.rb +73 -0
- data/test/filters/test_redcloth.rb +33 -0
- data/test/filters/test_relativize_paths.rb +533 -0
- data/test/filters/test_rubypants.rb +18 -0
- data/test/filters/test_sass.rb +229 -0
- data/test/filters/test_slim.rb +35 -0
- data/test/filters/test_typogruby.rb +21 -0
- data/test/filters/test_uglify_js.rb +30 -0
- data/test/filters/test_xsl.rb +105 -0
- data/test/filters/test_yui_compressor.rb +44 -0
- data/test/gem_loader.rb +11 -0
- data/test/helper.rb +207 -0
- data/test/helpers/test_blogging.rb +754 -0
- data/test/helpers/test_breadcrumbs.rb +81 -0
- data/test/helpers/test_capturing.rb +41 -0
- data/test/helpers/test_filtering.rb +106 -0
- data/test/helpers/test_html_escape.rb +32 -0
- data/test/helpers/test_link_to.rb +249 -0
- data/test/helpers/test_rendering.rb +89 -0
- data/test/helpers/test_tagging.rb +87 -0
- data/test/helpers/test_text.rb +24 -0
- data/test/helpers/test_xml_sitemap.rb +103 -0
- data/test/tasks/test_clean.rb +67 -0
- metadata +327 -15
- data/bin/nanoc-select +0 -86
- data/lib/nanoc-select.rb +0 -11
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Nanoc
|
|
4
|
+
|
|
5
|
+
# Represents an item representation, but provides an interface that is
|
|
6
|
+
# easier to use when writing compilation and routing rules. It is also
|
|
7
|
+
# responsible for fetching the necessary information from the compiler, such
|
|
8
|
+
# as assigns.
|
|
9
|
+
#
|
|
10
|
+
# The API provided by item representation proxies allows layout identifiers
|
|
11
|
+
# to be given as literals instead of as references to {Nanoc::Layout}.
|
|
12
|
+
class ItemRepProxy
|
|
13
|
+
|
|
14
|
+
extend Forwardable
|
|
15
|
+
|
|
16
|
+
def_delegators :@item_rep, :item, :name, :binary, :binary?, :compiled_content, :has_snapshot?, :raw_path, :path
|
|
17
|
+
def_delegator :@item_rep, :snapshot
|
|
18
|
+
|
|
19
|
+
# @param [Nanoc::ItemRep] item_rep The item representation that this
|
|
20
|
+
# proxy should behave like
|
|
21
|
+
#
|
|
22
|
+
# @param [Nanoc::Compiler] compiler The compiler that will provide the
|
|
23
|
+
# necessary compilation-related functionality.
|
|
24
|
+
def initialize(item_rep, compiler)
|
|
25
|
+
@item_rep = item_rep
|
|
26
|
+
@compiler = compiler
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Runs the item content through the given filter with the given arguments.
|
|
30
|
+
# This method will replace the content of the `:last` snapshot with the
|
|
31
|
+
# filtered content of the last snapshot.
|
|
32
|
+
#
|
|
33
|
+
# This method is supposed to be called only in a compilation rule block
|
|
34
|
+
# (see {Nanoc::CompilerDSL#compile}).
|
|
35
|
+
#
|
|
36
|
+
# @see Nanoc::ItemRep#filter
|
|
37
|
+
#
|
|
38
|
+
# @param [Symbol] filter_name The name of the filter to run the item
|
|
39
|
+
# representations' content through
|
|
40
|
+
#
|
|
41
|
+
# @param [Hash] filter_args The filter arguments that should be passed to
|
|
42
|
+
# the filter's #run method
|
|
43
|
+
#
|
|
44
|
+
# @return [void]
|
|
45
|
+
def filter(name, args={})
|
|
46
|
+
set_assigns
|
|
47
|
+
@item_rep.filter(name, args)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Lays out the item using the given layout. This method will replace the
|
|
51
|
+
# content of the `:last` snapshot with the laid out content of the last
|
|
52
|
+
# snapshot.
|
|
53
|
+
#
|
|
54
|
+
# This method is supposed to be called only in a compilation rule block
|
|
55
|
+
# (see {Nanoc::CompilerDSL#compile}).
|
|
56
|
+
#
|
|
57
|
+
# @see Nanoc::ItemRep#layout
|
|
58
|
+
#
|
|
59
|
+
# @param [String] layout_identifier The identifier of the layout to use
|
|
60
|
+
#
|
|
61
|
+
# @return [void]
|
|
62
|
+
def layout(layout_identifier, extra_filter_args={})
|
|
63
|
+
set_assigns
|
|
64
|
+
|
|
65
|
+
layout = layout_with_identifier(layout_identifier)
|
|
66
|
+
filter_name, filter_args = @compiler.rules_collection.filter_for_layout(layout)
|
|
67
|
+
filter_args = filter_args.merge(extra_filter_args)
|
|
68
|
+
|
|
69
|
+
@item_rep.layout(layout, filter_name, filter_args)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Returns true because this item is already a proxy, and therefore doesn’t
|
|
73
|
+
# need to be wrapped anymore.
|
|
74
|
+
#
|
|
75
|
+
# @api private
|
|
76
|
+
#
|
|
77
|
+
# @return [true]
|
|
78
|
+
#
|
|
79
|
+
# @see Nanoc::ItemRep#is_proxy?
|
|
80
|
+
# @see Nanoc::ItemRepRecorderProxy#is_proxy?
|
|
81
|
+
def is_proxy?
|
|
82
|
+
true
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def set_assigns
|
|
88
|
+
@item_rep.assigns = @compiler.assigns_for(@item_rep)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def layouts
|
|
92
|
+
@compiler.site.layouts
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def layout_with_identifier(layout_identifier)
|
|
96
|
+
layout ||= layouts.find { |l| l.identifier == layout_identifier.cleaned_identifier }
|
|
97
|
+
raise Nanoc::Errors::UnknownLayout.new(layout_identifier) if layout.nil?
|
|
98
|
+
layout
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Nanoc
|
|
4
|
+
|
|
5
|
+
# Represents a fake iem representation that does not actually perform any
|
|
6
|
+
# actual filtering, layouting or snapshotting, but instead keeps track of
|
|
7
|
+
# what would happen if a real item representation would have been used
|
|
8
|
+
# instead. It therefore “records” the actions that happens upon it.
|
|
9
|
+
#
|
|
10
|
+
# The list of recorded actions is used during compilation to determine
|
|
11
|
+
# whether an item representation needs to be recompiled: if the list of
|
|
12
|
+
# actions is different from the list of actions from the previous
|
|
13
|
+
# compilation run, the item needs to be recompiled; if it is the same, it
|
|
14
|
+
# may not need to be recompiled.
|
|
15
|
+
#
|
|
16
|
+
# @api private
|
|
17
|
+
class ItemRepRecorderProxy
|
|
18
|
+
|
|
19
|
+
extend Forwardable
|
|
20
|
+
|
|
21
|
+
def_delegators :@item_rep, :item, :name, :binary, :binary?, :compiled_content, :has_snapshot?, :raw_path, :path, :assigns, :assigns=
|
|
22
|
+
|
|
23
|
+
# @example The compilation rule and the corresponding rule memory
|
|
24
|
+
#
|
|
25
|
+
# # rule
|
|
26
|
+
# compile '/foo/' do
|
|
27
|
+
# filter :erb
|
|
28
|
+
# filter :myfilter, :arg1 => 'stuff'
|
|
29
|
+
# layout 'meh'
|
|
30
|
+
# end
|
|
31
|
+
#
|
|
32
|
+
# # memory
|
|
33
|
+
# [
|
|
34
|
+
# [ :filter, :erb, {} ],
|
|
35
|
+
# [ :filter, :myfilter, { :arg1 => 'stuff' } ],
|
|
36
|
+
# [ :layout, 'meh' ]
|
|
37
|
+
# ]
|
|
38
|
+
#
|
|
39
|
+
# @return [Array] The list of recorded actions (“rule memory”)
|
|
40
|
+
attr_reader :rule_memory
|
|
41
|
+
|
|
42
|
+
# @param [Nanoc::ItemRep] item_rep The item representation that this
|
|
43
|
+
# proxy should behave like
|
|
44
|
+
def initialize(item_rep)
|
|
45
|
+
@item_rep = item_rep
|
|
46
|
+
@rule_memory = []
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# @return [void]
|
|
50
|
+
#
|
|
51
|
+
# @see Nanoc::ItemRepProxy#filter, Nanoc::ItemRep#filter
|
|
52
|
+
def filter(name, args={})
|
|
53
|
+
@rule_memory << [ :filter, name, args ]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @return [void]
|
|
57
|
+
#
|
|
58
|
+
# @see Nanoc::ItemRepProxy#layout, Nanoc::ItemRep#layout
|
|
59
|
+
def layout(layout_identifier, extra_filter_args=nil)
|
|
60
|
+
if extra_filter_args
|
|
61
|
+
@rule_memory << [ :layout, layout_identifier, extra_filter_args ]
|
|
62
|
+
else
|
|
63
|
+
@rule_memory << [ :layout, layout_identifier ]
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @return [void]
|
|
68
|
+
#
|
|
69
|
+
# @see Nanoc::ItemRep#snapshot
|
|
70
|
+
def snapshot(snapshot_name, params={})
|
|
71
|
+
@rule_memory << [ :snapshot, snapshot_name, params ]
|
|
72
|
+
|
|
73
|
+
# Count
|
|
74
|
+
existing = Set.new
|
|
75
|
+
names = @rule_memory.select { |r| r[0] == :snapshot }.map { |r| r[2] }
|
|
76
|
+
names.each do |n|
|
|
77
|
+
if existing.include?(n)
|
|
78
|
+
raise Nanoc::Errors::CannotCreateMultipleSnapshotsWithSameName.new(@item_rep, snapshot_name)
|
|
79
|
+
end
|
|
80
|
+
existing << n
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @return [{}]
|
|
85
|
+
def content
|
|
86
|
+
{}
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Returns true because this item is already a proxy, and therefore doesn’t
|
|
90
|
+
# need to be wrapped anymore.
|
|
91
|
+
#
|
|
92
|
+
# @return [true]
|
|
93
|
+
#
|
|
94
|
+
# @see Nanoc::ItemRep#is_proxy?
|
|
95
|
+
# @see Nanoc::ItemRepProxy#is_proxy?
|
|
96
|
+
def is_proxy?
|
|
97
|
+
true
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Nanoc
|
|
4
|
+
|
|
5
|
+
# Responsible for determining whether an item or a layout is outdated.
|
|
6
|
+
#
|
|
7
|
+
# @api private
|
|
8
|
+
class OutdatednessChecker
|
|
9
|
+
|
|
10
|
+
extend Nanoc::Memoization
|
|
11
|
+
|
|
12
|
+
# @option params [Nanoc::Site] :site (nil) The site this outdatedness
|
|
13
|
+
# checker belongs to.
|
|
14
|
+
#
|
|
15
|
+
# @option params [Nanoc::ChecksumStore] :checksum_store (nil) The
|
|
16
|
+
# checksum store where checksums of items, layouts, … are stored.
|
|
17
|
+
#
|
|
18
|
+
# @option params [Nanoc::DependencyTracker] :dependency_tracker (nil) The
|
|
19
|
+
# dependency tracker for the given site.
|
|
20
|
+
def initialize(params={})
|
|
21
|
+
@site = params[:site] or raise ArgumentError,
|
|
22
|
+
'Nanoc::OutdatednessChecker#initialize needs a :site parameter'
|
|
23
|
+
@checksum_store = params[:checksum_store] or raise ArgumentError,
|
|
24
|
+
'Nanoc::OutdatednessChecker#initialize needs a :checksum_store parameter'
|
|
25
|
+
@dependency_tracker = params[:dependency_tracker] or raise ArgumentError,
|
|
26
|
+
'Nanoc::OutdatednessChecker#initialize needs a :dependency_tracker parameter'
|
|
27
|
+
|
|
28
|
+
@basic_outdatedness_reasons = {}
|
|
29
|
+
@outdatedness_reasons = {}
|
|
30
|
+
@objects_outdated_due_to_dependencies = {}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Checks whether the given object is outdated and therefore needs to be
|
|
34
|
+
# recompiled.
|
|
35
|
+
#
|
|
36
|
+
# @param [Nanoc::Item, Nanoc::ItemRep, Nanoc::Layout] obj The object
|
|
37
|
+
# whose outdatedness should be checked.
|
|
38
|
+
#
|
|
39
|
+
# @return [Boolean] true if the object is outdated, false otherwise
|
|
40
|
+
def outdated?(obj)
|
|
41
|
+
!outdatedness_reason_for(obj).nil?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Calculates the reason why the given object is outdated.
|
|
45
|
+
#
|
|
46
|
+
# @param [Nanoc::Item, Nanoc::ItemRep, Nanoc::Layout] obj The object
|
|
47
|
+
# whose outdatedness reason should be calculated.
|
|
48
|
+
#
|
|
49
|
+
# @return [Nanoc::OutdatednessReasons::Generic, nil] The reason why the
|
|
50
|
+
# given object is outdated, or nil if the object is not outdated.
|
|
51
|
+
def outdatedness_reason_for(obj)
|
|
52
|
+
reason = basic_outdatedness_reason_for(obj)
|
|
53
|
+
if reason.nil? && outdated_due_to_dependencies?(obj)
|
|
54
|
+
reason = Nanoc::OutdatednessReasons::DependenciesOutdated
|
|
55
|
+
end
|
|
56
|
+
reason
|
|
57
|
+
end
|
|
58
|
+
memoize :outdatedness_reason_for
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
# Checks whether the given object is outdated and therefore needs to be
|
|
63
|
+
# recompiled. This method does not take dependencies into account; use
|
|
64
|
+
# {#outdated?} if you want to include dependencies in the outdatedness
|
|
65
|
+
# check.
|
|
66
|
+
#
|
|
67
|
+
# @param [Nanoc::Item, Nanoc::ItemRep, Nanoc::Layout] obj The object
|
|
68
|
+
# whose outdatedness should be checked.
|
|
69
|
+
#
|
|
70
|
+
# @return [Boolean] true if the object is outdated, false otherwise
|
|
71
|
+
def basic_outdated?(obj)
|
|
72
|
+
!basic_outdatedness_reason_for(obj).nil?
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Calculates the reason why the given object is outdated. This method does
|
|
76
|
+
# not take dependencies into account; use {#outdatedness_reason_for?} if
|
|
77
|
+
# you want to include dependencies in the outdatedness check.
|
|
78
|
+
#
|
|
79
|
+
# @param [Nanoc::Item, Nanoc::ItemRep, Nanoc::Layout] obj The object
|
|
80
|
+
# whose outdatedness reason should be calculated.
|
|
81
|
+
#
|
|
82
|
+
# @return [Nanoc::OutdatednessReasons::Generic, nil] The reason why the
|
|
83
|
+
# given object is outdated, or nil if the object is not outdated.
|
|
84
|
+
def basic_outdatedness_reason_for(obj)
|
|
85
|
+
case obj.type
|
|
86
|
+
when :item_rep
|
|
87
|
+
# Outdated if rules outdated
|
|
88
|
+
return Nanoc::OutdatednessReasons::RulesModified if
|
|
89
|
+
rule_memory_differs_for(obj)
|
|
90
|
+
|
|
91
|
+
# Outdated if checksums are missing or different
|
|
92
|
+
return Nanoc::OutdatednessReasons::NotEnoughData if !checksums_available?(obj.item)
|
|
93
|
+
return Nanoc::OutdatednessReasons::SourceModified if !checksums_identical?(obj.item)
|
|
94
|
+
|
|
95
|
+
# Outdated if compiled file doesn't exist (yet)
|
|
96
|
+
return Nanoc::OutdatednessReasons::NotWritten if obj.raw_path && !File.file?(obj.raw_path)
|
|
97
|
+
|
|
98
|
+
# Outdated if code snippets outdated
|
|
99
|
+
return Nanoc::OutdatednessReasons::CodeSnippetsModified if site.code_snippets.any? do |cs|
|
|
100
|
+
object_modified?(cs)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Outdated if configuration outdated
|
|
104
|
+
return Nanoc::OutdatednessReasons::ConfigurationModified if object_modified?(site.config)
|
|
105
|
+
|
|
106
|
+
# Not outdated
|
|
107
|
+
return nil
|
|
108
|
+
when :item
|
|
109
|
+
obj.reps.find { |rep| basic_outdatedness_reason_for(rep) }
|
|
110
|
+
when :layout
|
|
111
|
+
# Outdated if rules outdated
|
|
112
|
+
return Nanoc::OutdatednessReasons::RulesModified if
|
|
113
|
+
rule_memory_differs_for(obj)
|
|
114
|
+
|
|
115
|
+
# Outdated if checksums are missing or different
|
|
116
|
+
return Nanoc::OutdatednessReasons::NotEnoughData if !checksums_available?(obj)
|
|
117
|
+
return Nanoc::OutdatednessReasons::SourceModified if !checksums_identical?(obj)
|
|
118
|
+
|
|
119
|
+
# Not outdated
|
|
120
|
+
return nil
|
|
121
|
+
else
|
|
122
|
+
raise RuntimeError, "do not know how to check outdatedness of #{obj.inspect}"
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
memoize :basic_outdatedness_reason_for
|
|
126
|
+
|
|
127
|
+
# Checks whether the given object is outdated due to dependencies.
|
|
128
|
+
#
|
|
129
|
+
# @param [Nanoc::Item, Nanoc::ItemRep, Nanoc::Layout] obj The object
|
|
130
|
+
# whose outdatedness should be checked.
|
|
131
|
+
#
|
|
132
|
+
# @param [Set] processed The collection of items that has been visited
|
|
133
|
+
# during this outdatedness check. This is used to prevent checks for
|
|
134
|
+
# items that (indirectly) depend on their own from looping
|
|
135
|
+
# indefinitely. It should not be necessary to pass this a custom value.
|
|
136
|
+
#
|
|
137
|
+
# @return [Boolean] true if the object is outdated, false otherwise
|
|
138
|
+
def outdated_due_to_dependencies?(obj, processed=Set.new)
|
|
139
|
+
# Convert from rep to item if necessary
|
|
140
|
+
obj = obj.item if obj.type == :item_rep
|
|
141
|
+
|
|
142
|
+
# Get from cache
|
|
143
|
+
if @objects_outdated_due_to_dependencies.has_key?(obj)
|
|
144
|
+
return @objects_outdated_due_to_dependencies[obj]
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Check processed
|
|
148
|
+
# Don’t return true; the false will be or’ed into a true if there
|
|
149
|
+
# really is a dependency that is causing outdatedness.
|
|
150
|
+
return false if processed.include?(obj)
|
|
151
|
+
|
|
152
|
+
# Calculate
|
|
153
|
+
is_outdated = dependency_tracker.objects_causing_outdatedness_of(obj).any? do |other|
|
|
154
|
+
other.nil? || basic_outdated?(other) || outdated_due_to_dependencies?(other, processed.merge([obj]))
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Cache
|
|
158
|
+
@objects_outdated_due_to_dependencies[obj] = is_outdated
|
|
159
|
+
|
|
160
|
+
# Done
|
|
161
|
+
is_outdated
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# @param [Nanoc::ItemRep, Nanoc::Layout] obj The layout or item
|
|
165
|
+
# representation to check the rule memory for
|
|
166
|
+
#
|
|
167
|
+
# @return [Boolean] true if the rule memory for the given item
|
|
168
|
+
# represenation has changed, false otherwise
|
|
169
|
+
def rule_memory_differs_for(obj)
|
|
170
|
+
rules_collection.rule_memory_differs_for(obj)
|
|
171
|
+
end
|
|
172
|
+
memoize :rule_memory_differs_for
|
|
173
|
+
|
|
174
|
+
# @param obj
|
|
175
|
+
#
|
|
176
|
+
# @return [Boolean] false if either the new or the old checksum for the
|
|
177
|
+
# given object is not available, true if both checksums are available
|
|
178
|
+
def checksums_available?(obj)
|
|
179
|
+
!!checksum_store[obj] && obj.checksum
|
|
180
|
+
end
|
|
181
|
+
memoize :checksums_available?
|
|
182
|
+
|
|
183
|
+
# @param obj
|
|
184
|
+
#
|
|
185
|
+
# @return [Boolean] false if the old and new checksums for the given
|
|
186
|
+
# object differ, true if they are identical
|
|
187
|
+
def checksums_identical?(obj)
|
|
188
|
+
checksum_store[obj] == obj.checksum
|
|
189
|
+
end
|
|
190
|
+
memoize :checksums_identical?
|
|
191
|
+
|
|
192
|
+
# @param obj
|
|
193
|
+
#
|
|
194
|
+
# @return [Boolean] true if the old and new checksums for the given object
|
|
195
|
+
# are available and identical, false otherwise
|
|
196
|
+
def object_modified?(obj)
|
|
197
|
+
!checksums_available?(obj) || !checksums_identical?(obj)
|
|
198
|
+
end
|
|
199
|
+
memoize :object_modified?
|
|
200
|
+
|
|
201
|
+
# @return [Nanoc::ChecksumStore] The checksum store
|
|
202
|
+
def checksum_store
|
|
203
|
+
@checksum_store
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# @return [Nanoc::RulesCollection] The rules collection
|
|
207
|
+
def rules_collection
|
|
208
|
+
site.compiler.rules_collection
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# @return [Nanoc::DependencyTracker] The dependency tracker
|
|
212
|
+
def dependency_tracker
|
|
213
|
+
@dependency_tracker
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# @return [Nanoc::Site] The site
|
|
217
|
+
def site
|
|
218
|
+
@site
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module Nanoc
|
|
4
|
+
|
|
5
|
+
# Module that contains all outdatedness reasons.
|
|
6
|
+
module OutdatednessReasons
|
|
7
|
+
|
|
8
|
+
# A generic outdatedness reason. An outdatedness reason is basically a
|
|
9
|
+
# descriptive message that explains why a given object is outdated.
|
|
10
|
+
class Generic
|
|
11
|
+
|
|
12
|
+
# @return [String] A descriptive message for this outdatedness reason
|
|
13
|
+
attr_reader :message
|
|
14
|
+
|
|
15
|
+
# @param [String] message The descriptive message for this outdatedness
|
|
16
|
+
# reason
|
|
17
|
+
def initialize(message)
|
|
18
|
+
@message = message
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
CodeSnippetsModified = Generic.new(
|
|
24
|
+
'The code snippets have been modified since the last time the site was compiled.')
|
|
25
|
+
|
|
26
|
+
ConfigurationModified = Generic.new(
|
|
27
|
+
'The site configuration has been modified since the last time the site was compiled.')
|
|
28
|
+
|
|
29
|
+
DependenciesOutdated = Generic.new(
|
|
30
|
+
'This item uses content or attributes that have changed since the last time the site was compiled.')
|
|
31
|
+
|
|
32
|
+
NotEnoughData = Generic.new(
|
|
33
|
+
'Not enough data is present to correctly determine whether the item is outdated.')
|
|
34
|
+
|
|
35
|
+
NotWritten = Generic.new(
|
|
36
|
+
'This item representation has not yet been written to the output directory (but it does have a path).')
|
|
37
|
+
|
|
38
|
+
RulesModified = Generic.new(
|
|
39
|
+
'The rules file has been modified since the last time the site was compiled.')
|
|
40
|
+
|
|
41
|
+
SourceModified = Generic.new(
|
|
42
|
+
'The source file of this item has been modified since the last time the site was compiled.')
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|