Make validateProtocol return Boolean

Ref https://github.com/sbt/sbt/issues/4905

To deprecate and unsupport HTTP, first log all the error messages out then throw at sbt level.
This commit is contained in:
Eugene Yokota 2020-06-05 18:59:08 -04:00
parent 1c462be007
commit 375613efbf
8 changed files with 35 additions and 27 deletions

View File

@ -246,7 +246,12 @@ lazy val lmCore = (project in file("core"))
), ),
exclude[ReversedMissingMethodProblem]( exclude[ReversedMissingMethodProblem](
"sbt.librarymanagement.MavenRepository.allowInsecureProtocol" "sbt.librarymanagement.MavenRepository.allowInsecureProtocol"
) ),
exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.ResolverFunctions.validateURLRepository"),
exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.ResolverFunctions.validateMavenRepo"),
exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.ResolverFunctions.validateArtifact"),
exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.*.validateProtocol"),
), ),
) )
.configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache)

View File

@ -14,7 +14,7 @@ final class Artifact private (
val extraAttributes: Map[String, String], val extraAttributes: Map[String, String],
val checksum: Option[sbt.librarymanagement.Checksum], val checksum: Option[sbt.librarymanagement.Checksum],
val allowInsecureProtocol: Boolean) extends sbt.librarymanagement.ArtifactExtra with Serializable { val allowInsecureProtocol: Boolean) extends sbt.librarymanagement.ArtifactExtra with Serializable {
private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateArtifact(this, logger) private[sbt] def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateArtifact(this, logger)
private def this(name: String) = this(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None, false) private def this(name: String) = this(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None, false)
private def this(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]) = this(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, false) private def this(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]) = this(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, false)

View File

