Skip to content

Commit 6080642

Browse files
authored
Make package command handle directories in extra classpath (#3096)
1 parent 0812d33 commit 6080642

File tree

2 files changed

+87
-17
lines changed

2 files changed

+87
-17
lines changed

modules/cli/src/main/scala/scala/cli/commands/package0/Package.scala

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -856,26 +856,28 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
856856
alreadyExistsCheck: () => Either[BuildException, Unit],
857857
logger: Logger
858858
): Either[BuildException, Unit] = either {
859-
val byteCodeZipEntries = os.walk(build.output)
860-
.filter(os.isFile(_))
861-
.map { path =>
862-
val name = path.relativeTo(build.output).toString
863-
val content = os.read.bytes(path)
864-
val lastModified = os.mtime(path)
865-
val ent = new ZipEntry(name)
866-
ent.setLastModifiedTime(FileTime.fromMillis(lastModified))
867-
ent.setSize(content.length)
868-
(ent, content)
869-
}
859+
val compiledClasses = os.walk(build.output).filter(os.isFile(_))
860+
val (extraClasseFolders, extraJars) =
861+
build.options.classPathOptions.extraClassPath.partition(os.isDir(_))
862+
val extraClasses = extraClasseFolders.flatMap(os.walk(_)).filter(os.isFile(_))
863+
864+
val byteCodeZipEntries = (compiledClasses ++ extraClasses).map { path =>
865+
val name = path.relativeTo(build.output).toString
866+
val content = os.read.bytes(path)
867+
val lastModified = os.mtime(path)
868+
val ent = new ZipEntry(name)
869+
ent.setLastModifiedTime(FileTime.fromMillis(lastModified))
870+
ent.setSize(content.length)
871+
(ent, content)
872+
}
870873

871874
val provided = build.options.notForBloopOptions.packageOptions.provided ++ extraProvided
872-
val allFiles =
873-
build.artifacts.runtimeArtifacts.map(_._2) ++ build.options.classPathOptions.extraClassPath
874-
val files =
875-
if (provided.isEmpty) allFiles
875+
val allJars = build.artifacts.runtimeArtifacts.map(_._2) ++ extraJars.filter(os.exists(_))
876+
val jars =
877+
if (provided.isEmpty) allJars
876878
else {
877879
val providedFilesSet = value(providedFiles(build, provided, logger)).toSet
878-
allFiles.filterNot(providedFilesSet.contains)
880+
allJars.filterNot(providedFilesSet.contains)
879881
}
880882

881883
val preambleOpt =
@@ -889,7 +891,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
889891
None
890892
val params = Parameters.Assembly()
891893
.withExtraZipEntries(byteCodeZipEntries)
892-
.withFiles(files.map(_.toIO))
894+
.withFiles(jars.map(_.toIO))
893895
.withMainClass(mainClassOpt)
894896
.withPreambleOpt(preambleOpt)
895897
value(alreadyExistsCheck())

modules/integration/src/test/scala/scala/cli/integration/PackageTestDefinitions.scala

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ abstract class PackageTestDefinitions extends ScalaCliSuite with TestScalaVersio
7272
expect(output == message)
7373
}
7474
}
75+
7576
test("resource directory for coursier bootstrap launcher") {
7677
val fileName = "hello.sc"
7778
val message = "1,2,3"
@@ -273,6 +274,7 @@ abstract class PackageTestDefinitions extends ScalaCliSuite with TestScalaVersio
273274
expect(output == message)
274275
}
275276
}
277+
276278
def smallModulesJsTest(jvm: Boolean): Unit = {
277279
val fileName = "Hello.scala"
278280
val message = "Hello World from JS"
@@ -656,6 +658,72 @@ abstract class PackageTestDefinitions extends ScalaCliSuite with TestScalaVersio
656658
}
657659
}
658660

661+
test("assembly classpath") {
662+
val lib = os.rel / "lib"
663+
val app = os.rel / "app"
664+
val inputs = TestInputs(
665+
lib / "lib" / "Message.scala" ->
666+
s"""package lib
667+
|
668+
|object Message {
669+
| def hello(name: String) = s"Hello $$name"
670+
|}
671+
|""".stripMargin,
672+
app / "app" / "Hello.scala" ->
673+
s"""package app
674+
|
675+
|import lib.Message.hello
676+
|
677+
|object Hello {
678+
| def main(args: Array[String]): Unit = println(hello("assembly"))
679+
|}
680+
|""".stripMargin
681+
)
682+
inputs.fromRoot { root =>
683+
val classpath = os.proc(
684+
TestUtil.cli,
685+
"compile",
686+
extraOptions,
687+
"--print-classpath",
688+
lib.toString
689+
).call(
690+
cwd = root,
691+
stdin = os.Inherit
692+
).out.text().trim
693+
694+
os.proc(
695+
TestUtil.cli,
696+
"--power",
697+
"package",
698+
extraOptions,
699+
"--main-class",
700+
"app.Hello",
701+
"--assembly",
702+
"-o",
703+
"hello.jar",
704+
s"--classpath=$classpath",
705+
app.toString
706+
).call(
707+
cwd = root,
708+
stdin = os.Inherit,
709+
stdout = os.Inherit
710+
)
711+
712+
val launcher = root / "hello.jar"
713+
expect(os.isFile(launcher))
714+
715+
Using.resource(new ZipFile(launcher.toIO)) { zf =>
716+
val entries = zf.entries()
717+
.asScala
718+
.iterator
719+
.map(_.getName)
720+
.toVector
721+
expect(entries.exists(_.endsWith("lib/Message.class")))
722+
expect(entries.contains("app/Hello.class"))
723+
}
724+
}
725+
}
726+
659727
test("assembly provided") {
660728
val inputs = TestInputs(
661729
os.rel / "Hello.scala" ->

0 commit comments

Comments
 (0)