diff options
author | Christopher Vogt <oss.nsp@cvogt.org> | 2016-02-06 13:03:36 -0500 |
---|---|---|
committer | Christopher Vogt <oss.nsp@cvogt.org> | 2016-03-04 15:06:30 -0500 |
commit | 974942db43ff2d1fa7ba71ad60f9bb9eae2d8631 (patch) | |
tree | d7235df9d4d6a67753dc2a20ab6bfcb7a24dc74c /stage2/DefaultBuild.scala | |
download | cbt-974942db43ff2d1fa7ba71ad60f9bb9eae2d8631.tar.gz cbt-974942db43ff2d1fa7ba71ad60f9bb9eae2d8631.tar.bz2 cbt-974942db43ff2d1fa7ba71ad60f9bb9eae2d8631.zip |
CBT Version 1.0-BETA
Diffstat (limited to 'stage2/DefaultBuild.scala')
-rw-r--r-- | stage2/DefaultBuild.scala | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/stage2/DefaultBuild.scala b/stage2/DefaultBuild.scala new file mode 100644 index 0000000..c0072ff --- /dev/null +++ b/stage2/DefaultBuild.scala @@ -0,0 +1,233 @@ +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 => _,_} + + + + +abstract class PackageBuild(context: Context) extends Build(context) with ArtifactInfo{ + def `package`: Seq[File] = lib.concurrently( enableConcurrency )( + Seq(() => jar, () => docJar, () => srcJar) + )( _() ) + + private object cacheJarBasicBuild extends Cache[File] + def jar: File = cacheJarBasicBuild{ + lib.jar( artifactId, version, compile, jarTarget ) + } + + private object cacheSrcJarBasicBuild extends Cache[File] + def srcJar: File = cacheSrcJarBasicBuild{ + lib.srcJar(sources, artifactId, version, scalaTarget) + } + + private object cacheDocBasicBuild extends Cache[File] + def docJar: File = cacheDocBasicBuild{ + lib.docJar( sources, dependencyClasspath, apiTarget, jarTarget, artifactId, version, scalacOptions ) + } + + override def jars = jar +: dependencyJars + override def exportedJars: Seq[File] = Seq(jar) +} +abstract class PublishBuild(context: Context) extends PackageBuild(context){ + def name = artifactId + def description: String + def url: URL + def developers: Seq[Developer] + def licenses: Seq[License] + def scmUrl: String + def scmConnection: String + def pomExtra: Seq[scala.xml.Node] = Seq() + + // ========== package ========== + + /** put additional xml that should go into the POM file in here */ + def pom: File = lib.pom( + groupId = groupId, + artifactId = artifactId, + version = version, + name = name, + description = description, + url = url, + developers = developers, + licenses = licenses, + scmUrl = scmUrl, + scmConnection = scmConnection, + dependencies = dependencies, + pomExtra = pomExtra, + jarTarget = jarTarget + ) + + // ========== publish ========== + final protected def releaseFolder = s"/${groupId.replace(".","/")}/$artifactId/$version/" + def snapshotUrl = new URL("https://oss.sonatype.org/content/repositories/snapshots") + def releaseUrl = new URL("https://oss.sonatype.org/service/local/staging/deploy/maven2") + def publishSnapshot: Unit = lib.publishSnapshot(sourceFiles, pom +: `package`, new URL(snapshotUrl + releaseFolder) ) + def publishSigned: Unit = lib.publishSigned(sourceFiles, pom +: `package`, new URL(releaseUrl + releaseFolder) ) +} + + +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 = new File(context.cwd) + assert( projectDirectory.exists, "projectDirectory does not exist: "+projectDirectory ) + 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 = new File(projectDirectory+"/src/") + + /** base directory where stuff should be generated */ + def target = new File(projectDirectory+"/target") + /** base directory where stuff should be generated for this scala version*/ + def scalaTarget = new File(target + s"/scala-$scalaMajorVersion") + /** directory where jars (and the pom file) should be put */ + def jarTarget = scalaTarget + /** directory where the scaladoc should be put */ + def apiTarget = new File(scalaTarget + "/api") + /** directory where the class files should be put (in package directories) */ + def compileTarget = new 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: String) = 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/") + .map(new File(_)) + .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: Unit = lib.runMainIfFound( runClass, Seq(), classLoader ) + + def test: Unit = lib.test(context) + + context.logger.composition(">"*80) + context.logger.composition("class "+this.getClass) + context.logger.composition("dir "+context.cwd) + context.logger.composition("sources "+sources.toList.mkString(" ")) + context.logger.composition("target "+target) + 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+")" +} |