aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--stage1/Stage1Lib.scala20
-rw-r--r--stage1/cbt.scala8
-rw-r--r--stage1/resolver.scala1
-rw-r--r--stage2/Lib.scala54
-rw-r--r--stage2/PackageJars.scala2
5 files changed, 60 insertions, 25 deletions
diff --git a/stage1/Stage1Lib.scala b/stage1/Stage1Lib.scala
index 83febe8..565a06c 100644
--- a/stage1/Stage1Lib.scala
+++ b/stage1/Stage1Lib.scala
@@ -184,8 +184,9 @@ class Stage1Lib( logger: Logger ) extends BaseLib{
val arrayClass = classOf[Array[String]]
val unitClass = classOf[Unit]
- iterateClasses( classesRootDirectory, classLoader, true ).filter(
- _.getDeclaredMethods().exists( m =>
+ iterateClasses( classesRootDirectory, classLoader, true ).filter( c =>
+ !c.isInterface &&
+ c.getDeclaredMethods().exists( m =>
m.getName == "main"
&& m.getParameterTypes.toList == List(arrayClass)
&& m.getReturnType == unitClass
@@ -481,6 +482,21 @@ ${sourceFiles.sorted.mkString(" \\\n")}
StandardOpenOption.APPEND
)
}
+ def cached[T]( targetDirectory: File, inputLastModified: Long )( action: () => T ): (Option[T],Long) = {
+ val t = targetDirectory
+ val start = System.currentTimeMillis
+ def lastSucceeded = t.lastModified
+ def outputLastModified = t.listRecursive.diff(t :: Nil).map(_.lastModified).maxOption.getOrElse(0l)
+ def updateSucceeded(time: Long) = Files.setLastModifiedTime( t.toPath, FileTime.fromMillis(time) )
+ (
+ ( inputLastModified >= lastSucceeded ).option{
+ val result: T = action()
+ updateSucceeded( start )
+ result
+ },
+ outputLastModified
+ )
+ }
}
import scala.reflect._
diff --git a/stage1/cbt.scala b/stage1/cbt.scala
index cb6cb10..b97ad44 100644
--- a/stage1/cbt.scala
+++ b/stage1/cbt.scala
@@ -20,6 +20,13 @@ object `package`{
private val lib = new BaseLib
+ implicit class CbtBooleanExtensions(condition: Boolean){
+ def option[T](value: =>T): Option[T] = if(condition) Some(value) else None
+ }
+ implicit class CbtStringExtensions(string: String){
+ def escape = string.replace("\\","\\\\").replace("\"","\\\"")
+ def quote = s""""$escape""""
+ }
implicit class PathExtensionMethods( path: Path ){
def /(s: String): Path = path.resolve(s)
def ++( s: String ): Path = {
@@ -64,6 +71,7 @@ object `package`{
def lastModifiedRecursive = listRecursive.map(_.lastModified).max
def readAsString = new String( readAllBytes( file.toPath ) )
+ def quote = s"new _root_.java.io.File(${string.quote})"
}
implicit class URLExtensionMethods( url: URL ){
def ++( s: String ): URL = new URL( url.toString ++ s )
diff --git a/stage1/resolver.scala b/stage1/resolver.scala
index 105177e..47d4460 100644
--- a/stage1/resolver.scala
+++ b/stage1/resolver.scala
@@ -172,6 +172,7 @@ case class Dependencies( dependencies: Seq[Dependency] )(implicit val logger: Lo
case class PostBuildDependency(target: File, _dependencies: Seq[DependencyImplementation])(implicit val logger: Logger, val transientCache: java.util.Map[AnyRef,AnyRef], val classLoaderCache: ClassLoaderCache) extends DependencyImplementation{
override final lazy val lastModified = (target++".last-success").lastModified
def moduleKey = target.string
+ override def show = s"PostBuildDependency($target)"
override def targetClasspath = exportedClasspath
override def exportedClasspath = ClassPath( Seq(target) )
override def dependencies = _dependencies
diff --git a/stage2/Lib.scala b/stage2/Lib.scala
index d5a964a..1c34c9c 100644
--- a/stage2/Lib.scala
+++ b/stage2/Lib.scala
@@ -283,7 +283,35 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){
m
}
- def createJar( jarFile: File, files: Seq[File], baseDirectory: Option[File] = None, mainClass: Option[String] = None ): Option[File] = {
+ def autoRelative( files: Seq[File], collector: PartialFunction[(File,String), String] = { case (_,r) => r }): Seq[(File, String)] = {
+ val map = files.sorted.flatMap{ base =>
+ val b = base.getCanonicalFile.string
+ if( base.isDirectory ){
+ base.listRecursive.map{ f =>
+ f -> f.getCanonicalFile.string.stripPrefix(b).stripPrefix(File.separator)
+ }
+ } else {
+ Seq( base -> base.getName )
+ }
+ }.collect{
+ case v@(file, _) if collector.isDefinedAt(v) => file -> collector(v)
+ }
+ val relatives = map.unzip._2
+ val duplicateFiles = (relatives diff relatives.distinct).distinct
+ assert(
+ duplicateFiles.isEmpty,
+ {
+ val rs = relatives.toSet
+ "Conflicting:\n\n" +
+ map.filter(rs contains _._2).groupBy(_._2).mapValues(_.map(_._1).sorted).toSeq.sortBy(_._1).map{
+ case (name, files) => s"$name:\n" ++ files.mkString("\n")
+ }.mkString("\n\n")
+ }
+ )
+ map
+ }
+
+ def createJar( jarFile: File, files: Seq[File], mainClass: Option[String] = None ): Option[File] = {
deleteIfExists(jarFile.toPath)
if( files.isEmpty ){
None
@@ -293,32 +321,14 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){
val jar = new JarOutputStream(new FileOutputStream(jarFile), createManifest(mainClass))
try{
assert( files.forall(_.exists) )
- val names = for {
- base <- files.map(realpath)
- file <- base.listRecursive if file.isFile
- } yield {
- val name = {
- Some(base).filter(_.isDirectory) orElse baseDirectory map (_.string) map (
- file.string stripPrefix _ stripPrefix File.separator
- ) getOrElse (
- throw new Exception(
- "Trying to add absolute path to jar: " + file
- )
- )
- }
- val entry = new JarEntry( name )
+ autoRelative(files).collect{
+ case (file, relative) if file.isFile =>
+ val entry = new JarEntry( relative )
entry.setTime(file.lastModified)
jar.putNextEntry(entry)
jar.write( readAllBytes( file.toPath ) )
jar.closeEntry
- name
}
-
- val duplicateFiles = (names diff names.distinct).distinct
- assert(
- duplicateFiles.isEmpty,
- s"Conflicting file names when trying to create $jarFile: "++duplicateFiles.mkString(", ")
- )
} finally {
jar.close
}
diff --git a/stage2/PackageJars.scala b/stage2/PackageJars.scala
index 910741d..221920b 100644
--- a/stage2/PackageJars.scala
+++ b/stage2/PackageJars.scala
@@ -18,7 +18,7 @@ trait PackageJars extends BaseBuild with ArtifactInfo{
def srcJar: Option[File] = taskCache[PackageJars]("srcJar").memoize{
lib.createJar(
- jarTarget / jarFilePrefix++"-sources.jar", nonEmptySourceFiles, Some(projectDirectory)
+ jarTarget / jarFilePrefix++"-sources.jar", nonEmptySourceFiles
)
}