diff --git a/modules/cli/src/main/scala/scala/cli/commands/run/Run.scala b/modules/cli/src/main/scala/scala/cli/commands/run/Run.scala index b03b8cbedc..6a87b3c05d 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/run/Run.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/run/Run.scala @@ -556,7 +556,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers { ) } } - process.onExit().thenApply(_ => if os.exists(jsDest) then os.remove(jsDest)) + process.onExit().thenApply(_ => if os.exists(jsDest) then os.remove.all(jsDest)) Right((process, None)) } } @@ -613,7 +613,9 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers { esModule = esModule ) } - process.onExit().thenApply(_ => if os.exists(jsDest) then os.remove(jsDest)) + process.onExit().thenApply(_ => + if os.exists(jsDest) then os.remove.all(jsDest) + ) Right((process, None)) } } @@ -842,7 +844,10 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers { noOpt = noOpt, logger = logger ).map(outputPath => f(outputPath)) - finally if os.exists(dest) then os.remove(dest) + // `dest` starts as a file, but `linkJs` replaces it with a directory when the linker emits + // several files (Wasm, or JS module splitting), so a plain `os.remove` would throw + // `DirectoryNotEmptyException` and fail the command after it already succeeded. + finally if os.exists(dest) then os.remove.all(dest) } def withNativeLauncher[T]( diff --git a/modules/integration/src/test/scala/scala/cli/integration/TestTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/TestTestDefinitions.scala index da821e2d98..31c64af20e 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/TestTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/TestTestDefinitions.scala @@ -377,6 +377,26 @@ abstract class TestTestDefinitions extends ScalaCliSuite with TestScalaVersionAr } } + test("successful test Wasm") { + successfulTestInputs().fromRoot { root => + // The Wasm backend emits several files (main.js, __loader.js, main.wasm), so the linked + // output is a directory: the command must still exit 0 after cleaning it up. + val output = os.proc( + TestUtil.cli, + "--power", + "test", + extraOptions, + ".", + "--js-emit-wasm", + "--js-module-kind", + "es" + ) + .call(cwd = root) + .out.text() + expect(output.contains("Hello from tests")) + } + } + test("successful test esmodule import JS") { successfulESModuleTestInputs.fromRoot { root => val output = os.proc(TestUtil.cli, "test", extraOptions, ".", "--js")