nanoc-checking 1.0.1 → 1.0.3
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 +4 -4
- data/NEWS.md +12 -0
- data/README.md +2 -2
- data/lib/nanoc/checking/check.rb +3 -2
- data/lib/nanoc/checking/checks/external_links.rb +5 -4
- data/lib/nanoc/checking/checks/internal_links.rb +3 -3
- data/lib/nanoc/checking/checks/mixed_content.rb +1 -1
- data/lib/nanoc/checking/link_collector.rb +132 -0
- data/lib/nanoc/checking/runner.rb +1 -1
- data/lib/nanoc/checking/version.rb +1 -1
- data/lib/nanoc/checking.rb +1 -0
- metadata +17 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89d7860391ed030af4773bd204ce6a94b7c76b966c42b2384efb53619f5b33f4
|
4
|
+
data.tar.gz: c60649c0f1f12ca8475f4c06e47348fa39dc599dcfc30c21f06e801f15f942df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3db4309a8fbd02942f9d8cd3db83701779ae44fd0f0e32cb92cdfc4569a3c05572ad52e309317ce911e7fd1775afe255b1c1fba4e2ff90d150716ab7f48e6d3e
|
7
|
+
data.tar.gz: 2e5839f8e46c65adf9721ab8eb29a09ea8734204eaa83475fb83ec66c87d0dcb440d5dc4fe06a3f476e7336f78d0af39d095d11657712f32c6473709c77e3e33
|
data/NEWS.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# nanoc-checking news
|
2
2
|
|
3
|
+
## 1.0.3 (2024-03-15)
|
4
|
+
|
5
|
+
Fixes:
|
6
|
+
|
7
|
+
- Restore compatibility with Nanoc 4.12.20
|
8
|
+
|
9
|
+
## 1.0.2 (2022-01-15)
|
10
|
+
|
11
|
+
Fixes:
|
12
|
+
|
13
|
+
- Ensure compatibility with latest version of Nanoc
|
14
|
+
|
3
15
|
## 1.0.1 (2021-01-01)
|
4
16
|
|
5
17
|
Enhancements:
|
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.
|
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.
|
5
|
+
For details, see the [Checking correctness of Nanoc sites](https://nanoc.app/doc/testing/) chapter of the Nanoc documentation.
|
data/lib/nanoc/checking/check.rb
CHANGED
@@ -13,7 +13,7 @@ module Nanoc
|
|
13
13
|
class Check < Nanoc::Core::Context
|
14
14
|
extend DDPlugin::Plugin
|
15
15
|
|
16
|
-
|
16
|
+
prepend MemoWise
|
17
17
|
|
18
18
|
attr_reader :issues
|
19
19
|
|
@@ -78,13 +78,14 @@ module Nanoc
|
|
78
78
|
end
|
79
79
|
|
80
80
|
# @private
|
81
|
-
|
81
|
+
def excluded_patterns
|
82
82
|
@config
|
83
83
|
.fetch(:checks, {})
|
84
84
|
.fetch(:all, {})
|
85
85
|
.fetch(:exclude_files, [])
|
86
86
|
.map { |pattern| Regexp.new(pattern) }
|
87
87
|
end
|
88
|
+
memo_wise :excluded_patterns
|
88
89
|
|
89
90
|
# @private
|
90
91
|
def output_html_filenames
|
@@ -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::
|
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
|
24
|
+
"broken reference to <#{res.href}>: #{res.explanation}",
|
25
25
|
subject: filename,
|
26
26
|
)
|
27
27
|
end
|
@@ -71,7 +71,8 @@ module Nanoc
|
|
71
71
|
next
|
72
72
|
end
|
73
73
|
|
74
|
-
|
74
|
+
case res.code
|
75
|
+
when /^3..$/
|
75
76
|
if i == 4
|
76
77
|
return Result.new(href, 'too many redirects')
|
77
78
|
end
|
@@ -87,7 +88,7 @@ module Nanoc
|
|
87
88
|
end
|
88
89
|
|
89
90
|
url = URI.parse(location)
|
90
|
-
|
91
|
+
when '200'
|
91
92
|
return nil
|
92
93
|
else
|
93
94
|
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::
|
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
|
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
|
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::
|
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,132 @@
|
|
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
|
+
Nanoc::Extra::JRubyNokogiriWarner.check_and_warn
|
27
|
+
|
28
|
+
@filenames = filenames
|
29
|
+
@filter =
|
30
|
+
case mode
|
31
|
+
when nil
|
32
|
+
->(_h) { true }
|
33
|
+
when :external
|
34
|
+
->(h) { external_href?(h) }
|
35
|
+
when :internal
|
36
|
+
->(h) { internal_href?(h) }
|
37
|
+
else
|
38
|
+
raise ArgumentError, 'Expected mode argument to be :internal, :external or nil'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def filenames_per_href
|
43
|
+
grouped_filenames { |filename| hrefs_in_file(filename) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def filenames_per_resource_uri
|
47
|
+
grouped_filenames { |filename| resource_uris_in_file(filename) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def external_href?(href)
|
51
|
+
return false if internal_href?(href)
|
52
|
+
|
53
|
+
href =~ %r{^(//|[a-z-]+:)}
|
54
|
+
end
|
55
|
+
|
56
|
+
def internal_href?(href)
|
57
|
+
return false if href.nil?
|
58
|
+
|
59
|
+
href.start_with?('file:/')
|
60
|
+
end
|
61
|
+
|
62
|
+
# all links
|
63
|
+
def hrefs_in_file(filename)
|
64
|
+
uris_in_file filename, nil
|
65
|
+
end
|
66
|
+
|
67
|
+
# embedded resources, used by the mixed-content checker
|
68
|
+
def resource_uris_in_file(filename)
|
69
|
+
uris_in_file filename, %w[audio base form iframe img link object script source video]
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def grouped_filenames
|
75
|
+
require 'nokogiri'
|
76
|
+
grouped_filenames = {}
|
77
|
+
@filenames.each do |filename|
|
78
|
+
yield(filename).each do |resouce_uri|
|
79
|
+
grouped_filenames[resouce_uri] ||= Set.new
|
80
|
+
grouped_filenames[resouce_uri] << filename
|
81
|
+
end
|
82
|
+
end
|
83
|
+
grouped_filenames
|
84
|
+
end
|
85
|
+
|
86
|
+
def uris_in_file(filename, tag_names)
|
87
|
+
uris = Set.new
|
88
|
+
base_uri = URI("file://#{filename}")
|
89
|
+
doc = Nokogiri::HTML(::File.read(filename))
|
90
|
+
doc.traverse do |tag|
|
91
|
+
next unless tag_names.nil? || tag_names.include?(tag.name)
|
92
|
+
|
93
|
+
attrs = []
|
94
|
+
attrs += URI_ATTRS[tag.name] unless URI_ATTRS[tag.name].nil?
|
95
|
+
attrs += GLOBAL_ATTRS if tag_names.nil?
|
96
|
+
next if attrs.nil?
|
97
|
+
|
98
|
+
attrs.each do |attr_name|
|
99
|
+
next if tag[attr_name].nil?
|
100
|
+
|
101
|
+
if attr_name == :srcset
|
102
|
+
uris = uris.merge(tag[attr_name].split(',').map { |v| v.strip.split[0].strip }.compact)
|
103
|
+
elsif %i[about ping resource].include?(attr_name)
|
104
|
+
uris = uris.merge(tag[attr_name].split.map(&:strip).compact)
|
105
|
+
else
|
106
|
+
uris << tag[attr_name.to_s]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Strip fragment
|
112
|
+
uris.map! { |uri| uri.gsub(/#.*$/, '') }
|
113
|
+
|
114
|
+
# Resolve paths relative to the filename, return invalid URIs as-is
|
115
|
+
uris.map! do |uri|
|
116
|
+
if uri.start_with?('//')
|
117
|
+
# Don’t modify protocol-relative URLs. They’re absolute!
|
118
|
+
uri
|
119
|
+
else
|
120
|
+
begin
|
121
|
+
URI.join(base_uri, uri).to_s
|
122
|
+
rescue
|
123
|
+
uri
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
uris.select(&@filter)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
data/lib/nanoc/checking.rb
CHANGED
@@ -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.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Defreyne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nanoc-cli
|
@@ -16,40 +16,40 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '4.
|
19
|
+
version: '4.12'
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 4.
|
22
|
+
version: 4.12.5
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '4.
|
29
|
+
version: '4.12'
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 4.
|
32
|
+
version: 4.12.5
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: nanoc-core
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '4.
|
39
|
+
version: '4.12'
|
40
40
|
- - ">="
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: 4.
|
42
|
+
version: 4.12.5
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: '4.
|
49
|
+
version: '4.12'
|
50
50
|
- - ">="
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version: 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,13 +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.
|
81
|
+
homepage: https://nanoc.app/
|
81
82
|
licenses:
|
82
83
|
- MIT
|
83
|
-
metadata:
|
84
|
+
metadata:
|
85
|
+
rubygems_mfa_required: 'true'
|
86
|
+
source_code_uri: https://github.com/nanoc/nanoc/tree/nanoc-checking-v1.0.3/nanoc-checking
|
84
87
|
post_install_message:
|
85
88
|
rdoc_options: []
|
86
89
|
require_paths:
|
@@ -89,14 +92,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
89
92
|
requirements:
|
90
93
|
- - ">="
|
91
94
|
- !ruby/object:Gem::Version
|
92
|
-
version: '2.
|
95
|
+
version: '2.7'
|
93
96
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
97
|
requirements:
|
95
98
|
- - ">="
|
96
99
|
- !ruby/object:Gem::Version
|
97
100
|
version: '0'
|
98
101
|
requirements: []
|
99
|
-
rubygems_version: 3.
|
102
|
+
rubygems_version: 3.5.3
|
100
103
|
signing_key:
|
101
104
|
specification_version: 4
|
102
105
|
summary: Checking support for Nanoc
|