aboutsummaryrefslogtreecommitdiff
path: root/stage1/Stage1Lib.scala
diff options
context:
space:
mode:
authorChristopher Vogt <oss.nsp@cvogt.org>2017-02-15 03:30:46 -0500
committerChristopher Vogt <oss.nsp@cvogt.org>2017-02-15 04:07:21 -0500
commit4f4c34f3f52b87057626682dd43a21cd83e2ff7a (patch)
tree12396906bde5f51cc8fc274c387d77e438bd2c23 /stage1/Stage1Lib.scala
parent7ee113962134e3c9c4659d6de9de3c7015174d3f (diff)
downloadcbt-4f4c34f3f52b87057626682dd43a21cd83e2ff7a.tar.gz
cbt-4f4c34f3f52b87057626682dd43a21cd83e2ff7a.tar.bz2
cbt-4f4c34f3f52b87057626682dd43a21cd83e2ff7a.zip
add package to generated Build in build.scala and in-package discovery
This should allow for build to add other builds to their dependencies and interact with them in a type-safe way. And ever regardless it seems like good practice to never have the same class existing in the same package or the top-level package even if they don’t end up on the same classpath. This might also help make stack traces easier to understand. Also improve error messages for mistakes with the build class, e.g. constructor, super classes, etc.
Diffstat (limited to 'stage1/Stage1Lib.scala')
-rw-r--r--stage1/Stage1Lib.scala54
1 files changed, 31 insertions, 23 deletions
diff --git a/stage1/Stage1Lib.scala b/stage1/Stage1Lib.scala
index 505b298..79df450 100644
--- a/stage1/Stage1Lib.scala
+++ b/stage1/Stage1Lib.scala
@@ -146,35 +146,43 @@ class Stage1Lib( logger: Logger ) extends BaseLib{
pickOne( "Which one do you want to run?", mainClasses )( _.toString )
}
- def mainClasses( targetDirectory: File, classLoader : ClassLoader ): Seq[Class[_]] = {
- val arrayClass = classOf[Array[String]]
- val unitClass = classOf[Unit]
-
- listFilesRecursive(targetDirectory)
+ /** 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)
.filter(_.isFile)
.map(_.getPath)
.collect{
// no $ to avoid inner classes
case path if !path.contains("$") && path.endsWith(".class") =>
- try{
- classLoader.loadClass(
- path
- .stripSuffix(".class")
- .stripPrefix(targetDirectory.getPath)
- .stripPrefix(File.separator) // 1 for the slash
- .replace(File.separator, ".")
- )
- } catch {
- case e: ClassNotFoundException => null
- case e: NoClassDefFoundError => null
- }
- }.filterNot(_ == null).filter(
- _.getDeclaredMethods().exists( m =>
- m.getName == "main"
- && m.getParameterTypes.toList == List(arrayClass)
- && m.getReturnType == unitClass
- )
+ path.stripSuffix(".class")
+ .stripPrefix(classesRootDirectory.getPath)
+ .stripPrefix(File.separator) // 1 for the slash
+ .replace(File.separator, ".")
+ }
+
+ /** ignoreMissingClasses allows ignoring other classes root directories which are subdirectories of this one */
+ def iterateClasses( classesRootDirectory: File, classLoader: ClassLoader, ignoreMissingClasses: Boolean ) =
+ iterateClassNames(classesRootDirectory).map{ name =>
+ try{
+ classLoader.loadClass(name)
+ } catch {
+ case e: ClassNotFoundException if ignoreMissingClasses => null
+ case e: NoClassDefFoundError if ignoreMissingClasses => null
+ }
+ }.filterNot(ignoreMissingClasses && _ == null)
+
+ def mainClasses( classesRootDirectory: File, classLoader: ClassLoader ): Seq[Class[_]] = {
+ val arrayClass = classOf[Array[String]]
+ val unitClass = classOf[Unit]
+
+ iterateClasses( classesRootDirectory, classLoader, true ).filter(
+ _.getDeclaredMethods().exists( m =>
+ m.getName == "main"
+ && m.getParameterTypes.toList == List(arrayClass)
+ && m.getReturnType == unitClass
)
+ )
}
implicit class ClassLoaderExtensions(classLoader: ClassLoader){