nanoc 4.4.7 → 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +9 -7
  3. data/NEWS.md +6 -0
  4. data/lib/nanoc.rb +1 -0
  5. data/lib/nanoc/base.rb +0 -1
  6. data/lib/nanoc/base/feature.rb +1 -1
  7. data/lib/nanoc/base/repos/data_source.rb +1 -1
  8. data/lib/nanoc/base/repos/site_loader.rb +1 -1
  9. data/lib/nanoc/base/services/action_provider.rb +1 -1
  10. data/lib/nanoc/base/services/filter.rb +1 -1
  11. data/lib/nanoc/checking.rb +7 -9
  12. data/lib/nanoc/checking/check.rb +1 -1
  13. data/lib/nanoc/checking/checks.rb +9 -17
  14. data/lib/nanoc/checking/checks/internal_links.rb +2 -0
  15. data/lib/nanoc/checking/checks/mixed_content.rb +2 -0
  16. data/lib/nanoc/checking/checks/stale.rb +2 -0
  17. data/lib/nanoc/checking/runner.rb +2 -2
  18. data/lib/nanoc/cli.rb +9 -6
  19. data/lib/nanoc/cli/commands/deploy.rb +4 -4
  20. data/lib/nanoc/cli/commands/show-plugins.rb +12 -12
  21. data/lib/nanoc/cli/stream_cleaners.rb +7 -7
  22. data/lib/nanoc/data_sources.rb +0 -3
  23. data/lib/nanoc/data_sources/filesystem.rb +2 -0
  24. data/lib/nanoc/deploying/deployer.rb +1 -1
  25. data/lib/nanoc/deploying/deployers.rb +6 -9
  26. data/lib/nanoc/deploying/deployers/fog.rb +2 -0
  27. data/lib/nanoc/deploying/deployers/git.rb +118 -0
  28. data/lib/nanoc/deploying/deployers/rsync.rb +2 -0
  29. data/lib/nanoc/extra.rb +5 -6
  30. data/lib/nanoc/filters.rb +28 -55
  31. data/lib/nanoc/filters/asciidoc.rb +2 -0
  32. data/lib/nanoc/filters/bluecloth.rb +2 -0
  33. data/lib/nanoc/filters/coffeescript.rb +2 -0
  34. data/lib/nanoc/filters/colorize_syntax.rb +2 -0
  35. data/lib/nanoc/filters/erb.rb +2 -0
  36. data/lib/nanoc/filters/erubis.rb +9 -8
  37. data/lib/nanoc/filters/haml.rb +2 -0
  38. data/lib/nanoc/filters/handlebars.rb +2 -0
  39. data/lib/nanoc/filters/kramdown.rb +2 -0
  40. data/lib/nanoc/filters/less.rb +2 -0
  41. data/lib/nanoc/filters/markaby.rb +2 -0
  42. data/lib/nanoc/filters/maruku.rb +2 -0
  43. data/lib/nanoc/filters/mustache.rb +2 -0
  44. data/lib/nanoc/filters/pandoc.rb +2 -0
  45. data/lib/nanoc/filters/rainpress.rb +2 -0
  46. data/lib/nanoc/filters/rdiscount.rb +2 -0
  47. data/lib/nanoc/filters/rdoc.rb +2 -0
  48. data/lib/nanoc/filters/redcarpet.rb +2 -0
  49. data/lib/nanoc/filters/redcloth.rb +2 -0
  50. data/lib/nanoc/filters/relativize_paths.rb +2 -0
  51. data/lib/nanoc/filters/rubypants.rb +2 -0
  52. data/lib/nanoc/filters/sass.rb +2 -0
  53. data/lib/nanoc/filters/slim.rb +2 -0
  54. data/lib/nanoc/filters/typogruby.rb +2 -0
  55. data/lib/nanoc/filters/uglify_js.rb +2 -0
  56. data/lib/nanoc/filters/xsl.rb +2 -0
  57. data/lib/nanoc/filters/yui_compressor.rb +2 -0
  58. data/lib/nanoc/helpers.rb +12 -11
  59. data/lib/nanoc/version.rb +1 -1
  60. data/nanoc.gemspec +1 -0
  61. data/spec/nanoc/base/filter_spec.rb +2 -2
  62. data/spec/nanoc/cli/commands/deploy_spec.rb +2 -2
  63. data/spec/nanoc/cli/commands/show_plugins_spec.rb +18 -0
  64. data/spec/nanoc/deploying/git_spec.rb +302 -0
  65. data/spec/spec_helper.rb +2 -0
  66. data/test/deploying/test_git.rb +261 -0
  67. metadata +20 -5
  68. data/lib/nanoc/base/plugin_registry.rb +0 -219
  69. data/spec/nanoc/base/plugin_registry_spec.rb +0 -29
  70. data/test/base/test_plugin.rb +0 -26
