diff options
author | Christopher Vogt <oss.nsp@cvogt.org> | 2016-03-07 01:36:40 -0500 |
---|---|---|
committer | Christopher Vogt <oss.nsp@cvogt.org> | 2016-03-07 01:36:40 -0500 |
commit | e958dec0dbbcf7f7a28cd21641e76390fb3dba6a (patch) | |
tree | ec0933e230b0c3f222fceb82b3eec177d56ea979 /stage2/BasicBuild.scala | |
parent | f0dc760df8757caea1d83b15142a3d0704488636 (diff) | |
download | cbt-e958dec0dbbcf7f7a28cd21641e76390fb3dba6a.tar.gz cbt-e958dec0dbbcf7f7a28cd21641e76390fb3dba6a.tar.bz2 cbt-e958dec0dbbcf7f7a28cd21641e76390fb3dba6a.zip |
cleanup: whitespace changes, separated more things into their own files, use ++ for strings everywhere. Added ++ method to File and URL and use it in many places
Diffstat (limited to 'stage2/BasicBuild.scala')
-rw-r--r-- | stage2/BasicBuild.scala | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala new file mode 100644 index 0000000..6da31b7 --- /dev/null +++ b/stage2/BasicBuild.scala @@ -0,0 +1,164 @@ +package cbt +import cbt.paths._ + +import java.io._ +import java.lang.reflect.InvocationTargetException +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.reflect.runtime.{universe => ru} +import scala.util._ + +import ammonite.ops.{cwd => _,_} + +class BasicBuild(context: Context) extends Build(context) +class Build(val context: Context) extends Dependency with TriggerLoop{ + // library available to builds + final val logger = context.logger + override final protected val lib: Lib = new Lib(logger) + + // ========== general stuff ========== + + def enableConcurrency = false + final def projectDirectory: File = context.cwd + assert( projectDirectory.exists, "projectDirectory does not exist: " ++ projectDirectory.string ) + final def usage: Unit = new lib.ReflectBuild(this).usage +/* + def scaffold: Unit = lib.generateBasicBuildFile( + projectDirectory, scalaVersion, groupId, artifactId, version + ) +*/ + // ========== meta data ========== + + def scalaVersion: String = constants.scalaVersion + final def scalaMajorVersion: String = scalaVersion.split("\\.").take(2).mkString(".") + def zincVersion = "0.3.9" + + def dependencies: Seq[Dependency] = Seq( + "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" + + /** 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() + + + /** SBT-like dependency builder DSL */ + class GroupIdAndArtifactId( groupId: String, artifactId: String ){ + def %(version: String) = new MavenDependency(groupId, artifactId, version)(lib.logger) + } + implicit class DependencyBuilder(groupId: String){ + def %%(artifactId: String) = new GroupIdAndArtifactId( groupId, artifactId++"_"++scalaMajorVersion ) + def %(artifactId: String) = new GroupIdAndArtifactId( groupId, artifactId ) + } + + final def BuildDependency(path: File) = cbt.BuildDependency( + context.copy( cwd = 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(Seq(compile)) + def exportedJars: Seq[File] = Seq() + // ========== compile, run, test ========== + + /** scalac options used for zinc and scaladoc */ + def scalacOptions: Seq[String] = Seq( "-feature", "-deprecation", "-unchecked" ) + + val updated: Boolean = { + val existingClassFiles = lib.listFilesRecursive(compileTarget) + val sourcesChanged = existingClassFiles.nonEmpty && { + val oldestClassFile = existingClassFiles.sortBy(_.lastModified).head + val oldestClassFileAge = oldestClassFile.lastModified + val changedSourceFiles = sourceFiles.filter(_.lastModified > oldestClassFileAge) + if(changedSourceFiles.nonEmpty){ + /* + println(changedSourceFiles) + println(changedSourceFiles.map(_.lastModified)) + println(changedSourceFiles.map(_.lastModified > oldestClassFileAge)) + println(oldestClassFile) + println(oldestClassFileAge) + println("-"*80) + */ + } + changedSourceFiles.nonEmpty + } + sourcesChanged || transitiveDependencies.map(_.updated).fold(false)(_ || _) + } + + private object cacheCompileBasicBuild extends Cache[File] + def compile: File = cacheCompileBasicBuild{ + //println(transitiveDependencies.filter(_.updated).mkString("\n")) + lib.compile( + updated, + sourceFiles, compileTarget, dependencyClasspath, scalacOptions, + zincVersion = zincVersion, scalaVersion = scalaVersion + ) + } + + def runClass: String = "Main" + def run: ExitCode = lib.runMainIfFound( runClass, context.args, classLoader ) + + def test: ExitCode = lib.test(context) + + context.logger.composition(">"*80) + context.logger.composition("class " ++ this.getClass.toString) + context.logger.composition("dir " ++ context.cwd.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 ++ "(" ++ context.cwd.string ++ ")" +} |