sla 0.3.0 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 408ec43b2728bd5d2a1461b747b487506976e020894684d8270154a5e9b807a1
4
- data.tar.gz: 8620e841cde6cc02ba87e2c35a32d278c197f65363e85fad6fd4adec3adcbf1e
3
+ metadata.gz: b7ab0a2c8232984458067a9d9a501011c50c4e6e3c500631a516b2f495b02fa6
4
+ data.tar.gz: 3d1af9be056a2cabc8dbf39dc37d14795b549f4f4e19803be82663d761eb7e5e
5
5
  SHA512:
6
- metadata.gz: d7b55730a4502b09df9c59ca8a3f0b49aa2986a2b6b548f8f26e8a8e5650075497acaef75f020e93354eb2f33d0538c6176ad3d3d070e11b0600e8ca6eddab34
7
- data.tar.gz: 94eeaa6c32a22a8f894bf6c65b0b74084120a071897028d4888952ac7d7dd28d10dcfe289a5230bd053c06b2a307ee32ddcf96e50f8bfc900c94eaa03b60a4ca
6
+ metadata.gz: 10d4a3dd2bcffcba10b4866ab5200dd9ded805c73bc196666efbe827005ea10620180d61667d02e9aa28c809dba07e4ca6d6dd7f2f6fd8668d3c741d526c332f
7
+ data.tar.gz: 9998c057a56599449bb8077c1fdfba755d70a4877d83a6cbe9d25b243248d6b588d08bdc2c8cb9db87b6ecbf90852a8efde1eb31871e13ed7705d220bbc2484c
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
- Site Link Analyzer
2
- ==================================================
1
+ # Site Link Analyzer
3
2
 
