summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/classpath
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2016-03-22 21:25:35 +0100
committerLukas Rytz <lukas.rytz@gmail.com>2016-03-22 21:28:27 +0100
commit6cb50acfb5ee4df342e83d8505116d4607f45d1c (patch)
treebd37410452b625a74c5337f9a5509ae8451b5189 /src/compiler/scala/tools/nsc/classpath
parentad48e5918081c679546f50b6f52dd8e0813754e7 (diff)
downloadscala-6cb50acfb5ee4df342e83d8505116d4607f45d1c.tar.gz
scala-6cb50acfb5ee4df342e83d8505116d4607f45d1c.tar.bz2
scala-6cb50acfb5ee4df342e83d8505116d4607f45d1c.zip
Enable flat classpath by default
Implements VirtualDirectoryFlatClassPath, which is required for the presentation compiler created for the repl's tab-completion. Various minor cleanups in the flat classpath implementation.
Diffstat (limited to 'src/compiler/scala/tools/nsc/classpath')
-rw-r--r--src/compiler/scala/tools/nsc/classpath/AggregateFlatClassPath.scala10
-rw-r--r--src/compiler/scala/tools/nsc/classpath/DirectoryFlatClassPath.scala148
-rw-r--r--src/compiler/scala/tools/nsc/classpath/FileUtils.scala6
-rw-r--r--src/compiler/scala/tools/nsc/classpath/FlatClassPath.scala9
-rw-r--r--src/compiler/scala/tools/nsc/classpath/FlatClassPathFactory.scala25
-rw-r--r--src/compiler/scala/tools/nsc/classpath/VirtualDirectoryFlatClassPath.scala39
-rw-r--r--src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala8
-rw-r--r--src/compiler/scala/tools/nsc/classpath/ZipArchiveFileLookup.scala2
8 files changed, 137 insertions, 110 deletions
diff --git a/src/compiler/scala/tools/nsc/classpath/AggregateFlatClassPath.scala b/src/compiler/scala/tools/nsc/classpath/AggregateFlatClassPath.scala
index 3f06264e3c..7bfb3240eb 100644
--- a/src/compiler/scala/tools/nsc/classpath/AggregateFlatClassPath.scala
+++ b/src/compiler/scala/tools/nsc/classpath/AggregateFlatClassPath.scala
@@ -18,7 +18,6 @@ import scala.tools.nsc.util.ClassRepresentation
* @param aggregates classpath instances containing entries which this class processes
*/
case class AggregateFlatClassPath(aggregates: Seq[FlatClassPath]) extends FlatClassPath {
-
override def findClassFile(className: String): Option[AbstractFile] = {
@tailrec
def find(aggregates: Seq[FlatClassPath]): Option[AbstractFile] =
@@ -37,8 +36,7 @@ case class AggregateFlatClassPath(aggregates: Seq[FlatClassPath]) extends FlatCl
@tailrec
def findEntry[T <: ClassRepClassPathEntry](aggregates: Seq[FlatClassPath], getEntries: FlatClassPath => Seq[T]): Option[T] =
if (aggregates.nonEmpty) {
- val entry = getEntries(aggregates.head)
- .find(_.name == simpleClassName)
+ val entry = getEntries(aggregates.head).find(_.name == simpleClassName)
if (entry.isDefined) entry
else findEntry(aggregates.tail, getEntries)
} else None
@@ -46,7 +44,11 @@ case class AggregateFlatClassPath(aggregates: Seq[FlatClassPath]) extends FlatCl
val classEntry = findEntry(aggregates, classesGetter(pkg))
val sourceEntry = findEntry(aggregates, sourcesGetter(pkg))
- mergeClassesAndSources(classEntry.toList, sourceEntry.toList).headOption
+ (classEntry, sourceEntry) match {
+ case (Some(c), Some(s)) => Some(ClassAndSourceFilesEntry(c.file, s.file))
+ case (c @ Some(_), _) => c
+ case (_, s) => s
+ }
}
override def asURLs: Seq[URL] = aggregates.flatMap(_.asURLs)
diff --git a/src/compiler/scala/tools/nsc/classpath/DirectoryFlatClassPath.scala b/src/compiler/scala/tools/nsc/classpath/DirectoryFlatClassPath.scala
index 81d2f7320f..e3964dfa78 100644
--- a/src/compiler/scala/tools/nsc/classpath/DirectoryFlatClassPath.scala
+++ b/src/compiler/scala/tools/nsc/classpath/DirectoryFlatClassPath.scala
@@ -4,7 +4,6 @@
package scala.tools.nsc.classpath
import java.io.File
-import java.io.FileFilter
import java.net.URL
import scala.reflect.io.AbstractFile
import scala.reflect.io.PlainFile
@@ -12,97 +11,101 @@ import scala.tools.nsc.util.ClassRepresentation
import FileUtils._
/**
- * A trait allowing to look for classpath entries of given type in directories.
- * It provides common logic for classes handling class and source files.
+ * A trait allowing to look for classpath entries in directories. It provides common logic for
+ * classes handling class and source files.
* It makes use of the fact that in the case of nested directories it's easy to find a file
* when we have a name of a package.
+ * It abstracts over the file representation to work with both JFile and AbstractFile.
*/
-trait DirectoryFileLookup[FileEntryType <: ClassRepClassPathEntry] extends FlatClassPath {
- val dir: File
- assert(dir != null, "Directory file in DirectoryFileLookup cannot be null")
+trait DirectoryLookup[FileEntryType <: ClassRepClassPathEntry] extends FlatClassPath {
+ type F
+
+ val dir: F
+
+ protected def emptyFiles: Array[F] // avoids reifying ClassTag[F]
+ protected def getSubDir(dirName: String): Option[F]
+ protected def listChildren(dir: F, filter: Option[F => Boolean] = None): Array[F]
+ protected def getName(f: F): String
+ protected def toAbstractFile(f: F): AbstractFile
+ protected def isPackage(f: F): Boolean
- override def asURLs: Seq[URL] = Seq(dir.toURI.toURL)
- override def asClassPathStrings: Seq[String] = Seq(dir.getPath)
+ protected def createFileEntry(file: AbstractFile): FileEntryType
+ protected def isMatchingFile(f: F): Boolean
- import FlatClassPath.RootPackage
- private def getDirectory(forPackage: String): Option[File] = {
- if (forPackage == RootPackage) {
+ private def getDirectory(forPackage: String): Option[F] = {
+ if (forPackage == FlatClassPath.RootPackage) {
Some(dir)
} else {
val packageDirName = FileUtils.dirPath(forPackage)
- val packageDir = new File(dir, packageDirName)
- if (packageDir.exists && packageDir.isDirectory) {
- Some(packageDir)
- } else None
+ getSubDir(packageDirName)
}
}
- override private[nsc] def packages(inPackage: String): Seq[PackageEntry] = {
+ private[nsc] def packages(inPackage: String): Seq[PackageEntry] = {
val dirForPackage = getDirectory(inPackage)
- val nestedDirs: Array[File] = dirForPackage match {
- case None => Array.empty
- case Some(directory) => directory.listFiles(DirectoryFileLookup.packageDirectoryFileFilter)
+ val nestedDirs: Array[F] = dirForPackage match {
+ case None => emptyFiles
+ case Some(directory) => listChildren(directory, Some(isPackage))
}
val prefix = PackageNameUtils.packagePrefix(inPackage)
- val entries = nestedDirs map { file =>
- PackageEntryImpl(prefix + file.getName)
- }
- entries
+ nestedDirs.map(f => PackageEntryImpl(prefix + getName(f)))
}
protected def files(inPackage: String): Seq[FileEntryType] = {
val dirForPackage = getDirectory(inPackage)
- val files: Array[File] = dirForPackage match {
- case None => Array.empty
- case Some(directory) => directory.listFiles(fileFilter)
- }
- val entries = files map { file =>
- val wrappedFile = new scala.reflect.io.File(file)
- createFileEntry(new PlainFile(wrappedFile))
+ val files: Array[F] = dirForPackage match {
+ case None => emptyFiles
+ case Some(directory) => listChildren(directory, Some(isMatchingFile))
}
- entries
+ files.map(f => createFileEntry(toAbstractFile(f)))
}
- override private[nsc] def list(inPackage: String): FlatClassPathEntries = {
+ private[nsc] def list(inPackage: String): FlatClassPathEntries = {
val dirForPackage = getDirectory(inPackage)
- val files: Array[File] = dirForPackage match {
- case None => Array.empty
- case Some(directory) => directory.listFiles()
+ val files: Array[F] = dirForPackage match {
+ case None => emptyFiles
+ case Some(directory) => listChildren(directory)
}
val packagePrefix = PackageNameUtils.packagePrefix(inPackage)
val packageBuf = collection.mutable.ArrayBuffer.empty[PackageEntry]
val fileBuf = collection.mutable.ArrayBuffer.empty[FileEntryType]
for (file <- files) {
- if (file.isPackage) {
- val pkgEntry = PackageEntryImpl(packagePrefix + file.getName)
- packageBuf += pkgEntry
- } else if (fileFilter.accept(file)) {
- val wrappedFile = new scala.reflect.io.File(file)
- val abstractFile = new PlainFile(wrappedFile)
- fileBuf += createFileEntry(abstractFile)
- }
+ if (isPackage(file))
+ packageBuf += PackageEntryImpl(packagePrefix + getName(file))
+ else if (isMatchingFile(file))
+ fileBuf += createFileEntry(toAbstractFile(file))
}
FlatClassPathEntries(packageBuf, fileBuf)
}
-
- protected def createFileEntry(file: AbstractFile): FileEntryType
- protected def fileFilter: FileFilter
}
-object DirectoryFileLookup {
+trait JFileDirectoryLookup[FileEntryType <: ClassRepClassPathEntry] extends DirectoryLookup[FileEntryType] {
+ type F = File
- private[classpath] object packageDirectoryFileFilter extends FileFilter {
- override def accept(pathname: File): Boolean = pathname.isPackage
+ protected def emptyFiles: Array[File] = Array.empty
+ protected def getSubDir(packageDirName: String): Option[File] = {
+ val packageDir = new File(dir, packageDirName)
+ if (packageDir.exists && packageDir.isDirectory) Some(packageDir)
+ else None
}
-}
+ protected def listChildren(dir: File, filter: Option[File => Boolean]): Array[File] = filter match {
+ case Some(f) => dir.listFiles(mkFileFilter(f))
+ case None => dir.listFiles()
+ }
+ protected def getName(f: File): String = f.getName
+ protected def toAbstractFile(f: File): AbstractFile = new PlainFile(new scala.reflect.io.File(f))
+ protected def isPackage(f: File): Boolean = f.isPackage
-case class DirectoryFlatClassPath(dir: File)
- extends DirectoryFileLookup[ClassFileEntryImpl]
- with NoSourcePaths {
+ assert(dir != null, "Directory file in DirectoryFileLookup cannot be null")
+ def asURLs: Seq[URL] = Seq(dir.toURI.toURL)
+ def asClassPathStrings: Seq[String] = Seq(dir.getPath)
+}
+
+case class DirectoryFlatClassPath(dir: File) extends JFileDirectoryLookup[ClassFileEntryImpl] with NoSourcePaths {
override def findClass(className: String): Option[ClassRepresentation[AbstractFile]] = findClassFile(className) map ClassFileEntryImpl
- override def findClassFile(className: String): Option[AbstractFile] = {
+ def findClassFile(className: String): Option[AbstractFile] = {
val relativePath = FileUtils.dirPath(className)
val classFile = new File(s"$dir/$relativePath.class")
if (classFile.exists) {
@@ -112,31 +115,19 @@ case class DirectoryFlatClassPath(dir: File)
} else None
}
- override protected def createFileEntry(file: AbstractFile): ClassFileEntryImpl = ClassFileEntryImpl(file)
- override protected def fileFilter: FileFilter = DirectoryFlatClassPath.classFileFilter
-
- override private[nsc] def classes(inPackage: String): Seq[ClassFileEntry] = files(inPackage)
-}
-
-object DirectoryFlatClassPath {
+ protected def createFileEntry(file: AbstractFile): ClassFileEntryImpl = ClassFileEntryImpl(file)
+ protected def isMatchingFile(f: File): Boolean = f.isClass
- private val classFileFilter = new FileFilter {
- override def accept(pathname: File): Boolean = pathname.isClass
- }
+ private[nsc] def classes(inPackage: String): Seq[ClassFileEntry] = files(inPackage)
}
-case class DirectoryFlatSourcePath(dir: File)
- extends DirectoryFileLookup[SourceFileEntryImpl]
- with NoClassPaths {
+case class DirectoryFlatSourcePath(dir: File) extends JFileDirectoryLookup[SourceFileEntryImpl] with NoClassPaths {
+ def asSourcePathString: String = asClassPathString
- override def asSourcePathString: String = asClassPathString
+ protected def createFileEntry(file: AbstractFile): SourceFileEntryImpl = SourceFileEntryImpl(file)
+ protected def isMatchingFile(f: File): Boolean = endsScalaOrJava(f.getName)
- override protected def createFileEntry(file: AbstractFile): SourceFileEntryImpl = SourceFileEntryImpl(file)
- override protected def fileFilter: FileFilter = DirectoryFlatSourcePath.sourceFileFilter
-
- override def findClass(className: String): Option[ClassRepresentation[AbstractFile]] = {
- findSourceFile(className) map SourceFileEntryImpl
- }
+ override def findClass(className: String): Option[ClassRepresentation[AbstractFile]] = findSourceFile(className) map SourceFileEntryImpl
private def findSourceFile(className: String): Option[AbstractFile] = {
val relativePath = FileUtils.dirPath(className)
@@ -151,12 +142,5 @@ case class DirectoryFlatSourcePath(dir: File)
}
}
- override private[nsc] def sources(inPackage: String): Seq[SourceFileEntry] = files(inPackage)
-}
-
-object DirectoryFlatSourcePath {
-
- private val sourceFileFilter = new FileFilter {
- override def accept(pathname: File): Boolean = endsScalaOrJava(pathname.getName)
- }
+ private[nsc] def sources(inPackage: String): Seq[SourceFileEntry] = files(inPackage)
}
diff --git a/src/compiler/scala/tools/nsc/classpath/FileUtils.scala b/src/compiler/scala/tools/nsc/classpath/FileUtils.scala
index ee2528e15c..bbcfcb24ca 100644
--- a/src/compiler/scala/tools/nsc/classpath/FileUtils.scala
+++ b/src/compiler/scala/tools/nsc/classpath/FileUtils.scala
@@ -3,7 +3,7 @@
*/
package scala.tools.nsc.classpath
-import java.io.{ File => JFile }
+import java.io.{File => JFile, FileFilter}
import java.net.URL
import scala.reflect.internal.FatalError
import scala.reflect.io.AbstractFile
@@ -65,4 +65,8 @@ object FileUtils {
// because then some tests in partest don't pass
private def mayBeValidPackage(dirName: String): Boolean =
(dirName != "META-INF") && (dirName != "") && (dirName.charAt(0) != '.')
+
+ def mkFileFilter(f: JFile => Boolean) = new FileFilter {
+ def accept(pathname: JFile): Boolean = f(pathname)
+ }
}
diff --git a/src/compiler/scala/tools/nsc/classpath/FlatClassPath.scala b/src/compiler/scala/tools/nsc/classpath/FlatClassPath.scala
index cb201617d2..e95ffe02e3 100644
--- a/src/compiler/scala/tools/nsc/classpath/FlatClassPath.scala
+++ b/src/compiler/scala/tools/nsc/classpath/FlatClassPath.scala
@@ -28,11 +28,8 @@ trait FlatClassPath extends ClassFileLookup[AbstractFile] {
override def findClass(className: String): Option[ClassRepresentation[AbstractFile]] = {
val (pkg, simpleClassName) = PackageNameUtils.separatePkgAndClassNames(className)
- val foundClassFromClassFiles = classes(pkg)
- .find(_.name == simpleClassName)
-
- def findClassInSources = sources(pkg)
- .find(_.name == simpleClassName)
+ val foundClassFromClassFiles = classes(pkg).find(_.name == simpleClassName)
+ def findClassInSources = sources(pkg).find(_.name == simpleClassName)
foundClassFromClassFiles orElse findClassInSources
}
@@ -50,7 +47,7 @@ case class FlatClassPathEntries(packages: Seq[PackageEntry], classesAndSources:
object FlatClassPathEntries {
import scala.language.implicitConversions
// to have working unzip method
- implicit def entry2Tuple(entry: FlatClassPathEntries) = (entry.packages, entry.classesAndSources)
+ implicit def entry2Tuple(entry: FlatClassPathEntries): (Seq[PackageEntry], Seq[ClassRepClassPathEntry]) = (entry.packages, entry.classesAndSources)
}
sealed trait ClassRepClassPathEntry extends ClassRepresentation[AbstractFile]
diff --git a/src/compiler/scala/tools/nsc/classpath/FlatClassPathFactory.scala b/src/compiler/scala/tools/nsc/classpath/FlatClassPathFactory.scala
index d8ca325885..463301696e 100644
--- a/src/compiler/scala/tools/nsc/classpath/FlatClassPathFactory.scala
+++ b/src/compiler/scala/tools/nsc/classpath/FlatClassPathFactory.scala
@@ -3,6 +3,7 @@
*/
package scala.tools.nsc.classpath
+import scala.reflect.io.VirtualDirectory
import scala.tools.nsc.Settings
import scala.tools.nsc.io.AbstractFile
import FileUtils.AbstractFileOps
@@ -12,16 +13,9 @@ import FileUtils.AbstractFileOps
* it uses proper type of classpath depending on a types of particular files containing sources or classes.
*/
class FlatClassPathFactory(settings: Settings) extends ClassPathFactory[FlatClassPath] {
+ def newClassPath(file: AbstractFile): FlatClassPath = FlatClassPathFactory.newClassPath(file, settings)
- override def newClassPath(file: AbstractFile): FlatClassPath =
- if (file.isJarOrZip)
- ZipAndJarFlatClassPathFactory.create(file, settings)
- else if (file.isDirectory)
- new DirectoryFlatClassPath(file.file)
- else
- sys.error(s"Unsupported classpath element: $file")
-
- override def sourcesInPath(path: String): List[FlatClassPath] =
+ def sourcesInPath(path: String): List[FlatClassPath] =
for {
file <- expandPath(path, expandStar = false)
dir <- Option(AbstractFile getDirectory file)
@@ -35,3 +29,16 @@ class FlatClassPathFactory(settings: Settings) extends ClassPathFactory[FlatClas
else
sys.error(s"Unsupported sourcepath element: $file")
}
+
+object FlatClassPathFactory {
+ def newClassPath(file: AbstractFile, settings: Settings): FlatClassPath = file match {
+ case vd: VirtualDirectory => VirtualDirectoryFlatClassPath(vd)
+ case _ =>
+ if (file.isJarOrZip)
+ ZipAndJarFlatClassPathFactory.create(file, settings)
+ else if (file.isDirectory)
+ new DirectoryFlatClassPath(file.file)
+ else
+ sys.error(s"Unsupported classpath element: $file")
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/classpath/VirtualDirectoryFlatClassPath.scala b/src/compiler/scala/tools/nsc/classpath/VirtualDirectoryFlatClassPath.scala
new file mode 100644
index 0000000000..06cdab583c
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/classpath/VirtualDirectoryFlatClassPath.scala
@@ -0,0 +1,39 @@
+package scala.tools.nsc.classpath
+
+import scala.tools.nsc.util.ClassRepresentation
+import scala.reflect.io.{Path, PlainFile, VirtualDirectory, AbstractFile}
+import FileUtils._
+import java.net.URL
+
+case class VirtualDirectoryFlatClassPath(dir: VirtualDirectory) extends FlatClassPath with DirectoryLookup[ClassFileEntryImpl] with NoSourcePaths {
+ type F = AbstractFile
+
+ protected def emptyFiles: Array[AbstractFile] = Array.empty
+ protected def getSubDir(packageDirName: String): Option[AbstractFile] =
+ Option(dir.lookupName(packageDirName, directory = true))
+ protected def listChildren(dir: AbstractFile, filter: Option[AbstractFile => Boolean] = None): Array[F] = filter match {
+ case Some(f) => dir.iterator.filter(f).toArray
+ case _ => dir.toArray
+ }
+ def getName(f: AbstractFile): String = f.name
+ def toAbstractFile(f: AbstractFile): AbstractFile = f
+ def isPackage(f: AbstractFile): Boolean = f.isPackage
+
+ // mimic the behavior of the old nsc.util.DirectoryClassPath
+ def asURLs: Seq[URL] = Seq(new URL(dir.name))
+ def asClassPathStrings: Seq[String] = Seq(dir.path)
+
+ override def findClass(className: String): Option[ClassRepresentation[AbstractFile]] = findClassFile(className) map ClassFileEntryImpl
+
+ def findClassFile(className: String): Option[AbstractFile] = {
+ val relativePath = FileUtils.dirPath(className)
+ val classFile = new PlainFile(Path(s"$dir/$relativePath.class"))
+ if (classFile.exists) Some(classFile)
+ else None
+ }
+
+ private[nsc] def classes(inPackage: String): Seq[ClassFileEntry] = files(inPackage)
+
+ protected def createFileEntry(file: AbstractFile): ClassFileEntryImpl = ClassFileEntryImpl(file)
+ protected def isMatchingFile(f: AbstractFile): Boolean = f.isClass
+}
diff --git a/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala b/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala
index 85c7c3c843..6ec3805d8b 100644
--- a/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala
+++ b/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala
@@ -19,7 +19,6 @@ import FileUtils._
* when there are a lot of projects having a lot of common dependencies.
*/
sealed trait ZipAndJarFileLookupFactory {
-
private val cache = collection.mutable.Map.empty[AbstractFile, FlatClassPath]
def create(zipFile: AbstractFile, settings: Settings): FlatClassPath = {
@@ -44,7 +43,6 @@ sealed trait ZipAndJarFileLookupFactory {
* It should be the only way of creating them as it provides caching.
*/
object ZipAndJarFlatClassPathFactory extends ZipAndJarFileLookupFactory {
-
private case class ZipArchiveFlatClassPath(zipFile: File)
extends ZipArchiveFileLookup[ClassFileEntryImpl]
with NoSourcePaths {
@@ -67,10 +65,7 @@ object ZipAndJarFlatClassPathFactory extends ZipAndJarFileLookupFactory {
* with a particularly prepared scala-library.jar. It should have all classes listed in the manifest like e.g. this entry:
* Name: scala/Function2$mcFJD$sp.class
*/
- private case class ManifestResourcesFlatClassPath(file: ManifestResources)
- extends FlatClassPath
- with NoSourcePaths {
-
+ private case class ManifestResourcesFlatClassPath(file: ManifestResources) extends FlatClassPath with NoSourcePaths {
override def findClassFile(className: String): Option[AbstractFile] = {
val (pkg, simpleClassName) = PackageNameUtils.separatePkgAndClassNames(className)
classes(pkg).find(_.name == simpleClassName).map(_.file)
@@ -163,7 +158,6 @@ object ZipAndJarFlatClassPathFactory extends ZipAndJarFileLookupFactory {
* It should be the only way of creating them as it provides caching.
*/
object ZipAndJarFlatSourcePathFactory extends ZipAndJarFileLookupFactory {
-
private case class ZipArchiveFlatSourcePath(zipFile: File)
extends ZipArchiveFileLookup[SourceFileEntryImpl]
with NoClassPaths {
diff --git a/src/compiler/scala/tools/nsc/classpath/ZipArchiveFileLookup.scala b/src/compiler/scala/tools/nsc/classpath/ZipArchiveFileLookup.scala
index 1d0de57779..a24d989306 100644
--- a/src/compiler/scala/tools/nsc/classpath/ZipArchiveFileLookup.scala
+++ b/src/compiler/scala/tools/nsc/classpath/ZipArchiveFileLookup.scala
@@ -57,7 +57,7 @@ trait ZipArchiveFileLookup[FileEntryType <: ClassRepClassPathEntry] extends Flat
} getOrElse FlatClassPathEntries(Seq.empty, Seq.empty)
}
- private def findDirEntry(pkg: String) = {
+ private def findDirEntry(pkg: String): Option[archive.DirEntry] = {
val dirName = s"${FileUtils.dirPath(pkg)}/"
archive.allDirs.get(dirName)
}