nanoc 4.4.6 → 4.4.7

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.
@@ -16,6 +16,9 @@ module Nanoc::Int
16
16
 
17
17
  action_provider ||= Nanoc::Int::ActionProvider.named(:rule_dsl).for(site)
18
18
 
19
+ outdatedness_store =
20
+ Nanoc::Int::OutdatednessStore.new(site: site, reps: item_rep_repo)
21
+
19
22
  outdatedness_checker =
20
23
  Nanoc::Int::OutdatednessChecker.new(
21
24
  site: site,
@@ -40,6 +43,7 @@ module Nanoc::Int
40
43
  outdatedness_checker: outdatedness_checker,
41
44
  reps: item_rep_repo,
42
45
  action_provider: action_provider,
46
+ outdatedness_store: outdatedness_store,
43
47
  }
44
48
 
45
49
  Nanoc::Int::Compiler.new(site, params)
@@ -82,12 +82,8 @@ module Nanoc::Int
82
82
 
83
83
  Reasons = Nanoc::Int::OutdatednessReasons
84
84
 
85
- # @param [Nanoc::Int::Site] site
86
- # @param [Nanoc::Int::ChecksumStore] checksum_store
87
- # @param [Nanoc::Int::DependencyStore] dependency_store
88
- # @param [Nanoc::Int::RuleMemoryStore] rule_memory_store
89
- # @param [Nanoc::Int::ActionProvider] action_provider
90
- # @param [Nanoc::Int::ItemRepRepo] reps
85
+ # FIXME: Replace C::Any with proper types
86
+ contract C::KeywordArgs[site: Nanoc::Int::Site, checksum_store: Nanoc::Int::ChecksumStore, dependency_store: Nanoc::Int::DependencyStore, rule_memory_store: Nanoc::Int::RuleMemoryStore, action_provider: C::Any, reps: Nanoc::Int::ItemRepRepo] => C::Any
91
87
  def initialize(site:, checksum_store:, dependency_store:, rule_memory_store:, action_provider:, reps:)
92
88
  @site = site
93
89
  @checksum_store = checksum_store
@@ -12,8 +12,6 @@ module ::Nanoc::Checking::Checks
12
12
  identifiers :external_links, :elinks
13
13
 
14
14
  def run
15
- require 'parallel'
16
-
17
15
  # Find all broken external hrefs
18
16
  # TODO: de-duplicate this (duplicated in internal links check)
19
17
  filenames = output_filenames.select { |f| File.extname(f) == '.html' && !excluded_file?(f) }
@@ -163,7 +163,7 @@ module Nanoc::DataSources
163
163
  attributes,
164
164
  identifier,
165
165
  content_checksum_data: proto_doc.content_checksum_data,
166
- attributes_checksum_data: proto_doc.attributes_checksum_data,
166
+ attributes_checksum_data: attributes_checksum_data_for(proto_doc, content_filename, meta_filename),
167
167
  )
168
168
  end
169
169
  end
@@ -171,16 +171,25 @@ module Nanoc::DataSources
171
171
  res
172
172
  end
173
173
 
174
- def attributes_for(proto_doc, content_filename, meta_filename)
175
- extra_attributes = {
174
+ def attributes_checksum_data_for(proto_doc, content_filename, meta_filename)
175
+ YAML.dump(
176
+ attributes: proto_doc.attributes_checksum_data,
177
+ extra_attributes: extra_attributes_for(content_filename, meta_filename),
178
+ )
179
+ end
180
+
181
+ def extra_attributes_for(content_filename, meta_filename)
182
+ {
176
183
  filename: content_filename,
177
184
  content_filename: content_filename,
178
185
  meta_filename: meta_filename,
179
186
  extension: content_filename ? ext_of(content_filename)[1..-1] : nil,
180
187
  mtime: mtime_of(content_filename, meta_filename),
181
188
  }
189
+ end
182
190
 
183
- extra_attributes.merge(proto_doc.attributes)
191
+ def attributes_for(proto_doc, content_filename, meta_filename)
192
+ extra_attributes_for(content_filename, meta_filename).merge(proto_doc.attributes)
184
193
  end
185
194
 
186
195
  def identifier_for(content_filename, meta_filename, dir_name)
@@ -1,4 +1,4 @@
1
1
  module Nanoc
2
2
  # The current Nanoc version.
3
- VERSION = '4.4.6'.freeze
3
+ VERSION = '4.4.7'.freeze
4
4
  end
@@ -9,16 +9,18 @@ describe Nanoc::Int::Compiler do
9
9
  dependency_store: dependency_store,
10
10
  outdatedness_checker: outdatedness_checker,
11
11
  reps: reps,
12
+ outdatedness_store: outdatedness_store,
12
13
  )
