Skip to content

Commit d0300dd

Browse files
committed
Create command to check for updates
1 parent dae48e2 commit d0300dd

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

lib/docs/core/scraper.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,35 @@ def options
132132
end
133133
end
134134

135+
def get_latest_version
136+
raise NotImplementedError
137+
end
138+
139+
# Returns whether or not this scraper is outdated.
140+
#
141+
# The default implementation assumes the documentation uses a semver(-like) approach when it comes to versions.
142+
# Patch updates are ignored because there are usually little to no documentation changes in bug-fix-only releases.
143+
#
144+
# Scrapers of documentations that do not use this versioning approach should override this method.
145+
#
146+
# Examples of the default implementation:
147+
# 1 -> 2 = outdated
148+
# 1.1 -> 1.2 = outdated
149+
# 1.1.1 -> 1.1.2 = not outdated
150+
def is_outdated(current_version, latest_version)
151+
current_parts = current_version.split(/\./).map(&:to_i)
152+
latest_parts = latest_version.split(/\./).map(&:to_i)
153+
154+
# Only check the first two parts, the third part is for patch updates
155+
[0, 1].each do |i|
156+
break if i >= current_parts.length or i >= latest_parts.length
157+
return true if latest_parts[i] > current_parts[i]
158+
return false if latest_parts[i] < current_parts[i]
159+
end
160+
161+
false
162+
end
163+
135164
private
136165

137166
def request_one(url)

lib/tasks/updates.thor

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
class UpdatesCLI < Thor
2+
def self.to_s
3+
'Updates'
4+
end
5+
6+
def initialize(*args)
7+
require 'docs'
8+
require 'progress_bar'
9+
super
10+
end
11+
12+
desc 'check [doc]...', 'Check for outdated documentations'
13+
def check(*names)
14+
# Convert names to a list of Scraper instances
15+
# Versions are omitted, if v10 is outdated than v8 is aswell
16+
docs = names.map {|name| Docs.find(name.split(/@|~/)[0], false)}.uniq
17+
18+
# Check all documentations for updates when no arguments are given
19+
docs = Docs.all if docs.empty?
20+
21+
progress_bar = ::ProgressBar.new docs.length
22+
progress_bar.write
23+
24+
results = docs.map do |doc|
25+
result = check_doc(doc)
26+
progress_bar.increment!
27+
result
28+
end
29+
30+
outdated = results.select {|result| result.is_a?(Hash) && result[:is_outdated]}
31+
return if outdated.empty?
32+
33+
logger.info("Outdated documentations (#{outdated.length}):")
34+
outdated.each do |result|
35+
logger.info("#{result[:name]}: #{result[:current_version]} -> #{result[:latest_version]}")
36+
end
37+
rescue Docs::DocNotFound => error
38+
logger.error(error)
39+
logger.info('Run "thor docs:list" to see the list of docs.')
40+
end
41+
42+
private
43+
44+
def check_doc(doc)
45+
# Scraper versions are always sorted from new to old
46+
# Therefore, the first item's release value is the latest current scraper version
47+
#
48+
# For example, a scraper could scrape 3 versions: 10, 11 and 12
49+
# doc.versions.first would be the scraper for version 12 if the scraper is written like all the other scrapers are
50+
instance = doc.versions.first.new
51+
52+
current_version = instance.options[:release]
53+
return nil if current_version.nil?
54+
55+
latest_version = instance.get_latest_version
56+
return nil if latest_version.nil?
57+
58+
{
59+
name: doc.name,
60+
current_version: current_version,
61+
latest_version: latest_version,
62+
is_outdated: instance.is_outdated(current_version, latest_version)
63+
}
64+
rescue NotImplementedError
65+
logger.warn("Can't check #{doc.name}, get_latest_version is not implemented")
66+
rescue => error
67+
logger.error("Error while checking #{doc.name}: #{error}")
68+
end
69+
70+
def logger
71+
@logger ||= Logger.new($stdout).tap do |logger|
72+
logger.formatter = proc do |severity, datetime, progname, msg|
73+
prefix = severity != "INFO" ? "[#{severity}] " : ""
74+
"#{prefix}#{msg}\n"
75+
end
76+
end
77+
end
78+
end

0 commit comments

Comments
 (0)