dependency filters, selecting/filtering UpdateReport

This commit is contained in:
Mark Harrah 2011-04-10 16:22:48 -04:00
parent d9e7dd8392
commit a53ed46ce4
3 changed files with 134 additions and 27 deletions

View File

@ -0,0 +1,66 @@
/* sbt -- Simple Build Tool
* Copyright 2011 Mark Harrah
*/
package sbt
trait DependencyFilterExtra
{
def moduleFilter(organization: NameFilter = AllPassFilter, name: NameFilter = AllPassFilter, revision: NameFilter = AllPassFilter): ModuleFilter =
new ModuleFilter {
def apply(m: ModuleID): Boolean = organization.accept(m.organization) && name.accept(m.name) && revision.accept(m.revision)
}
def artifactFilter(name: NameFilter = AllPassFilter, `type`: NameFilter = AllPassFilter, extension: NameFilter = AllPassFilter, classifier: NameFilter = AllPassFilter): ArtifactFilter =
new ArtifactFilter {
def apply(a: Artifact): Boolean = name.accept(a.name) && `type`.accept(a.`type`) && extension.accept(a.extension) && classifier.accept(a.classifier getOrElse "")
}
def configurationFilter(name: NameFilter = AllPassFilter): ConfigurationFilter =
new ConfigurationFilter {
def apply(c: String): Boolean = name.accept(c)
}
}
object DependencyFilter extends DependencyFilterExtra
{
def make(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): DependencyFilter =
new DependencyFilter {
def apply(c: String, m: ModuleID, a: Artifact): Boolean = configuration(c) && module(m) && artifact(a)
}
def apply(x: DependencyFilter, y: DependencyFilter, combine: (Boolean, Boolean) => Boolean): DependencyFilter =
new DependencyFilter {
def apply(c: String, m: ModuleID, a: Artifact): Boolean = combine(x(c, m, a), y(c, m, a))
}
def allPass: DependencyFilter = configurationFilter()
implicit def fnToModuleFilter(f: ModuleID => Boolean): ModuleFilter = new ModuleFilter { def apply(m: ModuleID) = f(m) }
implicit def fnToArtifactFilter(f: Artifact => Boolean): ArtifactFilter = new ArtifactFilter { def apply(m: Artifact) = f(m) }
implicit def fnToConfigurationFilter(f: String => Boolean): ConfigurationFilter = new ConfigurationFilter { def apply(c: String) = f(c) }
}
trait DependencyFilter
{
def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean
final def &&(o: DependencyFilter) = DependencyFilter(this, o, _ && _)
final def ||(o: DependencyFilter) = DependencyFilter(this, o, _ || _)
final def -- (o: DependencyFilter) = DependencyFilter(this, o, _ && !_)
}
sealed trait SubDepFilter[Arg, Self <: SubDepFilter[Arg, Self]] extends DependencyFilter
{ self: Self =>
def apply(a: Arg): Boolean
protected def make(f: Arg => Boolean): Self
final def &(o: Self): Self = combine(o, _ && _)
final def |(o: Self): Self = combine(o, _ || _)
final def -(o: Self): Self = combine(o, _ && !_)
private[this] def combine(o: Self, f: (Boolean, Boolean) => Boolean): Self = make( (m: Arg) => f(this(m), o(m)) )
}
trait ModuleFilter extends SubDepFilter[ModuleID, ModuleFilter]
{
protected final def make(f: ModuleID => Boolean) = new ModuleFilter { def apply(m: ModuleID) = f(m) }
final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(module)
}
trait ArtifactFilter extends SubDepFilter[Artifact, ArtifactFilter]
{
protected final def make(f: Artifact => Boolean) = new ArtifactFilter { def apply(m: Artifact) = f(m) }
final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(artifact)
}
trait ConfigurationFilter extends SubDepFilter[String, ConfigurationFilter]
{
protected final def make(f: String => Boolean) = new ConfigurationFilter { def apply(m: String) = f(m) }
final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(configuration)
}

