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