A script that looks for obsolete URIs still in the code base.

This commit is contained in:
j2blake 2013-10-21 17:01:57 -04:00
parent a3dc250653
commit 701e946bd2
6 changed files with 379 additions and 0 deletions

View file

@ -0,0 +1,64 @@
require 'find'
class DirectoryWalker
# ------------------------------------------------------------------------------------
private
# ------------------------------------------------------------------------------------
def start_walking()
Find.find(@directory_root) do |path|
if FileTest.directory?(path)
if File.basename(path).start_with?(".")
Find.prune # Don't look any further into this directory.
else
next
end
elsif @known_exceptions.skip?(path)
Find.prune
else
scan_file(path)
end
end
end
def scan_file(path)
@report.register_file(path)
lines = File.readlines(path)
lines.each_index do |index|
line_number = index + 1
line = lines[index].strip
scan_line(path, line_number, line) unless @known_exceptions.skip?(path, line_number)
end
end
def scan_line(path, line_number, line)
@obsolete_uris.uris.each do |uri|
next if @known_exceptions.skip?(path, line_number, uri)
@report.add_event(Event.new(path, line_number, line, uri)) if line =~ Regexp.new(Regexp.quote(uri))
end
if @complete
@obsolete_uris.localnames.each do |localname|
term = ":#{localname}"
next if @known_exceptions.skip?(path, line_number, term)
@report.add_event(Event.new(path, line_number, line, term)) if line =~ Regexp.new(Regexp.quote(term))
end
end
end
# ------------------------------------------------------------------------------------
public
# ------------------------------------------------------------------------------------
def initialize(directory_root, obsolete_uris, known_exceptions, report, complete)
@directory_root = File.expand_path(directory_root)
@obsolete_uris = obsolete_uris
@known_exceptions = known_exceptions
@report = report
@complete = complete
end
def walk()
start_walking()
end
end

View file

@ -0,0 +1,21 @@
class Event
# ------------------------------------------------------------------------------------
private
# ------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------
public
# ------------------------------------------------------------------------------------
def initialize(path, line_number, line, string)
@path = path
@line_number = line_number
@line = line
@string = string
@is_localname = string[0] == ?:
end
def to_s()
"#{@path} \n #{@line_number} #{@line} \n #{@string} #{@is_localname ? "Localname" : "URI"}"
end
end

View file

@ -0,0 +1,77 @@
class KnownExceptionsError < StandardError; end
class ExtensionSkipper
def initialize(extension)
@extension = extension
end
def skip?(path, line, uri)
return File.extname(path) == @extension
end
end
class PathSkipper
def initialize(root_path, relative_path)
@root_path = root_path
@absolute_path = File.expand_path(relative_path, @root_path)
end
def skip?(path, line, uri)
return @absolute_path == File.expand_path(path, @root_path)
end
end
class LineSkipper
def initialize(root_path, relative_path, line_number)
@inner = PathSkipper.new(root_path, relative_path)
@line_number = line_number
end
def skip?(path, line, uri)
return @inner.skip?(path, line, uri) && line == @line_number
end
end
class KnownExceptions
# ------------------------------------------------------------------------------------
private
# ------------------------------------------------------------------------------------
def parse_file(file)
skippers = []
File.readlines(file).each do |line|
# ignore blank lines, and lines starting with '#' or '!'.
line.strip!
next if line.length == 0 || line[0..0] == '#' || line[0] == ?!
if line =~ /^\.[^\/]*$/
skippers << ExtensionSkipper.new(line)
elsif line =~ /^(\S+)\s*$/
skippers << PathSkipper.new(@root_path, $1)
elsif line =~ /^(\S+)\s*(\d+)\s*$/
skippers << LineSkipper.new(@root_path, $1, $2.to_i)
else
raise "BOGUS line in known_exceptions file: '#{line}'"
end
end
skippers
end
# ------------------------------------------------------------------------------------
public
# ------------------------------------------------------------------------------------
def initialize(root_path, file)
@root_path = File.expand_path(root_path)
@skippers = parse_file(file)
end
def skip?(file, line_number = -1, string = "@!#IMPOSSIBLE#!@")
@skippers.each() do |skipper|
if skipper.skip?(file, line_number, string)
return true
end
end
false
end
end

View file

