2011-04-10 22:22:48 +02:00
/* sbt -- Simple Build Tool
* Copyright 2011 Mark Harrah
*/
package sbt
import java.io.File
2011-04-11 03:30:03 +02:00
/* * Provides information about dependency resolution.
* It does not include information about evicted modules , only about the modules ultimately selected by the conflict manager .
* This means that for a given configuration , there should only be one revision for a given organization and module name .
2011-04-16 01:55:22 +02:00
* @param cachedDescriptor the location of the resolved module descriptor in the cache
2011-04-11 03:30:03 +02:00
* @param configurations a sequence containing one report for each configuration resolved .
* @see sbt . RichUpdateReport
*/
2011-07-09 03:54:59 +02:00
final class UpdateReport ( val cachedDescriptor : File , val configurations : Seq [ ConfigurationReport ] , val stats : UpdateStats )
2011-04-10 22:22:48 +02:00
{
2011-07-09 03:54:59 +02:00
override def toString = "Update report:\n\t" + stats + "\n" + configurations . mkString
2011-04-11 03:30:03 +02:00
/* * All resolved modules in all configurations. */
2011-04-10 22:22:48 +02:00
def allModules : Seq [ ModuleID ] = configurations . flatMap ( _ . allModules ) . distinct
2011-04-11 03:30:03 +02:00
2011-04-10 22:22:48 +02:00
def retrieve ( f : ( String , ModuleID , Artifact , File ) => File ) : UpdateReport =
2011-07-09 03:54:59 +02:00
new UpdateReport ( cachedDescriptor , configurations map { _ retrieve f } , stats )
2011-04-11 03:30:03 +02:00
/* * Gets the report for the given configuration, or `None` if the configuration was not resolved. */
2011-04-10 22:22:48 +02:00
def configuration ( s : String ) = configurations . find ( _ . configuration == s )
2011-04-11 03:30:03 +02:00
/* * Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */
2011-04-11 16:19:04 +02:00
def allConfigurations : Seq [ String ] = configurations . map ( _ . configuration )
2011-04-10 22:22:48 +02:00
}
2011-04-11 03:30:03 +02:00
/* * Provides information about resolution of a single configuration.
* @param configuration the configuration this report is for .
* @param modules a seqeuence containing one report for each module resolved for this configuration .
*/
2011-07-09 03:54:59 +02:00
final class ConfigurationReport ( val configuration : String , val modules : Seq [ ModuleReport ] , val evicted : Seq [ ModuleID ] )
2011-04-10 22:22:48 +02:00
{
2011-07-09 03:54:59 +02:00
override def toString = "\t" + configuration + ":\n" + modules . mkString + evicted . map ( "\t\t(EVICTED) " + _ + "\n" ) . mkString
2011-04-11 03:30:03 +02:00
/* * All resolved modules for this configuration.
* For a given organization and module name , there is only one revision / `ModuleID` in this sequence .
*/
2011-04-10 22:22:48 +02:00
def allModules : Seq [ ModuleID ] = modules . map ( _ . module )
2011-04-11 03:30:03 +02:00
2011-04-10 22:22:48 +02:00
def retrieve ( f : ( String , ModuleID , Artifact , File ) => File ) : ConfigurationReport =
2011-07-09 03:54:59 +02:00
new ConfigurationReport ( configuration , modules map { _ . retrieve ( ( mid , art , file ) => f ( configuration , mid , art , file ) ) } , evicted )
2011-04-10 22:22:48 +02:00
}
2011-04-11 03:30:03 +02:00
/* * Provides information about the resolution of a module.
* This information is in the context of a specific configuration .
* @param module the `ModuleID` this report is for .
* @param artifacts the resolved artifacts for this module , paired with the File the artifact was retrieved to . This File may be in the
*/
2011-04-10 22:22:48 +02:00
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 )
2011-04-11 03:30:03 +02:00
/* * Provides extra methods for filtering the contents of an `UpdateReport` and for obtaining references to a selected subset of the underlying files. */
2011-04-10 22:22:48 +02:00
final class RichUpdateReport ( report : UpdateReport )
{
import DependencyFilter._
2011-04-11 03:30:03 +02:00
/* * Obtains all successfully retrieved files in all configurations and modules. */
2011-04-10 22:22:48 +02:00
def allFiles : Seq [ File ] = matching ( DependencyFilter . allPass )
2011-04-11 03:30:03 +02:00
/* * Obtains all successfully retrieved files in configurations, modules, and artifacts matching the specified filter. */
2011-04-10 22:22:48 +02:00
def matching ( f : DependencyFilter ) : Seq [ File ] = select0 ( f ) . distinct
2011-04-11 03:30:03 +02:00
/* * Obtains all successfully retrieved files matching all provided filters. An unspecified argument matches all files. */
2011-04-10 22:22:48 +02:00
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
}
2011-04-11 03:30:03 +02:00
/* * Constructs a new report that only contains files matching the specified filter. */
2011-04-10 22:22:48 +02:00
def filter ( f : DependencyFilter ) : UpdateReport =
2011-06-20 03:01:29 +02:00
moduleReportMap { ( configuration , 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 )
2011-04-10 22:22:48 +02:00
}
2011-04-16 00:32:20 +02:00
def substitute ( f : ( String , ModuleID , Seq [ ( Artifact , File ) ] ) => Seq [ ( Artifact , File ) ] ) : UpdateReport =
2011-06-20 03:01:29 +02:00
moduleReportMap { ( configuration , modReport ) =>
val newArtifacts = f ( configuration , modReport . module , modReport . artifacts )
new ModuleReport ( modReport . module , newArtifacts , Nil )
}
def toSeq : Seq [ ( String , ModuleID , Artifact , File ) ] =
for ( confReport <- report . configurations ; modReport <- confReport . modules ; ( artifact , file ) <- modReport . artifacts ) yield
( confReport . configuration , modReport . module , artifact , file )
def allMissing : Seq [ ( String , ModuleID , Artifact ) ] =
for ( confReport <- report . configurations ; modReport <- confReport . modules ; artifact <- modReport . missingArtifacts ) yield
( confReport . configuration , modReport . module , artifact )
def addMissing ( f : ModuleID => Seq [ Artifact ] ) : UpdateReport =
moduleReportMap { ( configuration , modReport ) =>
import modReport._
new ModuleReport ( module , artifacts , ( missingArtifacts ++ f ( module ) ) . distinct )
}
def moduleReportMap ( f : ( String , ModuleReport ) => ModuleReport ) : UpdateReport =
2011-04-16 00:32:20 +02:00
{
val newConfigurations = report . configurations . map { confReport =>
import confReport._
2011-06-20 03:01:29 +02:00
val newModules = modules map { modReport => f ( configuration , modReport ) }
2011-07-09 03:54:59 +02:00
new ConfigurationReport ( configuration , newModules , evicted )
2011-04-16 00:32:20 +02:00
}
2011-07-09 03:54:59 +02:00
new UpdateReport ( report . cachedDescriptor , newConfigurations , report . stats )
2011-04-16 00:32:20 +02:00
}
2011-04-10 22:22:48 +02:00
}
2011-04-16 00:32:20 +02:00
}
2011-07-09 03:54:59 +02:00
final class UpdateStats ( val resolveTime : Long , val downloadTime : Long , val downloadSize : Long )
{
override def toString = Seq ( "Resolve time: " + resolveTime + " ms" , "Download time: " + downloadTime + " ms" , "Download size: " + downloadSize + " bytes" ) . mkString ( ", " )
}