mirror of https://github.com/sbt/sbt.git
Offline option in CLI tool, minor refactoring in MavenRepository
This commit is contained in:
parent
7c4cf0ff72
commit
ee1a6a68f6
|
|
@ -4,15 +4,18 @@ package cli
|
|||
import java.io.File
|
||||
|
||||
import caseapp._
|
||||
import coursier.core.{Fetch, Parse, Repository}, Repository.CachePolicy
|
||||
import coursier.core.{MavenRepository, Parse, Repository}, Repository.CachePolicy
|
||||
|
||||
import scalaz.concurrent.Task
|
||||
|
||||
case class Coursier(scope: List[String],
|
||||
keepOptional: Boolean,
|
||||
fetch: Boolean,
|
||||
@ExtraName("v") verbose: List[Unit],
|
||||
@ExtraName("N") maxIterations: Int = 100) extends App {
|
||||
case class Coursier(
|
||||
scope: List[String],
|
||||
keepOptional: Boolean,
|
||||
fetch: Boolean,
|
||||
@ExtraName("c") offline: Boolean,
|
||||
@ExtraName("v") verbose: List[Unit],
|
||||
@ExtraName("N") maxIterations: Int = 100
|
||||
) extends App {
|
||||
|
||||
val verbose0 = verbose.length
|
||||
|
||||
|
|
@ -26,8 +29,8 @@ case class Coursier(scope: List[String],
|
|||
|
||||
def fileRepr(f: File) = f.toString
|
||||
|
||||
val logger: Fetch.Logger with FilesLogger =
|
||||
new Fetch.Logger with FilesLogger {
|
||||
val logger: MavenRepository.Logger with FilesLogger =
|
||||
new MavenRepository.Logger with FilesLogger {
|
||||
def println(s: String) = Console.err.println(s)
|
||||
|
||||
def downloading(url: String) =
|
||||
|
|
@ -55,17 +58,13 @@ case class Coursier(scope: List[String],
|
|||
}
|
||||
|
||||
val cachedMavenCentral = Repository.mavenCentral.copy(
|
||||
fetch = Repository.mavenCentral.fetch.copy(
|
||||
cache = Some(centralCacheDir),
|
||||
logger = if (verbose0 <= 1) None else Some(logger)
|
||||
)
|
||||
cache = Some(centralCacheDir),
|
||||
logger = if (verbose0 <= 1) None else Some(logger)
|
||||
)
|
||||
val repositories = Seq[Repository](
|
||||
cachedMavenCentral,
|
||||
Repository.ivy2Local.copy(
|
||||
fetch = Repository.ivy2Local.fetch.copy(
|
||||
logger = if (verbose0 <= 1) None else Some(logger)
|
||||
)
|
||||
logger = if (verbose0 <= 1) None else Some(logger)
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -149,13 +148,17 @@ case class Coursier(scope: List[String],
|
|||
if (fetch) {
|
||||
println()
|
||||
|
||||
val cachePolicy: CachePolicy = CachePolicy.Default
|
||||
val cachePolicy: CachePolicy =
|
||||
if (offline)
|
||||
CachePolicy.LocalOnly
|
||||
else
|
||||
CachePolicy.Default
|
||||
|
||||
val artifacts = res.artifacts
|
||||
|
||||
val files = new Files(
|
||||
Seq(
|
||||
cachedMavenCentral.fetch.root -> centralFilesCacheDir
|
||||
cachedMavenCentral.root -> centralFilesCacheDir
|
||||
),
|
||||
() => ???,
|
||||
if (verbose0 <= 0) None else Some(logger)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import js.Dynamic.{global => g}
|
|||
|
||||
import scala.scalajs.js.timers._
|
||||
|
||||
object Fetch {
|
||||
object MavenRepository {
|
||||
|
||||
def encodeURIComponent(s: String): String =
|
||||
g.encodeURIComponent(s).asInstanceOf[String]
|
||||
|
|
@ -84,18 +84,24 @@ object Fetch {
|
|||
|
||||
}
|
||||
|
||||
case class Fetch(root: String,
|
||||
logger: Option[Fetch.Logger] = None) {
|
||||
case class MavenRepository(
|
||||
root: String,
|
||||
ivyLike: Boolean = false,
|
||||
logger: Option[MavenRepository.Logger] = None
|
||||
) extends BaseMavenRepository(root, ivyLike) {
|
||||
|
||||
def apply(artifact: Artifact,
|
||||
cachePolicy: Repository.CachePolicy): EitherT[Task, String, String] = {
|
||||
|
||||
def fetch(
|
||||
artifact: Artifact,
|
||||
cachePolicy: Repository.CachePolicy
|
||||
): EitherT[Task, String, String] = {
|
||||
|
||||
val url0 = root + artifact.url
|
||||
|
||||
EitherT(
|
||||
Task { implicit ec =>
|
||||
Future(logger.foreach(_.fetching(url0)))
|
||||
.flatMap(_ => Fetch.get(url0))
|
||||
.flatMap(_ => MavenRepository.get(url0))
|
||||
.map{ s => logger.foreach(_.fetched(url0)); \/-(s) }
|
||||
.recover{case e: Exception =>
|
||||
logger.foreach(_.other(url0, e.getMessage))
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package coursier
|
||||
package test
|
||||
|
||||
import coursier.core.{Fetch, Repository}
|
||||
import coursier.core.{Repository, MavenRepository}
|
||||
import coursier.test.compatibility._
|
||||
|
||||
import utest._
|
||||
|
|
@ -18,7 +18,7 @@ object JsTests extends TestSuite {
|
|||
}
|
||||
|
||||
'get{
|
||||
Fetch.get("http://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.1.3/logback-classic-1.1.3.pom")
|
||||
MavenRepository.get("http://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.1.3/logback-classic-1.1.3.pom")
|
||||
.map(core.compatibility.xmlParse)
|
||||
.map{ xml =>
|
||||
assert(xml.right.toOption.exists(_.label == "project"))
|
||||
|
|
|
|||
|
|
@ -8,14 +8,19 @@ import scala.io.Codec
|
|||
import scalaz._, Scalaz._
|
||||
import scalaz.concurrent.Task
|
||||
|
||||
case class Fetch(root: String,
|
||||
cache: Option[File] = None,
|
||||
logger: Option[Fetch.Logger] = None) {
|
||||
case class MavenRepository(
|
||||
root: String,
|
||||
cache: Option[File] = None,
|
||||
ivyLike: Boolean = false,
|
||||
logger: Option[MavenRepository.Logger] = None
|
||||
) extends BaseMavenRepository(root, ivyLike) {
|
||||
|
||||
val isLocal = root.startsWith("file:///")
|
||||
|
||||
def apply(artifact: Artifact,
|
||||
cachePolicy: Repository.CachePolicy): EitherT[Task, String, String] = {
|
||||
def fetch(
|
||||
artifact: Artifact,
|
||||
cachePolicy: Repository.CachePolicy
|
||||
): EitherT[Task, String, String] = {
|
||||
|
||||
def locally(eitherFile: String \/ File) = {
|
||||
Task {
|
||||
|
|
@ -44,7 +49,7 @@ case class Fetch(root: String,
|
|||
val url = new URL(urlStr)
|
||||
|
||||
def log = Task(logger.foreach(_.downloading(urlStr)))
|
||||
def get = Fetch.readFully(url.openStream())
|
||||
def get = MavenRepository.readFully(url.openStream())
|
||||
|
||||
log.flatMap(_ => get)
|
||||
}
|
||||
|
|
@ -70,7 +75,7 @@ case class Fetch(root: String,
|
|||
|
||||
}
|
||||
|
||||
object Fetch {
|
||||
object MavenRepository {
|
||||
|
||||
trait Logger {
|
||||
def downloading(url: String): Unit
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package coursier.test
|
||||
|
||||
import coursier.core.Fetch
|
||||
import coursier.core.MavenRepository
|
||||
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
import scalaz.concurrent.Task
|
||||
|
|
@ -14,10 +14,12 @@ package object compatibility {
|
|||
}
|
||||
|
||||
def textResource(path: String)(implicit ec: ExecutionContext): Future[String] = Future {
|
||||
def is = getClass.getClassLoader
|
||||
.getResource(path).openStream()
|
||||
def is = getClass
|
||||
.getClassLoader
|
||||
.getResource(path)
|
||||
.openStream()
|
||||
|
||||
new String(Fetch.readFullySync(is), "UTF-8")
|
||||
new String(MavenRepository.readFullySync(is), "UTF-8")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package coursier.core
|
||||
|
||||
import coursier.core.Resolution.ModuleVersion
|
||||
import coursier.core.Repository.CachePolicy
|
||||
|
||||
import scalaz.{-\/, \/-, \/, EitherT}
|
||||
import scalaz.concurrent.Task
|
||||
|
|
@ -8,19 +8,21 @@ import scalaz.concurrent.Task
|
|||
import coursier.core.compatibility.encodeURIComponent
|
||||
|
||||
trait Repository {
|
||||
def find(module: Module,
|
||||
version: String,
|
||||
cachePolicy: Repository.CachePolicy = Repository.CachePolicy.Default): EitherT[Task, String, (Artifact.Source, Project)]
|
||||
def find(
|
||||
module: Module,
|
||||
version: String,
|
||||
cachePolicy: Repository.CachePolicy = Repository.CachePolicy.Default
|
||||
): EitherT[Task, String, (Artifact.Source, Project)]
|
||||
}
|
||||
|
||||
object Repository {
|
||||
|
||||
val mavenCentral = MavenRepository(Fetch("https://repo1.maven.org/maven2/"))
|
||||
val mavenCentral = MavenRepository("https://repo1.maven.org/maven2/")
|
||||
|
||||
val sonatypeReleases = MavenRepository(Fetch("https://oss.sonatype.org/content/repositories/releases/"))
|
||||
val sonatypeSnapshots = MavenRepository(Fetch("https://oss.sonatype.org/content/repositories/snapshots/"))
|
||||
val sonatypeReleases = MavenRepository("https://oss.sonatype.org/content/repositories/releases/")
|
||||
val sonatypeSnapshots = MavenRepository("https://oss.sonatype.org/content/repositories/snapshots/")
|
||||
|
||||
lazy val ivy2Local = MavenRepository(Fetch("file://" + sys.props("user.home") + "/.ivy2/local/"), ivyLike = true)
|
||||
lazy val ivy2Local = MavenRepository("file://" + sys.props("user.home") + "/.ivy2/local/", ivyLike = true)
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -34,9 +36,11 @@ object Repository {
|
|||
* version (e.g. version interval). Which version get chosen depends on
|
||||
* the repository implementation.
|
||||
*/
|
||||
def find(repositories: Seq[Repository],
|
||||
module: Module,
|
||||
version: String): EitherT[Task, Seq[String], (Artifact.Source, Project)] = {
|
||||
def find(
|
||||
repositories: Seq[Repository],
|
||||
module: Module,
|
||||
version: String
|
||||
): EitherT[Task, Seq[String], (Artifact.Source, Project)] = {
|
||||
|
||||
val lookups = repositories.map(repo => repo -> repo.find(module, version).run)
|
||||
val task = lookups.foldLeft(Task.now(-\/(Nil)): Task[Seq[String] \/ (Artifact.Source, Project)]) {
|
||||
|
|
@ -131,7 +135,7 @@ object Repository {
|
|||
}
|
||||
}
|
||||
|
||||
object MavenRepository {
|
||||
object BaseMavenRepository {
|
||||
|
||||
def ivyLikePath(org: String,
|
||||
name: String,
|
||||
|
|
@ -154,7 +158,7 @@ object MavenRepository {
|
|||
project: Project): Seq[Artifact] = {
|
||||
|
||||
def ivyLikePath0(subDir: String, baseSuffix: String, ext: String) =
|
||||
MavenRepository.ivyLikePath(dependency.module.organization, dependency.module.name, project.version, subDir, baseSuffix, ext)
|
||||
BaseMavenRepository.ivyLikePath(dependency.module.organization, dependency.module.name, project.version, subDir, baseSuffix, ext)
|
||||
|
||||
val path =
|
||||
if (ivyLike)
|
||||
|
|
@ -206,13 +210,20 @@ object MavenRepository {
|
|||
|
||||
}
|
||||
|
||||
case class MavenRepository(fetch: Fetch,
|
||||
ivyLike: Boolean = false) extends Repository {
|
||||
abstract class BaseMavenRepository(
|
||||
root: String,
|
||||
ivyLike: Boolean
|
||||
) extends Repository {
|
||||
|
||||
def fetch(
|
||||
artifact: Artifact,
|
||||
cachePolicy: CachePolicy
|
||||
): EitherT[Task, String, String]
|
||||
|
||||
import Repository._
|
||||
import MavenRepository._
|
||||
import BaseMavenRepository._
|
||||
|
||||
val source = MavenRepository.Source(fetch.root, ivyLike)
|
||||
val source = BaseMavenRepository.Source(root, ivyLike)
|
||||
|
||||
def projectArtifact(module: Module, version: String): Artifact = {
|
||||
val path = (
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ object CoursierBuild extends Build {
|
|||
organization := "com.github.alexarchambault",
|
||||
scalaVersion := "2.11.6",
|
||||
crossScalaVersions := Seq("2.10.5", "2.11.6"),
|
||||
resolvers += "Scalaz Bintray Repo" at "http://dl.bintray.com/scalaz/releases"
|
||||
resolvers += "Scalaz Bintray Repo" at "http://dl.bintray.com/scalaz/releases",
|
||||
resolvers += Resolver.sonatypeRepo("snapshots")
|
||||
) ++ publishingSettings
|
||||
|
||||
private lazy val commonCoreSettings = commonSettings ++ Seq[Setting[_]](
|
||||
|
|
@ -123,7 +124,7 @@ object CoursierBuild extends Build {
|
|||
.settings(
|
||||
name := "coursier-cli",
|
||||
libraryDependencies ++= Seq(
|
||||
"com.github.alexarchambault" %% "case-app" % "0.2.2",
|
||||
"com.github.alexarchambault" %% "case-app" % "0.3.0-SNAPSHOT",
|
||||
"ch.qos.logback" % "logback-classic" % "1.1.3"
|
||||
) ++ {
|
||||
if (scalaVersion.value startsWith "2.10.")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package coursier
|
||||
package web
|
||||
|
||||
import coursier.core.{Repository, MavenRepository, Fetch}
|
||||
import coursier.core.{Repository, BaseMavenRepository, MavenRepository}
|
||||
import japgolly.scalajs.react.vdom.{TagMod, Attr}
|
||||
import japgolly.scalajs.react.vdom.Attrs.dangerouslySetInnerHtml
|
||||
import japgolly.scalajs.react.{ReactEventI, ReactComponentB, BackendScope}
|
||||
|
|
@ -111,7 +111,7 @@ class Backend($: BackendScope[Unit, State]) {
|
|||
g.$("#resLogTab a:last").tab("show")
|
||||
$.modState(_.copy(resolving = true, log = Nil))
|
||||
|
||||
val logger: Fetch.Logger = new Fetch.Logger {
|
||||
val logger: MavenRepository.Logger = new MavenRepository.Logger {
|
||||
def fetched(url: String) = {
|
||||
println(s"<- $url")
|
||||
$.modState(s => s.copy(log = s"<- $url" +: s.log))
|
||||
|
|
@ -135,7 +135,7 @@ class Backend($: BackendScope[Unit, State]) {
|
|||
|
||||
res
|
||||
.process
|
||||
.run(fetch(s.repositories.map(r => r.copy(fetch = r.fetch.copy(logger = Some(logger))))), 100)
|
||||
.run(fetch(s.repositories.map(r => r.copy(logger = Some(logger)))), 100)
|
||||
}
|
||||
|
||||
// For reasons that are unclear to me, not delaying this when using the runNow execution context
|
||||
|
|
@ -246,7 +246,7 @@ object App {
|
|||
)),
|
||||
<.td(Seq[Seq[TagMod]](
|
||||
res.projectCache.get(dep.moduleVersion) match {
|
||||
case Some((source: MavenRepository.Source, proj)) if !source.ivyLike =>
|
||||
case Some((source: BaseMavenRepository.Source, proj)) if !source.ivyLike =>
|
||||
// FIXME Maven specific, generalize with source.artifacts
|
||||
val version0 = finalVersionOpt getOrElse dep.version
|
||||
val relPath =
|
||||
|
|
@ -401,14 +401,14 @@ object App {
|
|||
def repoItem(repo: MavenRepository) =
|
||||
<.tr(
|
||||
<.td(
|
||||
<.a(^.href := repo.fetch.root,
|
||||
repo.fetch.root
|
||||
<.a(^.href := repo.root,
|
||||
repo.root
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val sortedRepos = repos
|
||||
.sortBy(repo => repo.fetch.root)
|
||||
.sortBy(repo => repo.root)
|
||||
|
||||
<.table(^.`class` := "table",
|
||||
<.thead(
|
||||
|
|
|
|||
Loading…
Reference in New Issue