4
3
  [![Gem Version](https://badge.fury.io/rb/sla.svg)](https://badge.fury.io/rb/sla)
5
- [![Build Status](https://travis-ci.com/DannyBen/sla.svg?branch=master)](https://travis-ci.com/DannyBen/sla)
4
+ [![Build Status](https://github.com/DannyBen/sla/workflows/Test/badge.svg)](https://github.com/DannyBen/sla/actions?query=workflow%3ATest)
6
5
  [![Maintainability](https://api.codeclimate.com/v1/badges/f78192aead8a74535a24/maintainability)](https://codeclimate.com/github/DannyBen/sla/maintainability)
7
6
 
8
7
  ---
@@ -11,45 +10,58 @@ SLA is a simple broken links checker, with built in caching.
11
10
 
12
11
  ![SLA Demo](demo/cast.svg "SLA Demo")
13
12
 
14
- Install
15
- --------------------------------------------------
13
+ ## Install
16
14
 
17
- ```
15
+ ### Install using Ruby
16
+
17
+ ```shell
18
18
  $ gem install sla
19
19
  ```
20
20
 
21
+ ### Install using Docker
22
+
23
+ ```shell
24
+ alias sla='docker run --rm -it --network host -v /tmp/sla_cache:/app/cache dannyben/sla'
25
+ ```
26
+
27
+ The `--network host` flag is only necessary if you intend to check links on `localhost`.
21
28
 
22
- Features
23
- --------------------------------------------------
29
+ ## Features
24
30
 
25
31
  - Easy to use command line interface.
26
32
  - Built in caching, to avoid overtaxing the server.
27
33
  - Show and save list of broken links to a log file.
28
34
  - Exits with non zero code on failure, for CI integration.
29
35
 
30
-
31
- Usage
32
- --------------------------------------------------
36
+ ## Usage
33
37
 
34
38
  ```
35
39
  $ sla --help
36
- SLA
40
+ Site Link Analyzer
37
41
 
38
42
  Usage:
39
- sla check DOMAIN [options]
40
- sla (-h|--help|--version)
43
+ sla URL [options]
44
+ sla --help | -h | --version
41
45
 
42
- Commands:
43
- check
44
- Start checking for broken links on a given domain.
45
-
46
46
  Options:
47
+ --verbose, -v
48
+ Show detailed output
49
+
50
+ --simple, -s
51
+ Show simple output of errors only
52
+
47
53
  --depth, -d DEPTH
48
- Set crawling depth [default: 5].
54
+ Set crawling depth [default: 5]
55
+
56
+ --external, -x
57
+ Also check external links
58
+
59
+ --ignore, -i URLS
60
+ Specify a list of space delimited patterns to skip
61
+ URLs that contain any of the strings in this list will be skipped
49
62
 
50
63
  --cache, -c LIFE
51
- Set cache life [default: 1d]. LIFE can be in any of the
52
- following formats:
64
+ Set cache life [default: 1d]. LIFE can be in any of the following formats:
53
65
  10 = 10 seconds
54
66
  20s = 20 seconds
55
67
  10m = 10 minutes
@@ -57,24 +69,38 @@ Options:
57
69
  10d = 10 days
58
70
 
59
71
  --cache-dir DIR
60
- Set the cache directory.
72
+ Set the cache directory
61
73
 
62
- --external, -x
63
- Also check external links.
74
+ -h --help
75
+ Show this help
64
76
 
65
- --log, -l LOGFILE
66
- Save errors to log file.
77
+ --version
78
+ Show version number
67
79
 
68
- --ignore, -i URLS
69
- Specify a list of space delimited URLs to skip.
70
- URLs that start with the strings in this list will be skipped.
80
+ Parameters:
81
+ URL
82
+ URL to scan
83
+
84
+ Environment Variables:
85
+ SLA_SLEEP
86
+ Set number of seconds to sleep between calls (for debugging purposes)
71
87
 
72
88
  Examples:
73
- sla check example.com
74
- sla check example.com -c10m -d10
75
- sla check example.com --cache-dir my_cache
76
- sla check example.com --depth 10 --log my_log.log
77
- sla check example.com --cache 30d
78
- sla check example.com --ignore "/admin /customer/login"
89
+ sla example.com
90
+ sla example.com -c10m -d10
91
+ sla example.com --cache-dir my_cache
92
+ sla example.com --depth 10
93
+ sla example.com --cache 30d --external
94
+ sla example.com --simple > out.log
95
+ sla example.com --ignore "/admin /customer/login"
79
96
 
80
97
  ```
98
+
99
+ ## Contributing / Support
100
+
101
+ If you experience any issue, have a question or a suggestion, or if you wish
102
+ to contribute, feel free to [open an issue][issues].
103
+
104
+ ---
105
+
106
+ [issues]: https://github.com/DannyBen/sla/issues
data/lib/sla/checker.rb CHANGED
@@ -8,23 +8,12 @@ module SLA
8
8
  @check_external = check_external
9
9
  end
10
10
 
11
- def deeply_checked
12
- @deeply_checked ||= {}
13
- end
14
-
15
- def checked
16
- @checked ||= {}
17
- end
18
-
19
11
  def check(page, &block)
20
- return if ignore? page
21
- return if page.depth >= max_depth
22
- return unless page.valid?
12
+ return if skip? page
23
13
 
24
14
  yield [:source, page] if block_given?
25
15
 
26
- pages = page.pages
27
- pages.reject! { |page| page.external? } if !check_external
16
+ pages = page_list page
28
17
 
29
18
  pages.each do |page|
30
19
  if checked.has_key? page.url or ignore? page
@@ -45,6 +34,18 @@ module SLA
45
34
 
46
35
  private
47
36
 
37
+ def page_list(page)
38
+ if check_external
39
+ page.pages
40
+ else
41
+ page.pages.reject { |page| page.external? }
42
+ end
43
+ end
44
+
45
+ def skip?(page)
46
+ ignore?(page) or page.depth >= max_depth or !page.valid?
47
+ end
48
+
48
49
  def ignore?(page)
49
50
  return false unless ignore
50
51
 
@@ -55,6 +56,14 @@ module SLA
55
56
  false
56
57
  end
57
58
 
59
+ def deeply_checked
60
+ @deeply_checked ||= {}
61
+ end
62
+
63
+ def checked
64
+ @checked ||= {}
65
+ end
66
+
58
67
  end
59
68
  end
60
69
 
@@ -6,12 +6,11 @@ module SLA
6
6
  attr_accessor :count, :failed
7
7
 
8
8
  def initialize
9
- @count = 0
10
- @failed = 0
9
+ @count, @failed = 0, 0
11
10
  end
12
11
 
13
12
  def success?
14
- failed == 0
13
+ count > 0 and failed == 0
15
14
  end
16
15
 
17
16
  def handle(action, page)
@@ -10,15 +10,21 @@ module SLA
10
10
  @count += 1
11
11
 
12
12
  return if page.valid?
13
-
14
13
  @failed += 1
15
14
 
15
+ show_status page
16
+ end
17
+
18
+ private
19
+
20
+ def show_status(page)
16
21
  if last_source
17
22
  say "!txtpur!SOURCE #{last_source}"
18
23
  @last_source = nil
19
24
  end
20
25
 
21
26
  say " !txtred!FAIL!txtrst! #{page.depth} #{page.url}"
27
+ say " !txtred!#{page.code}!txtrst! #{page.error}" unless page.code == 404
22
28
  end
23
29
 
24
30
  end
@@ -1,16 +1,25 @@
1
1
  module SLA
2
2
  module Formatters
3
3
  class TTY < Base
4
- attr_reader :last_source
4
+ attr_reader :last_source, :screen_width
5
5
 
6
6
  def handle(action, page)
7
- screen_width = terminal_width
8
-
7
+ @screen_width = terminal_width
9
8
  @last_source = page.url if action == :source
10
9
 
11
10
  return unless action == :check
12
11
  @count += 1
13
12
 
13
+ show_status page
14
+ end
15
+
16
+ def footer_prefix
17
+ terminal? ? "\033[2K\n" : "\n"
18
+ end
19
+
20
+ private
21
+
22
+ def show_status(page)
14
23
  if page.valid?
15
24
  status = "PASS"
16
25
  color = "!txtgrn!"
@@ -25,6 +34,7 @@ module SLA
25
34
  end
26
35
 
27
36
  resay " !txtred!FAIL!txtrst! #{page.depth} #{page.url}"
37
+ resay " !txtred!#{page.code}!txtrst! #{page.error}" unless page.code == 404
28
38
  end
29
39
 
30
40
  message = "[#{failed}/#{count} @ #{page.depth}] #{status}"
@@ -33,11 +43,6 @@ module SLA
33
43
  resay "[#{failed}/#{count} @ #{page.depth}] #{color}#{status}!txtrst! #{url} "
34
44
  end
35
45
 
36
- def footer_prefix
37
- terminal? ? "\033[2K\n" : "\n"
38
- end
39
-
40
-
41
46
  end
42
47
  end
43
- end
48
+ end
@@ -5,26 +5,37 @@ module SLA
5
5
  case action
6
6
  when :source
7
7
  say "\n!txtpur!SOURCE #{page.url}"
8
-
8
+
9
9
  when :check
10
- @count += 1
11
-
12
- if page.valid?
13
- status = "PASS"
14
- color = "!txtgrn!"
15
- else
16
- @failed += 1
17
- status = "FAIL"
18
- color = "!txtred!"
19
- end
20
-
21
- say " #{color}#{status}!txtrst! #{page.depth} #{page.url}"
10
+ show_check_status page
22
11
 
23
12
  when :skip
24
13
  say " !txtblu!SKIP!txtrst! #{page.depth} #{page.url}"
25
14
 
26
15
  end
27
16
  end
17
+
18
+ private
19
+
20
+ def show_check_status(page)
21
+ @count += 1
22
+
23
+ show_error = false
24
+
25
+ if page.valid?
26
+ status = "PASS"
27
+ color = "!txtgrn!"
28
+ else
29
+ @failed += 1
30
+ status = "FAIL"
31
+ color = "!txtred!"
32
+ show_error = page.code != 404
33
+ end
34
+
35
+ say " #{color}#{status}!txtrst! #{page.depth} #{page.url}"
36
+ say " !txtred!#{page.code}!txtrst! #{page.error}" if show_error
37
+ end
38
+
28
39
  end
29
40
  end
30
41
  end
data/lib/sla/page.rb CHANGED
@@ -1,83 +1,88 @@
1
- class Page
2
- attr_reader :uri, :parent, :depth
3
-
4
- def initialize(uri, parent: nil, depth: 0)
5
- if uri.is_a? String
6
- uri = "http://#{uri}" unless uri.start_with? 'http'
7
- uri = URI.parse uri
8
- uri.fragment = false
1
+ module SLA
2
+ class Page
3
+ attr_reader :uri, :parent, :depth
4
+
5
+ def initialize(uri, parent: nil, depth: 0)
6
+ if uri.is_a? String
7
+ uri = "http://#{uri}" unless uri.start_with? 'http'
8
+ uri = URI.parse uri
9
+ uri.fragment = false
10
+ end
11
+
12
+ @uri, @parent, @depth = uri, parent, depth
9
13
  end
10
14
 
11
- @uri, @parent, @depth = uri, parent, depth
12
- end
15
+ def error
16
+ response.error
17
+ end
13
18
 
14
- def error
15
- response.error
16
- end
19
+ def code
20
+ response.code || 'ERR'
21
+ end
17
22
 
18
- def external?
19
- byebug unless uri.respond_to? :host
20
- uri.host != parent.uri.host
21
- end
23
+ def external?
24
+ parent ? (uri.host != parent.uri.host) : false
25
+ end
22
26
 
23
- def inspect
24
- "#<Page url: #{url}, depth: #{depth}>"
25
- end
27
+ def inspect
28
+ "#<Page url: #{url}, depth: #{depth}>"
29
+ end
26
30
 
27
- def pages
28
- @pages ||= pages!
29
- end
31
+ def pages
32
+ @pages ||= pages!
33
+ end
30
34
 
31
- def url
32
- uri.to_s
33
- end
35
+ def url
36
+ uri.to_s
37
+ end
34
38
 
35
- def valid?
36
- !response.error
37
- end
39
+ def valid?
40
+ !response.error
41
+ end
38
42
 
39
- private
43
+ private
40
44
 
41
- def anchors
42
- @anchors ||= dom.css('a[href]')
43
- end
45
+ def anchors
46
+ @anchors ||= dom.css('a[href]')
47
+ end
44
48
 
45
- def content
46
- @content ||= response.content
47
- end
49
+ def content
50
+ @content ||= response.content
51
+ end
48
52
 
49
- def dom
50
- @dom ||= Nokogiri::HTML content
51
- end
53
+ def dom
54
+ @dom ||= Nokogiri::HTML content
55
+ end
52
56
 
53
- def normalize_url(new_url)
54
- new_url = URI.parse new_url
55
- new_url.fragment = false
57
+ def normalize_url(new_url)
58
+ new_url = URI.parse new_url
59
+ new_url.fragment = false
56
60
 
57
- result = new_url.absolute? ? new_url : URI.join(url, new_url)
61
+ result = new_url.absolute? ? new_url : URI.join(url, new_url)
58
62
 
59
- result.scheme =~ /^http/ ? result.to_s : nil
60
- end
63
+ result.scheme =~ /^http/ ? result.to_s : nil
64
+ end
61
65
 
62
- def pages!
63
- result = {}
64
- anchors.each do |a|
65
- url = normalize_url a['href']
66
- next unless url
67
- page = Page.new url, parent: self, depth: depth+1
68
- result[url] = page
66
+ def pages!
67
+ result = {}
68
+ anchors.each do |a|
69
+ url = normalize_url a['href']
70
+ next unless url
71
+ page = Page.new url, parent: self, depth: depth+1
72
+ result[url] = page
73
+ end
74
+ result.values
69
75
  end
70
- result.values
71
- end
72
76
 
73
- def response
74
- @response ||= response!
75
- end
77
+ def response
78
+ @response ||= response!
79
+ end
76
80
 
77
- def response!
78
- response = WebCache.get url
79
- @uri = response.base_uri
80
- response
81
- end
81
+ def response!
82
+ response = WebCache.get url
83
+ @uri = response.base_uri
84
+ response
85
+ end
82
86
 
83
- end
87
+ end
88
+ end
data/lib/sla/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module SLA
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sla
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-28 00:00:00.000000000 Z
11
+ date: 2021-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colsole
@@ -50,14 +50,14 @@ dependencies:
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '0.6'
53
+ version: '0.7'
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '0.6'
60
+ version: '0.7'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: nokogiri
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -110,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
110
  - !ruby/object:Gem::Version
111
111
  version: '0'
112
112
  requirements: []
113
- rubygems_version: 3.0.3
113
+ rubygems_version: 3.2.16
114
114
  signing_key:
115
115
  specification_version: 4
116
116
  summary: Command Line Site Link Analyzer