nanoc 3.7.5 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
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