link-checker 0.0.0 → 0.1.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.
- data/Gemfile +1 -1
- data/Gemfile.lock +8 -14
- data/README.md +15 -3
- data/VERSION +1 -1
- data/bin/check-links +1 -1
- data/lib/link_checker.rb +65 -44
- data/link-checker.gemspec +6 -6
- data/spec/link-checker_spec.rb +15 -25
- data/spec/spec_helper.rb +1 -0
- metadata +57 -22
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
archive-tar-minitar (0.5.2)
|
5
4
|
colorize (0.5.8)
|
6
5
|
columnize (0.3.6)
|
6
|
+
debugger (1.2.0)
|
7
|
+
columnize (>= 0.3.1)
|
8
|
+
debugger-linecache (~> 1.1.1)
|
9
|
+
debugger-ruby_core_source (~> 1.1.3)
|
10
|
+
debugger-linecache (1.1.2)
|
11
|
+
debugger-ruby_core_source (>= 1.1.1)
|
12
|
+
debugger-ruby_core_source (1.1.3)
|
7
13
|
diff-lcs (1.1.3)
|
8
14
|
fakeweb (1.3.0)
|
9
15
|
git (1.2.5)
|
@@ -13,8 +19,6 @@ GEM
|
|
13
19
|
rake
|
14
20
|
rdoc
|
15
21
|
json (1.7.5)
|
16
|
-
linecache19 (0.5.12)
|
17
|
-
ruby_core_source (>= 0.1.4)
|
18
22
|
multi_json (1.3.6)
|
19
23
|
nokogiri (1.5.5)
|
20
24
|
rake (0.9.2.2)
|
@@ -28,16 +32,6 @@ GEM
|
|
28
32
|
rspec-expectations (2.11.3)
|
29
33
|
diff-lcs (~> 1.1.3)
|
30
34
|
rspec-mocks (2.11.3)
|
31
|
-
ruby-debug-base19 (0.11.25)
|
32
|
-
columnize (>= 0.3.1)
|
33
|
-
linecache19 (>= 0.5.11)
|
34
|
-
ruby_core_source (>= 0.1.4)
|
35
|
-
ruby-debug19 (0.11.6)
|
36
|
-
columnize (>= 0.3.1)
|
37
|
-
linecache19 (>= 0.5.11)
|
38
|
-
ruby-debug-base19 (>= 0.11.19)
|
39
|
-
ruby_core_source (0.1.5)
|
40
|
-
archive-tar-minitar (>= 0.5.2)
|
41
35
|
simplecov (0.6.4)
|
42
36
|
multi_json (~> 1.0)
|
43
37
|
simplecov-html (~> 0.5.3)
|
@@ -48,9 +42,9 @@ PLATFORMS
|
|
48
42
|
|
49
43
|
DEPENDENCIES
|
50
44
|
colorize (~> 0.5.8)
|
45
|
+
debugger
|
51
46
|
fakeweb (~> 1.3.0)
|
52
47
|
jeweler (~> 1.8.4)
|
53
48
|
nokogiri (~> 1.5.5)
|
54
49
|
rspec (~> 2.11.0)
|
55
|
-
ruby-debug19 (~> 0.11.6)
|
56
50
|
simplecov (~> 0.6.4)
|
data/README.md
CHANGED
@@ -4,12 +4,24 @@ This Ruby gem allows you to easily check the links in your Octopress web site.
|
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
|
7
|
+
Add the ```link-checker``` gem to your project's ```Gemfile```:
|
8
|
+
|
9
|
+
gem "link-checker"
|
10
|
+
|
11
|
+
Then ```bundle install``` to install the gem.
|
8
12
|
|
9
13
|
## Usage
|
10
14
|
|
11
|
-
|
15
|
+
You can use the ```check-links``` command to specify any directory to scan for HTML files. It will scan each ```.html``` or ```.htm``` file and then check each link within each file.
|
16
|
+
|
17
|
+
For example, to check the links for a Jekyll or Octopress site:
|
18
|
+
|
19
|
+
check-links 'public'
|
12
20
|
|
13
21
|
## Testing
|
14
22
|
|
15
|
-
|
23
|
+
The ```link-checker``` gem uses [RSpec](http://rspec.info) for testing and has 100% test coverage, verified using [simplecov](https://github.com/colszowka/simplecov).
|
24
|
+
|
25
|
+
Run the specs with:
|
26
|
+
|
27
|
+
rake spec
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.1.0
|
data/bin/check-links
CHANGED
data/lib/link_checker.rb
CHANGED
@@ -5,69 +5,90 @@ require 'net/https'
|
|
5
5
|
require 'uri'
|
6
6
|
require 'colorize'
|
7
7
|
|
8
|
-
|
8
|
+
class LinkChecker
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@target_path = target_path
|
14
|
-
end
|
10
|
+
def initialize(target_path)
|
11
|
+
@target_path = target_path
|
12
|
+
end
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
14
|
+
def find_html_files
|
15
|
+
Find.find(@target_path).map {|path|
|
16
|
+
FileTest.file?(path) && (path =~ /\.html?$/) ? path : nil
|
17
|
+
}.reject{|path| path.nil?}
|
18
|
+
end
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
def self.find_external_links(file_path)
|
21
|
+
Nokogiri::HTML(open(file_path)).css('a').
|
22
|
+
select{|link| link.attribute('href').value =~ /^https?\:\/\// }
|
23
|
+
end
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
return self.check_link(response['location'])
|
25
|
+
def self.check_link(uri, redirected=false)
|
26
|
+
uri = URI.parse(uri)
|
27
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
28
|
+
http.use_ssl = true if uri.scheme == "https"
|
29
|
+
http.start do
|
30
|
+
path = (uri.path.empty?) ? '/' : uri.path
|
31
|
+
http.request_get(path) do |response|
|
32
|
+
case response
|
33
|
+
when Net::HTTPSuccess then
|
34
|
+
if redirected
|
35
|
+
return Redirect.new(uri)
|
39
36
|
else
|
40
|
-
|
37
|
+
return Good.new
|
41
38
|
end
|
39
|
+
when Net::HTTPRedirection then
|
40
|
+
return self.check_link(response['location'], true)
|
41
|
+
else
|
42
|
+
raise Error.new(response)
|
42
43
|
end
|
43
44
|
end
|
44
45
|
end
|
46
|
+
end
|
45
47
|
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
def check_links
|
49
|
+
find_html_files.each do |file|
|
50
|
+
bad_checks = []
|
51
|
+
warnings = []
|
49
52
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
self.class.find_external_links(file).each do |link|
|
54
|
+
uri = link.attribute('href').value
|
55
|
+
begin
|
56
|
+
response = self.class.check_link(uri)
|
57
|
+
if response.class.eql? Redirect
|
58
|
+
warnings << { :link => link, :response => response }
|
56
59
|
end
|
60
|
+
rescue => error
|
61
|
+
bad_checks << { :link => link, :response => error }
|
57
62
|
end
|
58
|
-
|
59
|
-
|
63
|
+
end
|
64
|
+
|
65
|
+
if bad_checks.empty?
|
66
|
+
if warnings.empty?
|
60
67
|
puts "Checked: #{file}".green
|
61
68
|
else
|
62
|
-
puts "
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
69
|
+
puts "Checked: #{file}".yellow
|
70
|
+
end
|
71
|
+
warnings.each do |warning|
|
72
|
+
puts " Warning: #{warning[:link].attribute('href').value}".yellow
|
73
|
+
puts " Redirected to: #{warning[:response].final_destination.to_s}".yellow
|
74
|
+
end
|
75
|
+
else
|
76
|
+
puts "Problem: #{file}".red
|
77
|
+
bad_checks.each do |check|
|
78
|
+
puts " Link: #{check[:link].attribute('href').value}".red
|
79
|
+
puts " Response: #{check[:response].response.inspect}".red
|
67
80
|
end
|
68
81
|
end
|
69
82
|
end
|
83
|
+
end
|
70
84
|
|
85
|
+
class Good; end
|
86
|
+
|
87
|
+
class Redirect
|
88
|
+
attr_reader :final_destination
|
89
|
+
def initialize(final_destination)
|
90
|
+
@final_destination = final_destination
|
91
|
+
end
|
71
92
|
end
|
72
93
|
|
73
94
|
class Error < StandardError
|
data/link-checker.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "link-checker"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ryan Alyn Porter"]
|
12
|
-
s.date = "2012-10-
|
12
|
+
s.date = "2012-10-04"
|
13
13
|
s.description = "Check the links in a web site before deploying, using Nokogiri."
|
14
14
|
s.executables = ["check-links"]
|
15
15
|
s.extra_rdoc_files = [
|
@@ -368,7 +368,7 @@ Gem::Specification.new do |s|
|
|
368
368
|
s.homepage = "https://github.com/endymion/link-checker"
|
369
369
|
s.licenses = ["MIT"]
|
370
370
|
s.require_paths = ["lib"]
|
371
|
-
s.rubygems_version = "1.8.
|
371
|
+
s.rubygems_version = "1.8.24"
|
372
372
|
s.summary = "Check the links in a web site before deploying."
|
373
373
|
|
374
374
|
if s.respond_to? :specification_version then
|
@@ -380,16 +380,16 @@ Gem::Specification.new do |s|
|
|
380
380
|
s.add_development_dependency(%q<rspec>, ["~> 2.11.0"])
|
381
381
|
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
382
382
|
s.add_development_dependency(%q<simplecov>, ["~> 0.6.4"])
|
383
|
-
s.add_development_dependency(%q<ruby-debug19>, ["~> 0.11.6"])
|
384
383
|
s.add_development_dependency(%q<fakeweb>, ["~> 1.3.0"])
|
384
|
+
s.add_development_dependency(%q<debugger>, [">= 0"])
|
385
385
|
else
|
386
386
|
s.add_dependency(%q<nokogiri>, ["~> 1.5.5"])
|
387
387
|
s.add_dependency(%q<colorize>, ["~> 0.5.8"])
|
388
388
|
s.add_dependency(%q<rspec>, ["~> 2.11.0"])
|
389
389
|
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
390
390
|
s.add_dependency(%q<simplecov>, ["~> 0.6.4"])
|
391
|
-
s.add_dependency(%q<ruby-debug19>, ["~> 0.11.6"])
|
392
391
|
s.add_dependency(%q<fakeweb>, ["~> 1.3.0"])
|
392
|
+
s.add_dependency(%q<debugger>, [">= 0"])
|
393
393
|
end
|
394
394
|
else
|
395
395
|
s.add_dependency(%q<nokogiri>, ["~> 1.5.5"])
|
@@ -397,8 +397,8 @@ Gem::Specification.new do |s|
|
|
397
397
|
s.add_dependency(%q<rspec>, ["~> 2.11.0"])
|
398
398
|
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
399
399
|
s.add_dependency(%q<simplecov>, ["~> 0.6.4"])
|
400
|
-
s.add_dependency(%q<ruby-debug19>, ["~> 0.11.6"])
|
401
400
|
s.add_dependency(%q<fakeweb>, ["~> 1.3.0"])
|
401
|
+
s.add_dependency(%q<debugger>, [">= 0"])
|
402
402
|
end
|
403
403
|
end
|
404
404
|
|
data/spec/link-checker_spec.rb
CHANGED
@@ -1,20 +1,19 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'link_checker'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe LinkChecker do
|
5
5
|
|
6
6
|
before(:all) do
|
7
7
|
@site_path = 'spec/test-site/public/'
|
8
8
|
end
|
9
9
|
|
10
10
|
it "finds all of the HTML files in the target path." do
|
11
|
-
|
12
|
-
files = checker.find_html_files
|
11
|
+
files = LinkChecker.new(@site_path).find_html_files
|
13
12
|
files.size.should == 3
|
14
13
|
end
|
15
14
|
|
16
15
|
it "finds all of the external links in an HTML file." do
|
17
|
-
links =
|
16
|
+
links = LinkChecker.find_external_links(
|
18
17
|
'spec/test-site/public/blog/2012/10/02/a-list-of-links/index.html')
|
19
18
|
links.size.should == 4
|
20
19
|
end
|
@@ -33,12 +32,12 @@ describe Link::Checker do
|
|
33
32
|
end
|
34
33
|
|
35
34
|
it "declares good links to be good." do
|
36
|
-
|
35
|
+
LinkChecker.check_link(@good_uri).class.should be LinkChecker::Good
|
37
36
|
end
|
38
37
|
|
39
38
|
it "declares bad links to be bad." do
|
40
|
-
expect {
|
41
|
-
raise_error(
|
39
|
+
expect { LinkChecker.check_link(@bad_uri) }.to(
|
40
|
+
raise_error(LinkChecker::Error))
|
42
41
|
end
|
43
42
|
|
44
43
|
describe "follows redirects to the destination and" do
|
@@ -46,14 +45,16 @@ describe Link::Checker do
|
|
46
45
|
it "declares good redirect targets to be good." do
|
47
46
|
FakeWeb.register_uri(:get, @redirect_uri,
|
48
47
|
:location => @good_uri, :status => ["302", "Moved"])
|
49
|
-
|
48
|
+
result = LinkChecker.check_link(@redirect_uri)
|
49
|
+
result.class.should be LinkChecker::Redirect
|
50
|
+
result.final_destination.to_s.should == @good_uri
|
50
51
|
end
|
51
52
|
|
52
53
|
it "declares bad redirect targets to be bad." do
|
53
54
|
FakeWeb.register_uri(:get, @redirect_uri,
|
54
55
|
:location => @bad_uri, :status => ["302", "Moved"])
|
55
|
-
expect {
|
56
|
-
raise_error(
|
56
|
+
expect { LinkChecker.check_link(@redirect_uri) }.to(
|
57
|
+
raise_error(LinkChecker::Error))
|
57
58
|
end
|
58
59
|
|
59
60
|
end
|
@@ -62,31 +63,20 @@ describe Link::Checker do
|
|
62
63
|
|
63
64
|
describe "prints output" do
|
64
65
|
|
65
|
-
before(:all) do
|
66
|
-
@uris =
|
67
|
-
%w{
|
68
|
-
http://goodlink.com
|
69
|
-
http://brokenlink.com
|
70
|
-
http://twitter.com/share
|
71
|
-
http://octopress.org
|
72
|
-
}
|
73
|
-
end
|
74
|
-
|
75
66
|
it "prints green when the links are all good." do
|
76
|
-
|
67
|
+
LinkChecker.stub(:check_link) { true }
|
77
68
|
$stdout.should_receive(:puts).with(/Checked/i).exactly(3).times
|
78
|
-
|
69
|
+
LinkChecker.new(@site_path).check_links
|
79
70
|
end
|
80
71
|
|
81
72
|
it "prints green when the links are all bad." do
|
82
|
-
|
73
|
+
LinkChecker.stub(:check_link).and_raise LinkChecker::Error.new('blah')
|
83
74
|
$stdout.should_receive(:puts).with(/Problem/i).exactly(3).times
|
84
75
|
$stdout.should_receive(:puts).with(/Link/i).at_least(3).times
|
85
76
|
$stdout.should_receive(:puts).with(/Response/i).at_least(3).times
|
86
|
-
|
77
|
+
LinkChecker.new(@site_path).check_links
|
87
78
|
end
|
88
79
|
|
89
|
-
|
90
80
|
end
|
91
81
|
|
92
82
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: link-checker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: 1.5.5
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.5.5
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: colorize
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ~>
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: 0.5.8
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.5.8
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: rspec
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ~>
|
@@ -43,10 +53,15 @@ dependencies:
|
|
43
53
|
version: 2.11.0
|
44
54
|
type: :development
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.11.0
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: jeweler
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ~>
|
@@ -54,10 +69,15 @@ dependencies:
|
|
54
69
|
version: 1.8.4
|
55
70
|
type: :development
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.8.4
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: simplecov
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
83
|
- - ~>
|
@@ -65,29 +85,44 @@ dependencies:
|
|
65
85
|
version: 0.6.4
|
66
86
|
type: :development
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 0.6.4
|
69
94
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
71
|
-
requirement:
|
95
|
+
name: fakeweb
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
72
97
|
none: false
|
73
98
|
requirements:
|
74
99
|
- - ~>
|
75
100
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
101
|
+
version: 1.3.0
|
77
102
|
type: :development
|
78
103
|
prerelease: false
|
79
|
-
version_requirements:
|
80
|
-
- !ruby/object:Gem::Dependency
|
81
|
-
name: fakeweb
|
82
|
-
requirement: &70228592616280 !ruby/object:Gem::Requirement
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
83
105
|
none: false
|
84
106
|
requirements:
|
85
107
|
- - ~>
|
86
108
|
- !ruby/object:Gem::Version
|
87
109
|
version: 1.3.0
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: debugger
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
88
118
|
type: :development
|
89
119
|
prerelease: false
|
90
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
91
126
|
description: Check the links in a web site before deploying, using Nokogiri.
|
92
127
|
email:
|
93
128
|
executables:
|
@@ -459,7 +494,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
459
494
|
version: '0'
|
460
495
|
segments:
|
461
496
|
- 0
|
462
|
-
hash:
|
497
|
+
hash: 3227380414018538119
|
463
498
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
464
499
|
none: false
|
465
500
|
requirements:
|
@@ -468,7 +503,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
468
503
|
version: '0'
|
469
504
|
requirements: []
|
470
505
|
rubyforge_project:
|
471
|
-
rubygems_version: 1.8.
|
506
|
+
rubygems_version: 1.8.24
|
472
507
|
signing_key:
|
473
508
|
specification_version: 3
|
474
509
|
summary: Check the links in a web site before deploying.
|