13
14
  end
14
15
 
15
- let(:checksum_store) { :__irrelevant_checksum_store }
16
- let(:rule_memory_store) { :__irrelevant_rule_memory_store }
16
+ let(:checksum_store) { Nanoc::Int::ChecksumStore.new(objects: items) }
17
+ let(:rule_memory_store) { Nanoc::Int::RuleMemoryStore.new }
17
18
 
18
19
  let(:dependency_store) { Nanoc::Int::DependencyStore.new(items.to_a) }
19
20
  let(:reps) { Nanoc::Int::ItemRepRepo.new }
20
21
 
21
22
  let(:outdatedness_checker) { double(:outdatedness_checker) }
23
+ let(:outdatedness_store) { Nanoc::Int::OutdatednessStore.new(site: site, reps: reps) }
22
24
  let(:action_provider) { double(:action_provider) }
23
25
 
24
26
  let(:compiled_content_cache) { Nanoc::Int::CompiledContentCache.new(items: items) }
@@ -50,10 +52,13 @@ describe Nanoc::Int::Compiler do
50
52
  end
51
53
 
52
54
  let(:memory) do
53
- [
54
- Nanoc::Int::ProcessingActions::Filter.new(:erb, {}),
55
- Nanoc::Int::ProcessingActions::Snapshot.new(:last, nil),
56
- ]
55
+ actions =
56
+ [
57
+ Nanoc::Int::ProcessingActions::Filter.new(:erb, {}),
58
+ Nanoc::Int::ProcessingActions::Snapshot.new(:last, nil),
59
+ ]
60
+
61
+ Nanoc::Int::RuleMemory.new(nil, actions: actions)
57
62
  end
58
63
 
59
64
  before do
@@ -72,7 +77,10 @@ describe Nanoc::Int::Compiler do
72
77
  end
73
78
 
74
79
  describe '#compile_reps' do
75
- subject { compiler.send(:compile_reps) }
80
+ subject do
81
+ compiler.send(:determine_outdatedness)
82
+ compiler.send(:compile_reps)
83
+ end
76
84
 
77
85
  before do
78
86
  allow(action_provider).to receive(:snapshots_defs_for).with(rep).and_return(snapshot_defs_for_rep)
@@ -93,6 +101,21 @@ describe Nanoc::Int::Compiler do
93
101
  .to('3')
94
102
  end
95
103
 
104
+ it 'removes the item rep from the outdatedness store' do
105
+ expect(compiler.outdatedness_store.include?(rep)).not_to be
106
+ expect { subject }.not_to change { compiler.outdatedness_store.include?(rep) }
107
+ end
108
+
109
+ context 'rep in outdatedness store' do
110
+ before do
111
+ compiler.outdatedness_store.add(rep)
112
+ end
113
+
114
+ it 'removes the item rep from the outdatedness store' do
115
+ expect { subject }.to change { compiler.outdatedness_store.include?(rep) }.from(true).to(false)
116
+ end
117
+ end
118
+
96
119
  context 'exception' do
97
120
  let(:item) { Nanoc::Int::Item.new('<%= raise "lol" %>', {}, '/hi.md') }
98
121
 
@@ -112,11 +135,28 @@ describe Nanoc::Int::Compiler do
112
135
  expect(err.unwrap.message).to eq('lol')
113
136
  end
114
137
  end
138
+
139
+ it 'adds the item rep to the outdatedness store' do
140
+ expect { subject rescue nil }.to change { compiler.outdatedness_store.include?(rep) }.from(false).to(true)
141
+ end
142
+
143
+ context 'rep in outdatedness store' do
144
+ before do
145
+ compiler.outdatedness_store.add(rep)
146
+ end
147
+
148
+ it 'keeps the item rep in the outdatedness store' do
149
+ expect(compiler.outdatedness_store.include?(rep)).to be
150
+ expect { subject rescue nil }.not_to change { compiler.outdatedness_store.include?(rep) }
151
+ end
152
+ end
115
153
  end
