nanoc-core 4.11.12 → 4.11.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/nanoc/core.rb +37 -0
- data/lib/nanoc/core/basic_item_rep_collection_view.rb +88 -0
- data/lib/nanoc/core/basic_item_rep_view.rb +83 -0
- data/lib/nanoc/core/basic_item_view.rb +54 -0
- data/lib/nanoc/core/checksummer.rb +2 -0
- data/lib/nanoc/core/compilation_item_rep_collection_view.rb +12 -0
- data/lib/nanoc/core/compilation_item_rep_view.rb +51 -0
- data/lib/nanoc/core/compilation_item_view.rb +47 -0
- data/lib/nanoc/core/compilation_phases/abstract.rb +48 -0
- data/lib/nanoc/core/compilation_phases/cache.rb +43 -0
- data/lib/nanoc/core/compilation_phases/mark_done.rb +23 -0
- data/lib/nanoc/core/compilation_phases/notify.rb +19 -0
- data/lib/nanoc/core/compilation_phases/recalculate.rb +49 -0
- data/lib/nanoc/core/compilation_phases/resume.rb +52 -0
- data/lib/nanoc/core/compilation_phases/write.rb +84 -0
- data/lib/nanoc/core/compilation_stages/build_reps.rb +36 -0
- data/lib/nanoc/core/compilation_stages/calculate_checksums.rb +42 -0
- data/lib/nanoc/core/compilation_stages/cleanup.rb +43 -0
- data/lib/nanoc/core/compilation_stages/compile_reps.rb +96 -0
- data/lib/nanoc/core/compilation_stages/determine_outdatedness.rb +49 -0
- data/lib/nanoc/core/compilation_stages/forget_outdated_dependencies.rb +20 -0
- data/lib/nanoc/core/compilation_stages/load_stores.rb +35 -0
- data/lib/nanoc/core/compilation_stages/postprocess.rb +21 -0
- data/lib/nanoc/core/compilation_stages/preprocess.rb +32 -0
- data/lib/nanoc/core/compilation_stages/prune.rb +30 -0
- data/lib/nanoc/core/compilation_stages/store_post_compilation_state.rb +20 -0
- data/lib/nanoc/core/compilation_stages/store_pre_compilation_state.rb +32 -0
- data/lib/nanoc/core/compiler.rb +214 -0
- data/lib/nanoc/core/compiler_loader.rb +48 -0
- data/lib/nanoc/core/config_loader.rb +95 -0
- data/lib/nanoc/core/config_view.rb +67 -0
- data/lib/nanoc/core/configuration.rb +2 -4
- data/lib/nanoc/core/document_view_mixin.rb +87 -0
- data/lib/nanoc/core/errors.rb +97 -0
- data/lib/nanoc/core/executor.rb +134 -0
- data/lib/nanoc/core/feature.rb +92 -0
- data/lib/nanoc/core/filter.rb +269 -0
- data/lib/nanoc/core/identifiable_collection_view.rb +111 -0
- data/lib/nanoc/core/item_collection_with_reps_view.rb +12 -0
- data/lib/nanoc/core/item_collection_without_reps_view.rb +12 -0
- data/lib/nanoc/core/item_rep_builder.rb +54 -0
- data/lib/nanoc/core/item_rep_selector.rb +67 -0
- data/lib/nanoc/core/item_rep_writer.rb +85 -0
- data/lib/nanoc/core/layout_collection_view.rb +12 -0
- data/lib/nanoc/core/layout_view.rb +9 -0
- data/lib/nanoc/core/mutable_config_view.rb +16 -0
- data/lib/nanoc/core/mutable_document_view_mixin.rb +60 -0
- data/lib/nanoc/core/mutable_identifiable_collection_view.rb +19 -0
- data/lib/nanoc/core/mutable_item_collection_view.rb +34 -0
- data/lib/nanoc/core/mutable_item_view.rb +9 -0
- data/lib/nanoc/core/mutable_layout_collection_view.rb +26 -0
- data/lib/nanoc/core/mutable_layout_view.rb +9 -0
- data/lib/nanoc/core/outdatedness_checker.rb +222 -0
- data/lib/nanoc/core/outdatedness_rules/attributes_modified.rb +41 -0
- data/lib/nanoc/core/outdatedness_rules/code_snippets_modified.rb +31 -0
- data/lib/nanoc/core/outdatedness_rules/content_modified.rb +21 -0
- data/lib/nanoc/core/outdatedness_rules/item_collection_extended.rb +20 -0
- data/lib/nanoc/core/outdatedness_rules/layout_collection_extended.rb +20 -0
- data/lib/nanoc/core/outdatedness_rules/not_written.rb +17 -0
- data/lib/nanoc/core/outdatedness_rules/rules_modified.rb +45 -0
- data/lib/nanoc/core/outdatedness_rules/uses_always_outdated_filter.rb +26 -0
- data/lib/nanoc/core/post_compile_item_collection_view.rb +12 -0
- data/lib/nanoc/core/post_compile_item_rep_collection_view.rb +12 -0
- data/lib/nanoc/core/post_compile_item_rep_view.rb +33 -0
- data/lib/nanoc/core/post_compile_item_view.rb +20 -0
- data/lib/nanoc/core/pruner.rb +119 -0
- data/lib/nanoc/core/site_loader.rb +102 -0
- data/lib/nanoc/core/trivial_error.rb +10 -0
- data/lib/nanoc/core/version.rb +1 -1
- data/lib/nanoc/core/view.rb +43 -0
- data/lib/nanoc/core/view_context_for_compilation.rb +6 -6
- metadata +95 -2
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Core
|
5
|
+
module OutdatednessRules
|
6
|
+
class AttributesModified < Nanoc::Core::OutdatednessRule
|
7
|
+
include Nanoc::Core::ContractsSupport
|
8
|
+
|
9
|
+
affects_props :attributes, :compiled_content
|
10
|
+
|
11
|
+
contract C::Or[Nanoc::Core::ItemRep, Nanoc::Core::Item, Nanoc::Core::Configuration, Nanoc::Core::Layout], C::Named['Nanoc::Core::OutdatednessChecker'] => C::Maybe[Nanoc::Core::OutdatednessReasons::Generic]
|
12
|
+
def apply(obj, outdatedness_checker)
|
13
|
+
case obj
|
14
|
+
when Nanoc::Core::ItemRep
|
15
|
+
apply(obj.item, outdatedness_checker)
|
16
|
+
when Nanoc::Core::Item, Nanoc::Core::Layout, Nanoc::Core::Configuration
|
17
|
+
if outdatedness_checker.checksum_store[obj] == outdatedness_checker.checksums.checksum_for(obj)
|
18
|
+
return nil
|
19
|
+
end
|
20
|
+
|
21
|
+
old_checksums = outdatedness_checker.checksum_store.attributes_checksum_for(obj)
|
22
|
+
unless old_checksums
|
23
|
+
return Nanoc::Core::OutdatednessReasons::AttributesModified.new(true)
|
24
|
+
end
|
25
|
+
|
26
|
+
new_checksums = outdatedness_checker.checksums.attributes_checksum_for(obj)
|
27
|
+
|
28
|
+
attributes = Set.new(old_checksums.keys) + Set.new(new_checksums.keys)
|
29
|
+
changed_attributes = attributes.reject { |a| old_checksums[a] == new_checksums[a] }
|
30
|
+
|
31
|
+
if changed_attributes.any?
|
32
|
+
Nanoc::Core::OutdatednessReasons::AttributesModified.new(changed_attributes)
|
33
|
+
end
|
34
|
+
else
|
35
|
+
raise ArgumentError
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Core
|
5
|
+
module OutdatednessRules
|
6
|
+
class CodeSnippetsModified < Nanoc::Core::OutdatednessRule
|
7
|
+
DDMemoize.activate(self)
|
8
|
+
|
9
|
+
include Nanoc::Core::ContractsSupport
|
10
|
+
|
11
|
+
affects_props :raw_content, :attributes, :compiled_content, :path
|
12
|
+
|
13
|
+
def apply(_obj, outdatedness_checker)
|
14
|
+
if any_snippets_modified?(outdatedness_checker)
|
15
|
+
Nanoc::Core::OutdatednessReasons::CodeSnippetsModified
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
memoized def any_snippets_modified?(outdatedness_checker)
|
22
|
+
outdatedness_checker.site.code_snippets.any? do |cs|
|
23
|
+
ch_old = outdatedness_checker.checksum_store[cs]
|
24
|
+
ch_new = outdatedness_checker.checksums.checksum_for(cs)
|
25
|
+
ch_old != ch_new
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Core
|
5
|
+
module OutdatednessRules
|
6
|
+
class ContentModified < Nanoc::Core::OutdatednessRule
|
7
|
+
affects_props :raw_content, :compiled_content
|
8
|
+
|
9
|
+
def apply(obj, outdatedness_checker)
|
10
|
+
obj = obj.item if obj.is_a?(Nanoc::Core::ItemRep)
|
11
|
+
|
12
|
+
ch_old = outdatedness_checker.checksum_store.content_checksum_for(obj)
|
13
|
+
ch_new = outdatedness_checker.checksums.content_checksum_for(obj)
|
14
|
+
if ch_old != ch_new
|
15
|
+
Nanoc::Core::OutdatednessReasons::ContentModified
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Core
|
5
|
+
module OutdatednessRules
|
6
|
+
class ItemCollectionExtended < Nanoc::Core::OutdatednessRule
|
7
|
+
affects_props :raw_content
|
8
|
+
|
9
|
+
contract Nanoc::Core::ItemCollection, C::Named['Nanoc::Core::OutdatednessChecker'] => C::Maybe[Nanoc::Core::OutdatednessReasons::Generic]
|
10
|
+
def apply(_obj, outdatedness_checker)
|
11
|
+
new_items = outdatedness_checker.dependency_store.new_items
|
12
|
+
|
13
|
+
if new_items.any?
|
14
|
+
Nanoc::Core::OutdatednessReasons::ItemCollectionExtended.new(new_items)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Core
|
5
|
+
module OutdatednessRules
|
6
|
+
class LayoutCollectionExtended < Nanoc::Core::OutdatednessRule
|
7
|
+
affects_props :raw_content
|
8
|
+
|
9
|
+
contract Nanoc::Core::LayoutCollection, C::Named['Nanoc::Core::OutdatednessChecker'] => C::Maybe[Nanoc::Core::OutdatednessReasons::Generic]
|
10
|
+
def apply(_obj, outdatedness_checker)
|
11
|
+
new_layouts = outdatedness_checker.dependency_store.new_layouts
|
12
|
+
|
13
|
+
if new_layouts.any?
|
14
|
+
Nanoc::Core::OutdatednessReasons::LayoutCollectionExtended.new(new_layouts)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Core
|
5
|
+
module OutdatednessRules
|
6
|
+
class NotWritten < Nanoc::Core::OutdatednessRule
|
7
|
+
affects_props :raw_content, :attributes, :compiled_content, :path
|
8
|
+
|
9
|
+
def apply(obj, _outdatedness_checker)
|
10
|
+
if obj.raw_paths.values.flatten.compact.any? { |fn| !File.file?(fn) }
|
11
|
+
Nanoc::Core::OutdatednessReasons::NotWritten
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Core
|
5
|
+
module OutdatednessRules
|
6
|
+
class RulesModified < Nanoc::Core::OutdatednessRule
|
7
|
+
affects_props :compiled_content, :path
|
8
|
+
|
9
|
+
def apply(obj, outdatedness_checker)
|
10
|
+
# Check rules of obj itself
|
11
|
+
if rules_modified?(obj, outdatedness_checker)
|
12
|
+
return Nanoc::Core::OutdatednessReasons::RulesModified
|
13
|
+
end
|
14
|
+
|
15
|
+
# Check rules of layouts used by obj
|
16
|
+
layouts = layouts_touched_by(obj, outdatedness_checker)
|
17
|
+
if layouts.any? { |layout| rules_modified?(layout, outdatedness_checker) }
|
18
|
+
return Nanoc::Core::OutdatednessReasons::RulesModified
|
19
|
+
end
|
20
|
+
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def rules_modified?(obj, outdatedness_checker)
|
27
|
+
seq_old = outdatedness_checker.action_sequence_store[obj]
|
28
|
+
seq_new = outdatedness_checker.action_sequence_for(obj).serialize
|
29
|
+
|
30
|
+
!seq_old.eql?(seq_new)
|
31
|
+
end
|
32
|
+
|
33
|
+
def layouts_touched_by(obj, outdatedness_checker)
|
34
|
+
actions = outdatedness_checker.action_sequence_store[obj]
|
35
|
+
layout_actions = actions.select { |a| a.first == :layout }
|
36
|
+
|
37
|
+
layout_actions.map do |layout_action|
|
38
|
+
layout_pattern = layout_action[1]
|
39
|
+
outdatedness_checker.site.layouts[layout_pattern]
|
40
|
+
end.compact
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Core
|
5
|
+
module OutdatednessRules
|
6
|
+
class UsesAlwaysOutdatedFilter < Nanoc::Core::OutdatednessRule
|
7
|
+
affects_props :raw_content, :attributes, :path
|
8
|
+
|
9
|
+
def apply(obj, outdatedness_checker)
|
10
|
+
seq = outdatedness_checker.action_sequence_for(obj)
|
11
|
+
if any_always_outdated?(seq)
|
12
|
+
Nanoc::Core::OutdatednessReasons::UsesAlwaysOutdatedFilter
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def any_always_outdated?(seq)
|
17
|
+
seq
|
18
|
+
.select { |a| a.is_a?(Nanoc::Core::ProcessingActions::Filter) }
|
19
|
+
.map { |a| Nanoc::Core::Filter.named(a.filter_name) }
|
20
|
+
.compact
|
21
|
+
.any?(&:always_outdated?)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Core
|
5
|
+
class PostCompileItemRepView < ::Nanoc::Core::BasicItemRepView
|
6
|
+
def item_view_class
|
7
|
+
Nanoc::Core::PostCompileItemView
|
8
|
+
end
|
9
|
+
|
10
|
+
def compiled_content(snapshot: nil)
|
11
|
+
compilation_context = @context.compilation_context
|
12
|
+
snapshot_contents = compilation_context.compiled_content_cache[_unwrap] || {}
|
13
|
+
|
14
|
+
snapshot_name = snapshot || (snapshot_contents[:pre] ? :pre : :last)
|
15
|
+
|
16
|
+
unless snapshot_contents[snapshot_name]
|
17
|
+
raise Nanoc::Core::Errors::NoSuchSnapshot.new(_unwrap, snapshot_name)
|
18
|
+
end
|
19
|
+
|
20
|
+
content = snapshot_contents[snapshot_name]
|
21
|
+
if content.binary?
|
22
|
+
raise Nanoc::Core::Errors::CannotGetCompiledContentOfBinaryItem.new(_unwrap)
|
23
|
+
end
|
24
|
+
|
25
|
+
content.string
|
26
|
+
end
|
27
|
+
|
28
|
+
def raw_path(snapshot: :last)
|
29
|
+
@item_rep.raw_path(snapshot: snapshot)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Core
|
5
|
+
class PostCompileItemView < Nanoc::Core::CompilationItemView
|
6
|
+
def reps
|
7
|
+
Nanoc::Core::PostCompileItemRepCollectionView.new(@context.reps[_unwrap], @context)
|
8
|
+
end
|
9
|
+
|
10
|
+
# @deprecated Use {#modified_reps} instead
|
11
|
+
def modified
|
12
|
+
modified_reps
|
13
|
+
end
|
14
|
+
|
15
|
+
def modified_reps
|
16
|
+
reps.select { |rep| rep._unwrap.modified? }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Core
|
5
|
+
# Responsible for finding and deleting files in the site’s output directory
|
6
|
+
# that are not managed by Nanoc.
|
7
|
+
class Pruner
|
8
|
+
include Nanoc::Core::ContractsSupport
|
9
|
+
|
10
|
+
contract Nanoc::Core::Configuration, Nanoc::Core::ItemRepRepo, C::KeywordArgs[dry_run: C::Optional[C::Bool], exclude: C::Optional[C::IterOf[String]]] => C::Any
|
11
|
+
def initialize(config, reps, dry_run: false, exclude: [])
|
12
|
+
@config = config
|
13
|
+
@reps = reps
|
14
|
+
@dry_run = dry_run
|
15
|
+
@exclude = Set.new(exclude)
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
return unless File.directory?(@config.output_dir)
|
20
|
+
|
21
|
+
compiled_files = @reps.flat_map { |r| r.raw_paths.values.flatten }.compact
|
22
|
+
present_files, present_dirs = files_and_dirs_in(@config.output_dir + '/')
|
23
|
+
|
24
|
+
remove_stray_files(present_files, compiled_files)
|
25
|
+
remove_empty_directories(present_dirs)
|
26
|
+
end
|
27
|
+
|
28
|
+
contract String => C::Bool
|
29
|
+
def filename_excluded?(filename)
|
30
|
+
pathname = Pathname.new(strip_output_dir(filename))
|
31
|
+
@exclude.any? { |e| pathname_components(pathname).include?(e) }
|
32
|
+
end
|
33
|
+
|
34
|
+
contract String => String
|
35
|
+
def strip_output_dir(filename)
|
36
|
+
if filename.start_with?(@config.output_dir)
|
37
|
+
filename[@config.output_dir.size..-1]
|
38
|
+
else
|
39
|
+
filename
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
contract Pathname => C::ArrayOf[String]
|
44
|
+
def pathname_components(pathname)
|
45
|
+
components = []
|
46
|
+
tmp = pathname
|
47
|
+
loop do
|
48
|
+
old = tmp
|
49
|
+
components << File.basename(tmp)
|
50
|
+
tmp = File.dirname(tmp)
|
51
|
+
break if old == tmp
|
52
|
+
end
|
53
|
+
components.reverse
|
54
|
+
end
|
55
|
+
|
56
|
+
contract C::ArrayOf[String], C::ArrayOf[String] => self
|
57
|
+
# @api private
|
58
|
+
def remove_stray_files(present_files, compiled_files)
|
59
|
+
(present_files - compiled_files).each do |f|
|
60
|
+
delete_file(f) unless filename_excluded?(f)
|
61
|
+
end
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
65
|
+
contract C::ArrayOf[String] => self
|
66
|
+
# @api private
|
67
|
+
def remove_empty_directories(present_dirs)
|
68
|
+
present_dirs.reverse_each do |dir|
|
69
|
+
next if Dir.foreach(dir) { |n| break true if n !~ /\A\.\.?\z/ }
|
70
|
+
next if filename_excluded?(dir)
|
71
|
+
|
72
|
+
delete_dir(dir)
|
73
|
+
end
|
74
|
+
self
|
75
|
+
end
|
76
|
+
|
77
|
+
contract String => C::ArrayOf[C::ArrayOf[String]]
|
78
|
+
# @api private
|
79
|
+
def files_and_dirs_in(dir)
|
80
|
+
present_files = []
|
81
|
+
present_dirs = []
|
82
|
+
|
83
|
+
expanded_dir = File.expand_path(dir)
|
84
|
+
|
85
|
+
Find.find(dir) do |f|
|
86
|
+
case File.ftype(f)
|
87
|
+
when 'file'
|
88
|
+
unless filename_excluded?(f)
|
89
|
+
present_files << f
|
90
|
+
end
|
91
|
+
when 'directory'
|
92
|
+
if filename_excluded?(f)
|
93
|
+
Find.prune
|
94
|
+
elsif expanded_dir != File.expand_path(f)
|
95
|
+
present_dirs << f
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
[present_files, present_dirs]
|
101
|
+
end
|
102
|
+
|
103
|
+
protected
|
104
|
+
|
105
|
+
def delete_file(file)
|
106
|
+
log_delete_and_run(file) { FileUtils.rm(file) }
|
107
|
+
end
|
108
|
+
|
109
|
+
def delete_dir(dir)
|
110
|
+
log_delete_and_run(dir) { Dir.rmdir(dir) }
|
111
|
+
end
|
112
|
+
|
113
|
+
def log_delete_and_run(thing)
|
114
|
+
Nanoc::Core::NotificationCenter.post(:file_pruned, thing)
|
115
|
+
yield unless @dry_run
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Core
|
5
|
+
class SiteLoader
|
6
|
+
ENCODING_REGEX = /\A#\s+(-\*-\s+)?(en)?coding: (?<encoding>[^\s]+)(\s+-\*-\s*)?\n{0,2}/.freeze
|
7
|
+
|
8
|
+
def new_from_cwd
|
9
|
+
site_from_config(Nanoc::Core::ConfigLoader.new.new_from_cwd)
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [Boolean]
|
13
|
+
def self.cwd_is_nanoc_site?
|
14
|
+
Nanoc::Core::ConfigLoader.cwd_is_nanoc_site?
|
15
|
+
end
|
16
|
+
|
17
|
+
def gen_data_source_for_config(config)
|
18
|
+
data_sources_to_aggregate =
|
19
|
+
with_data_sources(config) do |data_sources|
|
20
|
+
data_sources.map do |ds|
|
21
|
+
Nanoc::Core::PrefixedDataSource.new(ds, ds.items_root, ds.layouts_root)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
Nanoc::Core::AggregateDataSource.new(data_sources_to_aggregate, config)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def site_from_config(config)
|
31
|
+
code_snippets = code_snippets_from_config(config)
|
32
|
+
code_snippets.each(&:load)
|
33
|
+
|
34
|
+
data_source = gen_data_source_for_config(config)
|
35
|
+
|
36
|
+
Nanoc::Core::Site.new(
|
37
|
+
config: config,
|
38
|
+
code_snippets: code_snippets,
|
39
|
+
data_source: data_source,
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def with_data_sources(config, &_block)
|
44
|
+
data_sources = create_data_sources(config)
|
45
|
+
|
46
|
+
begin
|
47
|
+
data_sources.each(&:use)
|
48
|
+
yield(data_sources)
|
49
|
+
ensure
|
50
|
+
data_sources.each(&:unuse)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def create_data_sources(config)
|
55
|
+
config[:data_sources].map do |data_source_hash|
|
56
|
+
# Get data source class
|
57
|
+
data_source_class = Nanoc::Core::DataSource.named(data_source_hash[:type].to_sym)
|
58
|
+
if data_source_class.nil?
|
59
|
+
raise Nanoc::Core::Errors::UnknownDataSource.new(data_source_hash[:type])
|
60
|
+
end
|
61
|
+
|
62
|
+
# Create data source
|
63
|
+
data_source_class.new(
|
64
|
+
config,
|
65
|
+
data_source_hash[:items_root],
|
66
|
+
data_source_hash[:layouts_root],
|
67
|
+
data_source_hash.merge(data_source_hash[:config] || {}),
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def code_snippets_from_config(config)
|
73
|
+
config[:lib_dirs].flat_map do |lib|
|
74
|
+
Dir["#{lib}/**/*.rb"].sort.map do |filename|
|
75
|
+
Nanoc::Core::CodeSnippet.new(
|
76
|
+
read_code_snippet_contents(filename),
|
77
|
+
filename,
|
78
|
+
)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def encoding_from_magic_comment(raw)
|
84
|
+
match = ENCODING_REGEX.match(raw)
|
85
|
+
match ? match['encoding'] : nil
|
86
|
+
end
|
87
|
+
|
88
|
+
def read_code_snippet_contents(filename)
|
89
|
+
raw = File.read(filename, encoding: 'ASCII-8BIT')
|
90
|
+
|
91
|
+
enc = encoding_from_magic_comment(raw)
|
92
|
+
if enc
|
93
|
+
raw = raw.force_encoding(enc).encode('UTF-8').sub(ENCODING_REGEX, '')
|
94
|
+
else
|
95
|
+
raw.force_encoding('UTF-8')
|
96
|
+
end
|
97
|
+
|
98
|
+
raw
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|