mirror of https://github.com/sbt/sbt.git
Add support for fallback artifact in SBT plugin
This commit is contained in:
parent
4b3659bd0f
commit
3367f49058
|
|
@ -413,7 +413,8 @@ lazy val plugin = project
|
||||||
scriptedLaunchOpts ++= Seq(
|
scriptedLaunchOpts ++= Seq(
|
||||||
"-Xmx1024M",
|
"-Xmx1024M",
|
||||||
"-XX:MaxPermSize=256M",
|
"-XX:MaxPermSize=256M",
|
||||||
"-Dplugin.version=" + version.value
|
"-Dplugin.version=" + version.value,
|
||||||
|
"-Dsbttest.base=" + (sourceDirectory.value / "sbt-test").getAbsolutePath
|
||||||
),
|
),
|
||||||
scriptedBufferLog := false
|
scriptedBufferLog := false
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ object CoursierPlugin extends AutoPlugin {
|
||||||
val coursierVerbosity = Keys.coursierVerbosity
|
val coursierVerbosity = Keys.coursierVerbosity
|
||||||
val coursierResolvers = Keys.coursierResolvers
|
val coursierResolvers = Keys.coursierResolvers
|
||||||
val coursierSbtResolvers = Keys.coursierSbtResolvers
|
val coursierSbtResolvers = Keys.coursierSbtResolvers
|
||||||
|
val coursierFallbackDependencies = Keys.coursierFallbackDependencies
|
||||||
val coursierCache = Keys.coursierCache
|
val coursierCache = Keys.coursierCache
|
||||||
val coursierProject = Keys.coursierProject
|
val coursierProject = Keys.coursierProject
|
||||||
val coursierProjects = Keys.coursierProjects
|
val coursierProjects = Keys.coursierProjects
|
||||||
|
|
@ -39,6 +40,7 @@ object CoursierPlugin extends AutoPlugin {
|
||||||
coursierVerbosity := Settings.defaultVerbosityLevel,
|
coursierVerbosity := Settings.defaultVerbosityLevel,
|
||||||
coursierResolvers <<= Tasks.coursierResolversTask,
|
coursierResolvers <<= Tasks.coursierResolversTask,
|
||||||
coursierSbtResolvers <<= externalResolvers in updateSbtClassifiers,
|
coursierSbtResolvers <<= externalResolvers in updateSbtClassifiers,
|
||||||
|
coursierFallbackDependencies <<= Tasks.coursierFallbackDependenciesTask,
|
||||||
coursierCache := Cache.default,
|
coursierCache := Cache.default,
|
||||||
update <<= Tasks.updateTask(withClassifiers = false),
|
update <<= Tasks.updateTask(withClassifiers = false),
|
||||||
updateClassifiers <<= Tasks.updateTask(withClassifiers = true),
|
updateClassifiers <<= Tasks.updateTask(withClassifiers = true),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
package coursier
|
||||||
|
|
||||||
|
import java.net.URL
|
||||||
|
|
||||||
|
import scalaz.{ EitherT, Monad }
|
||||||
|
|
||||||
|
case class FallbackDependenciesRepository(
|
||||||
|
fallbacks: Map[(Module, String), (URL, Boolean)]
|
||||||
|
) extends Repository {
|
||||||
|
|
||||||
|
private val source = new Artifact.Source {
|
||||||
|
def artifacts(
|
||||||
|
dependency: Dependency,
|
||||||
|
project: Project,
|
||||||
|
overrideClassifiers: Option[Seq[String]]
|
||||||
|
) =
|
||||||
|
fallbacks.get(dependency.moduleVersion) match {
|
||||||
|
case None => Nil
|
||||||
|
case Some((url, changing)) =>
|
||||||
|
Seq(
|
||||||
|
Artifact(url.toString, Map.empty, Map.empty, Attributes("jar", ""), changing)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def find[F[_]](
|
||||||
|
module: Module,
|
||||||
|
version: String,
|
||||||
|
fetch: Fetch.Content[F]
|
||||||
|
)(implicit
|
||||||
|
F: Monad[F]
|
||||||
|
): EitherT[F, String, (Artifact.Source, Project)] =
|
||||||
|
fallbacks.get((module, version)) match {
|
||||||
|
case None =>
|
||||||
|
EitherT.left(F.point("No fallback URL found"))
|
||||||
|
|
||||||
|
case Some((url, _)) =>
|
||||||
|
val proj = Project(
|
||||||
|
module,
|
||||||
|
version,
|
||||||
|
Nil,
|
||||||
|
Map.empty,
|
||||||
|
None,
|
||||||
|
Nil,
|
||||||
|
Nil,
|
||||||
|
Nil,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
Nil,
|
||||||
|
Info.empty
|
||||||
|
)
|
||||||
|
|
||||||
|
EitherT.right(F.point((source, proj)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ package coursier
|
||||||
|
|
||||||
import coursier.ivy.{ IvyXml, IvyRepository }
|
import coursier.ivy.{ IvyXml, IvyRepository }
|
||||||
|
|
||||||
import java.net.MalformedURLException
|
import java.net.{ MalformedURLException, URL }
|
||||||
|
|
||||||
import sbt.{ Resolver, CrossVersion, ModuleID }
|
import sbt.{ Resolver, CrossVersion, ModuleID }
|
||||||
import sbt.mavenint.SbtPomExtraProperties
|
import sbt.mavenint.SbtPomExtraProperties
|
||||||
|
|
@ -85,6 +85,20 @@ object FromSbt {
|
||||||
} yield from -> dep.copy(configuration = to, attributes = attr)
|
} yield from -> dep.copy(configuration = to, attributes = attr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def fallbackDependencies(
|
||||||
|
allDependencies: Seq[ModuleID],
|
||||||
|
scalaVersion: String,
|
||||||
|
scalaBinaryVersion: String
|
||||||
|
): Seq[(Module, String, URL, Boolean)] =
|
||||||
|
for {
|
||||||
|
module <- allDependencies
|
||||||
|
artifact <- module.explicitArtifacts
|
||||||
|
url <- artifact.url.toSeq
|
||||||
|
} yield {
|
||||||
|
val (module0, version) = moduleVersion(module, scalaVersion, scalaBinaryVersion)
|
||||||
|
(module0, version, url, module.isChanging)
|
||||||
|
}
|
||||||
|
|
||||||
def project(
|
def project(
|
||||||
projectID: ModuleID,
|
projectID: ModuleID,
|
||||||
allDependencies: Seq[ModuleID],
|
allDependencies: Seq[ModuleID],
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package coursier
|
package coursier
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.net.URL
|
||||||
|
|
||||||
import coursier.core.Publication
|
import coursier.core.Publication
|
||||||
import sbt.{ GetClassifiersModule, Resolver, SettingKey, TaskKey }
|
import sbt.{ GetClassifiersModule, Resolver, SettingKey, TaskKey }
|
||||||
|
|
||||||
|
|
@ -18,6 +20,8 @@ object Keys {
|
||||||
|
|
||||||
val coursierCache = SettingKey[File]("coursier-cache", "")
|
val coursierCache = SettingKey[File]("coursier-cache", "")
|
||||||
|
|
||||||
|
val coursierFallbackDependencies = TaskKey[Seq[(Module, String, URL, Boolean)]]("coursier-fallback-dependencies", "")
|
||||||
|
|
||||||
val coursierProject = TaskKey[Project]("coursier-project", "")
|
val coursierProject = TaskKey[Project]("coursier-project", "")
|
||||||
val coursierProjects = TaskKey[Seq[Project]]("coursier-projects", "")
|
val coursierProjects = TaskKey[Seq[Project]]("coursier-projects", "")
|
||||||
val coursierPublications = TaskKey[Seq[(String, Publication)]]("coursier-publications", "")
|
val coursierPublications = TaskKey[Seq[(String, Publication)]]("coursier-publications", "")
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package coursier
|
package coursier
|
||||||
|
|
||||||
import java.io.{ OutputStreamWriter, File }
|
import java.io.{ OutputStreamWriter, File }
|
||||||
|
import java.net.URL
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
|
|
@ -42,6 +43,26 @@ object Tasks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def coursierFallbackDependenciesTask: Def.Initialize[sbt.Task[Seq[(Module, String, URL, Boolean)]]] =
|
||||||
|
(
|
||||||
|
sbt.Keys.state,
|
||||||
|
sbt.Keys.thisProjectRef
|
||||||
|
).flatMap { (state, projectRef) =>
|
||||||
|
|
||||||
|
val allDependenciesTask = allDependencies.in(projectRef).get(state)
|
||||||
|
|
||||||
|
for {
|
||||||
|
allDependencies <- allDependenciesTask
|
||||||
|
} yield {
|
||||||
|
|
||||||
|
FromSbt.fallbackDependencies(
|
||||||
|
allDependencies,
|
||||||
|
scalaVersion.in(projectRef).get(state),
|
||||||
|
scalaBinaryVersion.in(projectRef).get(state)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def coursierProjectTask: Def.Initialize[sbt.Task[Project]] =
|
def coursierProjectTask: Def.Initialize[sbt.Task[Project]] =
|
||||||
(
|
(
|
||||||
sbt.Keys.state,
|
sbt.Keys.state,
|
||||||
|
|
@ -181,19 +202,31 @@ object Tasks {
|
||||||
|
|
||||||
lazy val cm = coursierSbtClassifiersModule.value
|
lazy val cm = coursierSbtClassifiersModule.value
|
||||||
|
|
||||||
val currentProject =
|
val (currentProject, fallbackDependencies) =
|
||||||
if (sbtClassifiers)
|
if (sbtClassifiers) {
|
||||||
FromSbt.project(
|
val sv = scalaVersion.value
|
||||||
|
val sbv = scalaBinaryVersion.value
|
||||||
|
|
||||||
|
val proj = FromSbt.project(
|
||||||
cm.id,
|
cm.id,
|
||||||
cm.modules,
|
cm.modules,
|
||||||
cm.configurations.map(cfg => cfg.name -> cfg.extendsConfigs.map(_.name)).toMap,
|
cm.configurations.map(cfg => cfg.name -> cfg.extendsConfigs.map(_.name)).toMap,
|
||||||
scalaVersion.value,
|
sv,
|
||||||
scalaBinaryVersion.value
|
sbv
|
||||||
)
|
)
|
||||||
else {
|
|
||||||
|
val fallbackDeps = FromSbt.fallbackDependencies(
|
||||||
|
cm.modules,
|
||||||
|
sv,
|
||||||
|
sbv
|
||||||
|
)
|
||||||
|
|
||||||
|
(proj, fallbackDeps)
|
||||||
|
} else {
|
||||||
val proj = coursierProject.value
|
val proj = coursierProject.value
|
||||||
val publications = coursierPublications.value
|
val publications = coursierPublications.value
|
||||||
proj.copy(publications = publications)
|
val fallbackDeps = coursierFallbackDependencies.value
|
||||||
|
(proj.copy(publications = publications), fallbackDeps)
|
||||||
}
|
}
|
||||||
|
|
||||||
val ivySbt0 = ivySbt.value
|
val ivySbt0 = ivySbt.value
|
||||||
|
|
@ -277,7 +310,25 @@ object Tasks {
|
||||||
"ivy.home" -> (new File(sys.props("user.home")).toURI.getPath + ".ivy2")
|
"ivy.home" -> (new File(sys.props("user.home")).toURI.getPath + ".ivy2")
|
||||||
) ++ sys.props
|
) ++ sys.props
|
||||||
|
|
||||||
val repositories = Seq(globalPluginsRepo, interProjectRepo) ++ resolvers.flatMap(FromSbt.repository(_, ivyProperties))
|
val repositories = Seq(
|
||||||
|
globalPluginsRepo,
|
||||||
|
interProjectRepo
|
||||||
|
) ++ resolvers.flatMap(
|
||||||
|
FromSbt.repository(_, ivyProperties)
|
||||||
|
) ++ {
|
||||||
|
if (fallbackDependencies.isEmpty)
|
||||||
|
Nil
|
||||||
|
else {
|
||||||
|
val map = fallbackDependencies.map {
|
||||||
|
case (mod, ver, url, changing) =>
|
||||||
|
(mod, ver) -> ((url, changing))
|
||||||
|
}.toMap
|
||||||
|
|
||||||
|
Seq(
|
||||||
|
FallbackDependenciesRepository(map)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def report = {
|
def report = {
|
||||||
val pool = Executors.newFixedThreadPool(parallelDownloads, Strategy.DefaultDaemonThreadFactory)
|
val pool = Executors.newFixedThreadPool(parallelDownloads, Strategy.DefaultDaemonThreadFactory)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
scalaVersion := "2.11.8"
|
||||||
|
|
||||||
|
libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.41" from {
|
||||||
|
|
||||||
|
val f = file(sys.props("sbttest.base")) / "sbt-coursier" / "from" / "shapeless_2.11-2.3.0.jar"
|
||||||
|
|
||||||
|
if (!f.exists()) {
|
||||||
|
val url0 = "https://repo1.maven.org/maven2/com/chuusai/shapeless_2.11/2.3.0/shapeless_2.11-2.3.0.jar"
|
||||||
|
|
||||||
|
scala.Console.err.println(s"Fetching $url0")
|
||||||
|
|
||||||
|
val url = new java.net.URL(url0)
|
||||||
|
|
||||||
|
val is = url.openStream()
|
||||||
|
val os = new java.io.FileOutputStream(f)
|
||||||
|
|
||||||
|
var read = -1
|
||||||
|
val b = Array.fill[Byte](16*1024)(0)
|
||||||
|
while ({
|
||||||
|
read = is.read(b)
|
||||||
|
read >= 0
|
||||||
|
}) {
|
||||||
|
os.write(b, 0, read)
|
||||||
|
}
|
||||||
|
|
||||||
|
is.close()
|
||||||
|
os.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
f.toURI.toString
|
||||||
|
}
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
import java.io.File
|
||||||
|
import java.nio.file.Files
|
||||||
|
|
||||||
|
import shapeless._
|
||||||
|
|
||||||
|
object Main extends App {
|
||||||
|
case class CC(s: String)
|
||||||
|
val cc = CC("OK")
|
||||||
|
val l = Generic[CC].to(cc)
|
||||||
|
val msg = l.head
|
||||||
|
|
||||||
|
Files.write(new File("output").toPath, msg.getBytes("UTF-8"))
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
$ delete output
|
||||||
|
> run
|
||||||
|
$ exists output
|
||||||
Loading…
Reference in New Issue