Skip to content

Commit a1e6905

Browse files
Merge pull request #401 from swiftwasm/fix-packagetojs-wasm-opt-fallback
2 parents fc51187 + b579fb1 commit a1e6905

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

Plugins/PackageToJS/Sources/PackageToJS.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,11 @@ extension PackagingSystem {
293293
final class DefaultPackagingSystem: PackagingSystem {
294294

295295
private let printWarning: (String) -> Void
296+
private let which: (String) throws -> URL
296297

297-
init(printWarning: @escaping (String) -> Void) {
298+
init(printWarning: @escaping (String) -> Void, which: @escaping (String) throws -> URL = which(_:)) {
298299
self.printWarning = printWarning
300+
self.which = which
299301
}
300302

301303
func npmInstall(packageDir: String) throws {
@@ -309,6 +311,10 @@ final class DefaultPackagingSystem: PackagingSystem {
309311
func wasmOpt(_ arguments: [String], input: String, output: String) throws {
310312
guard let wasmOpt = try? which("wasm-opt") else {
311313
_ = warnMissingWasmOpt
314+
// Remove existing output file if it exists (to match wasm-opt behavior)
315+
if FileManager.default.fileExists(atPath: output) {
316+
try FileManager.default.removeItem(atPath: output)
317+
}
312318
try FileManager.default.copyItem(atPath: input, toPath: output)
313319
return
314320
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import Foundation
2+
import Testing
3+
4+
@testable import PackageToJS
5+
6+
@Suite struct DefaultPackagingSystemTests {
7+
8+
@Test func wasmOptFallbackHandlesNewOutputFile() throws {
9+
try withTemporaryDirectory { tempDir, _ in
10+
let inputFile = tempDir.appendingPathComponent("input.wasm")
11+
let outputFile = tempDir.appendingPathComponent("output.wasm")
12+
let inputContent = Data("input wasm content".utf8)
13+
try inputContent.write(to: inputFile)
14+
15+
var warnings: [String] = []
16+
// Create system with mock which function that always fails to find wasm-opt
17+
let system = DefaultPackagingSystem(
18+
printWarning: { warnings.append($0) },
19+
which: { _ in throw PackageToJSError("wasm-opt not found") }
20+
)
21+
22+
// This should work - fallback should copy file
23+
try system.wasmOpt(["-Os"], input: inputFile.path, output: outputFile.path)
24+
25+
// Verify the output file was created with input content
26+
let finalContent = try Data(contentsOf: outputFile)
27+
#expect(finalContent == inputContent)
28+
#expect(warnings.contains { $0.contains("wasm-opt is not installed") })
29+
}
30+
}
31+
32+
@Test func wasmOptFallbackHandlesExistingOutputFile() throws {
33+
try withTemporaryDirectory { tempDir, _ in
34+
let inputFile = tempDir.appendingPathComponent("input.wasm")
35+
let outputFile = tempDir.appendingPathComponent("output.wasm")
36+
let inputContent = Data("input wasm content".utf8)
37+
let existingContent = Data("existing output content".utf8)
38+
39+
// Create input file and existing output file
40+
try inputContent.write(to: inputFile)
41+
try existingContent.write(to: outputFile)
42+
43+
var warnings: [String] = []
44+
// Create system with mock which function that always fails to find wasm-opt
45+
let system = DefaultPackagingSystem(
46+
printWarning: { warnings.append($0) },
47+
which: { _ in throw PackageToJSError("wasm-opt not found") }
48+
)
49+
50+
// This should work - fallback should overwrite existing file
51+
try system.wasmOpt(["-Os"], input: inputFile.path, output: outputFile.path)
52+
53+
// Verify the output file was overwritten with input content
54+
let finalContent = try Data(contentsOf: outputFile)
55+
#expect(finalContent == inputContent)
56+
#expect(finalContent != existingContent)
57+
#expect(warnings.contains { $0.contains("wasm-opt is not installed") })
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)