aboutsummaryrefslogblamecommitdiff
path: root/stage2/BasicBuild.scala
blob: f785f01907d3aa2cf11e7e98cf60ac0240672ba3 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11



                  






                                       

                   
                                                             
                                                                                            
                                
                                                    
                                                                                  
                                       
                                                         
 
                                        
 
                                  
                               
                                                                           
                                                                                                   
                                                             
 


                                                   
                                                                           


                                          


                                                       
   
 
                                
                                                                       

                                                       
                                                  
                                                                             
                                                                
                                                              
                                   
                                                   
                                             
                                                                               
                                                     





                                                                                    



                                                                                                                      
                                                           






                                                                                                                 
 






                                                   
                                                                 



                           




                                                                                                   
                                                              
                                                         


                                                                                                                                  
 
                                       
                                   







                                                                                                  
                                                                   
                                                     





                                                                                  
                                                        


                                                        

                                                   
 

                                                         
                


                                                                                        



                               
                                                                                                         
 
                                        

                                    
                                                                  
                                                                   



                                                                        



                                        
                                                                                          
 
package cbt
import cbt.paths._

import java.io._
import java.net._
import java.nio.file.{Path =>_,_}
import java.nio.file.Files.readAllBytes
import java.security.MessageDigest
import java.util.jar._

import scala.collection.immutable.Seq
import scala.util._

class BasicBuild( context: Context ) extends Build( context )
class Build(val context: Context) extends Dependency with TriggerLoop with SbtDependencyDsl{
  // library available to builds
  implicit final val logger: Logger = context.logger
  implicit final val classLoaderCache: ClassLoaderCache = context.classLoaderCache
  implicit final val _context = context
  override final protected val lib: Lib = new Lib(logger)

  // ========== general stuff ==========

  override def canBeCached = false
  def enableConcurrency = false
  final def projectDirectory: File = lib.realpath(context.projectDirectory)
  assert( projectDirectory.exists, "projectDirectory does not exist: " ++ projectDirectory.string )
  final def usage: String = lib.usage(this.getClass, context)

  // ========== meta data ==========

  def scalaVersion: String = constants.scalaVersion
  final def scalaMajorVersion: String = lib.scalaMajorVersion(scalaVersion)
  def zincVersion = "0.3.9"

  def dependencies: Seq[Dependency] = Seq(
    MavenRepository.central.resolve(
      "org.scala-lang" % "scala-library" % scalaVersion
    )
  )

  // ========== paths ==========
  final private val defaultSourceDirectory = projectDirectory ++ "/src"

  /** base directory where stuff should be generated */
  def target: File = projectDirectory ++ "/target"
  /** base directory where stuff should be generated for this scala version*/
  def scalaTarget: File = target ++ s"/scala-$scalaMajorVersion"
  /** directory where jars (and the pom file) should be put */
  def jarTarget: File = scalaTarget
  /** directory where the scaladoc should be put */
  def apiTarget: File = scalaTarget ++ "/api"
  /** directory where the class files should be put (in package directories) */
  def compileTarget: File = scalaTarget ++ "/classes"
  /**
  File which cbt uses to determine if it needs to trigger an incremental re-compile.
  Last modified date is the time when the last successful compilation started.
  Contents is the cbt version git hash.
  */
  def compileStatusFile: File = compileTarget ++ ".last-success"

  /** Source directories and files. Defaults to .scala and .java files in src/ and top-level. */
  def sources: Seq[File] = Seq(defaultSourceDirectory) ++ projectDirectory.listFiles.toVector.filter(sourceFileFilter)

  /** Which file endings to consider being source files. */
  def sourceFileFilter(file: File): Boolean = file.toString.endsWith(".scala") || file.toString.endsWith(".java")

  /** Absolute path names for all individual files found in sources directly or contained in directories. */
  final def sourceFiles: Seq[File] = for {
    base <- sources.filter(_.exists).map(lib.realpath)
    file <- lib.listFilesRecursive(base) if file.isFile && sourceFileFilter(file)
  } yield file

  protected def assertSourceDirectories(): Unit = {
    val nonExisting =
      sources
        .filterNot( _.exists )
        .diff( Seq(defaultSourceDirectory) )
    assert(
      nonExisting.isEmpty,
      "Some sources do not exist: \n"++nonExisting.mkString("\n")
    )
  }
  assertSourceDirectories()

  def ScalaDependency(
    groupId: String, artifactId: String, version: String, classifier: Classifier = Classifier.none,
    scalaVersion: String = scalaMajorVersion
  ) = lib.ScalaDependency( groupId, artifactId, version, classifier, scalaVersion )

  final def BuildDependency(path: File) = cbt.BuildDependency(
    context.copy( projectDirectory = path, args = Seq() )
  )

  def triggerLoopFiles: Seq[File] = sources ++ transitiveDependencies.collect{ case b: TriggerLoop => b.triggerLoopFiles }.flatten

  def localJars           : Seq[File] =
    Seq(projectDirectory ++ "/lib")
      .filter(_.exists)
      .flatMap(_.listFiles)
      .filter(_.toString.endsWith(".jar"))

  //def cacheJar = false
  override def dependencyClasspath : ClassPath = ClassPath(localJars) ++ super.dependencyClasspath
  override def dependencyJars      : Seq[File] = localJars ++ super.dependencyJars

  def exportedClasspath   : ClassPath = ClassPath(compile.toSeq:_*)
  def targetClasspath = ClassPath(Seq(compileTarget))
  def exportedJars: Seq[File] = Seq()
  // ========== compile, run, test ==========

  /** scalac options used for zinc and scaladoc */
  def scalacOptions: Seq[String] = Seq( "-feature", "-deprecation", "-unchecked" )

  private object needsUpdateCache extends Cache[Boolean]
  def needsUpdate: Boolean = needsUpdateCache(
    context.cbtHasChanged
    || lib.needsUpdate( sourceFiles, compileStatusFile )
    || transitiveDependencies.exists(_.needsUpdate)
  )

  private object compileCache extends Cache[Option[File]]
  def compile: Option[File] = compileCache{
    lib.compile(
      needsUpdate,
      sourceFiles, compileTarget, compileStatusFile, dependencyClasspath, scalacOptions,
      context.classLoaderCache, zincVersion = zincVersion, scalaVersion = scalaVersion
    )
  }

  def runClass: String = "Main"
  def run: ExitCode = lib.runMainIfFound( runClass, context.args, classLoader(context.classLoaderCache) )

  def test: ExitCode = lib.test(context)

  context.logger.composition(">"*80)
  context.logger.composition("class   " ++ this.getClass.toString)
  context.logger.composition("dir     " ++ projectDirectory.string)
  context.logger.composition("sources " ++ sources.toList.mkString(" "))
  context.logger.composition("target  " ++ target.string)
  context.logger.composition("context " ++ context.toString)
  context.logger.composition("dependencyTree\n" ++ dependencyTree)
  context.logger.composition("<"*80)

  // ========== cbt internals ==========
  private[cbt] def finalBuild = this
  override def show = this.getClass.getSimpleName ++ "(" ++ projectDirectory.string ++ ")"
}