Create command to check for updates

pull/986/head
Jasper van Merle 6 years ago
parent dae48e2c7c
commit d0300dd585

@ -132,6 +132,35 @@ module Docs
end
end
def get_latest_version
raise NotImplementedError
end
# Returns whether or not this scraper is outdated.
#
# The default implementation assumes the documentation uses a semver(-like) approach when it comes to versions.
# Patch updates are ignored because there are usually little to no documentation changes in bug-fix-only releases.
#
# Scrapers of documentations that do not use this versioning approach should override this method.
#
# Examples of the default implementation:
# 1 -> 2 = outdated
# 1.1 -> 1.2 = outdated
# 1.1.1 -> 1.1.2 = not outdated
def is_outdated(current_version, latest_version)
current_parts = current_version.split(/\./).map(&:to_i)
latest_parts = latest_version.split(/\./).map(&:to_i)
# Only check the first two parts, the third part is for patch updates
[0, 1].each do |i|
break if i >= current_parts.length or i >= latest_parts.length
return true if latest_parts[i] > current_parts[i]
return false if latest_parts[i] < current_parts[i]
end
false
end
private
def request_one(url)

@ -0,0 +1,78 @@
class UpdatesCLI < Thor
def self.to_s
'Updates'
end
def initialize(*args)
require 'docs'
require 'progress_bar'
super
end
desc 'check [doc]...', 'Check for outdated documentations'
def check(*names)
# Convert names to a list of Scraper instances
# Versions are omitted, if v10 is outdated than v8 is aswell
docs = names.map {|name| Docs.find(name.split(/@|~/)[0], false)}.uniq
# Check all documentations for updates when no arguments are given
docs = Docs.all if docs.empty?
progress_bar = ::ProgressBar.new docs.length
progress_bar.write
results = docs.map do |doc|
result = check_doc(doc)
progress_bar.increment!
result
end
outdated = results.select {|result| result.is_a?(Hash) && result[:is_outdated]}
return if outdated.empty?
logger.info("Outdated documentations (#{outdated.length}):")
outdated.each do |result|
logger.info("#{result[:name]}: #{result[:current_version]} -> #{result[:latest_version]}")
end
rescue Docs::DocNotFound => error
logger.error(error)
logger.info('Run "thor docs:list" to see the list of docs.')
end
private
def check_doc(doc)
# Scraper versions are always sorted from new to old
# Therefore, the first item's release value is the latest current scraper version
#
# For example, a scraper could scrape 3 versions: 10, 11 and 12
# doc.versions.first would be the scraper for version 12 if the scraper is written like all the other scrapers are
instance = doc.versions.first.new
current_version = instance.options[:release]
return nil if current_version.nil?
latest_version = instance.get_latest_version
return nil if latest_version.nil?
{
name: doc.name,
current_version: current_version,
latest_version: latest_version,
is_outdated: instance.is_outdated(current_version, latest_version)
}
rescue NotImplementedError
logger.warn("Can't check #{doc.name}, get_latest_version is not implemented")
rescue => error
logger.error("Error while checking #{doc.name}: #{error}")
end
def logger
@logger ||= Logger.new($stdout).tap do |logger|
logger.formatter = proc do |severity, datetime, progname, msg|
prefix = severity != "INFO" ? "[#{severity}] " : ""
"#{prefix}#{msg}\n"
end
end
end
end
Loading…
Cancel
Save