diff options
Diffstat (limited to 'stage1')
-rw-r--r-- | stage1/Stage1Lib.scala | 20 | ||||
-rw-r--r-- | stage1/URLClassLoader.scala | 4 | ||||
-rw-r--r-- | stage1/cbt.scala | 32 | ||||
-rw-r--r-- | stage1/logger.scala | 4 | ||||
-rw-r--r-- | stage1/resolver.scala | 23 |
5 files changed, 62 insertions, 21 deletions
diff --git a/stage1/Stage1Lib.scala b/stage1/Stage1Lib.scala index 7f8f600..71e6ee5 100644 --- a/stage1/Stage1Lib.scala +++ b/stage1/Stage1Lib.scala @@ -12,7 +12,10 @@ import java.util.{Set=>_,Map=>_,List=>_,_} import javax.xml.bind.annotation.adapters.HexBinaryAdapter // CLI interop -case class ExitCode(integer: Int) +case class ExitCode(integer: Int){ + def ||( other: => ExitCode ) = if( this == ExitCode.Success ) this else other + def &&( other: => ExitCode ) = if( this != ExitCode.Success ) this else other +} object ExitCode{ val Success = ExitCode(0) val Failure = ExitCode(1) @@ -71,7 +74,7 @@ class Stage1Lib( logger: Logger ) extends BaseLib{ try{ Files.copy(stream, incomplete, StandardCopyOption.REPLACE_EXISTING) } finally { - stream.close() + stream.close } sha1.foreach{ hash => @@ -86,17 +89,11 @@ class Stage1Lib( logger: Logger ) extends BaseLib{ } } - def listFilesRecursive(f: File): Seq[File] = { - f +: ( - if( f.isDirectory ) f.listFiles.flatMap(listFilesRecursive).toVector else Seq[File]() - ) - } - // ========== compilation / execution ========== def runMain( cls: String, args: Seq[String], classLoader: ClassLoader, fakeInstance: Boolean = false ): ExitCode = { import java.lang.reflect.Modifier - logger.lib(s"Running $cls.main($args) with classLoader: " ++ classLoader.toString) + logger.run(s"Running $cls.main($args) with classLoader: " ++ classLoader.toString) trapExitCode{ val c = classLoader.loadClass(cls) val m = c.getMethod( "main", classOf[Array[String]] ) @@ -149,7 +146,8 @@ class Stage1Lib( logger: Logger ) extends BaseLib{ /** Given a directory corresponding to the root package, iterate the names of all classes derived from the class files found */ def iterateClassNames( classesRootDirectory: File ): Seq[String] = - listFilesRecursive(classesRootDirectory) + classesRootDirectory + .listRecursive .filter(_.isFile) .map(_.getPath) .collect{ @@ -270,7 +268,7 @@ class Stage1Lib( logger: Logger ) extends BaseLib{ _class, dualArgs ++ singleArgs ++ ( if(cp.isEmpty) Nil else Seq("-cp", cp) - ) ++ sourceFiles.map(_.toString), + ) ++ sourceFiles.map(_.string), zinc.classLoader ) } catch { diff --git a/stage1/URLClassLoader.scala b/stage1/URLClassLoader.scala index ff8d2a1..e93b1a4 100644 --- a/stage1/URLClassLoader.scala +++ b/stage1/URLClassLoader.scala @@ -8,6 +8,10 @@ case class URLClassLoader( classPath: ClassPath, parent: ClassLoader )( implicit classPath.strings.map( p => new URL("file:" ++ p) ).toArray, parent ) with CachingClassLoader{ + override def loadClass(name: String) = { + logger.log("classloader","loadClass " + name) + super.loadClass(name) + } val id = Math.abs( new java.util.Random().nextInt ) override def toString = ( scala.Console.BLUE diff --git a/stage1/cbt.scala b/stage1/cbt.scala index 4caa085..bc0e944 100644 --- a/stage1/cbt.scala +++ b/stage1/cbt.scala @@ -28,6 +28,28 @@ object `package`{ def /(s: String): File = new File( file, s ) def parent = lib.realpath(file ++ "/..") def string = file.toString + /* recursively deletes folders*/ + def deleteRecursive: Unit = { + val s = file.string + // some desperate attempts to keep people from accidentally deleting their hard drive + assert( file == file.getCanonicalFile, "deleteRecursive requires previous .getCanonicalFile" ) + assert( file.isAbsolute, "deleteRecursive requires absolute path" ) + assert( file.string != "", "deleteRecursive requires non-empty file path" ) + assert( s.split("/").size > 4, "deleteRecursive requires absolute path of at least depth 4" ) + assert( s.split("\\").size > 4, "deleteRecursive requires absolute path of at least depth 4" ) + assert( !listRecursive.exists(_.isHidden), "deleteRecursive requires no files to be hidden" ) + assert( listRecursive.forall(_.canWrite), "deleteRecursive requires all files to be writable" ) + if( file.isDirectory ){ + file.listFiles.map(_.deleteRecursive) + } + //file.delete + } + + def listRecursive: Seq[File] = { + file +: ( + if( file.isDirectory ) file.listFiles.flatMap(_.listRecursive).toVector else Seq[File]() + ) + } } implicit class URLExtensionMethods( url: URL ){ def ++( s: String ): URL = new URL( url.toString ++ s ) @@ -38,6 +60,16 @@ object `package`{ case e:java.lang.UnsupportedOperationException if e.getMessage === "empty.max" => None } } + implicit class ClassLoaderExtensions(classLoader: ClassLoader){ + def canLoad(className: String) = { + try{ + classLoader.loadClass(className) + true + } catch { + case e: ClassNotFoundException => false + } + } + } implicit class BuildInterfaceExtensions(build: BuildInterface){ import build._ // TODO: if every build has a method triggers a callback if files change diff --git a/stage1/logger.scala b/stage1/logger.scala index 8c8431a..373a954 100644 --- a/stage1/logger.scala +++ b/stage1/logger.scala @@ -20,7 +20,7 @@ case class Logger(enabledLoggers: Set[String], start: Long) { def log(name: String, msg: => String) = { if( ( - (enabledLoggers contains name) + (enabledLoggers contains name) || (enabledLoggers contains "all") ) && !(disabledLoggers contains name) ){ @@ -41,6 +41,7 @@ case class Logger(enabledLoggers: Set[String], start: Long) { final def git(msg: => String) = log(names.git, msg) final def pom(msg: => String) = log(names.pom, msg) final def dynamic(msg: => String) = log(names.dynamic, msg) + final def run(msg: => String) = log(names.run, msg) final def transientCache(msg: => String) = log(names.transientCache, msg) private object names{ @@ -53,6 +54,7 @@ case class Logger(enabledLoggers: Set[String], start: Long) { val lib = "lib" val test = "test" val pom = "pom" + val run = "run" val git = "git" val dynamic = "dynamic" val transientCache = "transientCache" diff --git a/stage1/resolver.scala b/stage1/resolver.scala index e02f931..ab3196a 100644 --- a/stage1/resolver.scala +++ b/stage1/resolver.scala @@ -89,6 +89,10 @@ trait DependencyImplementation extends Dependency{ def run( args: String* ): ExitCode = { runClass.map( runMain( _, args: _* ) ).getOrElse{ + // FIXME: this just doing nothing when class is not found has been repeatedly + // surprising. Let's try to make this more visible than just logging an error. + // Currently blocked on task `recursive` trying every subbuild and would error + // for all that don't have a run class. Maybe that's ok actually. logger.task( "No main class found for " ++ show ) ExitCode.Success } @@ -205,13 +209,6 @@ object Classifier{ abstract class DependenciesProxy{ } -class BoundMavenDependencies( - cbtLastModified: Long, mavenCache: File, urls: Seq[URL], mavenDependencies: Seq[MavenDependency] -)( - implicit logger: Logger, transientCache: java.util.Map[AnyRef,AnyRef], classLoaderCache: ClassLoaderCache -) extends Dependencies( - mavenDependencies.map( BoundMavenDependency(cbtLastModified,mavenCache,_,urls) ) -) case class MavenDependency( groupId: String, artifactId: String, version: String, classifier: Classifier = Classifier.none ){ @@ -229,6 +226,11 @@ case class BoundMavenDependency( implicit val logger: Logger, val transientCache: java.util.Map[AnyRef,AnyRef], val classLoaderCache: ClassLoaderCache ) extends ArtifactInfo with DependencyImplementation{ def moduleKey = this.getClass.getName ++ "(" ++ mavenDependency.serialize ++ ")" + override def hashCode = mavenDependency.hashCode + override def equals(other: Any) = other match{ + case o: BoundMavenDependency => o.mavenDependency == mavenDependency && o.repositories == repositories + case _ => false + } val MavenDependency( groupId, artifactId, version, classifier ) = mavenDependency assert( Option(groupId).collect{ @@ -261,7 +263,7 @@ case class BoundMavenDependency( import scala.collection.JavaConversions._ private def resolve(suffix: String, hash: Option[String], useClassifier: Boolean): File = { - logger.resolver("Resolving "+this) + logger.resolver(lib.blue("Resolving ")+this) val file = mavenCache ++ basePath(useClassifier) ++ "." ++ suffix val urls = repositories.map(_ ++ basePath(useClassifier) ++ "." ++ suffix) urls.find( @@ -284,7 +286,10 @@ case class BoundMavenDependency( def jar: File = taskCache[BoundMavenDependency]("jar").memoize{ resolve("jar", Some(jarSha1), true) } def pom: File = taskCache[BoundMavenDependency]("pom").memoize{ resolve("pom", Some(pomSha1), false) } - private def pomXml = XML.loadFile(pom.string) + private def pomXml = { + logger.resolver( "Loading pom file: " ++ pom.string ) + XML.loadFile(pom.string) + } // ========== pom traversal ========== private lazy val transitivePom: Seq[BoundMavenDependency] = { |