Skip to content

Instantly share code, notes, and snippets.

@retronym
Created October 20, 2011 22:03
Show Gist options
  • Save retronym/1302515 to your computer and use it in GitHub Desktop.
Save retronym/1302515 to your computer and use it in GitHub Desktop.
sbt-classifiers
>show update
[info] commons-io:commons-io:1.2:
[info] (Artifact(commons-io,jar,jar,None,ArraySeq(),None,Map()),project/.ivy/cache/commons-io/commons-io/jars/commons-io-1.2.jar)
[info] (Artifact(commons-io,src,jar,Some(sources),ArraySeq(),None,Map()),project/.ivy/cache/commons-io/commons-io/srcs/commons-io-1.2-sources.jar)
[info] (Artifact(commons-io,doc,jar,Some(javadoc),ArraySeq(),None,Map()),project/.ivy/cache/commons-io/commons-io/docs/commons-io-1.2-javadoc.jar)
> show update-sbt-classifiers
...
[info] commons-collections:commons-collections:3.2.1:
[info] (Artifact(commons-collections,src,jar,Some(sources),ArraySeq(),None,Map()),project/.ivy/cache/commons-collections/commons-collections/srcs/commons-collections-3.2.1-sources.jar)
[info] (Artifact(commons-collections,jar,jar,None,ArraySeq(),None,Map()),project/.ivy/cache/commons-collections/commons-collections/jars/commons-collections-3.2.1.jar)
import sbt._
import Keys._
import Defaults._
import Classpaths.withExcludes
object build extends Build {
lazy val scratch = Project(
id = "scratch",
base = file("."),
settings = Defaults.defaultSettings ++ inTask(updateSbtClassifiers)(Seq(
classifiersModule <<= (projectID, sbtDependency, transitiveClassifiers, loadedBuild, thisProjectRef) map { ( pid, sbtDep, classifiers, lb, ref) =>
val pluginIDs: Seq[ModuleID] = lb.units(ref.build).unit.plugins.fullClasspath.flatMap(_ get moduleID.key)
GetClassifiersModule.apply(pid, sbtDep +: pluginIDs, Configurations.Default :: Nil, classifiers)
},
updateSbtClassifiers in TaskGlobal <<= (ivySbt, classifiersModule, updateConfiguration, ivyScala, target in LocalRootProject, appConfiguration, streams) map {
(is, mod, c, ivyScala, out, app, s) =>
withExcludes(out, mod.classifiers, lock(app)) { excludes =>
transitiveScratch(is, "sbt", GetClassifiersConfiguration(mod, excludes, c, ivyScala), s.log)
}
}
)) ++ Seq(
classifiersModule in Keys.updateClassifiers <<= (projectID, update, transitiveClassifiers in Keys.updateClassifiers, ivyConfigurations in Keys.updateClassifiers) map { ( pid, up, classifiers, confs) =>
GetClassifiersModule(pid, up.allModules, confs, classifiers)
},
Keys.updateClassifiers <<= (ivySbt, classifiersModule in Keys.updateClassifiers, updateConfiguration, ivyScala, target in LocalRootProject, appConfiguration, streams) map { (is, mod, c, ivyScala, out, app, s) =>
withExcludes(out, mod.classifiers, lock(app)) { excludes =>
updateClassifiers(is, GetClassifiersConfiguration(mod, excludes, c, ivyScala), s.log)
}
}
)
)
import IvyActions._
def transitiveScratch(ivySbt: IvySbt, label: String, config: GetClassifiersConfiguration, log: Logger): UpdateReport =
{
import config.{configuration => c, ivyScala, module => mod}
import mod.{configurations => confs, id, modules => deps}
val base = restrictedCopy(id, true).copy(name = id.name + "$" + label)
val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala))
val report = update(module, c, log)
val newConfig = config.copy(module = mod.copy(modules = report.allModules))
updateClassifiers(ivySbt, newConfig, log)
}
def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, log: Logger): UpdateReport =
{
import config.{configuration => c, module => mod, _}
import mod.{configurations => confs, _}
assert(!classifiers.isEmpty, "classifiers cannot be empty")
val baseModules = modules map { m => restrictedCopy(m, true) }
val deps = baseModules.distinct map classifiedArtifacts(classifiers, exclude)
val base = restrictedCopy(id, true).copy(name = id.name + classifiers.mkString("$","_",""))
val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs))
val upConf = new UpdateConfiguration(c.retrieve, true, c.logging)
update(module, upConf, log)
}
def classifiedArtifacts(classifiers: Seq[String], exclude: Map[ModuleID, Set[String]])(m: ModuleID): ModuleID =
{
val excluded = exclude getOrElse(restrictedCopy(m, false), Set.empty)
val included = classifiers filterNot excluded
m.copy(explicitArtifacts = classifiedArtifacts(m.name, included) :+ Artifact(m.name))
}
def classifiedArtifacts(name: String, classifiers: Seq[String]): Seq[Artifact] =
classifiers map { c => Artifact.classified(name, c) }
private[this] def restrictedCopy(m: ModuleID, confs: Boolean) =
ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes, configurations = if(confs) m.configurations else None)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment