nanoc 3.7.5 → 3.8.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +2 -2
  3. data/Gemfile +1 -1
  4. data/NEWS.md +24 -3
  5. data/README.md +1 -1
  6. data/bin/nanoc +1 -1
  7. data/lib/nanoc/base/compilation/dependency_tracker.rb +1 -1
  8. data/lib/nanoc/base/compilation/item_rep_recorder_proxy.rb +1 -1
  9. data/lib/nanoc/base/compilation/rule.rb +15 -1
  10. data/lib/nanoc/base/result_data/item_rep.rb +27 -10
  11. data/lib/nanoc/base/source_data/item_array.rb +2 -0
  12. data/lib/nanoc/base/source_data/site.rb +1 -0
  13. data/lib/nanoc/cli.rb +16 -7
  14. data/lib/nanoc/cli/commands/autocompile.rb +1 -1
  15. data/lib/nanoc/cli/commands/create-site.rb +2 -2
  16. data/lib/nanoc/cli/commands/show-rules.rb +3 -6
  17. data/lib/nanoc/cli/commands/watch.rb +3 -3
  18. data/lib/nanoc/cli/error_handler.rb +1 -1
  19. data/lib/nanoc/cli/logger.rb +3 -5
  20. data/lib/nanoc/data_sources/filesystem.rb +2 -2
  21. data/lib/nanoc/extra/auto_compiler.rb +1 -1
  22. data/lib/nanoc/extra/checking/checks.rb +2 -0
  23. data/lib/nanoc/extra/checking/checks/mixed_content.rb +31 -0
  24. data/lib/nanoc/extra/deployers/fog.rb +24 -0
  25. data/lib/nanoc/extra/link_collector.rb +42 -9
  26. data/lib/nanoc/extra/pruner.rb +1 -1
  27. data/lib/nanoc/filters/colorize_syntax.rb +4 -4
  28. data/lib/nanoc/filters/pandoc.rb +23 -4
  29. data/lib/nanoc/filters/sass/sass_filesystem_importer.rb +4 -2
  30. data/lib/nanoc/helpers/blogging.rb +17 -6
  31. data/lib/nanoc/helpers/tagging.rb +1 -1
  32. data/lib/nanoc/helpers/text.rb +1 -1
  33. data/lib/nanoc/version.rb +1 -1
  34. data/tasks/test.rake +1 -1
  35. data/test/base/test_item_array.rb +8 -0
  36. data/test/base/test_item_rep.rb +51 -0
  37. data/test/base/test_item_rep_recorder_proxy.rb +19 -0
  38. data/test/base/test_rule.rb +10 -0
  39. data/test/cli/commands/test_create_site.rb +13 -0
  40. data/test/cli/test_cli.rb +30 -0
  41. data/test/extra/checking/checks/test_mixed_content.rb +188 -0
  42. data/test/extra/deployers/test_fog.rb +32 -0
  43. data/test/filters/test_pandoc.rb +17 -3
  44. data/test/filters/test_sass.rb +11 -0
  45. data/test/helper.rb +3 -3
  46. data/test/helpers/test_blogging.rb +30 -0
  47. metadata +6 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 271aacd59754102c8bd997df253a98ca21f7fac3
4
- data.tar.gz: 37db9384d0b9dbcbc80bb22714d856766fa9af42
3
+ metadata.gz: e62cf6c5f843fd4a0ed676cac0ce30d3cb8e45b9
4
+ data.tar.gz: c9cb11079a6a930f93e3e977e50b28db2d8bc5e9
5
5
  SHA512:
6
- metadata.gz: 2b38d502d8dc8d17401312089add955515c7807e1b85bf7c9993fa68350cf9201b859eb305425fa69e2cb13b40d10d2ac2487150d0a3678f444883fb069e0ad0
7
- data.tar.gz: a468ae8a49f2d3a025f0946aae7a58ee8e4328b3f188c5052e6d64a91751fb55c41077e64d025adff3bac3dfa40c886ca2a77a33f9baa7489249158808e52a09
6
+ metadata.gz: d5417fff2968fb9b1efbdc49095ebb4b2e0ff17cd1cdbfeb7a2e81ad059c0bdad3940bfeaa06956b9d07a923e2c2e4b50d4470851a07b5071b6f3409c3f124c2
7
+ data.tar.gz: cb15bed72ebe0b15babbee93386554fc2512fbd17c8ffce24a2224448a22ab8876d551a2ab550cdd396bbcfa84106405c1e87e7f7e6d1f2078fda4054a10cb36
data/ChangeLog CHANGED
@@ -1,3 +1,3 @@
1
1
  For a list of all changes, please see the changelog on the project repository
