2009-08-16 20:29:08 +02:00
/* sbt -- Simple Build Tool
2010-02-08 05:45:19 +01:00
* Copyright 2008 , 2009 , 2010 Mark Harrah
2009-08-16 20:29:08 +02:00
*/
2010-01-16 01:05:23 +01:00
package sbt
2009-08-16 20:29:08 +02:00
import java.io.File
import java.net. { URI , URL }
import scala.xml.NodeSeq
2010-09-13 05:13:48 +02:00
import org.apache.ivy.plugins.resolver. { DependencyResolver , IBiblioResolver }
2009-08-16 20:29:08 +02:00
import org.apache.ivy.util.url.CredentialsStore
2010-09-22 04:10:21 +02:00
final case class ModuleID ( organization : String , name : String , revision : String , configurations : Option [ String ] = None , isChanging : Boolean = false , isTransitive : Boolean = true , explicitArtifacts : Seq [ Artifact ] = Nil , extraAttributes : Map [ String ,String ] = Map . empty , crossVersion : Boolean = false )
2009-08-16 20:29:08 +02:00
{
2011-07-24 05:07:54 +02:00
override def toString =
organization + ":" + name + ":" + revision +
( configurations match { case Some ( s ) => ":" + s ; case None => "" } ) +
( if ( extraAttributes . isEmpty ) "" else " " + extraString )
def extraString = extraAttributes . map { case ( k , v ) => k + "=" + v } mkString ( "(" , ", " , ")" )
2010-09-22 04:10:21 +02:00
def cross ( v : Boolean ) = copy ( crossVersion = v )
2011-02-15 00:57:10 +01:00
// () required for chaining
2009-08-16 20:29:08 +02:00
def notTransitive ( ) = intransitive ( )
2010-09-22 04:10:21 +02:00
def intransitive ( ) = copy ( isTransitive = false )
def changing ( ) = copy ( isChanging = true )
2009-08-16 20:29:08 +02:00
def from ( url : String ) = artifacts ( Artifact ( name , new URL ( url ) ) )
def classifier ( c : String ) = artifacts ( Artifact ( name , c ) )
2010-09-22 04:10:21 +02:00
def artifacts ( newArtifacts : Artifact * ) = copy ( explicitArtifacts = newArtifacts ++ this . explicitArtifacts )
def extra ( attributes : ( String , String ) * ) = copy ( extraAttributes = this . extraAttributes ++ ModuleID . checkE ( attributes ) )
2010-04-27 23:58:05 +02:00
def sources ( ) = artifacts ( Artifact . sources ( name ) )
def javadoc ( ) = artifacts ( Artifact . javadoc ( name ) )
2009-10-02 04:56:23 +02:00
def withSources ( ) = jarIfEmpty . sources ( )
def withJavadoc ( ) = jarIfEmpty . javadoc ( )
private def jarIfEmpty = if ( explicitArtifacts . isEmpty ) jar ( ) else this
2010-04-27 23:58:05 +02:00
def jar ( ) = artifacts ( Artifact ( name ) )
2009-08-16 20:29:08 +02:00
}
object ModuleID
{
2009-09-27 20:39:26 +02:00
def checkE ( attributes : Seq [ ( String , String ) ] ) =
for ( ( key , value ) <- attributes ) yield
if ( key . startsWith ( "e:" ) ) ( key , value ) else ( "e:" + key , value )
2009-08-16 20:29:08 +02:00
}
2010-10-26 23:59:24 +02:00
sealed trait Resolver
2009-08-16 20:29:08 +02:00
{
def name : String
}
2010-09-13 05:13:48 +02:00
final class RawRepository ( val resolver : DependencyResolver ) extends Resolver
{
def name = resolver . getName
2011-06-19 02:17:50 +02:00
override def toString = "Raw(" + resolver . toString + ")"
2010-09-13 05:13:48 +02:00
}
2011-06-20 21:25:23 +02:00
sealed case class ChainedResolver ( name : String , resolvers : Seq [ Resolver ] ) extends Resolver
2009-08-16 20:29:08 +02:00
sealed case class MavenRepository ( name : String , root : String ) extends Resolver
{
override def toString = name + ": " + root
}
2010-10-26 23:59:24 +02:00
final class Patterns ( val ivyPatterns : Seq [ String ] , val artifactPatterns : Seq [ String ] , val isMavenCompatible : Boolean )
2009-09-27 20:39:26 +02:00
{
2010-01-16 01:05:23 +01:00
private [ sbt ] def mavenStyle ( ) : Patterns = Patterns ( ivyPatterns , artifactPatterns , true )
private [ sbt ] def withIvys ( patterns : Seq [ String ] ) : Patterns = Patterns ( patterns ++ ivyPatterns , artifactPatterns , isMavenCompatible )
private [ sbt ] def withArtifacts ( patterns : Seq [ String ] ) : Patterns = Patterns ( ivyPatterns , patterns ++ artifactPatterns , isMavenCompatible )
2009-09-27 20:39:26 +02:00
}
object Patterns
{
2011-04-06 00:44:47 +02:00
implicit def defaultPatterns : Patterns = Resolver . defaultPatterns
2009-09-27 20:39:26 +02:00
def apply ( artifactPatterns : String * ) : Patterns = Patterns ( true , artifactPatterns : _ * )
2011-06-03 00:35:25 +02:00
def apply ( isMavenCompatible : Boolean , artifactPatterns : String * ) : Patterns = Patterns ( artifactPatterns , artifactPatterns , isMavenCompatible )
2009-09-27 20:39:26 +02:00
def apply ( ivyPatterns : Seq [ String ] , artifactPatterns : Seq [ String ] , isMavenCompatible : Boolean ) : Patterns = new Patterns ( ivyPatterns , artifactPatterns , isMavenCompatible )
}
2009-08-16 20:29:08 +02:00
object RepositoryHelpers
{
2010-10-26 23:59:24 +02:00
final case class SshConnection ( authentication : Option [ SshAuthentication ] , hostname : Option [ String ] , port : Option [ Int ] )
2009-08-16 20:29:08 +02:00
{
def copy ( authentication : Option [ SshAuthentication ] ) = SshConnection ( authentication , hostname , port )
}
/* * Configuration specific to an Ivy filesystem resolver. */
2010-10-26 23:59:24 +02:00
final case class FileConfiguration ( isLocal : Boolean , isTransactional : Option [ Boolean ] )
2009-08-16 20:29:08 +02:00
{
def transactional ( ) = FileConfiguration ( isLocal , Some ( true ) )
def nontransactional ( ) = FileConfiguration ( isLocal , Some ( false ) )
def nonlocal ( ) = FileConfiguration ( false , isTransactional )
}
sealed trait SshAuthentication extends NotNull
2010-04-29 02:45:35 +02:00
final case class PasswordAuthentication ( user : String , password : Option [ String ] ) extends SshAuthentication
final case class KeyFileAuthentication ( user : String , keyfile : File , password : Option [ String ] ) extends SshAuthentication
2009-08-16 20:29:08 +02:00
}
2009-09-27 20:39:26 +02:00
import RepositoryHelpers. { SshConnection , FileConfiguration }
2009-08-16 20:29:08 +02:00
import RepositoryHelpers. { KeyFileAuthentication , PasswordAuthentication , SshAuthentication }
/* * sbt interface to an Ivy repository based on patterns, which is most Ivy repositories. */
sealed abstract class PatternsBasedRepository extends Resolver
{
type RepositoryType <: PatternsBasedRepository
/* * Should be implemented to create a new copy of this repository but with `patterns` as given. */
protected def copy ( patterns : Patterns ) : RepositoryType
/* * The object representing the configured patterns for this repository. */
def patterns : Patterns
2009-08-20 06:02:06 +02:00
2009-08-16 20:29:08 +02:00
/* * Enables maven 2 compatibility for this repository. */
def mavenStyle ( ) = copy ( patterns . mavenStyle ( ) )
/* * Adds the given patterns for resolving / publishing Ivy files. */
def ivys ( ivyPatterns : String * ) : RepositoryType = copy ( patterns . withIvys ( ivyPatterns ) )
/* * Adds the given patterns for resolving / publishing artifacts. */
def artifacts ( artifactPatterns : String * ) : RepositoryType = copy ( patterns . withArtifacts ( artifactPatterns ) )
}
/* * sbt interface for an Ivy filesystem repository. More convenient construction is done using Resolver.file. */
final case class FileRepository ( name : String , configuration : FileConfiguration , patterns : Patterns ) extends PatternsBasedRepository
{
type RepositoryType = FileRepository
protected def copy ( patterns : Patterns ) : FileRepository = FileRepository ( name , configuration , patterns )
private def copy ( configuration : FileConfiguration ) = FileRepository ( name , configuration , patterns )
def transactional ( ) = copy ( configuration . transactional ( ) )
def nonlocal ( ) = copy ( configuration . nonlocal ( ) )
}
final case class URLRepository ( name : String , patterns : Patterns ) extends PatternsBasedRepository
{
type RepositoryType = URLRepository
protected def copy ( patterns : Patterns ) : URLRepository = URLRepository ( name , patterns )
}
/* * sbt interface for an Ivy ssh-based repository (ssh and sftp). Requires the Jsch library.. */
sealed abstract class SshBasedRepository extends PatternsBasedRepository
{
type RepositoryType <: SshBasedRepository
protected def copy ( connection : SshConnection ) : RepositoryType
private def copy ( authentication : SshAuthentication ) : RepositoryType = copy ( connection . copy ( Some ( authentication ) ) )
2009-08-20 06:02:06 +02:00
2009-08-16 20:29:08 +02:00
/* * The object representing the configured ssh connection for this repository. */
def connection : SshConnection
2009-08-20 06:02:06 +02:00
2009-08-16 20:29:08 +02:00
/* * Configures this to use the specified user name and password when connecting to the remote repository. */
2010-04-29 02:45:35 +02:00
def as ( user : String , password : String ) : RepositoryType = as ( user , Some ( password ) )
def as ( user : String ) : RepositoryType = as ( user , None )
def as ( user : String , password : Option [ String ] ) = copy ( new PasswordAuthentication ( user , password ) )
2009-08-16 20:29:08 +02:00
/* * Configures this to use the specified keyfile and password for the keyfile when connecting to the remote repository. */
2010-04-29 02:45:35 +02:00
def as ( user : String , keyfile : File ) : RepositoryType = as ( user , keyfile , None )
def as ( user : String , keyfile : File , password : String ) : RepositoryType = as ( user , keyfile , Some ( password ) )
def as ( user : String , keyfile : File , password : Option [ String ] ) : RepositoryType = copy ( new KeyFileAuthentication ( user , keyfile , password ) )
2009-08-16 20:29:08 +02:00
}
/* * sbt interface for an Ivy repository over ssh. More convenient construction is done using Resolver.ssh. */
final case class SshRepository ( name : String , connection : SshConnection , patterns : Patterns , publishPermissions : Option [ String ] ) extends SshBasedRepository
{
type RepositoryType = SshRepository
protected def copy ( patterns : Patterns ) : SshRepository = SshRepository ( name , connection , patterns , publishPermissions )
protected def copy ( connection : SshConnection ) : SshRepository = SshRepository ( name , connection , patterns , publishPermissions )
/* * Defines the permissions to set when publishing to this repository. */
def withPermissions ( publishPermissions : String ) : SshRepository = withPermissions ( Some ( publishPermissions ) )
def withPermissions ( publishPermissions : Option [ String ] ) : SshRepository = SshRepository ( name , connection , patterns , publishPermissions )
}
/* * sbt interface for an Ivy repository over sftp. More convenient construction is done using Resolver.sftp. */
final case class SftpRepository ( name : String , connection : SshConnection , patterns : Patterns ) extends SshBasedRepository
{
type RepositoryType = SftpRepository
protected def copy ( patterns : Patterns ) : SftpRepository = SftpRepository ( name , connection , patterns )
protected def copy ( connection : SshConnection ) : SftpRepository = SftpRepository ( name , connection , patterns )
}
import Resolver._
object ScalaToolsReleases extends MavenRepository ( ScalaToolsReleasesName , ScalaToolsReleasesRoot )
object ScalaToolsSnapshots extends MavenRepository ( ScalaToolsSnapshotsName , ScalaToolsSnapshotsRoot )
object DefaultMavenRepository extends MavenRepository ( "public" , IBiblioResolver . DEFAULT_M2_ROOT )
2010-10-26 23:59:24 +02:00
object JavaNet1Repository extends JavaNet1Repository
sealed trait JavaNet1Repository extends Resolver
2009-08-16 20:29:08 +02:00
{
def name = "java.net Maven1 Repository"
}
object Resolver
{
val ScalaToolsReleasesName = "Scala-Tools Maven2 Repository"
val ScalaToolsSnapshotsName = "Scala-Tools Maven2 Snapshots Repository"
val ScalaToolsReleasesRoot = "http://scala-tools.org/repo-releases"
val ScalaToolsSnapshotsRoot = "http://scala-tools.org/repo-snapshots"
2010-02-07 01:23:06 +01:00
/* * Add the local, Maven Central, and Scala Tools releases repositories to the user repositories. */
2009-08-16 20:29:08 +02:00
def withDefaultResolvers ( userResolvers : Seq [ Resolver ] ) : Seq [ Resolver ] =
withDefaultResolvers ( userResolvers , true )
2010-02-07 01:23:06 +01:00
/* * Add the local Ivy and Maven Central repositories to the user repositories. If `scalaTools` is true, add the Scala Tools releases repository as well. */
2009-08-16 20:29:08 +02:00
def withDefaultResolvers ( userResolvers : Seq [ Resolver ] , scalaTools : Boolean ) : Seq [ Resolver ] =
withDefaultResolvers ( userResolvers , true , scalaTools )
2010-02-07 01:23:06 +01:00
/* * Add the local Ivy repository to the user repositories.
* If `scalaTools` is true , add the Scala Tools releases repository .
* If `mavenCentral` is true , add the Maven Central repository . */
2009-08-16 20:29:08 +02:00
def withDefaultResolvers ( userResolvers : Seq [ Resolver ] , mavenCentral : Boolean , scalaTools : Boolean ) : Seq [ Resolver ] =
2011-03-12 16:28:53 +01:00
Seq ( Resolver . defaultLocal ) ++
2009-08-16 20:29:08 +02:00
userResolvers ++
single ( DefaultMavenRepository , mavenCentral ) ++
single ( ScalaToolsReleases , scalaTools )
private def single [ T ] ( value : T , nonEmpty : Boolean ) : Seq [ T ] = if ( nonEmpty ) Seq ( value ) else Nil
/* * A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */
sealed abstract class Define [ RepositoryType <: SshBasedRepository ] extends NotNull
{
/* * Subclasses should implement this method to */
protected def construct ( name : String , connection : SshConnection , patterns : Patterns ) : RepositoryType
/* * Constructs this repository type with the given `name`. `basePatterns` are the initial patterns to use. A ManagedProject
* has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns . */
def apply ( name : String ) ( implicit basePatterns : Patterns ) : RepositoryType =
apply ( name , None , None , None )
/* * Constructs this repository type with the given `name` and `hostname`. `basePatterns` are the initial patterns to use.
* A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns . */
def apply ( name : String , hostname : String ) ( implicit basePatterns : Patterns ) : RepositoryType =
apply ( name , Some ( hostname ) , None , None )
/* * Constructs this repository type with the given `name`, `hostname`, and the `basePath` against which the initial
* patterns will be resolved . `basePatterns` are the initial patterns to use .
* A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns . */
def apply ( name : String , hostname : String , basePath : String ) ( implicit basePatterns : Patterns ) : RepositoryType =
apply ( name , Some ( hostname ) , None , Some ( basePath ) )
/* * Constructs this repository type with the given `name`, `hostname`, and `port`. `basePatterns` are the initial patterns to use.
* A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns . */
def apply ( name : String , hostname : String , port : Int ) ( implicit basePatterns : Patterns ) : RepositoryType =
apply ( name , Some ( hostname ) , Some ( port ) , None )
/* * Constructs this repository type with the given `name`, `hostname`, `port`, and the `basePath` against which the initial
* patterns will be resolved . `basePatterns` are the initial patterns to use .
* A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns . */
def apply ( name : String , hostname : String , port : Int , basePath : String ) ( implicit basePatterns : Patterns ) : RepositoryType =
apply ( name , Some ( hostname ) , Some ( port ) , Some ( basePath ) )
/* * Constructs this repository type with the given `name`, `hostname`, `port`, and the `basePath` against which the initial
* patterns will be resolved . `basePatterns` are the initial patterns to use . All but the `name` are optional ( use None ) .
* A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns . */
def apply ( name : String , hostname : Option [ String ] , port : Option [ Int ] , basePath : Option [ String ] ) ( implicit basePatterns : Patterns ) : RepositoryType =
construct ( name , SshConnection ( None , hostname , port ) , resolvePatterns ( basePath , basePatterns ) )
}
/* * A factory to construct an interface to an Ivy SSH resolver. */
object ssh extends Define [ SshRepository ]
{
protected def construct ( name : String , connection : SshConnection , patterns : Patterns ) = SshRepository ( name , connection , patterns , None )
}
/* * A factory to construct an interface to an Ivy SFTP resolver. */
object sftp extends Define [ SftpRepository ]
{
protected def construct ( name : String , connection : SshConnection , patterns : Patterns ) = SftpRepository ( name , connection , patterns )
}
/* * A factory to construct an interface to an Ivy filesytem resolver. */
object file
{
/* * Constructs a file resolver with the given name. The patterns to use must be explicitly specified
* using the `ivys` or `artifacts` methods on the constructed resolver object . */
2009-10-02 04:56:23 +02:00
def apply ( name : String ) : FileRepository = FileRepository ( name , defaultFileConfiguration , Patterns ( false ) )
2009-08-16 20:29:08 +02:00
/* * Constructs a file resolver with the given name and base directory. */
def apply ( name : String , baseDirectory : File ) ( implicit basePatterns : Patterns ) : FileRepository =
2009-10-02 04:56:23 +02:00
baseRepository ( new File ( baseDirectory . toURI . normalize ) getAbsolutePath ) ( FileRepository ( name , defaultFileConfiguration , _ ) )
2009-08-16 20:29:08 +02:00
}
object url
{
/* * Constructs a URL resolver with the given name. The patterns to use must be explicitly specified
* using the `ivys` or `artifacts` methods on the constructed resolver object . */
2009-10-02 04:56:23 +02:00
def apply ( name : String ) : URLRepository = URLRepository ( name , Patterns ( false ) )
2009-08-16 20:29:08 +02:00
/* * Constructs a file resolver with the given name and base directory. */
def apply ( name : String , baseURL : URL ) ( implicit basePatterns : Patterns ) : URLRepository =
2009-10-02 04:56:23 +02:00
baseRepository ( baseURL . toURI . normalize . toString ) ( URLRepository ( name , _ ) )
2009-08-16 20:29:08 +02:00
}
2009-10-02 04:56:23 +02:00
private def baseRepository [ T ] ( base : String ) ( construct : Patterns => T ) ( implicit basePatterns : Patterns ) : T =
construct ( resolvePatterns ( base , basePatterns ) )
2009-08-20 06:02:06 +02:00
2009-08-16 20:29:08 +02:00
/* * If `base` is None, `patterns` is returned unchanged.
* Otherwise , the ivy file and artifact patterns in `patterns` are resolved against the given base . */
private def resolvePatterns ( base : Option [ String ] , patterns : Patterns ) : Patterns =
base match
{
2009-10-02 04:56:23 +02:00
case Some ( path ) => resolvePatterns ( path , patterns )
2009-08-16 20:29:08 +02:00
case None => patterns
}
/* * Resolves the ivy file and artifact patterns in `patterns` against the given base. */
2009-10-02 04:56:23 +02:00
private def resolvePatterns ( base : String , basePatterns : Patterns ) : Patterns =
2009-08-16 20:29:08 +02:00
{
2009-10-02 04:56:23 +02:00
val normBase = base . replace ( '\\' , '/' )
def resolve ( pattern : String ) = if ( normBase . endsWith ( "/" ) || pattern . startsWith ( "/" ) ) normBase + pattern else normBase + "/" + pattern
2009-08-16 20:29:08 +02:00
def resolveAll ( patterns : Seq [ String ] ) = patterns . map ( resolve )
Patterns ( resolveAll ( basePatterns . ivyPatterns ) , resolveAll ( basePatterns . artifactPatterns ) , basePatterns . isMavenCompatible )
}
2009-10-02 04:56:23 +02:00
2009-08-16 20:29:08 +02:00
def defaultFileConfiguration = FileConfiguration ( true , None )
def mavenStylePatterns = Patterns ( Nil , mavenStyleBasePattern : : Nil , true )
2010-01-10 22:47:38 +01:00
def ivyStylePatterns = defaultIvyPatterns //Patterns(Nil, Nil, false)
2009-08-16 20:29:08 +02:00
def defaultPatterns = mavenStylePatterns
2011-07-24 05:07:54 +02:00
def mavenStyleBasePattern = "[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]/[artifact]-[revision](-[classifier]).[ext]"
def localBasePattern = "[organisation]/[module]/" + PluginPattern + "[revision]/[type]s/[artifact](-[classifier]).[ext]"
def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]"
final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)"
2009-08-20 06:02:06 +02:00
2011-07-20 03:29:05 +02:00
def mavenLocal = MavenRepository ( "Maven2 Local" , ( new File ( Path . userHome , ".m2/repository/" ) ) . toURI . toURL . toExternalForm )
2011-03-12 16:28:53 +01:00
def defaultLocal = defaultUserFileRepository ( "local" )
def defaultShared = defaultUserFileRepository ( "shared" )
def defaultUserFileRepository ( id : String ) =
{
val pList = ( "${ivy.home}/" + id + "/" + localBasePattern ) : : Nil
FileRepository ( id , defaultFileConfiguration , Patterns ( pList , pList , false ) )
}
2009-08-16 20:29:08 +02:00
def defaultIvyPatterns =
{
val pList = List ( localBasePattern )
Patterns ( pList , pList , false )
}
}
object Configurations
{
def config ( name : String ) = new Configuration ( name )
2011-02-03 01:32:24 +01:00
def default : Seq [ Configuration ] = defaultMavenConfigurations
2011-06-15 01:32:36 +02:00
def defaultMavenConfigurations : Seq [ Configuration ] = Seq ( Compile , Runtime , Test , Provided , Optional )
def defaultInternal : Seq [ Configuration ] = Seq ( CompileInternal , RuntimeInternal , TestInternal )
def auxiliary : Seq [ Configuration ] = Seq ( Sources , Docs , Pom )
2011-06-23 01:17:10 +02:00
def names ( cs : Seq [ Configuration ] ) = cs . map ( _ . name )
2011-04-20 04:24:52 +02:00
lazy val RuntimeInternal = optionalInternal ( Runtime )
lazy val TestInternal = fullInternal ( Test )
lazy val IntegrationTestInternal = fullInternal ( IntegrationTest )
lazy val CompileInternal = fullInternal ( Compile )
def internalMap ( c : Configuration ) = c match {
case Compile => CompileInternal
case Test => TestInternal
case Runtime => RuntimeInternal
case IntegrationTest => IntegrationTestInternal
case _ => c
}
def internal ( base : Configuration , ext : Configuration * ) = config ( base . name + "-internal" ) extend ( ext : _ * ) hide ;
def fullInternal ( base : Configuration ) : Configuration = internal ( base , base , Optional , Provided )
def optionalInternal ( base : Configuration ) : Configuration = internal ( base , base , Optional )
2009-08-20 06:02:06 +02:00
2009-08-16 20:29:08 +02:00
lazy val Default = config ( "default" )
lazy val Compile = config ( "compile" )
2011-06-10 13:48:53 +02:00
lazy val IntegrationTest = config ( "it" ) extend ( Runtime )
2011-07-03 21:44:53 +02:00
lazy val Provided = config ( "provided" ) ;
2011-06-15 01:32:36 +02:00
lazy val Docs = config ( "docs" )
2010-11-14 02:21:06 +01:00
lazy val Runtime = config ( "runtime" ) extend ( Compile )
2011-06-10 13:48:53 +02:00
lazy val Test = config ( "test" ) extend ( Runtime )
2009-08-16 20:29:08 +02:00
lazy val Sources = config ( "sources" )
lazy val System = config ( "system" )
lazy val Optional = config ( "optional" )
2011-06-15 01:32:36 +02:00
lazy val Pom = config ( "pom" )
2009-08-16 20:29:08 +02:00
lazy val CompilerPlugin = config ( "plugin" ) hide
2009-08-20 06:02:06 +02:00
2010-01-16 01:05:23 +01:00
private [ sbt ] val DefaultMavenConfiguration = defaultConfiguration ( true )
private [ sbt ] val DefaultIvyConfiguration = defaultConfiguration ( false )
private [ sbt ] def DefaultConfiguration ( mavenStyle : Boolean ) = if ( mavenStyle ) DefaultMavenConfiguration else DefaultIvyConfiguration
private [ sbt ] def defaultConfiguration ( mavenStyle : Boolean ) = if ( mavenStyle ) Configurations . Compile else Configurations . Default
private [ sbt ] def removeDuplicates ( configs : Iterable [ Configuration ] ) = Set ( scala . collection . mutable . Map ( configs . map ( config => ( config . name , config ) ) . toSeq : _ * ) . values . toList : _ * )
2009-08-16 20:29:08 +02:00
}
/* * Represents an Ivy configuration. */
2010-11-14 02:21:06 +01:00
final case class Configuration ( name : String , description : String , isPublic : Boolean , extendsConfigs : List [ Configuration ] , transitive : Boolean )
2009-08-16 20:29:08 +02:00
{
require ( name != null && ! name . isEmpty )
require ( description != null )
def this ( name : String ) = this ( name , "" , true , Nil , true )
def describedAs ( newDescription : String ) = Configuration ( name , newDescription , isPublic , extendsConfigs , transitive )
def extend ( configs : Configuration * ) = Configuration ( name , description , isPublic , configs . toList : :: extendsConfigs , transitive )
def notTransitive = intransitive
def intransitive = Configuration ( name , description , isPublic , extendsConfigs , false )
def hide = Configuration ( name , description , false , extendsConfigs , transitive )
override def toString = name
}
2010-11-14 02:21:06 +01:00
final case class Artifact ( name : String , `type` : String , extension : String , classifier : Option [ String ] , configurations : Iterable [ Configuration ] , url : Option [ URL ] , extraAttributes : Map [ String ,String ] )
2009-09-09 05:13:30 +02:00
{
2010-04-24 00:50:47 +02:00
def extra ( attributes : ( String , String ) * ) = Artifact ( name , `type` , extension , classifier , configurations , url , extraAttributes ++ ModuleID . checkE ( attributes ) )
2009-09-09 05:13:30 +02:00
}
2011-06-15 01:32:36 +02:00
import Configurations. { config , Docs , Optional , Pom , Sources }
2009-08-16 20:29:08 +02:00
object Artifact
{
def apply ( name : String ) : Artifact = Artifact ( name , defaultType , defaultExtension , None , Nil , None )
2009-09-09 05:13:30 +02:00
def apply ( name : String , extra : Map [ String ,String ] ) : Artifact = Artifact ( name , defaultType , defaultExtension , None , Nil , None , extra )
2009-08-16 20:29:08 +02:00
def apply ( name : String , classifier : String ) : Artifact = Artifact ( name , defaultType , defaultExtension , Some ( classifier ) , Nil , None )
def apply ( name : String , `type` : String , extension : String ) : Artifact = Artifact ( name , `type` , extension , None , Nil , None )
2009-10-02 04:56:23 +02:00
def apply ( name : String , `type` : String , extension : String , classifier : String ) : Artifact = Artifact ( name , `type` , extension , Some ( classifier ) , Nil , None )
2009-08-16 20:29:08 +02:00
def apply ( name : String , url : URL ) : Artifact = Artifact ( name , extract ( url , defaultType ) , extract ( url , defaultExtension ) , None , Nil , Some ( url ) )
2009-09-09 05:13:30 +02:00
def apply ( name : String , `type` : String , extension : String , classifier : Option [ String ] , configurations : Iterable [ Configuration ] , url : Option [ URL ] ) : Artifact =
Artifact ( name , `type` , extension , classifier , configurations , url , Map . empty )
2011-06-15 01:32:36 +02:00
2009-08-16 20:29:08 +02:00
val defaultExtension = "jar"
val defaultType = "jar"
2011-06-15 01:32:36 +02:00
2011-06-12 02:09:15 +02:00
def sources ( name : String ) = classified ( name , SourceClassifier )
def javadoc ( name : String ) = classified ( name , DocClassifier )
2011-06-15 01:32:36 +02:00
def pom ( name : String ) = Artifact ( name , PomType , PomType , None , Pom : : Nil , None )
2011-06-12 02:09:15 +02:00
val DocClassifier = "javadoc"
val SourceClassifier = "sources"
2011-06-15 01:32:36 +02:00
val PomType = "pom"
2009-08-20 06:02:06 +02:00
def extract ( url : URL , default : String ) : String = extract ( url . toString , default )
def extract ( name : String , default : String ) : String =
2009-08-16 20:29:08 +02:00
{
2009-08-18 06:51:08 +02:00
val i = name . lastIndexOf ( '.' )
2009-08-16 20:29:08 +02:00
if ( i >= 0 )
2009-08-18 06:51:08 +02:00
name . substring ( i + 1 )
2009-08-16 20:29:08 +02:00
else
default
}
2009-08-18 06:51:08 +02:00
def defaultArtifact ( file : File ) =
{
val name = file . getName
val i = name . lastIndexOf ( '.' )
val base = if ( i >= 0 ) name . substring ( 0 , i ) else name
2011-02-12 02:09:42 +01:00
Artifact ( base , extract ( name , defaultType ) , extract ( name , defaultExtension ) , None , Nil , Some ( file . toURI . toURL ) )
2009-08-18 06:51:08 +02:00
}
2011-04-16 01:55:22 +02:00
def artifactName ( scalaVersion : String , module : ModuleID , artifact : Artifact ) : String =
2011-04-14 13:32:42 +02:00
{
import artifact._
val classifierStr = classifier match { case None => "" ; case Some ( c ) => "-" + c }
2011-04-16 01:55:22 +02:00
val base = if ( module . crossVersion ) IvySbt . crossName ( artifact . name , scalaVersion ) else artifact . name
base + "-" + module . revision + classifierStr + "." + artifact . extension
2011-04-14 13:32:42 +02:00
}
2011-04-16 01:55:22 +02:00
def cross ( enable : Boolean , scalaVersion : String ) : String = if ( enable ) "_" + scalaVersion else ""
2011-06-12 02:09:15 +02:00
2011-06-15 01:32:36 +02:00
val classifierConfMap = Map ( SourceClassifier -> Sources , DocClassifier -> Docs )
val classifierTypeMap = Map ( SourceClassifier -> "src" , DocClassifier -> "doc" )
def classifierConf ( classifier : String ) : Configuration = classifierConfMap . getOrElse ( classifier , Optional )
2011-06-13 03:32:52 +02:00
def classifierType ( classifier : String ) : String = classifierTypeMap . getOrElse ( classifier , defaultType )
2011-06-15 01:32:36 +02:00
def classified ( name : String , classifier : String ) : Artifact =
Artifact ( name , classifierType ( classifier ) , defaultExtension , Some ( classifier ) , classifierConf ( classifier ) : : Nil , None )
2009-08-16 20:29:08 +02:00
}
2010-10-26 23:59:24 +02:00
final case class ModuleConfiguration ( organization : String , name : String , revision : String , resolver : Resolver )
2009-09-27 20:39:26 +02:00
object ModuleConfiguration
{
def apply ( org : String , resolver : Resolver ) : ModuleConfiguration = apply ( org , "*" , "*" , resolver )
def apply ( org : String , name : String , resolver : Resolver ) : ModuleConfiguration = ModuleConfiguration ( org , name , "*" , resolver )
2010-07-15 01:24:50 +02:00
}