@@ -1,6 +1,8 @@
1
1
  module Nanoc::Filters
2
2
  # @api private
3
3
  class RelativizePaths < Nanoc::Filter
4
+ identifier :relativize_paths
5
+
4
6
  require 'nanoc/helpers/link_to'
5
7
  include Nanoc::Helpers::LinkTo
6
8
 
@@ -1,6 +1,8 @@
1
1
  module Nanoc::Filters
2
2
  # @api private
3
3
  class RubyPants < Nanoc::Filter
4
+ identifier :rubypants
5
+
4
6
  requires 'rubypants'
5
7
 
6
8
  # Runs the content through [RubyPants](http://rubydoc.info/gems/rubypants/).
@@ -1,6 +1,8 @@
1
1
  module Nanoc::Filters
2
2
  # @api private
3
3
  class Sass < Nanoc::Filter
4
+ identifier :sass
5
+
4
6
  requires 'sass', 'nanoc/filters/sass/sass_filesystem_importer'
5
7
 
6
8
  # Runs the content through [Sass](http://sass-lang.com/).
@@ -1,6 +1,8 @@
1
1
  module Nanoc::Filters
2
2
  # @api private
3
3
  class Slim < Nanoc::Filter
4
+ identifier :slim
5
+
4
6
  requires 'slim'
5
7
 
6
8
  # Runs the content through [Slim](http://slim-lang.com/).
@@ -1,6 +1,8 @@
1
1
  module Nanoc::Filters
2
2
  # @api private
3
3
  class Typogruby < Nanoc::Filter
4
+ identifier :typogruby
5
+
4
6
  requires 'typogruby'
5
7
 
6
8
  # Runs the content through [Typogruby](http://avdgaag.github.com/typogruby/).
@@ -1,6 +1,8 @@
1
1
  module Nanoc::Filters
2
2
  # @api private
3
3
  class UglifyJS < Nanoc::Filter
4
+ identifier :uglify_js
5
+
4
6
  requires 'uglifier'
5
7
 
6
8
  # Runs the content through [UglifyJS](https://github.com/mishoo/UglifyJS2/).
@@ -1,6 +1,8 @@
1
1
  module Nanoc::Filters
2
2
  # @api private
3
3
  class XSL < Nanoc::Filter
4
+ identifier :xsl
5
+
4
6
  requires 'nokogiri'
5
7
 
6
8
  # Runs the item content through an [XSLT](http://www.w3.org/TR/xslt)
@@ -1,6 +1,8 @@
1
1
  module Nanoc::Filters
2
2
  # @api private
3
3
  class YUICompressor < Nanoc::Filter
4
+ identifier :yui_compressor
5
+
4
6
  requires 'yuicompressor'
5
7
 
6
8
  # Compress Javascript or CSS using [YUICompressor](http://rubydoc.info/gems/yuicompressor).
data/lib/nanoc/helpers.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  module Nanoc::Helpers
2
- autoload 'Blogging', 'nanoc/helpers/blogging'
3
- autoload 'Breadcrumbs', 'nanoc/helpers/breadcrumbs'
4
- autoload 'Capturing', 'nanoc/helpers/capturing'
5
- autoload 'ChildParent', 'nanoc/helpers/child_parent'
6
- autoload 'Filtering', 'nanoc/helpers/filtering'
7
- autoload 'HTMLEscape', 'nanoc/helpers/html_escape'
8
- autoload 'LinkTo', 'nanoc/helpers/link_to'
9
- autoload 'Rendering', 'nanoc/helpers/rendering'
10
- autoload 'Tagging', 'nanoc/helpers/tagging'
11
- autoload 'Text', 'nanoc/helpers/text'
12
- autoload 'XMLSitemap', 'nanoc/helpers/xml_sitemap'
13
2
  end
3
+
4
+ require_relative 'helpers/blogging'
5
+ require_relative 'helpers/breadcrumbs'
6
+ require_relative 'helpers/capturing'
7
+ require_relative 'helpers/child_parent'
8
+ require_relative 'helpers/filtering'
9
+ require_relative 'helpers/html_escape'
10
+ require_relative 'helpers/link_to'
11
+ require_relative 'helpers/rendering'
12
+ require_relative 'helpers/tagging'
13
+ require_relative 'helpers/text'
14
+ require_relative 'helpers/xml_sitemap'
data/lib/nanoc/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Nanoc
2
2
  # The current Nanoc version.
