diff options
-rw-r--r-- | stage1/Stage1Lib.scala | 104 | ||||
-rw-r--r-- | stage2/BasicBuild.scala | 6 | ||||
-rw-r--r-- | stage2/Lib.scala | 98 | ||||
-rw-r--r-- | stage2/PackageBuild.scala | 20 |
4 files changed, 122 insertions, 106 deletions
diff --git a/stage1/Stage1Lib.scala b/stage1/Stage1Lib.scala index e4fe15e..105fe3e 100644 --- a/stage1/Stage1Lib.scala +++ b/stage1/Stage1Lib.scala @@ -127,64 +127,66 @@ class Stage1Lib( val logger: Logger ) extends BaseLib{ classLoaderCache: ClassLoaderCache, zincVersion: String, scalaVersion: String - ): File = { + ): Option[File] = { val cp = classpath.string if(classpath.files.isEmpty) throw new Exception("Trying to compile with empty classpath. Source files: " ++ files.toString) - if(files.isEmpty) - throw new Exception("Trying to compile no files. ClassPath: " ++ cp) - if( needsRecompile ){ - val zinc = JavaDependency("com.typesafe.zinc","zinc", zincVersion) - val zincDeps = zinc.transitiveDependencies - - val sbtInterface = - zincDeps - .collect{ case d @ JavaDependency( "com.typesafe.sbt", "sbt-interface", _, Classifier.none ) => d } - .headOption - .getOrElse( throw new Exception(s"cannot find sbt-interface in zinc $zincVersion dependencies: "++zincDeps.toString) ) - .jar - - val compilerInterface = - zincDeps - .collect{ case d @ JavaDependency( "com.typesafe.sbt", "compiler-interface", _, Classifier.sources ) => d } - .headOption - .getOrElse( throw new Exception(s"cannot find compiler-interface in zinc $zincVersion dependencies: "++zincDeps.toString) ) - .jar - - val scalaLibrary = JavaDependency("org.scala-lang","scala-library",scalaVersion).jar - val scalaReflect = JavaDependency("org.scala-lang","scala-reflect",scalaVersion).jar - val scalaCompiler = JavaDependency("org.scala-lang","scala-compiler",scalaVersion).jar - - val start = System.currentTimeMillis - - val code = redirectOutToErr{ - lib.runMain( - "com.typesafe.zinc.Main", - Seq( - "-scala-compiler", scalaCompiler.toString, - "-scala-library", scalaLibrary.toString, - "-sbt-interface", sbtInterface.toString, - "-compiler-interface", compilerInterface.toString, - "-scala-extra", scalaReflect.toString, - "-cp", cp, - "-d", compileTarget.toString - ) ++ scalacOptions.map("-S"++_) ++ files.map(_.toString), - zinc.classLoader(classLoaderCache) - ) - } - - if(code == ExitCode.Success){ - // write version and when last compilation started so we can trigger - // recompile if cbt version changed or newer source files are seen - Files.write(statusFile.toPath, "".getBytes)//cbtVersion.getBytes) - Files.setLastModifiedTime(statusFile.toPath, FileTime.fromMillis(start) ) - } else { - System.exit(code.integer) // FIXME: let's find a better solution for error handling. Maybe a monad after all. + if( files.isEmpty ){ + None + }else{ + if( needsRecompile ){ + val zinc = JavaDependency("com.typesafe.zinc","zinc", zincVersion) + val zincDeps = zinc.transitiveDependencies + + val sbtInterface = + zincDeps + .collect{ case d @ JavaDependency( "com.typesafe.sbt", "sbt-interface", _, Classifier.none ) => d } + .headOption + .getOrElse( throw new Exception(s"cannot find sbt-interface in zinc $zincVersion dependencies: "++zincDeps.toString) ) + .jar + + val compilerInterface = + zincDeps + .collect{ case d @ JavaDependency( "com.typesafe.sbt", "compiler-interface", _, Classifier.sources ) => d } + .headOption + .getOrElse( throw new Exception(s"cannot find compiler-interface in zinc $zincVersion dependencies: "++zincDeps.toString) ) + .jar + + val scalaLibrary = JavaDependency("org.scala-lang","scala-library",scalaVersion).jar + val scalaReflect = JavaDependency("org.scala-lang","scala-reflect",scalaVersion).jar + val scalaCompiler = JavaDependency("org.scala-lang","scala-compiler",scalaVersion).jar + + val start = System.currentTimeMillis + + val code = redirectOutToErr{ + lib.runMain( + "com.typesafe.zinc.Main", + Seq( + "-scala-compiler", scalaCompiler.toString, + "-scala-library", scalaLibrary.toString, + "-sbt-interface", sbtInterface.toString, + "-compiler-interface", compilerInterface.toString, + "-scala-extra", scalaReflect.toString, + "-cp", cp, + "-d", compileTarget.toString + ) ++ scalacOptions.map("-S"++_) ++ files.map(_.toString), + zinc.classLoader(classLoaderCache) + ) + } + + if(code == ExitCode.Success){ + // write version and when last compilation started so we can trigger + // recompile if cbt version changed or newer source files are seen + Files.write(statusFile.toPath, "".getBytes)//cbtVersion.getBytes) + Files.setLastModifiedTime(statusFile.toPath, FileTime.fromMillis(start) ) + } else { + System.exit(code.integer) // FIXME: let's find a better solution for error handling. Maybe a monad after all. + } } + Some( compileTarget ) } - compileTarget } def redirectOutToErr[T](code: => T): T = { val oldOut = System.out diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala index 27de538..9ed8c26 100644 --- a/stage2/BasicBuild.scala +++ b/stage2/BasicBuild.scala @@ -116,7 +116,7 @@ class Build(val context: Context) extends Dependency with TriggerLoop{ override def dependencyClasspath : ClassPath = ClassPath(localJars) ++ super.dependencyClasspath override def dependencyJars : Seq[File] = localJars ++ super.dependencyJars - def exportedClasspath : ClassPath = ClassPath(Seq(compile)) + def exportedClasspath : ClassPath = ClassPath(compile.toSeq:_*) def targetClasspath = ClassPath(Seq(compileTarget)) def exportedJars: Seq[File] = Seq() // ========== compile, run, test ========== @@ -132,8 +132,8 @@ class Build(val context: Context) extends Dependency with TriggerLoop{ ) } - private object compileCache extends Cache[File] - def compile: File = compileCache{ + private object compileCache extends Cache[Option[File]] + def compile: Option[File] = compileCache{ lib.compile( needsUpdate, sourceFiles, compileTarget, compileStatusFile, dependencyClasspath, scalacOptions, diff --git a/stage2/Lib.scala b/stage2/Lib.scala index fbbe870..dd4a12f 100644 --- a/stage2/Lib.scala +++ b/stage2/Lib.scala @@ -53,16 +53,18 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{ } } - def srcJar(sources: Seq[File], artifactId: String, version: String, jarTarget: File): File = { - val file = jarTarget ++ ("/"++artifactId++"-"++version++"-sources.jar") - lib.jarFile(file, sources) - file + def srcJar(sourceFiles: Seq[File], artifactId: String, version: String, jarTarget: File): Option[File] = { + lib.jarFile( + jarTarget ++ ("/"++artifactId++"-"++version++"-sources.jar"), + sourceFiles + ) } - def jar(artifactId: String, version: String, compileTarget: File, jarTarget: File): File = { - val file = jarTarget ++ ("/"++artifactId++"-"++version++".jar") - lib.jarFile(file, Seq(compileTarget)) - file + def jar(artifactId: String, version: String, compileTarget: File, jarTarget: File): Option[File] = { + lib.jarFile( + jarTarget ++ ("/"++artifactId++"-"++version++".jar"), + Seq(compileTarget) + ) } def docJar( @@ -75,9 +77,11 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{ version: String, compileArgs: Seq[String], classLoaderCache: ClassLoaderCache - ): File = { - apiTarget.mkdirs - if(sourceFiles.nonEmpty){ + ): Option[File] = { + if(sourceFiles.isEmpty){ + None + } else { + apiTarget.mkdirs val args = Seq( // FIXME: can we use compiler dependency here? "-cp", dependencyClasspath.string, // FIXME: does this break for builds that don't have scalac dependencies? @@ -91,10 +95,11 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{ ScalaDependencies(scalaVersion)(logger).classLoader(classLoaderCache) ) } + lib.jarFile( + jarTarget ++ ("/"++artifactId++"-"++version++"-javadoc.jar"), + Vector(apiTarget) + ) } - val docJar = jarTarget ++ ("/"++artifactId++"-"++version++"-javadoc.jar") - lib.jarFile(docJar, Vector(apiTarget)) - docJar } def test( context: Context ): ExitCode = { @@ -161,7 +166,10 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{ val ts = tasks(obj.getClass) taskName.map( NameTransformer.encode ).flatMap(ts.get).map{ method => val result: Option[Any] = Option(method.invoke(obj)) // null in case of Unit - result.map{ + result.flatMap{ + case v: Option[_] => v + case other => Some(other) + }.map{ value => // Try to render console representation. Probably not the best way to do this. scala.util.Try( value.getClass.getDeclaredMethod("toConsole") ) match { @@ -196,35 +204,41 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{ def dirname(path: File): File = new File(realpath(path).string.stripSuffix("/").split("/").dropRight(1).mkString("/")) def nameAndContents(file: File) = basename(file) -> readAllBytes(Paths.get(file.toString)) - def jarFile( jarFile: File, files: Seq[File] ): Unit = { - logger.lib("Start packaging "++jarFile.string) - val manifest = new Manifest - manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0") - val jar = new JarOutputStream(new FileOutputStream(jarFile.toString), manifest) - - val names = for { - base <- files.filter(_.exists).map(realpath) - file <- listFilesRecursive(base) if file.isFile - } yield { - val name = if(base.isDirectory){ - file.toString stripPrefix base.toString - } else file.toString - val entry = new JarEntry( name ) - entry.setTime(file.lastModified) - jar.putNextEntry(entry) - jar.write( readAllBytes( Paths.get(file.toString) ) ) - jar.closeEntry - name - } + def jarFile( jarFile: File, files: Seq[File] ): Option[File] = { + if( files.isEmpty ){ + None + } else { + logger.lib("Start packaging "++jarFile.string) + val manifest = new Manifest + manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0") + val jar = new JarOutputStream(new FileOutputStream(jarFile.toString), manifest) + + val names = for { + base <- files.filter(_.exists).map(realpath) + file <- listFilesRecursive(base) if file.isFile + } yield { + val name = if(base.isDirectory){ + file.toString stripPrefix base.toString + } else file.toString + val entry = new JarEntry( name ) + entry.setTime(file.lastModified) + jar.putNextEntry(entry) + jar.write( readAllBytes( Paths.get(file.toString) ) ) + jar.closeEntry + name + } - val duplicateFiles = (names diff names.distinct).distinct - assert( - duplicateFiles.isEmpty, - s"Conflicting file names when trying to create $jarFile: "++duplicateFiles.mkString(", ") - ) + val duplicateFiles = (names diff names.distinct).distinct + assert( + duplicateFiles.isEmpty, + s"Conflicting file names when trying to create $jarFile: "++duplicateFiles.mkString(", ") + ) + + jar.close + logger.lib("Done packaging " ++ jarFile.toString) - jar.close - logger.lib("Done packaging " ++ jarFile.toString) + Some(jarFile) + } } lazy val passphrase = diff --git a/stage2/PackageBuild.scala b/stage2/PackageBuild.scala index 8f6d185..79e54a7 100644 --- a/stage2/PackageBuild.scala +++ b/stage2/PackageBuild.scala @@ -4,23 +4,23 @@ import scala.collection.immutable.Seq abstract class PackageBuild(context: Context) extends BasicBuild(context) with ArtifactInfo{ def `package`: Seq[File] = lib.concurrently( enableConcurrency )( Seq(() => jar, () => docJar, () => srcJar) - )( _() ) + )( _() ).flatten - private object cacheJarBasicBuild extends Cache[File] - def jar: File = cacheJarBasicBuild{ - lib.jar( artifactId, version, compile, jarTarget ) + private object cacheJarBasicBuild extends Cache[Option[File]] + def jar: Option[File] = cacheJarBasicBuild{ + compile.flatMap( lib.jar( artifactId, version, _, jarTarget ) ) } - private object cacheSrcJarBasicBuild extends Cache[File] - def srcJar: File = cacheSrcJarBasicBuild{ + private object cacheSrcJarBasicBuild extends Cache[Option[File]] + def srcJar: Option[File] = cacheSrcJarBasicBuild{ lib.srcJar( sourceFiles, artifactId, version, scalaTarget ) } - private object cacheDocBasicBuild extends Cache[File] - def docJar: File = cacheDocBasicBuild{ + private object cacheDocBasicBuild extends Cache[Option[File]] + def docJar: Option[File] = cacheDocBasicBuild{ lib.docJar( scalaVersion, sourceFiles, dependencyClasspath, apiTarget, jarTarget, artifactId, version, scalacOptions, context.classLoaderCache ) } - override def jars = jar +: dependencyJars - override def exportedJars: Seq[File] = Seq(jar) + override def jars = jar.toVector ++ dependencyJars + override def exportedJars: Seq[File] = jar.toVector } |