nanoc-checking 1.0.2 → 1.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d5e37cf90a631812173adcadedb4d8bf9b9d93926b04f9ba25c524ab13bb2dc
4
- data.tar.gz: d1e2b8cd49d3b280ec203be153938ba3da0794ea5a57e3cb6ca3ff867bef2e01
3
+ metadata.gz: b380e10a13a38c13d712399af8308a0cb67b533094287649eb30283fceba9be3
4
+ data.tar.gz: bd6715348e5527f23bedf1812b56bc49d75e5827b5bb318a5165bf5cf689077f
5
5
  SHA512:
6
- metadata.gz: b9e144e2d1dc8565072f2d117416b4ba3f89635dfe21b1c1e1e18ad238bcd4f6baf7a285b37c1568c8f514ffb1b018cff6e97c6ea69093e512df2d65ba4932ff
7
- data.tar.gz: d196ee9d516d77824de90dc79226cc46f394c0ad32cb897005c684fb2112dbb751eeafae9538f3b9146d8fa89c9fc648aa2909a02f3d9eae2b53fbc4bcf48876
6
+ metadata.gz: 61e31cc485a14e7a75199c65df33d172dd69caad7d00be40725ec55ca5203f052213846b974dd842be2a33d021d10be184a1266810f9fdcddf89db1a7def572d
7
+ data.tar.gz: 2472f804af1d3facea1b840d89280070042b27fc03d91475b91db5e41a6783261a84ac62f83d6ea25811112ee85ff045e5a9110bc8ca398f08b4650dcfbc65ae
data/NEWS.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # nanoc-checking news
2
2
 