3
- VERSION = '4.4.7'.freeze
3
+ VERSION = '4.5.0'.freeze
4
4
  end
data/nanoc.gemspec CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
27
27
  s.add_runtime_dependency('cri', '~> 2.3')
28
28
  s.add_runtime_dependency('hamster', '~> 3.0')
29
29
  s.add_runtime_dependency('ref', '~> 2.0')
30
+ s.add_runtime_dependency('ddplugin', '~> 1.0')
30
31
 
31
32
  s.add_development_dependency('bundler', '>= 1.7.10', '< 2.0')
32
33
  s.add_development_dependency('appraisal', '~> 2.1')
@@ -1,7 +1,7 @@
1
1
  describe Nanoc::Filter do
2
2
  describe '.define' do
3
3
  context 'simple filter' do
4
- let(:filter_name) { 'b5355bbb4d772b9853d21be57da614dba521dbbb' }
4
+ let(:filter_name) { :b5355bbb4d772b9853d21be57da614dba521dbbb }
5
5
  let(:filter_class) { Nanoc::Filter.named(filter_name) }
6
6
 
7
7
  before do
@@ -20,7 +20,7 @@ describe Nanoc::Filter do
20
20
  end
21
21
 
22
22
  context 'filter that accesses assigns' do
23
- let(:filter_name) { 'd7ed105d460e99a3d38f46af023d9490c140fdd9' }
23
+ let(:filter_name) { :d7ed105d460e99a3d38f46af023d9490c140fdd9 }
24
24
  let(:filter_class) { Nanoc::Filter.named(filter_name) }
25
25
  let(:filter) { filter_class.new(assigns) }
26
26
  let(:assigns) { { animal: 'Giraffe' } }
@@ -1,4 +1,4 @@
1
- describe Nanoc::CLI::Commands::Shell, site: true, stdio: true do
1
+ describe Nanoc::CLI::Commands::Deploy, site: true, stdio: true do
2
2
  describe '#run' do
3
3
  let(:config) { {} }
4
4
 
@@ -75,7 +75,7 @@ describe Nanoc::CLI::Commands::Shell, site: true, stdio: true do
75
75
  let(:run) { Nanoc::CLI.run(command) }
76
76
 
77
77
  it 'lists all deployers' do
78
- expect { run }.to output(/Available deployers:\n fog\n rsync/).to_stdout
78
+ expect { run }.to output(/Available deployers:\n fog\n git\n rsync/).to_stdout
79
79
  end
80
80
 
81
81
  include_examples 'no effective deploy'
