From 7b4b63c1340fbc94999ddba9fa886eeb6f762e4e Mon Sep 17 00:00:00 2001 From: Jamie Magee Date: Tue, 26 Sep 2023 16:34:43 -0700 Subject: [PATCH] Add `sig`s for `errors` --- common/lib/dependabot/errors.rb | 96 ++++++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 13 deletions(-) diff --git a/common/lib/dependabot/errors.rb b/common/lib/dependabot/errors.rb index fbdba3d706..ecab63266f 100644 --- a/common/lib/dependabot/errors.rb +++ b/common/lib/dependabot/errors.rb @@ -1,20 +1,25 @@ -# typed: true +# typed: strong # frozen_string_literal: true +require "sorbet-runtime" require "dependabot/utils" module Dependabot class DependabotError < StandardError + extend T::Sig + BASIC_AUTH_REGEX = %r{://(?[^:]*:[^@%\s]+(@|%40))} # Remove any path segment from fury.io sources FURY_IO_PATH_REGEX = %r{fury\.io/(?.+)} + sig { params(message: T.nilable(String)).void } def initialize(message = nil) super(sanitize_message(message)) end private + sig { params(message: T.nilable(String)).returns(T.nilable(String)) } def sanitize_message(message) return message unless message.is_a?(String) @@ -26,18 +31,25 @@ def sanitize_message(message) filter_sensitive_data(message) end + sig { params(message: String).returns(String) } def filter_sensitive_data(message) replace_capture_groups(message, BASIC_AUTH_REGEX, "") end + sig { params(source: String).returns(String) } def sanitize_source(source) source = filter_sensitive_data(source) replace_capture_groups(source, FURY_IO_PATH_REGEX, "") end + sig do + params( + string: String, + regex: Regexp, + replacement: String + ).returns(String) + end def replace_capture_groups(string, regex, replacement) - return string unless string.is_a?(String) - string.scan(regex).flatten.compact.reduce(string) do |original_msg, match| original_msg.gsub(match, replacement) end @@ -55,8 +67,12 @@ class NotImplemented < DependabotError; end ##################### class BranchNotFound < DependabotError + extend T::Sig + + sig { returns(String) } attr_reader :branch_name + sig { params(branch_name: String, msg: T.nilable(String)).void } def initialize(branch_name, msg = nil) @branch_name = branch_name super(msg) @@ -64,8 +80,12 @@ def initialize(branch_name, msg = nil) end class RepoNotFound < DependabotError + extend T::Sig + + sig { returns(Dependabot::Source) } attr_reader :source + sig { params(source: Dependabot::Source, msg: T.nilable(String)).void } def initialize(source, msg = nil) @source = source super(msg) @@ -77,38 +97,50 @@ def initialize(source, msg = nil) ##################### class DependencyFileNotFound < DependabotError + extend T::Sig + + sig { returns(String) } attr_reader :file_path + sig { params(file_path: String, msg: T.nilable(String)).void } def initialize(file_path, msg = nil) @file_path = file_path super(msg || "#{file_path} not found") end + sig { returns(String) } def file_name - file_path.split("/").last + T.must(file_path.split("/").last) end + sig { returns(String) } def directory # Directory should always start with a `/` - file_path.split("/")[0..-2].join("/").sub(%r{^/*}, "/") + T.must(file_path.split("/")[0..-2]).join("/").sub(%r{^/*}, "/") end end class DependencyFileNotParseable < DependabotError + extend T::Sig + + sig { returns(String) } attr_reader :file_path + sig { params(file_path: String, msg: T.nilable(String)).void } def initialize(file_path, msg = nil) @file_path = file_path super(msg || "#{file_path} not parseable") end + sig { returns(String) } def file_name - file_path.split("/").last + T.must(file_path.split("/").last) end + sig { returns(String) } def directory # Directory should always start with a `/` - file_path.split("/")[0..-2].join("/").sub(%r{^/*}, "/") + T.must(file_path.split("/")[0..-2]).join("/").sub(%r{^/*}, "/") end end @@ -121,10 +153,14 @@ class DependencyFileNotResolvable < DependabotError; end ####################### class PrivateSourceAuthenticationFailure < DependabotError + extend T::Sig + + sig { returns(String) } attr_reader :source + sig { params(source: String).void } def initialize(source) - @source = sanitize_source(source) + @source = T.let(sanitize_source(source), String) msg = "The following source could not be reached as it requires " \ "authentication (and any provided details were invalid or lacked " \ "the required permissions): #{@source}" @@ -133,26 +169,38 @@ def initialize(source) end class PrivateSourceTimedOut < DependabotError + extend T::Sig + + sig { returns(String) } attr_reader :source + sig { params(source: String).void } def initialize(source) - @source = sanitize_source(source) + @source = T.let(sanitize_source(source), String) super("The following source timed out: #{@source}") end end class PrivateSourceCertificateFailure < DependabotError + extend T::Sig + + sig { returns(String) } attr_reader :source + sig { params(source: String).void } def initialize(source) - @source = sanitize_source(source) + @source = T.let(sanitize_source(source), String) super("Could not verify the SSL certificate for #{@source}") end end class MissingEnvironmentVariable < DependabotError + extend T::Sig + + sig { returns(String) } attr_reader :environment_variable + sig { params(environment_variable: String).void } def initialize(environment_variable) @environment_variable = environment_variable super("Missing environment variable #{@environment_variable}") @@ -168,11 +216,15 @@ class InconsistentRegistryResponse < DependabotError; end ########################### class GitDependenciesNotReachable < DependabotError + extend T::Sig + + sig { returns(T::Array[String]) } attr_reader :dependency_urls + sig { params(dependency_urls: T::Array[String]).void } def initialize(*dependency_urls) @dependency_urls = - dependency_urls.flatten.map { |uri| filter_sensitive_data(uri) } + T.let(dependency_urls.flatten.map { |uri| filter_sensitive_data(uri) }, T::Array[String]) msg = "The following git URLs could not be retrieved: " \ "#{@dependency_urls.join(', ')}" @@ -181,8 +233,12 @@ def initialize(*dependency_urls) end class GitDependencyReferenceNotFound < DependabotError + extend T::Sig + + sig { returns(String) } attr_reader :dependency + sig { params(dependency: String).void } def initialize(dependency) @dependency = dependency @@ -193,10 +249,14 @@ def initialize(dependency) end class PathDependenciesNotReachable < DependabotError + extend T::Sig + + sig { returns(T::Array[String]) } attr_reader :dependencies + sig { params(dependencies: T::Array[T.untyped]).void } def initialize(*dependencies) - @dependencies = dependencies.flatten + @dependencies = T.let(dependencies.flatten, T::Array[String]) msg = "The following path based dependencies could not be retrieved: " \ "#{@dependencies.join(', ')}" super(msg) @@ -204,8 +264,18 @@ def initialize(*dependencies) end class GoModulePathMismatch < DependabotError - attr_reader :go_mod, :declared_path, :discovered_path + extend T::Sig + + sig { returns(String) } + attr_reader :go_mod + + sig { returns(String) } + attr_reader :declared_path + + sig { returns(String) } + attr_reader :discovered_path + sig { params(go_mod: String, declared_path: String, discovered_path: String).void } def initialize(go_mod, declared_path, discovered_path) @go_mod = go_mod @declared_path = declared_path