Skip to content

Commit

Permalink
Make package command handle directories in extra classpath
Browse files Browse the repository at this point in the history
  • Loading branch information
joan38 committed Aug 15, 2024
1 parent 915e7cb commit 961f095
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -856,26 +856,28 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
alreadyExistsCheck: () => Either[BuildException, Unit],
logger: Logger
): Either[BuildException, Unit] = either {
val byteCodeZipEntries = os.walk(build.output)
.filter(os.isFile(_))
.map { path =>
val name = path.relativeTo(build.output).toString
val content = os.read.bytes(path)
val lastModified = os.mtime(path)
val ent = new ZipEntry(name)
ent.setLastModifiedTime(FileTime.fromMillis(lastModified))
ent.setSize(content.length)
(ent, content)
}
val compiledClasses = os.walk(build.output).filter(os.isFile(_))
val (extraClasseFolders, extraJars) =
build.options.classPathOptions.extraClassPath.partition(os.isDir(_))
val extraClasses = extraClasseFolders.flatMap(os.walk(_)).filter(os.isFile(_))

val byteCodeZipEntries = (compiledClasses ++ extraClasses).map { path =>
val name = path.relativeTo(build.output).toString
val content = os.read.bytes(path)
val lastModified = os.mtime(path)
val ent = new ZipEntry(name)
ent.setLastModifiedTime(FileTime.fromMillis(lastModified))
ent.setSize(content.length)
(ent, content)
}

val provided = build.options.notForBloopOptions.packageOptions.provided ++ extraProvided
val allFiles =
build.artifacts.runtimeArtifacts.map(_._2) ++ build.options.classPathOptions.extraClassPath
val files =
if (provided.isEmpty) allFiles
val allJars = build.artifacts.runtimeArtifacts.map(_._2) ++ extraJars.filter(os.exists(_))
val jars =
if (provided.isEmpty) allJars
else {
val providedFilesSet = value(providedFiles(build, provided, logger)).toSet
allFiles.filterNot(providedFilesSet.contains)
allJars.filterNot(providedFilesSet.contains)
}

val preambleOpt =
Expand All @@ -889,7 +891,7 @@ object Package extends ScalaCommand[PackageOptions] with BuildCommandHelpers {
None
val params = Parameters.Assembly()
.withExtraZipEntries(byteCodeZipEntries)
.withFiles(files.map(_.toIO))
.withFiles(jars.map(_.toIO))
.withMainClass(mainClassOpt)
.withPreambleOpt(preambleOpt)
value(alreadyExistsCheck())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ abstract class PackageTestDefinitions extends ScalaCliSuite with TestScalaVersio
expect(output == message)
}
}

test("resource directory for coursier bootstrap launcher") {
val fileName = "hello.sc"
val message = "1,2,3"
Expand Down Expand Up @@ -285,6 +286,7 @@ abstract class PackageTestDefinitions extends ScalaCliSuite with TestScalaVersio
expect(output == message)
}
}

def smallModulesJsTest(jvm: Boolean): Unit = {
val fileName = "Hello.scala"
val message = "Hello World from JS"
Expand Down Expand Up @@ -668,6 +670,72 @@ abstract class PackageTestDefinitions extends ScalaCliSuite with TestScalaVersio
}
}

test("assembly classpath") {
val lib = os.rel / "lib"
val app = os.rel / "app"
val inputs = TestInputs(
lib / "lib" / "Message.scala" ->
s"""package lib
|
|object Message {
| def hello(name: String) = s"Hello $$name"
|}
|""".stripMargin,
app / "app" / "Hello.scala" ->
s"""package app
|
|import lib.Message.hello
|
|object Hello {
| def main(args: Array[String]): Unit = println(hello("assembly"))
|}
|""".stripMargin
)
inputs.fromRoot { root =>
val classpath = os.proc(
TestUtil.cli,
"compile",
extraOptions,
"--print-classpath",
lib.toString
).call(
cwd = root,
stdin = os.Inherit
).out.text().trim

os.proc(
TestUtil.cli,
"--power",
"package",
extraOptions,
"--main-class",
"app.Hello",
"--assembly",
"-o",
"hello.jar",
s"--classpath=$classpath",
app.toString
).call(
cwd = root,
stdin = os.Inherit,
stdout = os.Inherit
)

val launcher = root / "hello.jar"
expect(os.isFile(launcher))

Using.resource(new ZipFile(launcher.toIO)) { zf =>
val entries = zf.entries()
.asScala
.iterator
.map(_.getName)
.toVector
expect(entries.exists(_.endsWith("lib/Message.class")))
expect(entries.contains("app/Hello.class"))
}
}
}

test("assembly provided") {
val inputs = TestInputs(
os.rel / "Hello.scala" ->
Expand Down

0 comments on commit 961f095

Please sign in to comment.