From e49fbef4e427c6a7b6a3960da2322cdbf3c7ff48 Mon Sep 17 00:00:00 2001 From: Alexandre Archambault Date: Sun, 30 Oct 2016 20:06:41 +0100 Subject: [PATCH] Minor fix in fallback dependencies in plugin --- .../FallbackDependenciesRepository.scala | 71 +++++++++++++++++-- .../sbt-coursier/from-no-head/build.sbt | 10 +++ .../from-no-head/project/plugins.sbt | 11 +++ .../from-no-head/src/main/scala/Main.scala | 11 +++ .../sbt-test/sbt-coursier/from-no-head/test | 3 + 5 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 plugin/src/sbt-test/sbt-coursier/from-no-head/build.sbt create mode 100644 plugin/src/sbt-test/sbt-coursier/from-no-head/project/plugins.sbt create mode 100644 plugin/src/sbt-test/sbt-coursier/from-no-head/src/main/scala/Main.scala create mode 100644 plugin/src/sbt-test/sbt-coursier/from-no-head/test diff --git a/plugin/src/main/scala-2.10/coursier/FallbackDependenciesRepository.scala b/plugin/src/main/scala-2.10/coursier/FallbackDependenciesRepository.scala index 08018ffe7..eb4b7a6a4 100644 --- a/plugin/src/main/scala-2.10/coursier/FallbackDependenciesRepository.scala +++ b/plugin/src/main/scala-2.10/coursier/FallbackDependenciesRepository.scala @@ -1,9 +1,68 @@ package coursier -import java.net.URL +import java.io.{ File, FileNotFoundException, IOException } +import java.net.{ HttpURLConnection, URL, URLConnection } import scalaz.{ EitherT, Monad } +object FallbackDependenciesRepository { + + def exists(url: URL): Boolean = { + + // Sometimes HEAD attempts fail even though standard GETs are fine. + // E.g. https://github.com/NetLogo/NetLogo/releases/download/5.3.1/NetLogo.jar + // returning 403s. Hence the second attempt below. + + val firstAttemptOpt = url.getProtocol match { + case "file" => + Some(new File(url.getPath).exists()) // FIXME Escaping / de-escaping needed here? + + case "http" | "https" => + + // HEAD request attempt, adapted from http://stackoverflow.com/questions/22541629/android-how-can-i-make-an-http-head-request/22545275#22545275 + + var conn: HttpURLConnection = null + try { + conn = url + .openConnection() + .asInstanceOf[HttpURLConnection] + conn.setRequestMethod("HEAD") + conn.getInputStream.close() + Some(true) + } catch { + case _: FileNotFoundException => + Some(false) + case _: IOException => // error other than not found + None + } finally { + if (conn != null) + conn.disconnect() + } + case _ => + None + } + + firstAttemptOpt.getOrElse { + var conn: URLConnection = null + try { + conn = url.openConnection() + // NOT setting request type to HEAD here. + conn.getInputStream.close() + true + } catch { + case _: IOException => + false + } finally { + conn match { + case conn0: HttpURLConnection => conn0.disconnect() + case _ => + } + } + } + } + +} + case class FallbackDependenciesRepository( fallbacks: Map[(Module, String), (URL, Boolean)] ) extends Repository { @@ -44,12 +103,10 @@ case class FallbackDependenciesRepository( else { val (dirUrlStr, fileName) = urlStr.splitAt(idx + 1) - fetch(Artifact(dirUrlStr, Map.empty, Map.empty, Attributes("", ""), changing = true, None)).flatMap { listing => - - val files = coursier.core.compatibility.listWebPageFiles(dirUrlStr, listing) - - if (files.contains(fileName)) { - + // Not sure F.point will make that run like Task.apply would have + // if F = Task + EitherT.right(F.point(FallbackDependenciesRepository.exists(url))).flatMap { exists => + if (exists) { val proj = Project( module, version, diff --git a/plugin/src/sbt-test/sbt-coursier/from-no-head/build.sbt b/plugin/src/sbt-test/sbt-coursier/from-no-head/build.sbt new file mode 100644 index 000000000..cdfa63ccf --- /dev/null +++ b/plugin/src/sbt-test/sbt-coursier/from-no-head/build.sbt @@ -0,0 +1,10 @@ +scalaVersion := "2.11.8" + +coursierCachePolicies := { + if (sys.props("os.name").startsWith("Windows")) + coursierCachePolicies.value + else + Seq(coursier.CachePolicy.ForceDownload) +} + +libraryDependencies += "ccl.northwestern.edu" % "netlogo" % "5.3.1" % "provided" from s"https://github.com/NetLogo/NetLogo/releases/download/5.3.1/NetLogo.jar" diff --git a/plugin/src/sbt-test/sbt-coursier/from-no-head/project/plugins.sbt b/plugin/src/sbt-test/sbt-coursier/from-no-head/project/plugins.sbt new file mode 100644 index 000000000..152225a9e --- /dev/null +++ b/plugin/src/sbt-test/sbt-coursier/from-no-head/project/plugins.sbt @@ -0,0 +1,11 @@ +{ + val pluginVersion = sys.props.getOrElse( + "plugin.version", + throw new RuntimeException( + """|The system property 'plugin.version' is not defined. + |Specify this property using the scriptedLaunchOpts -D.""".stripMargin + ) + ) + + addSbtPlugin("io.get-coursier" % "sbt-coursier" % pluginVersion) +} diff --git a/plugin/src/sbt-test/sbt-coursier/from-no-head/src/main/scala/Main.scala b/plugin/src/sbt-test/sbt-coursier/from-no-head/src/main/scala/Main.scala new file mode 100644 index 000000000..d75f66eaf --- /dev/null +++ b/plugin/src/sbt-test/sbt-coursier/from-no-head/src/main/scala/Main.scala @@ -0,0 +1,11 @@ +import java.io.File +import java.nio.file.Files + +object Main extends App { + // Not using directly the NetLogo 5.x lib, which seems to depend on Scala 2.9 + // Can't find a way to check that NetLogo.jar is in the classpath + // These don't work, even with fork := true: + // assert(Thread.currentThread.getContextClassLoader.getResource("org/nlogo/nvm/Task.class") != null) + // Thread.currentThread.getContextClassLoader.getResource("org/nlogo/nvm/Task.class") + Files.write(new File("output").toPath, "OK".getBytes("UTF-8")) +} diff --git a/plugin/src/sbt-test/sbt-coursier/from-no-head/test b/plugin/src/sbt-test/sbt-coursier/from-no-head/test new file mode 100644 index 000000000..2182f57b0 --- /dev/null +++ b/plugin/src/sbt-test/sbt-coursier/from-no-head/test @@ -0,0 +1,3 @@ +$ delete output +> run +$ exists output