diff --git a/cli/src/main/scala/coursier/cli/Helper.scala b/cli/src/main/scala/coursier/cli/Helper.scala index ae28c8b83..e5cec37a9 100644 --- a/cli/src/main/scala/coursier/cli/Helper.scala +++ b/cli/src/main/scala/coursier/cli/Helper.scala @@ -192,7 +192,7 @@ class Helper( filter = Some(dep => keepOptional || !dep.optional) ) - val fetchQuiet = coursier.fetch(repositories) + val fetchQuiet = coursier.fetchLocalFirst(repositories) val fetch0 = if (verbose0 == 0) fetchQuiet else { diff --git a/core/shared/src/main/scala/coursier/package.scala b/core/shared/src/main/scala/coursier/package.scala index f3c3a58f6..bb58b4391 100644 --- a/core/shared/src/main/scala/coursier/package.scala +++ b/core/shared/src/main/scala/coursier/package.scala @@ -1,3 +1,4 @@ +import scalaz.{ -\/, \/- } import scalaz.concurrent.Task /** @@ -109,4 +110,27 @@ package object coursier { ) } + def fetchLocalFirst( + repositories: Seq[core.Repository] + )(implicit + cachePolicy: CachePolicy + ): ResolutionProcess.Fetch[Task] = { + + modVers => + Task.gatherUnordered( + modVers + .map {case (module, version) => + def attempt(cachePolicy: CachePolicy) = + Repository.find(repositories, module, version)(cachePolicy) + .run + .map((module, version) -> _) + + attempt(CachePolicy.LocalOnly).flatMap { + case v @ (_, \/-(_)) => Task.now(v) + case (_, -\/(_)) => attempt(cachePolicy) + } + } + ) + } + } diff --git a/files/src/main/scala/coursier/Files.scala b/files/src/main/scala/coursier/Files.scala index e64e0e690..23c74fd85 100644 --- a/files/src/main/scala/coursier/Files.scala +++ b/files/src/main/scala/coursier/Files.scala @@ -38,7 +38,7 @@ case class Files( cacheDir + "/" + url.stripPrefix(base) } - if (artifact.extra.contains("local") || isLocal) + if (artifact.extra.contains("local")) artifact else artifact.copy(extra = artifact.extra + ("local" -> @@ -141,14 +141,19 @@ case class Files( val tasks = - for ((f, url) <- pairs if url != ("file:" + f) && url != ("file://" + f)) yield { - val file = new File(f) - cachePolicy[FileError \/ File]( - _.isLeft )( - locally(file) )( - _ => remote(file, url) - ).map(e => (file, url) -> e.map(_ => ())) - } + for ((f, url) <- pairs) yield + if (url != ("file:" + f) && url != ("file://" + f)) { + assert(!f.startsWith("file:/"), s"Wrong file detection: $f, $url") + val file = new File(f) + cachePolicy[FileError \/ File]( + _.isLeft)( + locally(file))( + _ => remote(file, url) + ).map(e => (file, url) -> e.map(_ => ())) + } else { + val file = new File(f) + Task.now(((file, url), \/-(()))) + } Nondeterminism[Task].gather(tasks) }