@ -0,0 +1,120 @@
=begin
--------------------------------------------------------------------------------
A utility that scans the code base for the presence of URIs that were made
obsolete by the ISF transition.
Accept a file of obsolete URIs.
Blank lines or lines beginning with '#' are comments.
Each non-comment line contains an obsolete URI.
Accept a file of known exceptions.
Blank lines or lines beginning with '#' are comments.
Each non-comment line is in one of these forms:
.xxx - denotes an extension that is exempt from scanning
[filepath] - denotes a path, relative to the codebase root, of a
file that should not be scanned.
[filepath] [line number] - denotes a particular line in a file for
which no error should be reported.
[filepath] [line number] [uri] - denotes a particular line in a file
on which the given uri will not be reported.
The command line will look like this:
ruby obsoleteUriChecker.rb <directory_root> <obsolete_uri_file> <known_exceptions_file> [complete]
Where:
directory_root - the path to the top if the directory tree we are scanning
obsolete_uri_file - the path to the file that lists the obsolete URIs
known_exceptions_file - the path to the file that lists the events that we should ignore
complete - optional parameter; if present, check for :localname as well as for the full URL.
E.g.:
ruby obsoleteUriChecker.rb ../../.. ../../../productMods/WEB-INF/ontologies/update/diff.tab.txt known_exceptions.txt complete
--------------------------------------------------------------------------------
=end
$: << File.dirname(File.expand_path(__FILE__))
require 'known_exceptions'
require 'obsolete_uris'
require 'report'
require 'event'
require 'directory_walker'
class UsageError < StandardError; end
class ObsoleteUriChecker
# ------------------------------------------------------------------------------------
private
# ------------------------------------------------------------------------------------
#
# Parse the arguments and complain if they don't make sense.
#
def parse_arguments(args)
raise UsageError, "usage is: obsoleteUriChecker.rb <directory_root> <obsolete_uri_file> <known_exceptions_file> [complete]" unless (3..4).include?(args.length)
if args[3]
raise UsageError, "If provided, the 4th argument must be 'complete'" unless args[3].downcase == 'complete'
complete = true
else
complete = false
end
directory_root = args[0]
raise UsageError, "Directory '#{directory_root}' does not exist." unless File.exist?(directory_root)
raise UsageError, "Directory '#{directory_root}' is not a directory." unless File.directory?(directory_root)
obsolete_uri_file = args[1]
raise UsageError, "File '#{obsolete_uri_file}' does not exist." unless File.exist?(obsolete_uri_file)
obsolete_uris = ObsoleteUris.new(obsolete_uri_file)
known_exceptions_file = args[2]
raise UsageError, "File '#{known_exceptions_file}' does not exist." unless File.exist?(known_exceptions_file)
known_exceptions = KnownExceptions.new(directory_root, known_exceptions_file)
return directory_root, obsolete_uris, known_exceptions, complete
end
# ------------------------------------------------------------------------------------
public
# ------------------------------------------------------------------------------------
def initialize(args)
@report = Report.new(args)
@directory_root, @obsolete_uris, @known_exceptions, @complete = parse_arguments(args)
rescue UsageError => e
puts "\n----------------\nUsage error\n----------------\n\n#{e}\n\n----------------\n\n"
exit
rescue ObsoleteUrisError => e
puts "\n----------------\nObsolete Uris file is invalid\n----------------\n\n#{e}\n\n----------------\n\n"
exit
rescue KnownExceptionsError => e
puts "\n----------------\Known Exceptions file is invalid\n----------------\n\n#{e}\n\n----------------\n\n"
exit
end
def scan()
walker = DirectoryWalker.new(@directory_root, @obsolete_uris, @known_exceptions, @report, @complete)
walker.walk
end
def report()
@report.report()
end
end
#
#
# ------------------------------------------------------------------------------------
# Standalone calling.
#
# Do this if this program was called from the command line. That is, if the command
# expands to the path of this file.
# ------------------------------------------------------------------------------------
#
if File.expand_path($0) == File.expand_path(__FILE__)
checker = ObsoleteUriChecker.new(ARGV)
checker.scan()
checker.report()
end

View file

@ -0,0 +1,42 @@
class ObsoleteUrisError < StandardError; end
class ObsoleteUris
# ------------------------------------------------------------------------------------
private
# ------------------------------------------------------------------------------------
def get_localname(uri)
delimiter = uri.rindex(/[\/#]/)
return uri[delimiter+1..-1] if delimiter
raise "BOGUS URI in obsolete_uris file -- no localname: '#{uri}'"
end
# ------------------------------------------------------------------------------------
public
# ------------------------------------------------------------------------------------
def initialize(file)
@uris = []
@localnames = []
File.read(file).split(/[\r\n]+/).each do |line|
# ignore blank lines, and lines starting with '#' or '!'.
line.strip!
next if line.length == 0 || line[0..0] == '#' || line[0] == ?!
if line =~ /^(\S+)/
@uris << $1
@localnames << get_localname($1)
else
raise "BOGUS line in obsolete_uris file: '#{line}'"
end
end
end
def uris()
@uris
end
def localnames()
@localnames
end
end

View file

@ -0,0 +1,55 @@
class Report
# ------------------------------------------------------------------------------------
private
# ------------------------------------------------------------------------------------
def state_arguments()
puts
puts "-----------------------------------------------------------------"
puts " directory to scan = #{@args[0]}"
puts " obsolete_uris_file = #{@args[1]}"
puts " known exceptions file = #{@args[2]}"
puts " complete = #{!@args[3].nil?}"
puts "-----------------------------------------------------------------"
puts
end
def file_summary()
puts " scanned #{@file_count} files"
@extensions_count.sort.each do |pair|
puts " #{pair[0]} #{pair[1]}"
end
end
def list_events()
@events.each do |event|
puts "Event: #{event}"
end
end
# ------------------------------------------------------------------------------------
public
# ------------------------------------------------------------------------------------
def initialize(args)
@args = args;
@file_count = 0
@extensions_count = Hash.new(0)
@events = []
end
def register_file(path)
@file_count += 1
@extensions_count[File.extname(path)] += 1
end
def add_event(event)
@events << event
end
def report()
state_arguments()
file_summary()
list_events()
end
end