@ -7,7 +7,7 @@ package sbt.librarymanagement
final class ChainedResolver private ( final class ChainedResolver private (
name: String, name: String,
val resolvers: Vector[sbt.librarymanagement.Resolver]) extends sbt.librarymanagement.Resolver(name) with Serializable { val resolvers: Vector[sbt.librarymanagement.Resolver]) extends sbt.librarymanagement.Resolver(name) with Serializable {
private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = resolvers.foreach(_.validateProtocol(logger)) private[sbt] override def validateProtocol(logger: sbt.util.Logger): Boolean = !resolvers.forall(!_.validateProtocol(logger))
override def equals(o: Any): Boolean = o match { override def equals(o: Any): Boolean = o match {

View File

@ -12,7 +12,7 @@ final class MavenRepo private (
val _allowInsecureProtocol: Boolean) extends sbt.librarymanagement.MavenRepository(name, root, localIfFile) with Serializable { val _allowInsecureProtocol: Boolean) extends sbt.librarymanagement.MavenRepository(name, root, localIfFile) with Serializable {
override def isCache: Boolean = false override def isCache: Boolean = false
override def allowInsecureProtocol: Boolean = _allowInsecureProtocol override def allowInsecureProtocol: Boolean = _allowInsecureProtocol
private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateMavenRepo(this, logger) private[sbt] override def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateMavenRepo(this, logger)
private def this(name: String, root: String) = this(name, root, true, false) private def this(name: String, root: String) = this(name, root, true, false)
private def this(name: String, root: String, localIfFile: Boolean) = this(name, root, localIfFile, false) private def this(name: String, root: String, localIfFile: Boolean) = this(name, root, localIfFile, false)

View File

@ -7,7 +7,7 @@ package sbt.librarymanagement
abstract class Resolver( abstract class Resolver(
val name: String) extends Serializable { val name: String) extends Serializable {
/** check for HTTP */ /** check for HTTP */
private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = () private[sbt] def validateProtocol(logger: sbt.util.Logger): Boolean = false

View File

@ -8,7 +8,7 @@ final class URLRepository private (
name: String, name: String,
patterns: sbt.librarymanagement.Patterns, patterns: sbt.librarymanagement.Patterns,
val allowInsecureProtocol: Boolean) extends sbt.librarymanagement.PatternsBasedRepository(name, patterns) with Serializable { val allowInsecureProtocol: Boolean) extends sbt.librarymanagement.PatternsBasedRepository(name, patterns) with Serializable {
private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateURLRepository(this, logger) private[sbt] override def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateURLRepository(this, logger)
private def this(name: String, patterns: sbt.librarymanagement.Patterns) = this(name, patterns, false) private def this(name: String, patterns: sbt.librarymanagement.Patterns) = this(name, patterns, false)
override def equals(o: Any): Boolean = o match { override def equals(o: Any): Boolean = o match {

View File

@ -147,7 +147,7 @@
{ "name": "allowInsecureProtocol", "type": "Boolean", "default": "false", "since": "1.3.0" } { "name": "allowInsecureProtocol", "type": "Boolean", "default": "false", "since": "1.3.0" }
], ],
"extra": [ "extra": [
"private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateArtifact(this, logger)" "private[sbt] def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateArtifact(this, logger)"
], ],
"parentsCompanion": "sbt.librarymanagement.ArtifactFunctions" "parentsCompanion": "sbt.librarymanagement.ArtifactFunctions"
}, },
@ -563,7 +563,7 @@
], ],
"extra": [ "extra": [
"/** check for HTTP */", "/** check for HTTP */",
"private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = ()" "private[sbt] def validateProtocol(logger: sbt.util.Logger): Boolean = false"
], ],
"types": [ "types": [
{ {
@ -575,7 +575,7 @@
{ "name": "resolvers", "type": "sbt.librarymanagement.Resolver*" } { "name": "resolvers", "type": "sbt.librarymanagement.Resolver*" }
], ],
"extra": [ "extra": [
"private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = resolvers.foreach(_.validateProtocol(logger))" "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Boolean = !resolvers.forall(!_.validateProtocol(logger))"
] ]
}, },
{ {
@ -603,7 +603,7 @@
"extra": [ "extra": [
"override def isCache: Boolean = false", "override def isCache: Boolean = false",
"override def allowInsecureProtocol: Boolean = _allowInsecureProtocol", "override def allowInsecureProtocol: Boolean = _allowInsecureProtocol",
"private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateMavenRepo(this, logger)" "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateMavenRepo(this, logger)"
], ],
"toString": "s\"$name: $root\"" "toString": "s\"$name: $root\""
}, },
@ -676,7 +676,7 @@
{ "name": "allowInsecureProtocol", "type": "boolean", "default": "false", "since": "1.3.0" } { "name": "allowInsecureProtocol", "type": "boolean", "default": "false", "since": "1.3.0" }
], ],
"extra": [ "extra": [
"private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateURLRepository(this, logger)" "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateURLRepository(this, logger)"
] ]
}, },
{ {

View File

@ -404,8 +404,9 @@ private[librarymanagement] abstract class ResolverFunctions {
Patterns().withIvyPatterns(pList).withArtifactPatterns(pList).withIsMavenCompatible(false) Patterns().withIvyPatterns(pList).withArtifactPatterns(pList).withIsMavenCompatible(false)
} }
// to display all error messages at once, just log here don't throw
private[sbt] def warnHttp(value: String, suggestion: String, logger: Logger): Unit = { private[sbt] def warnHttp(value: String, suggestion: String, logger: Logger): Unit = {
logger.warn(s"insecure HTTP request is deprecated '$value'; switch to HTTPS$suggestion") logger.error(s"insecure HTTP request is unsupported '$value'; switch to HTTPS$suggestion")
} }
private[sbt] def isInsecureUrl(str: String): Boolean = { private[sbt] def isInsecureUrl(str: String): Boolean = {
// don't try to parse str as URL because it could contain $variable from Ivy pattern // don't try to parse str as URL because it could contain $variable from Ivy pattern
@ -415,8 +416,8 @@ private[librarymanagement] abstract class ResolverFunctions {
|| str.startsWith("http://127.0.0.1/") || str.startsWith("http://127.0.0.1/")
|| str.startsWith("http://127.0.0.1:")) || str.startsWith("http://127.0.0.1:"))
} }
private[sbt] def validateURLRepository(repo: URLRepository, logger: Logger): Unit = { private[sbt] def validateURLRepository(repo: URLRepository, logger: Logger): Boolean = {
if (repo.allowInsecureProtocol) () if (repo.allowInsecureProtocol) false
else { else {
val patterns = repo.patterns val patterns = repo.patterns
val ivy = patterns.ivyPatterns.headOption match { val ivy = patterns.ivyPatterns.headOption match {
@ -430,34 +431,36 @@ private[librarymanagement] abstract class ResolverFunctions {
if (ivy || art) { if (ivy || art) {
warnHttp( warnHttp(
patterns.toString, patterns.toString,
s""" or opt-in as Resolver.url("${repo.name}", url(...)).withAllowInsecureProtocol(true)""", s""" or opt-in as Resolver.url("${repo.name}", url(...)).withAllowInsecureProtocol(true), or by using allowInsecureProtocol in repositories file""",
logger logger
) )
} true
} else false
} }
} }
private[sbt] def validateMavenRepo(repo: MavenRepo, logger: Logger): Unit = private[sbt] def validateMavenRepo(repo: MavenRepo, logger: Logger): Boolean =
if (repo.allowInsecureProtocol) () if (repo.allowInsecureProtocol) false
else if (isInsecureUrl(repo.root)) { else if (isInsecureUrl(repo.root)) {
warnHttp( warnHttp(
repo.root, repo.root,
s""" or opt-in as ("${repo.name}" at "${repo.root}").withAllowInsecureProtocol(true)""", s""" or opt-in as ("${repo.name}" at "${repo.root}").withAllowInsecureProtocol(true), or by using allowInsecureProtocol in repositories file""",
logger logger
) )
} true
} else false
private[sbt] def validateArtifact(art: Artifact, logger: Logger): Unit = private[sbt] def validateArtifact(art: Artifact, logger: Logger): Boolean =
if (art.allowInsecureProtocol) () if (art.allowInsecureProtocol) false
else { else
art.url foreach { url => art.url match {
if (isInsecureUrl(url.toString)) { case Some(url) if isInsecureUrl(url.toString) =>
warnHttp( warnHttp(
art.toString, art.toString,
" or opt-in using from(url(...), allowInsecureProtocol = true) on ModuleID or .withAllowInsecureProtocol(true) on Artifact", " or opt-in using from(url(...), allowInsecureProtocol = true) on ModuleID or .withAllowInsecureProtocol(true) on Artifact",
logger logger
) )
} true
case _ => false
} }
}
} }