116
154
  end
117
155
 
118
156
  describe '#compile_rep' do
119
- subject { compiler.send(:compile_rep, rep, is_outdated: is_outdated) }
157
+ let(:stage) { compiler.send(:compile_reps_stage) }
158
+
159
+ subject { stage.send(:compile_rep, rep, is_outdated: is_outdated) }
120
160
 
121
161
  let(:is_outdated) { true }
122
162
 
@@ -145,10 +185,10 @@ describe Nanoc::Int::Compiler do
145
185
  it 'generates expected output' do
146
186
  expect(rep.snapshot_contents[:last].string).to eql(item.content.string)
147
187
 
148
- expect { compiler.send(:compile_rep, rep, is_outdated: true) }
188
+ expect { stage.send(:compile_rep, rep, is_outdated: true) }
149
189
  .to raise_error(Nanoc::Int::Errors::UnmetDependency)
150
- compiler.send(:compile_rep, other_rep, is_outdated: true)
151
- compiler.send(:compile_rep, rep, is_outdated: true)
190
+ stage.send(:compile_rep, other_rep, is_outdated: true)
191
+ stage.send(:compile_rep, rep, is_outdated: true)
152
192
 
153
193
  expect(rep.snapshot_contents[:last].string).to eql('other=other content')
154
194
  end
@@ -171,10 +211,10 @@ describe Nanoc::Int::Compiler do
171
211
  expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:filtering_ended, rep, :erb).ordered
172
212
  expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:compilation_ended, rep).ordered
173
213
 
174
- expect { compiler.send(:compile_rep, rep, is_outdated: true) }
214
+ expect { stage.send(:compile_rep, rep, is_outdated: true) }
175
215
  .to raise_error(Nanoc::Int::Errors::UnmetDependency)
176
- compiler.send(:compile_rep, other_rep, is_outdated: true)
177
- compiler.send(:compile_rep, rep, is_outdated: true)
216
+ stage.send(:compile_rep, other_rep, is_outdated: true)
217
+ stage.send(:compile_rep, rep, is_outdated: true)
178
218
  end
179
219
  end
180
220
  end
@@ -0,0 +1,100 @@
1
+ describe Nanoc::Int::OutdatednessStore do
2
+ subject(:store) { described_class.new(site: site, reps: reps) }
3
+
4
+ let(:site) { double(:site) }
5
+ let(:reps) { Nanoc::Int::ItemRepRepo.new }
6
+
7
+ let(:item) { Nanoc::Int::Item.new('foo', {}, '/foo.md') }
8
+ let(:rep) { Nanoc::Int::ItemRep.new(item, :foo) }
9
+
10
+ let(:site) do
11
+ Nanoc::Int::Site.new(
12
+ config: config,
13
+ code_snippets: code_snippets,
14
+ items: items,
15
+ layouts: layouts,
16
+ )
17
+ end
18
+
19
+ let(:config) { Nanoc::Int::Configuration.new.with_defaults }
20
+ let(:items) { [] }
21
+ let(:layouts) { [] }
22
+ let(:code_snippets) { [] }
23
+
24
+ describe '#include?, #add and #remove' do
25
+ subject { store.include?(rep) }
26
+
27
+ context 'nothing added' do
28
+ it { is_expected.not_to be }
29
+ end
30
+
31
+ context 'rep added' do
32
+ before { store.add(rep) }
33
+ it { is_expected.to be }
34
+ end
35
+
36
+ context 'rep added and removed' do
37
+ before do
38
+ store.add(rep)
39
+ store.remove(rep)
40
+ end
41
+
42
+ it { is_expected.not_to be }
43
+ end
44
+
45
+ context 'rep added, removed, and added again' do
46
+ before do
47
+ store.add(rep)
48
+ store.remove(rep)
49
+ store.add(rep)
50
+ end
51
+
52
+ it { is_expected.to be }
53
+ end
54
+ end
55
+
56
+ describe '#to_a' do
57
+ subject { store.to_a }
58
+
59
+ context 'nothing added' do
60
+ it { is_expected.to be_empty }
61
+ end
62
+
63
+ context 'one rep added' do
64
+ before { store.add(rep) }
65
+ it { is_expected.to eql([rep]) }
66
+ end
67
+ end
68
+
69
+ describe 'reloading' do
70
+ subject do
71
+ store.store
72
+ store.load
73
+ store.include?(rep)
74
+ end
75
+
76
+ context 'not added' do
77
+ context 'rep part of new reps' do
78
+ before { reps << rep }
79
+ it { is_expected.not_to be }
80
+ end
81
+
82
+ context 'rep not part of new reps' do
83
+ it { is_expected.not_to be }
84
+ end
85
+ end
86
+
87
+ context 'added' do
88
+ before { store.add(rep) }
89
+
90
+ context 'rep part of new reps' do
91
+ before { reps << rep }
92
+ it { is_expected.to be }
93
+ end
94
+
95
+ context 'rep not part of new reps' do
96
+ it { is_expected.not_to be }
97
+ end
98
+ end
99
+ end
100
+ end
@@ -10,9 +10,22 @@ describe Nanoc::Int::OutdatednessChecker do
10
10
  )