3
+ ## 1.0.4 (2024-04-19)
4
+
5
+ Enhancements:
6
+
7
+ - Added support for `javascript:` pseudo-URLs (#1698)
8
+
9
+ ## 1.0.3 (2024-03-15)
10
+
11
+ Fixes:
12
+
13
+ - Restore compatibility with Nanoc 4.12.20
14
+
3
15
  ## 1.0.2 (2022-01-15)
4
16
 
5
17
  Fixes:
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # nanoc-checking
2
2
 
3
- This provides the `check` command and associated functionality for [Nanoc](https://nanoc.ws).
3
+ This provides the `check` command and associated functionality for [Nanoc](https://nanoc.app).
4
4
 
5
- For details, see the [Checking correctness of Nanoc sites](https://nanoc.ws/doc/testing/) chapter of the Nanoc documentation.
5
+ For details, see the [Checking correctness of Nanoc sites](https://nanoc.app/doc/testing/) chapter of the Nanoc documentation.
@@ -13,7 +13,7 @@ module Nanoc
13
13
  # Find all broken external hrefs
14
14
  # TODO: de-duplicate this (duplicated in internal links check)
15
15
  filenames = output_html_filenames.reject { |f| excluded_file?(f) }
16
- hrefs_with_filenames = ::Nanoc::Extra::LinkCollector.new(filenames, :external).filenames_per_href
16
+ hrefs_with_filenames = ::Nanoc::Checking::LinkCollector.new(filenames, :external).filenames_per_href
17
17
  results = select_invalid(hrefs_with_filenames.keys.shuffle)
18
18
 
19
19
  # Report them
@@ -21,7 +21,7 @@ module Nanoc
21
21
  filenames = hrefs_with_filenames[res.href]
22
22
  filenames.each do |filename|
23
23
  add_issue(
24
- "broken reference to #{res.href}: #{res.explanation}",
24
+ "broken reference to <#{res.href}>: #{res.explanation}",
25
25
  subject: filename,
26
26
  )
27
27
  end
@@ -43,6 +43,13 @@ module Nanoc
43
43
  end
44
44
 
45
45
  def validate(href)
46
+ # Skip javascript: URLs
47
+ #
48
+ # This needs to be handled explicitly, because URI.parse does not
49
+ # like `javascript:` URLs -- presumably because those are not
50
+ # technically valid URLs.
51
+ return nil if href.start_with?('javascript:')
52
+
46
53
  # Parse
47
54
  url = nil
48
55
  begin
@@ -71,7 +78,8 @@ module Nanoc
71
78
  next
72
79
  end
73
80
 
74
- if /^3..$/.match?(res.code)
81
+ case res.code
82
+ when /^3..$/
75
83
  if i == 4
76
84
  return Result.new(href, 'too many redirects')
77
85
  end
@@ -87,7 +95,7 @@ module Nanoc
87
95
  end
88
96
 
89
97
  url = URI.parse(location)
90
- elsif res.code == '200'
98
+ when '200'
91
99
  return nil
92
100
  else
93
101
  return Result.new(href, res.code)
@@ -18,14 +18,14 @@ module Nanoc
18
18
  def run
19
19
  # TODO: de-duplicate this (duplicated in external links check)
20
20
  filenames = output_html_filenames
21
- uris = ::Nanoc::Extra::LinkCollector.new(filenames, :internal).filenames_per_href
21
+ uris = ::Nanoc::Checking::LinkCollector.new(filenames, :internal).filenames_per_href
22
22
 
23
23
  uris.each_pair do |href, fns|
24
24
  fns.each do |filename|
25
25
  next if valid?(href, filename)
26
26
 
27
27
  add_issue(
28
- "broken reference to #{href}",
28
+ "broken reference to <#{href}>",
29
29
  subject: filename,
30
30
  )
31
31
  end
@@ -89,7 +89,7 @@ module Nanoc
89
89
  # FIXME: do not depend on current working directory
90
90
  origin = File.absolute_path(origin)
91
91
 
92
- relative_origin = origin[@config.output_dir.size..-1]
92
+ relative_origin = origin[@config.output_dir.size..]
93
93
  excludes = config.fetch(:exclude_origins, [])
94
94
  excludes.any? { |pattern| Regexp.new(pattern).match(relative_origin) }
95
95
  end
@@ -14,7 +14,7 @@ module Nanoc
14
14
 
15
15
  def run
16
16
  filenames = output_html_filenames
17
- resource_uris_with_filenames = ::Nanoc::Extra::LinkCollector.new(filenames).filenames_per_resource_uri
17
+ resource_uris_with_filenames = ::Nanoc::Checking::LinkCollector.new(filenames).filenames_per_resource_uri
18
18
 
19
19
  resource_uris_with_filenames.each_pair do |uri, fns|
20
20
  next unless guaranteed_insecure?(uri)
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ::Nanoc
4
+ module Checking
5
+ class LinkCollector
6
+ # HTML5 element attributes
7
+ URI_ATTRS = {
8
+ 'a' => %i[href ping],
9
+ 'area' => %i[href ping],
10
+ 'audio' => %i[src],
11
+ 'base' => %i[href],
12
+ 'blockquote' => %i[cite],
13
+ 'form' => %i[action],
14
+ 'iframe' => %i[src],
15
+ 'img' => %i[src srcset],
16
+ 'link' => %i[href],
17
+ 'object' => %i[data],
18
+ 'script' => %i[src],
19
+ 'source' => %i[src srcset],
20
+ 'video' => %i[poster src],
21
+ }.freeze
22
+ # HTML+RDFa global URI attributes
23
+ GLOBAL_ATTRS = %i[about resource].freeze
24
+
25
+ def initialize(filenames, mode = nil)
26
+ @filenames = filenames
27
+ @filter =
28
+ case mode
29
+ when nil
30
+ ->(_h) { true }
31
+ when :external
32
+ ->(h) { external_href?(h) }
33
+ when :internal
34
+ ->(h) { internal_href?(h) }
35
+ else
36
+ raise ArgumentError, 'Expected mode argument to be :internal, :external or nil'
37
+ end
38
+ end
39
+
40
+ def filenames_per_href
41
+ grouped_filenames { |filename| hrefs_in_file(filename) }
42
+ end
43
+
44
+ def filenames_per_resource_uri
45
+ grouped_filenames { |filename| resource_uris_in_file(filename) }
46
+ end
47
+
48
+ def external_href?(href)
49
+ return false if internal_href?(href)
50
+
51
+ href =~ %r{^(//|[a-z-]+:)}
52
+ end
53
+
54
+ def internal_href?(href)
55
+ return false if href.nil?
56
+
57
+ href.start_with?('file:/')
58
+ end
59
+
60
+ # all links
61
+ def hrefs_in_file(filename)
62
+ uris_in_file filename, nil
63
+ end
64
+
65
+ # embedded resources, used by the mixed-content checker
66
+ def resource_uris_in_file(filename)
67
+ uris_in_file filename, %w[audio base form iframe img link object script source video]
68
+ end
69
+
70
+ private
71
+
72
+ def grouped_filenames
73
+ require 'nokogiri'
74
+ grouped_filenames = {}
75
+ @filenames.each do |filename|
76
+ yield(filename).each do |resouce_uri|
77
+ grouped_filenames[resouce_uri] ||= Set.new
78
+ grouped_filenames[resouce_uri] << filename
79
+ end
80
+ end
81
+ grouped_filenames
82
+ end
83
+
84
+ def uris_in_file(filename, tag_names)
85
+ uris = Set.new
86
+ base_uri = URI("file://#{filename}")
87
+ doc = Nokogiri::HTML(::File.read(filename))
88
+ doc.traverse do |tag|
89
+ next unless tag_names.nil? || tag_names.include?(tag.name)
90
+
91
+ attrs = []
92
+ attrs += URI_ATTRS[tag.name] unless URI_ATTRS[tag.name].nil?
93
+ attrs += GLOBAL_ATTRS if tag_names.nil?
94
+ next if attrs.nil?
95
+
96
+ attrs.each do |attr_name|
97
+ next if tag[attr_name].nil?
98
+
99
+ if attr_name == :srcset
100
+ uris = uris.merge(tag[attr_name].split(',').map { |v| v.strip.split[0].strip }.compact)
101
+ elsif %i[about ping resource].include?(attr_name)
102
+ uris = uris.merge(tag[attr_name].split.map(&:strip).compact)
103
+ else
104
+ uris << tag[attr_name.to_s]
105
+ end
106
+ end
107
+ end
108
+
109
+ # Strip fragment
110
+ uris.map! { |uri| uri.gsub(/#.*$/, '') }
111
+
112
+ # Resolve paths relative to the filename, return invalid URIs as-is
113
+ uris.map! do |uri|
114
+ if uri.start_with?('//')
115
+ # Don’t modify protocol-relative URLs. They’re absolute!
116
+ uri
117
+ else
118
+ begin
119
+ URI.join(base_uri, uri).to_s
120
+ rescue
121
+ uri
122
+ end
123
+ end
124
+ end
125
+
126
+ uris.select(&@filter)
127
+ end
128
+ end
129
+ end
130
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Nanoc
4
4
  module Checking
5
- VERSION = '1.0.2'
5
+ VERSION = '1.0.4'
6
6
  end
7
7
  end
@@ -13,6 +13,7 @@ require_relative 'checking/check'
13
13
  require_relative 'checking/checks'
14
14
  require_relative 'checking/command_runners'
15
15
  require_relative 'checking/dsl'
16
+ require_relative 'checking/link_collector'
16
17
  require_relative 'checking/runner'
17
18
  require_relative 'checking/loader'
18
19
  require_relative 'checking/issue'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nanoc-checking
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Defreyne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-15 00:00:00.000000000 Z
11
+ date: 2024-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nanoc-cli
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '4.12'
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 4.12.4
22
+ version: 4.12.5
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '4.12'
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 4.12.4
32
+ version: 4.12.5
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: nanoc-core
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -39,7 +39,7 @@ dependencies:
39
39
  version: '4.12'
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: 4.12.4
42
+ version: 4.12.5
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
@@ -49,7 +49,7 @@ dependencies:
49
49
  version: '4.12'
50
50
  - - ">="
51
51
  - !ruby/object:Gem::Version
52
- version: 4.12.4
52
+ version: 4.12.5
53
53
  description: Provides checking functionality for Nanoc
54
54
  email: denis+rubygems@denis.ws
55
55
  executables: []
@@ -74,14 +74,16 @@ files:
74
74
  - lib/nanoc/checking/commands/check.rb
75
75
  - lib/nanoc/checking/dsl.rb
76
76
  - lib/nanoc/checking/issue.rb
77
+ - lib/nanoc/checking/link_collector.rb
77
78
  - lib/nanoc/checking/loader.rb
78
79
  - lib/nanoc/checking/runner.rb
79
80
  - lib/nanoc/checking/version.rb
80
- homepage: https://nanoc.ws/
81
+ homepage: https://nanoc.app/
81
82
  licenses:
82
83
  - MIT
83
84
  metadata:
84
85
  rubygems_mfa_required: 'true'
86
+ source_code_uri: https://github.com/nanoc/nanoc/tree/nanoc-checking-v1.0.4/nanoc-checking
85
87
  post_install_message:
86
88
  rdoc_options: []
87
89
  require_paths:
@@ -90,14 +92,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
90
92
  requirements:
91
93
  - - ">="
92
94
  - !ruby/object:Gem::Version
93
- version: '2.6'
95
+ version: '2.7'
94
96
  required_rubygems_version: !ruby/object:Gem::Requirement
95
97
  requirements:
96
98
  - - ">="
97
99
  - !ruby/object:Gem::Version
98
100
  version: '0'
99
101
  requirements: []
100
- rubygems_version: 3.3.4
102
+ rubygems_version: 3.5.9
101
103
  signing_key:
102
104
  specification_version: 4
103
105
  summary: Checking support for Nanoc