@@ -0,0 +1,18 @@
1
+ describe Nanoc::CLI::Commands::ShowPlugins, site: true, stdio: true do
2
+ describe '#run' do
3
+ it 'can be invoked' do
4
+ Nanoc::CLI.run(['show-plugins'])
5
+ end
6
+
7
+ context 'site with plugins' do
8
+ before do
9
+ File.write('lib/default.rb', 'Nanoc::Filter.define(:show_plugins_x) {}')
10
+ end
11
+
12
+ it 'outputs show_plugins_x under the right section' do
13
+ expect { Nanoc::CLI.run(['show-plugins']) }
14
+ .to output(/ custom:\n show_plugins_x/).to_stdout
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,302 @@
1
+ describe Nanoc::Deploying::Deployers::Git, stdio: true do
2
+ let(:deployer) { described_class.new(output_dir, options, dry_run: dry_run) }
3
+
4
+ subject { deployer.run }
5
+
6
+ let(:output_dir) { 'output/' }
7
+ let(:options) { remote_options.merge(branch_options).merge(forced_options) }
8
+ let(:dry_run) { false }
9
+
10
+ let(:remote_options) { {} }
11
+ let(:branch_options) { {} }
12
+ let(:forced_options) { {} }
13
+
14
+ def run_and_get_stdout(*args)
15
+ stdout = ''
16
+ piper = Nanoc::Extra::Piper.new(stdout: stdout, stderr: '')
17
+ piper.run(args, '')
18
+ stdout
19
+ end
20
+
21
+ def add_changes_to_remote
22
+ system('git', 'init', '--quiet', 'rere_tmp')
23
+ Dir.chdir('rere_tmp') do
24
+ system('git', 'config', 'user.name', 'Zebra Platypus')
25
+ system('git', 'config', 'user.email', 'zebra@platypus.example.com')
26
+ system('git', 'remote', 'add', 'origin', '../rere')
27
+
28
+ File.write('evil.txt', 'muaha')
29
+ system('git', 'add', 'evil.txt')
30
+ system('git', 'commit', '--quiet', '-m', 'muaha')
31
+ system('git', 'checkout', '--quiet', '-b', 'giraffe')
32
+ system('git', 'push', '--quiet', 'origin', 'master')
33
+ system('git', 'push', '--quiet', 'origin', 'giraffe')
34
+ end
35
+ end
36
+
37
+ def rev_list
38
+ run_and_get_stdout('git', 'rev-list', '--objects', '--all')
39
+ end
40
+
41
+ shared_examples 'branch configured properly' do
42
+ context 'clean working copy' do
43
+ it 'does not commit or push' do
44
+ subject
45
+ end
46
+ end
47
+
48
+ context 'non-clean working copy' do
49
+ before do
50
+ Dir.chdir(output_dir) { File.write('hello.txt', 'Hi there') }
51
+ end
52
+
53
+ shared_examples 'successful push' do
54
+ context 'no dry run' do
55
+ it 'outputs status' do
56
+ expect { subject }
57
+ .to output(/Deploying via Git to branch “#{branch}” on remote “#{remote}”…/)
58
+ .to_stdout
59
+ end
60
+
61
+ it 'makes a change in the local repo' do
62
+ expect { subject }
63
+ .to change { Dir.chdir(output_dir) { rev_list } }
64
+ .from(not_match(/^[a-f0-9]{40} hello\.txt$/))
65
+ .to(match(/^[a-f0-9]{40} hello\.txt$/))
66
+
67
+ expect(Dir.chdir(output_dir) { run_and_get_stdout('git', 'show', branch) })
68
+ .to match(/^Author: Nanoc <>$/)
69
+ end
70
+
71
+ it 'makes a change in the remote repo' do
72
+ expect { subject }
73
+ .to change { Dir.chdir('rere') { rev_list } }
74
+ .from(not_match(/^[a-f0-9]{40} hello\.txt$/))
75
+ .to(match(/^[a-f0-9]{40} hello\.txt$/))
76
+ end
77
+ end
78
+
79
+ context 'dry run' do
80
+ let(:dry_run) { true }
81
+
82
+ it 'makes a change in the local repo' do
83
+ expect { subject }
84
+ .not_to change { Dir.chdir(output_dir) { rev_list } }
85
+ end
86
+
87
+ it 'makes a change in the remote repo' do
88
+ expect { subject }
89
+ .not_to change { Dir.chdir('rere') { rev_list } }
90
+ end
91
+ end
92
+ end
93
+
94
+ context 'forced' do
95
+ let(:forced_options) { { forced: true } }
96
+
97
+ context 'remote has no other changes' do
98
+ include_examples 'successful push'
99
+ end
100
+
101
+ context 'remote has other changes' do
102
+ before { add_changes_to_remote }
103
+ include_examples 'successful push'
104
+ end
105
+ end
106
+
107
+ context 'not forced (implicit)' do
108
+ let(:forced_options) { {} }
109
+
110
+ context 'remote has no other changes' do
111
+ include_examples 'successful push'
112
+ end
113
+
114
+ context 'remote has other changes' do
115
+ before { add_changes_to_remote }
116
+
117
+ it 'raises' do
118
+ expect { subject }.to raise_error(Nanoc::Extra::Piper::Error)
119
+ end
120
+ end
121
+ end
122
+
123
+ context 'not forced (explicit)' do
124
+ let(:forced_options) { { forced: false } }
125
+
126
+ context 'remote has no other changes' do
127
+ include_examples 'successful push'
128
+ end
129
+
130
+ context 'remote has other changes' do
131
+ before { add_changes_to_remote }
132
+
133
+ it 'raises' do
134
+ expect { subject }.to raise_error(Nanoc::Extra::Piper::Error)
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ shared_examples 'remote configured properly' do
142
+ before do
143
+ system('git', 'init', '--bare', '--quiet', 'rere')
144
+ end
145
+
146
+ context 'default branch' do
147
+ context 'branch does not exist' do
148
+ it 'raises' do
149
+ expect { subject }.to raise_error(
150
+ Nanoc::Deploying::Deployers::Git::Errors::BranchDoesNotExist,
151
+ 'The branch to deploy, master, does not exist.',
152
+ )
153
+ end
154
+ end
155
+
156
+ context 'branch exists' do
157
+ before do
158
+ Dir.chdir(output_dir) do
159
+ system('git', 'commit', '--quiet', '-m', 'init', '--allow-empty')
160
+ end
161
+ end
162
+
163
+ let(:branch) { 'master' }
164
+
165
+ include_examples 'branch configured properly'
166
+ end
167
+ end
168
+
169
+ context 'custom branch' do
170
+ let(:branch) { 'giraffe' }
171
+ let(:branch_options) { { branch: branch } }
172
+
173
+ context 'branch does not exist' do
174
+ it 'raises' do
175
+ expect { subject }.to raise_error(
176
+ Nanoc::Deploying::Deployers::Git::Errors::BranchDoesNotExist,
177
+ 'The branch to deploy, giraffe, does not exist.',
178
+ )
179
+ end
180
+ end
181
+
182
+ context 'branch exists' do
183
+ before do
184
+ Dir.chdir(output_dir) do
185
+ system('git', 'commit', '--quiet', '-m', 'init', '--allow-empty')
186
+ system('git', 'branch', 'giraffe')
187
+ end
188
+ end
189
+
190
+ include_examples 'branch configured properly'
191
+ end
192
+ end
193
+ end
194
+
195
+ context 'output dir does not exist' do
196
+ it 'raises' do
197
+ expect { subject }.to raise_error(
198
+ Nanoc::Deploying::Deployers::Git::Errors::OutputDirDoesNotExist,
199
+ 'The directory to deploy, output/, does not exist.',
200
+ )
201
+ end
202
+ end
203
+
204
+ context 'output dir exists' do
205
+ before do
206
+ FileUtils.mkdir_p(output_dir)
207
+ end
208
+
209
+ context 'output dir is not a Git repo' do
210
+ it 'raises' do
211
+ expect { subject }.to raise_error(
212
+ Nanoc::Deploying::Deployers::Git::Errors::OutputDirIsNotAGitRepo,
213
+ 'The directory to deploy, output/, is not a Git repository.',
214
+ )
215
+ end
216
+ end
217
+
218
+ context 'output dir is a Git repo' do
219
+ before do
220
+ Dir.chdir(output_dir) do
221
+ system('git', 'init', '--quiet')
222
+ system('git', 'config', 'user.name', 'Donkey Giraffe')
223
+ system('git', 'config', 'user.email', 'donkey@giraffe.example.com')
224
+ end
225
+ end
226
+
227
+ context 'default remote' do
228
+ context 'remote does not exist' do
229
+ it 'raises' do
230
+ expect { subject }.to raise_error(
231
+ Nanoc::Deploying::Deployers::Git::Errors::RemoteDoesNotExist,
232
+ 'The remote to deploy to, origin, does not exist.',
233
+ )
234
+ end
235
+ end
236
+
237
+ context 'remote exists' do
238
+ before do
239
+ Dir.chdir(output_dir) do
240
+ system('git', 'remote', 'add', 'origin', '../rere')
241
+ end
242
+ end
243
+
244
+ let(:remote) { 'origin' }
245
+
246
+ include_examples 'remote configured properly'
247
+ end
248
+ end
249
+
250
+ context 'custom remote (name)' do
251
+ let(:remote_options) { { remote: 'donkey' } }
252
+
253
+ context 'remote does not exist' do
254
+ it 'raises' do
255
+ expect { subject }.to raise_error(
256
+ Nanoc::Deploying::Deployers::Git::Errors::RemoteDoesNotExist,
257
+ 'The remote to deploy to, donkey, does not exist.',
258
+ )
259
+ end
260
+ end
261
+
262
+ context 'remote exists' do
263
+ before do
264
+ Dir.chdir(output_dir) do
265
+ system('git', 'remote', 'add', 'donkey', '../rere')
266
+ end
267
+ end
268
+
269
+ let(:remote) { 'donkey' }
270
+
271
+ include_examples 'remote configured properly'
272
+ end
273
+ end
274
+
275
+ context 'custom remote (file:// URL)' do
276
+ let(:remote_options) { { remote: remote } }
277
+
278
+ let(:remote) { "file://#{Dir.getwd}/rere" }
279
+
280
+ include_examples 'remote configured properly'
281
+ end
282
+ end
283
+ end
284
+
285
+ describe '#remote_is_name?' do
286
+ def val(remote)
287
+ deployer.send(:remote_is_name?, remote)
288
+ end
289
+
290
+ it 'recognises names' do
291
+ expect(val('denis')).to be
292
+ end
293
+
294
+ it 'recognises URLs' do
295
+ expect(val('git@github.com:/foo')).not_to be
296
+ expect(val('http://example.com/donkey.git')).not_to be
297
+ expect(val('https://example.com/donkey.git')).not_to be
298
+ expect(val('ssh://example.com/donkey.git')).not_to be
299
+ expect(val('file:///example.com/donkey.git')).not_to be
300
+ end
301
+ end
302
+ end