View File

@ -50,30 +50,3 @@ object IvyRetrieve
def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport =
new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport))
}
final class UpdateReport(val configurations: Seq[ConfigurationReport])
{
override def toString = "Update report:\n" + configurations.mkString
def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct
def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport =
new UpdateReport(configurations map { _ retrieve f} )
def configuration(s: String) = configurations.find(_.configuration == s)
}
final class ConfigurationReport(val configuration: String, val modules: Seq[ModuleReport])
{
override def toString = "\t" + configuration + ":\n" + modules.mkString
def allModules: Seq[ModuleID] = modules.map(_.module)
def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport =
new ConfigurationReport(configuration, modules map { _.retrieve( (mid,art,file) => f(configuration, mid, art, file)) })
}
final class ModuleReport(val module: ModuleID, val artifacts: Seq[(Artifact, File)], val missingArtifacts: Seq[Artifact])
{
override def toString =
{
val arts = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art)
"\t\t" + module + ": " +
(if(arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n"
}
def retrieve(f: (ModuleID, Artifact, File) => File): ModuleReport =
new ModuleReport(module, artifacts.map { case (art,file) => (art, f(module, art, file)) }, missingArtifacts)
}

68
ivy/UpdateReport.scala Normal file
View File

@ -0,0 +1,68 @@
/* sbt -- Simple Build Tool
* Copyright 2011 Mark Harrah
*/
package sbt
import java.io.File
final class UpdateReport(val configurations: Seq[ConfigurationReport])
{
override def toString = "Update report:\n" + configurations.mkString
def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct
def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport =
new UpdateReport(configurations map { _ retrieve f} )
def configuration(s: String) = configurations.find(_.configuration == s)
}
final class ConfigurationReport(val configuration: String, val modules: Seq[ModuleReport])
{
override def toString = "\t" + configuration + ":\n" + modules.mkString
def allModules: Seq[ModuleID] = modules.map(_.module)
def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport =
new ConfigurationReport(configuration, modules map { _.retrieve( (mid,art,file) => f(configuration, mid, art, file)) })
}
final class ModuleReport(val module: ModuleID, val artifacts: Seq[(Artifact, File)], val missingArtifacts: Seq[Artifact])
{
override def toString =
{
val arts = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art)
"\t\t" + module + ": " +
(if(arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n"
}
def retrieve(f: (ModuleID, Artifact, File) => File): ModuleReport =
new ModuleReport(module, artifacts.map { case (art,file) => (art, f(module, art, file)) }, missingArtifacts)
}
object UpdateReport
{
implicit def richUpdateReport(report: UpdateReport): RichUpdateReport = new RichUpdateReport(report)
final class RichUpdateReport(report: UpdateReport)
{
import DependencyFilter._
def allFiles: Seq[File] = matching(DependencyFilter.allPass)
def matching(f: DependencyFilter): Seq[File] = select0(f).distinct
def select(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): Seq[File] =
matching(DependencyFilter.make(configuration, module, artifact))
private[this] def select0(f: DependencyFilter): Seq[File] =
for(cReport <- report.configurations; mReport <- cReport.modules; (artifact, file) <- mReport.artifacts if f(cReport.configuration, mReport.module, artifact)) yield {
if(file == null) error("Null file: conf=" + cReport.configuration + ", module=" + mReport.module + ", art: " + artifact)
file
}
def filter(f: DependencyFilter): UpdateReport =
{
val newConfigurations = report.configurations.map { confReport =>
import confReport._
val newModules =
modules map { modReport =>
import modReport._
val newArtifacts = artifacts filter { case (art, file) => f(configuration, module, art) }
val newMissing = missingArtifacts filter { art => f(configuration, module, art) }
new ModuleReport(module, newArtifacts, newMissing)
}
new ConfigurationReport(configuration, newModules)
}
new UpdateReport(newConfigurations)
}
}
}