2
- instead (http://projects.stoneship.org/hg/nanoc). For release notes, please
3
- see the NEWS file.
2
+ instead (https://github.com/nanoc/nanoc). For release notes, please see the
3
+ NEWS file.
data/Gemfile CHANGED
@@ -21,7 +21,7 @@ gem 'listen'
21
21
  gem 'markaby'
22
22
  gem 'maruku'
23
23
  gem 'mime-types'
24
- gem 'minitest', '~> 4.0'
24
+ gem 'minitest', '~> 5.0'
25
25
  gem 'mocha'
26
26
  if RUBY_VERSION >= '2.0.0'
27
27
  gem 'mustache', '~> 1.0'
data/NEWS.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # nanoc news
2
2
 
3
+ ## 3.8.0 (2015-05-04)
4
+
5
+ Features:
6
+
7
+ * Added `mixed_content` check (#542, #543) [Mike Pennisi]
8
+ * Added `commands_dirs` configuration option for specifying directories to read commands from (#475) [Gregory Pakosz]
9
+ * Added `:cdn_id` option to fog deployer for invalidating CDN objects (#451) [Vlatko Kosturjak]
10
+ * Add access to regular expressions group matches in rules (#478) [Michal Papis]
11
+ * Allow filtering the items array by regex (#458) [Mike Pennisi]
12
+
13
+ Enhancements:
14
+
15
+ * Added `:preserve_order` option to preserve order in Atom feed (#533, #534)
16
+ * Allowed accessing `:pre` snapshot from within item itself (#537, #538, #548)
17
+
18
+ Fixes:
19
+
20
+ * Allowed passing generic Pandoc options with :args (#526, #535)
21
+ * Fix crash when compiling extensionless binary items (#524, #525)
22
+ * Fix double snapshot creation error (#547)
23
+
3
24
  ## 3.7.5 (2015-01-12)
4
25
 
5
26
  Enhancements:
@@ -631,7 +652,7 @@ Removed:
631
652
  New:
632
653
 
633
654
  * `--pages` and `--assets` compiler options
634
- * `--no-color` commandline option
655
+ * `--no-color` command-line option
635
656
  * `Filtering` helper
636
657
  * `#relative_path_to` function in `LinkTo` helper
637
658
  * `rainpress` filter ([Rainpress site](http://code.google.com/p/rainpress/))
@@ -641,7 +662,7 @@ New:
641
662
 
642
663
  Changed:
643
664
 
644
- * The commandline option parser is now a lot more reliable
665
+ * The command-line option parser is now a lot more reliable
645
666
  * `#atom_feed` now takes optional `:content_proc`, `:excerpt_proc` and `:articles` parameters
646
667
  * The compile command show non-written items (those with `skip_output: true`)
647
668
  * The compile command compiles everything by default
@@ -696,7 +717,7 @@ New:
696
717
  * New `rdiscount` filter ([RDiscount site](http://github.com/rtomayko/rdiscount))
697
718
  * New `maruku` filter ([Maruku site](https://github.com/bhollis/maruku/))
698
719
  * New `erubis` filter ([Erubis site](http://www.kuwata-lab.com/erubis/))
699
- * A better commandline frontend
720
+ * A better command-line frontend
700
721
  * A new filesystem data source named `filesystem_combined`
701
722
  * Routers, which decide where compiled pages should be written to
702
723
  * Page/layout mtimes can now be retrieved through `page.mtime`/`layout.mtime`
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  [![Build status](http://img.shields.io/travis/nanoc/nanoc.svg)](https://travis-ci.org/nanoc/nanoc)
3
3
  [![Code Climate](http://img.shields.io/codeclimate/github/nanoc/nanoc.svg)](https://codeclimate.com/github/nanoc/nanoc)
4
4
  [![Code Coverage](http://img.shields.io/coveralls/nanoc/nanoc.svg)](https://coveralls.io/r/nanoc/nanoc)
5
- [![Documentation Coverage](http://inch-pages.github.io/github/nanoc/nanoc.svg)](http://inch-pages.github.io/github/nanoc/nanoc/)
5
+ [![Documentation Coverage](http://inch-ci.org/github/nanoc/nanoc.svg)](http://inch-ci.org/github/nanoc/nanoc/)
6
6
 
7
7
  ![nanoc logo](https://avatars1.githubusercontent.com/u/3260163?s=140)
8
8
 
data/bin/nanoc CHANGED
@@ -12,7 +12,7 @@ begin
12
12
  end
13
13
  rescue LoadError
14
14
  # no problem
15
- end
15
+ end if File.file?('Gemfile')
16
16
 
17
17
  # Add lib to load path
18
18
  $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
@@ -192,7 +192,7 @@ module Nanoc
192
192
  new_data[:edges].each do |edge|
193
193
  from_index, to_index = *edge
194
194
  from = from_index && previous_objects[from_index]
195
- to = to_index && previous_objects[to_index]
195
+ to = to_index && previous_objects[to_index]
196
196
  @graph.add_edge(from, to)
197
197
  end
198
198
 
@@ -70,7 +70,7 @@ module Nanoc
70
70
 
71
71
  # Count
72
72
  existing = Set.new
73
- names = @rule_memory.select { |r| r[0] == :snapshot }.map { |r| r[2] }
73
+ names = @rule_memory.select { |r| r[0] == :snapshot }.map { |r| r[1] }
74
74
  names.each do |n|
75
75
  if existing.include?(n)
76
76
  raise Nanoc::Errors::CannotCreateMultipleSnapshotsWithSameName.new(@item_rep, snapshot_name)
@@ -65,7 +65,21 @@ module Nanoc
65
65
  raise ArgumentError, 'Required :compiler option is missing'
66
66
  end
67
67
  rep = Nanoc::ItemRepProxy.new(rep, compiler) unless rep.proxy?
68
- Nanoc::RuleContext.new(rep: rep, compiler: compiler).instance_eval(&@block)
68
+ context = Nanoc::RuleContext.new(rep: rep, compiler: compiler)
69
+ context.instance_exec(matches(rep.item.identifier), &@block)
70
+ end
71
+
72
+ protected
73
+
74
+ # Matches the rule regexp against items identifier and gives back group
75
+ # captures if any
76
+ #
77
+ # @param [String] identifier Identifier to capture groups for
78
+ #
79
+ # @return [nil, Array] Captured groups, if any
80
+ def matches(identifier)
81
+ matches = @identifier_regex.match(identifier)
82
+ matches && matches.captures
69
83
  end
70
84
  end
71
85
  end
@@ -235,20 +235,29 @@ module Nanoc
235
235
  Nanoc::NotificationCenter.post(:visit_ended, item)
236
236
 
237
237
  # Get name of last pre-layout snapshot
238
- snapshot = params.fetch(:snapshot) { @content[:pre] ? :pre : :last }
239
- is_moving = [:pre, :post, :last].include?(snapshot)
238
+ snapshot_name = params.fetch(:snapshot) { @content[:pre] ? :pre : :last }
239
+ is_moving = [:pre, :post, :last].include?(snapshot_name)
240
240
 
241
241
  # Check existance of snapshot
242
- if !is_moving && snapshots.find { |s| s.first == snapshot && s.last == true }.nil?
243
- raise Nanoc::Errors::NoSuchSnapshot.new(self, snapshot)
242
+ snapshot = snapshots.find { |s| s.first == snapshot_name }
243
+ if !is_moving && (snapshot.nil? || snapshot[-1] == false)
244
+ raise Nanoc::Errors::NoSuchSnapshot.new(self, snapshot_name)
244
245
  end
245
246
 
246
- # Require compilation
247
- if @content[snapshot].nil? || (!self.compiled? && is_moving)
247
+ # Verify snapshot is usable
248
+ is_still_moving =
249
+ case snapshot_name
250
+ when :post, :last
251
+ true
252
+ when :pre
253
+ snapshot.nil? || !snapshot[-1]
254
+ end
255
+ is_usable_snapshot = @content[snapshot_name] && (self.compiled? || !is_still_moving)
256
+ unless is_usable_snapshot
248
257
  raise Nanoc::Errors::UnmetDependency.new(self)
249
- else
250
- @content[snapshot]
251
258
  end
259
+
260
+ @content[snapshot_name]
252
261
  end
253
262
 
254
263
  # Checks whether content exists at a given snapshot.
@@ -416,8 +425,16 @@ module Nanoc
416
425
  #
417
426
  # @return [void]
418
427
  def snapshot(snapshot_name, params = {})
419
- is_final = params.fetch(:final) { true }
420
- @content[snapshot_name] = @content[:last] unless self.binary?
428
+ is_final = params.fetch(:final, true)
429
+
430
+ unless self.binary?
431
+ @content[snapshot_name] = @content[:last]
432
+ end
433
+
434
+ if snapshot_name == :pre && is_final
435
+ snapshots << [:pre, true]
436
+ end
437
+
421
438
  write(snapshot_name) if is_final
422
439
  end
423
440
 
@@ -32,6 +32,8 @@ module Nanoc
32
32
  def [](*args)
33
33
  if 1 == args.size && args.first.is_a?(String)
34
34
  item_with_identifier(args.first)
35
+ elsif 1 == args.size && args.first.is_a?(Regexp)
36
+ @items.select { |i| i.identifier =~ args.first }
35
37
  else
36
38
  @items[*args]
37
39
  end
@@ -32,6 +32,7 @@ module Nanoc
32
32
  DEFAULT_CONFIG = {
33
33
  text_extensions: %w( css erb haml htm html js less markdown md php rb sass scss txt xhtml xml coffee hb handlebars mustache ms slim ).sort,
34
34
  lib_dirs: %w( lib ),
35
+ commands_dirs: %w( commands ),
35
36
  output_dir: 'output',
36
37
  data_sources: [{}],
37
38
  index_filenames: ['index.html'],
data/lib/nanoc/cli.rb CHANGED
@@ -47,9 +47,9 @@ module Nanoc::CLI
47
47
  @debug = boolean
48
48
  end
49
49
 
50
- # Invokes the nanoc commandline tool with the given arguments.
50
+ # Invokes the nanoc command-line tool with the given arguments.
51
51
  #
52
- # @param [Array<String>] args An array of commandline arguments
52
+ # @param [Array<String>] args An array of command-line arguments
53
53
  #
54
54
  # @return [void]
55
55
  def self.run(args)
@@ -59,7 +59,7 @@ module Nanoc::CLI
59
59
  end
60
60
  end
61
61
 
62
- # @return [Cri::Command] The root command, i.e. the commandline tool itself
62
+ # @return [Cri::Command] The root command, i.e. the command-line tool itself
63
63
  def self.root_command
64
64
  @root_command
65
65
  end
@@ -83,7 +83,7 @@ module Nanoc::CLI
83
83
 
84
84
  protected
85
85
 
86
- # Makes the commandline interface ready for use.
86
+ # Makes the command-line interface ready for use.
87
87
  #
88
88
  # @return [void]
89
89
  def self.setup
@@ -117,16 +117,25 @@ module Nanoc::CLI
117
117
  end
118
118
  end
119
119
 
120
- # Loads site-specific commands in `commands/`.
120
+ # Loads site-specific commands.
121
121
  #
122
122
  # @return [void]
123
123
  def self.load_custom_commands
124
- recursive_contents_of('commands').each do |filename|
124
+ if Nanoc::Site.cwd_is_nanoc_site?
125
+ site = Nanoc::Site.new('.')
126
+ site.config[:commands_dirs].each do |path|
127
+ load_commands_at(path)
128
+ end
129
+ end
130
+ end
131
+
132
+ def self.load_commands_at(path)
133
+ recursive_contents_of(path).each do |filename|
125
134
  # Create command
126
135
  command = Nanoc::CLI.load_command_at(filename)
127
136
 
128
137
  # Get supercommand
129
- pieces = filename.gsub(/^commands\/|\.rb$/, '').split('/')
138
+ pieces = filename.gsub(/^#{path}\/|\.rb$/, '').split('/')
130
139
  pieces = pieces[0, pieces.size - 1] || []
131
140
  root = Nanoc::CLI.root_command
132
141
  supercommand = pieces.reduce(root) do |cmd, piece|
@@ -5,7 +5,7 @@ summary 'start the autocompiler'
5
5
  be_hidden
6
6
  aliases :aco
7
7
  description <<-EOS
8
- Start the autocompiler web server. Unless overridden with commandline options
8
+ Start the autocompiler web server. Unless overridden with command-line options
9
9
  or configuration entries, the web server will run on port 3000 and listen on all
10
10
  IP addresses. Running the autocompiler requires the `mime/types` and `rack` gems.
11
11
 
@@ -4,7 +4,7 @@ usage 'create-site [options] path'
4
4
  aliases :create_site, :cs
5
5
  summary 'create a site'
6
6
  description "
7
- Create a new site at the given path. The site will use the `filesystem_unified` data source by default, but this can be changed using the `--datasource` commandline option.
7
+ Create a new site at the given path. The site will use the `filesystem_unified` data source by default, but this can be changed using the `--datasource` command-line option.
8
8
  "
9
9
 
10
10
  required :d, :datasource, 'specify the data source for the new site'
@@ -130,7 +130,7 @@ route '*' do
130
130
  item.identifier.chop + '.css'
131
131
  elsif item.binary?
132
132
  # Write item with identifier /foo/ to /foo.ext
133
- item.identifier.chop + '.' + item[:extension]
133
+ item.identifier.chop + (item[:extension] ? '.' + item[:extension] : '')
134
134
  else
135
135
  # Write item with identifier /foo/ to /foo/index.html
136
136
  item.identifier + 'index.html'
@@ -36,14 +36,12 @@ module Nanoc::CLI::Commands
36
36
  @calc[rep].each do |mem|
37
37
  puts format(' %s %s',
38
38
  @c.c(format('%-10s', mem[0].to_s), :blue),
39
- mem[1..-1].map(&:inspect).join(', ')
40
- )
39
+ mem[1..-1].map(&:inspect).join(', '))
41
40
  end
42
41
  if rep.raw_path
43
42
  puts format(' %s %s',
44
43
  @c.c(format('%-10s', 'write to'), :blue),
45
- rep.raw_path
46
- )
44
+ rep.raw_path)
47
45
  end
48
46
  end
49
47
  end
@@ -55,8 +53,7 @@ module Nanoc::CLI::Commands
55
53
  puts " (from #{layout[:filename]})" if layout[:filename]
56
54
  puts format(' %s %s',
57
55
  @c.c(format('%-10s', 'filter'), :blue),
58
- @calc[layout].map(&:inspect).join(', ')
59
- )
56
+ @calc[layout].map(&:inspect).join(', '))
60
57
  puts
61
58
  end
62
59
  end
@@ -67,8 +67,8 @@ module Nanoc::CLI::Commands
67
67
  rebuilder.call(nil)
68
68
 
69
69
  # Get directories to watch
70
- dirs_to_watch = watcher_config[:dirs_to_watch] || %w( content layouts lib )
71
- files_to_watch = watcher_config[:files_to_watch] || %w( nanoc.yaml config.yaml Rules rules Rules.rb rules.rb )
70
+ dirs_to_watch = watcher_config.fetch(:dirs_to_watch, %w( content layouts lib ))
71
+ files_to_watch = watcher_config.fetch(:files_to_watch, %w( nanoc.yaml config.yaml Rules rules Rules.rb rules.rb ))
72
72
  files_to_watch = Regexp.new(files_to_watch.map { |name| Regexp.quote(name) + '$' }.join('|'))
73
73
  ignore_dir = Regexp.new(Dir.glob('*').map { |dir| dir if File.directory?(dir) }.compact.join('|'))
74
74
 
@@ -95,7 +95,7 @@ module Nanoc::CLI::Commands
95
95
 
96
96
  # Allows sending user notifications in a cross-platform way.
97
97
  class Notifier
98
- # A list of commandline tool names that can be used to send notifications
98
+ # A list of command-line tool names that can be used to send notifications
99
99
  TOOLS = %w( growlnotify notify-send ) unless defined? TOOLS
100
100
 
101
101
  # Send a notification. If no notifier is found, no notification will be
@@ -283,7 +283,7 @@ module Nanoc::CLI
283
283
  if stack.empty?
284
284
  stream.puts ' (empty)'
285
285
  else
286
- stack.reverse.each do |obj|
286
+ stack.reverse_each do |obj|
287
287
  if obj.is_a?(Nanoc::ItemRep)
288
288
  stream.puts " - [item] #{obj.item.identifier} (rep #{obj.name})"
289
289
  else # layout
@@ -11,8 +11,8 @@ module Nanoc::CLI
11
11
  ACTION_COLORS = {
12
12
  create: "\e[32m", # green
13
13
  update: "\e[33m", # yellow
14
- identical: '', # (nothing)
15
- skip: '', # (nothing)
14
+ identical: '', # (nothing)
15
+ skip: '', # (nothing)
16
16
  delete: "\e[31m" # red
17
17
  }
18
18
 
@@ -46,9 +46,7 @@ module Nanoc::CLI
46
46
  action,
47
47
  "\e[0m",
48
48
  duration.nil? ? '' : format('[%2.2fs] ', duration),
49
- name
50
- )
51
- )
49
+ name))
52
50
  end
53
51
 
54
52
  # Logs a message.
@@ -119,7 +119,7 @@ module Nanoc::DataSources
119
119
  end
120
120
 
121
121
  # Get modification times
122
- meta_mtime = meta_filename ? File.stat(meta_filename).mtime : nil
122
+ meta_mtime = meta_filename ? File.stat(meta_filename).mtime : nil
123
123
  content_mtime = content_filename ? File.stat(content_filename).mtime : nil
124
124
  if meta_mtime && content_mtime
125
125
  mtime = meta_mtime > content_mtime ? meta_mtime : content_mtime
@@ -170,7 +170,7 @@ module Nanoc::DataSources
170
170
  end
171
171
 
172
172
  # Reorder elements and convert to extnames
173
- filenames[0] = meta_filenames[0] ? 'yaml' : nil
173
+ filenames[0] = meta_filenames[0] ? 'yaml' : nil
174
174
  filenames[1] = content_filenames[0] ? ext_of(content_filenames[0])[1..-1] || '' : nil
175
175
  end
176
176
 
@@ -65,7 +65,7 @@ module Nanoc::Extra
65
65
  rescue StandardError, ScriptError => e
66
66
  # Add compilation stack to env
67
67
  env['nanoc.stack'] = []
68
- stack.reverse.each do |obj|
68
+ stack.reverse_each do |obj|
69
69
  if obj.is_a?(Nanoc::ItemRep) # item rep
70
70
  env['nanoc.stack'] << "[item] #{obj.item.identifier} (rep #{obj.name})"
71
71
  else # layout
@@ -6,6 +6,7 @@ module Nanoc::Extra::Checking::Checks
6
6
  autoload 'HTML', 'nanoc/extra/checking/checks/html'
7
7
  autoload 'InternalLinks', 'nanoc/extra/checking/checks/internal_links'
8
8
  autoload 'Stale', 'nanoc/extra/checking/checks/stale'
9
+ autoload 'MixedContent', 'nanoc/extra/checking/checks/mixed_content'
9
10
 
10
11
  Nanoc::Extra::Checking::Check.register '::Nanoc::Extra::Checking::Checks::CSS', :css
11
12
  Nanoc::Extra::Checking::Check.register '::Nanoc::Extra::Checking::Checks::ExternalLinks', :external_links
@@ -14,4 +15,5 @@ module Nanoc::Extra::Checking::Checks
14
15
  Nanoc::Extra::Checking::Check.register '::Nanoc::Extra::Checking::Checks::InternalLinks', :internal_links
15
16
  Nanoc::Extra::Checking::Check.register '::Nanoc::Extra::Checking::Checks::InternalLinks', :ilinks
16
17
  Nanoc::Extra::Checking::Check.register '::Nanoc::Extra::Checking::Checks::Stale', :stale
18
+ Nanoc::Extra::Checking::Check.register '::Nanoc::Extra::Checking::Checks::MixedContent', :mixed_content
17
19
  end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc::Extra::Checking::Checks
4
+ # A check that verifies HTML files do not reference external resources with
5
+ # URLs that would trigger "mixed content" warnings.
6
+ class MixedContent < ::Nanoc::Extra::Checking::Check
7
+ PROTOCOL_PATTERN = /^(\w+):\/\//
8
+
9
+ def run
10
+ filenames = output_filenames.select { |f| File.extname(f) == '.html' }
11
+ resource_uris_with_filenames = ::Nanoc::Extra::LinkCollector.new(filenames).filenames_per_resource_uri
12
+
13
+ resource_uris_with_filenames.each_pair do |uri, fns|
14
+ next unless guaranteed_insecure?(uri)
15
+ fns.each do |filename|
16
+ add_issue(
17
+ "mixed content include: #{uri}",
18
+ subject: filename)
19
+ end
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def guaranteed_insecure?(href)
26
+ protocol = PROTOCOL_PATTERN.match(href)
27
+
28
+ protocol && protocol[1].downcase == 'http'
29
+ end
30
+ end
31
+ end