11
11
  end
12
12
 
13
- let(:site) { double(:site) }
14
13
  let(:checksum_store) { double(:checksum_store) }
15
- let(:dependency_store) { double(:dependency_store) }
14
+
15
+ let(:dependency_store) do
16
+ Nanoc::Int::DependencyStore.new(objects)
17
+ end
18
+
19
+ let(:objects) { [item] }
20
+
21
+ let(:site) do
22
+ Nanoc::Int::Site.new(
23
+ config: config,
24
+ items: [],
25
+ layouts: [],
26
+ code_snippets: [],
27
+ )
28
+ end
16
29
 
17
30
  let(:rule_memory_store) do
18
31
  Nanoc::Int::RuleMemoryStore.new
@@ -102,10 +115,6 @@ describe Nanoc::Int::OutdatednessChecker do
102
115
  describe '#outdated_due_to_dependencies?' do
103
116
  subject { outdatedness_checker.send(:outdated_due_to_dependencies?, item) }
104
117
 
105
- let(:dependency_store) do
106
- Nanoc::Int::DependencyStore.new(objects)
107
- end
108
-
109
118
  let(:checksum_store) { Nanoc::Int::ChecksumStore.new(objects: objects) }
110
119
 
111
120
  let(:other_item) { Nanoc::Int::Item.new('other stuff', {}, '/other.md') }
@@ -18,11 +18,19 @@ describe Nanoc::Int::OutdatednessRules do
18
18
  let(:item_rep) { Nanoc::Int::ItemRep.new(item, :default) }
19
19
  let(:item) { Nanoc::Int::Item.new('stuff', {}, '/foo.md') }
20
20
 
21
- let(:site) { double(:site) }
22
21
  let(:config) { Nanoc::Int::Configuration.new }
23
22
  let(:code_snippets) { [] }
24
23
  let(:objects) { [config] + code_snippets + [item] }
25
24
 
25
+ let(:site) do
26
+ Nanoc::Int::Site.new(
27
+ config: config,
28
+ items: [],
29
+ layouts: [],
30
+ code_snippets: code_snippets,
31
+ )
32
+ end
33
+
26
34
  let(:action_provider) { double(:action_provider) }
27
35
  let(:reps) { Nanoc::Int::ItemRepRepo.new }
28
36
  let(:dependency_store) { Nanoc::Int::DependencyStore.new(dependency_store_objects) }
@@ -67,15 +75,15 @@ describe Nanoc::Int::OutdatednessRules do
67
75
  context 'ConfigurationModified' do
68
76
  let(:rule_class) { Nanoc::Int::OutdatednessRules::ConfigurationModified }
69
77
 
70
- context 'only non-outdated snippets' do
71
- let(:config) { Nanoc::Int::CodeSnippet.new('asdf', 'lib/foo.md') }
78
+ context 'non-outdated' do
79
+ let(:config) { Nanoc::Int::Configuration.new }
72
80
 
73
81
  before { checksum_store.add(config) }
74
82
 
75
83
  it { is_expected.not_to be }
76
84
  end
77
85
 
78
- context 'only non-outdated snippets' do
86
+ context 'outdated' do
79
87
  let(:config) { Nanoc::Int::Configuration.new }
80
88
  let(:config_old) { Nanoc::Int::Configuration.new(hash: { foo: 125 }) }
81
89
 
@@ -1,3 +1,5 @@
1
+ require 'net/http'
2
+
1
3
  describe Nanoc::CLI::Commands::View, site: true, stdio: true do
2
4
  describe '#run' do
3
5
  def run_nanoc_cmd(cmd)
@@ -48,7 +48,19 @@ describe Nanoc::DataSources::Filesystem do
48
48
  expect(subject[0].identifier).to eq(Nanoc::Identifier.new('/bar/'))
49
49
  expect(subject[0].checksum_data).to be_nil
50
50
  expect(subject[0].content_checksum_data).to eq('test 1')
51
- expect(subject[0].attributes_checksum_data).to eq("num: 1\n")
51
+ end
52
+
53
+ it 'has the right attributes checksum data' do
54
+ cs = YAML.load(subject[0].attributes_checksum_data)
55
+
56
+ expect(cs[:attributes]).to eq("num: 1\n")
57
+ expect(cs[:extra_attributes]).to eq(
58
+ filename: 'foo/bar.html',
59
+ content_filename: 'foo/bar.html',
60
+ meta_filename: nil,
61
+ extension: 'html',
62
+ mtime: now,
63
+ )
52
64
  end
53
65
  end
54
66
  end
@@ -13,7 +13,7 @@ describe Nanoc::Extra::ParallelCollection do
13
13
  let!(:out) { [] }
14
14
 
15
15
  it 'is fast' do
16
- expect { subject }.to finish_in_under(0.2).seconds
16
+ expect { subject }.to finish_in_under(0.25).seconds
17
17
  end
18
18
 
19
19
  it 'is correct' do
@@ -66,7 +66,7 @@ describe Nanoc::Extra::ParallelCollection do
66
66
  end
67
67
 
68
68
  it 'is fast' do
69
- expect { subject }.to finish_in_under(0.2).seconds
69
+ expect { subject }.to finish_in_under(0.25).seconds
70
70
  end
71
71
 
72
72
  it 'does not leave threads lingering' do
@@ -1,9 +1,14 @@
1
1
  describe 'Outdatedness integration', site: true, stdio: true do
2
2
  context 'only attribute dependency' do
3
+ let(:time) { Time.now }
4
+
3
5
  before do
4
6
  File.write('content/foo.md', "---\ntitle: hello\n---\n\nfoo")
5
7
  File.write('content/bar.md', '<%= @items["/foo.*"][:title] %>')
6
8
 
9
+ FileUtils.touch('content/foo.md', mtime: time)
10
+ FileUtils.touch('content/bar.md', mtime: time)
11
+
7
12
  File.write('Rules', <<EOS)
8
13
  compile '/foo.*' do
9
14
  write '/foo.html'
@@ -29,6 +34,7 @@ EOS
29
34
 
30
35
  it 'shows file as outdated after modification' do
31
36
  File.write('content/bar.md', 'JUST BAR!')
37
+ FileUtils.touch('content/bar.md', mtime: time)
32
38
 
33
39
  expect { Nanoc::CLI.run(%w(show-data --no-color)) }.to(
34
40
  output(/^item \/foo\.md, rep default:\n is not outdated/).to_stdout,
@@ -40,6 +46,7 @@ EOS
40
46
 
41
47
  it 'shows file and dependencies as not outdated after content modification' do
42
48
  File.write('content/foo.md', "---\ntitle: hello\n---\n\nfoooOoooOOoooOooo")
49
+ FileUtils.touch('content/foo.md', mtime: time)
43
50
 
44
51
  expect { Nanoc::CLI.run(%w(show-data --no-color)) }.to(
45
52
  output(/^item \/foo\.md, rep default:\n is outdated: /).to_stdout,
@@ -51,6 +58,7 @@ EOS
51
58
 
52
59
  it 'shows file and dependencies as outdated after title modification' do
53
60
  File.write('content/foo.md', "---\ntitle: bye\n---\n\nfoo")
61
+ FileUtils.touch('content/foo.md', mtime: time)
54
62
 
55
63
  expect { Nanoc::CLI.run(%w(show-data --no-color)) }.to(
56
64
  output(/^item \/foo\.md, rep default:\n is outdated: /).to_stdout,