Add separate Builder class, use WasmTransformer (#131)
Resolves #127. * Add separate Builder class, use WasmTransformer * Don't apply the transformer in non-browser environments * Fix macOS Swift 5.2 build failure * Fix Package.swift errors * Fix cyclic dependency in `Package.swift` * Bump WasmTransformer requirement to 0.0.1 * Rename `case wasmer` to `case other`
This commit is contained in:
parent
703078dd83
commit
08956baf1d
|
@ -33,6 +33,11 @@
|
|||
"type": "shell",
|
||||
"command": "swift build && cd TestApp && ../.build/debug/carton dev"
|
||||
},
|
||||
{
|
||||
"label": "build release and run dev",
|
||||
"type": "shell",
|
||||
"command": "swift build -c release && cd TestApp && ../.build/release/carton dev"
|
||||
},
|
||||
{
|
||||
"label": "build and run dev on 9090 port",
|
||||
"type": "shell",
|
||||
|
|
|
@ -163,6 +163,15 @@
|
|||
"version": "4.32.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "WasmTransformer",
|
||||
"repositoryURL": "https://github.com/swiftwasm/WasmTransformer",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "c7cb17309372e57c9f75f7abd5c7323d667eaddc",
|
||||
"version": "0.0.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "websocket-kit",
|
||||
"repositoryURL": "https://github.com/vapor/websocket-kit.git",
|
||||
|
|
|
@ -26,6 +26,7 @@ let package = Package(
|
|||
.package(url: "https://github.com/vapor/vapor.git", from: "4.29.3"),
|
||||
.package(url: "https://github.com/apple/swift-crypto.git", from: "1.1.0"),
|
||||
.package(url: "https://github.com/JohnSundell/Splash.git", from: "0.14.0"),
|
||||
.package(url: "https://github.com/swiftwasm/WasmTransformer", .upToNextMinor(from: "0.0.1")),
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package. A target can define a module
|
||||
|
@ -51,6 +52,7 @@ let package = Package(
|
|||
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
|
||||
"CartonHelpers",
|
||||
openCombineProduct,
|
||||
"WasmTransformer",
|
||||
]
|
||||
),
|
||||
.target(
|
||||
|
|
|
@ -20,6 +20,7 @@ let package = Package(
|
|||
.package(url: "https://github.com/vapor/vapor.git", from: "4.29.3"),
|
||||
.package(url: "https://github.com/apple/swift-crypto.git", from: "1.1.0"),
|
||||
.package(url: "https://github.com/JohnSundell/Splash.git", from: "0.14.0"),
|
||||
.package(url: "https://github.com/swiftwasm/WasmTransformer", .upToNextMinor(from: "0.0.1")),
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package. A target can define a module
|
||||
|
@ -45,6 +46,7 @@ let package = Package(
|
|||
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
|
||||
"CartonHelpers",
|
||||
"OpenCombine",
|
||||
"WasmTransformer",
|
||||
]
|
||||
),
|
||||
.target(
|
||||
|
|
|
@ -21,7 +21,7 @@ import OpenCombine
|
|||
#endif
|
||||
import TSCBasic
|
||||
|
||||
extension Subscribers.Completion {
|
||||
public extension Subscribers.Completion {
|
||||
var result: Result<(), Failure> {
|
||||
switch self {
|
||||
case let .failure(error):
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
// Copyright 2020 Carton contributors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import CartonHelpers
|
||||
#if canImport(Combine)
|
||||
import Combine
|
||||
#else
|
||||
import OpenCombine
|
||||
#endif
|
||||
import Foundation
|
||||
import TSCBasic
|
||||
import WasmTransformer
|
||||
|
||||
public final class Builder {
|
||||
public enum Environment {
|
||||
case other
|
||||
case browser
|
||||
}
|
||||
|
||||
public let mainWasmPath: AbsolutePath
|
||||
|
||||
private var currentProcess: ProcessRunner?
|
||||
private let arguments: [String]
|
||||
private let environment: Environment
|
||||
private let terminal: InteractiveWriter
|
||||
private let fileSystem: FileSystem
|
||||
private var subscription: AnyCancellable?
|
||||
|
||||
public init(
|
||||
arguments: [String],
|
||||
mainWasmPath: AbsolutePath,
|
||||
environment: Environment = .browser,
|
||||
_ fileSystem: FileSystem,
|
||||
_ terminal: InteractiveWriter
|
||||
) {
|
||||
self.arguments = arguments
|
||||
self.mainWasmPath = mainWasmPath
|
||||
self.environment = environment
|
||||
self.terminal = terminal
|
||||
self.fileSystem = fileSystem
|
||||
}
|
||||
|
||||
public func run() -> AnyPublisher<String, Error> {
|
||||
let buildStarted = Date()
|
||||
let process = ProcessRunner(arguments, loadingMessage: "Compiling...", terminal)
|
||||
currentProcess = process
|
||||
|
||||
return process
|
||||
.publisher
|
||||
.handleEvents(receiveCompletion: { [weak self] in
|
||||
guard case .finished = $0, let self = self else { return }
|
||||
|
||||
self.terminal.logLookup(
|
||||
"`swift build` completed in ",
|
||||
String(format: "%.2f seconds", abs(buildStarted.timeIntervalSinceNow))
|
||||
)
|
||||
|
||||
guard self.environment == .browser else { return }
|
||||
|
||||
// FIXME: errors from these `try` expressions should be recoverable, not sure how to
|
||||
// do that in `handleEvents`, and `flatMap` doesnt' fit here as we need to track
|
||||
// publisher completion.
|
||||
// swiftlint:disable force_try
|
||||
let binary = try! self.fileSystem.readFileContents(self.mainWasmPath)
|
||||
|
||||
let loweringStarted = Date()
|
||||
let loweredBinary = try! lowerI64Imports(binary.contents)
|
||||
|
||||
self.terminal.logLookup(
|
||||
"Binary transformation for Safari compatibility completed in ",
|
||||
String(format: "%.2f seconds", abs(loweringStarted.timeIntervalSinceNow))
|
||||
)
|
||||
|
||||
try! self.fileSystem.writeFileContents(self.mainWasmPath, bytes: .init(loweredBinary))
|
||||
// swiftlint:enable force_try
|
||||
})
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
public func runAndWaitUntilFinished() throws {
|
||||
try await { completion in
|
||||
subscription = run()
|
||||
.sink(
|
||||
receiveCompletion: { completion($0.result) },
|
||||
receiveValue: { _ in }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -225,10 +225,10 @@ public final class Toolchain {
|
|||
"--enable-test-discovery", "--destination", destination ?? inferDestinationPath().pathString,
|
||||
]
|
||||
|
||||
try ProcessRunner(builderArguments, loadingMessage: "Compiling...", terminal)
|
||||
.waitUntilFinished()
|
||||
try Builder(arguments: builderArguments, mainWasmPath: mainWasmPath, fileSystem, terminal)
|
||||
.runAndWaitUntilFinished()
|
||||
|
||||
guard localFileSystem.exists(mainWasmPath) else {
|
||||
guard fileSystem.exists(mainWasmPath) else {
|
||||
terminal.write(
|
||||
"Failed to build the main executable binary, fix the build errors and restart\n",
|
||||
inColor: .red
|
||||
|
@ -257,9 +257,16 @@ public final class Toolchain {
|
|||
"-Xswiftc", "-color-diagnostics",
|
||||
]
|
||||
|
||||
try ProcessRunner(builderArguments, terminal).waitUntilFinished()
|
||||
try Builder(
|
||||
arguments: builderArguments,
|
||||
mainWasmPath: testBundlePath,
|
||||
environment: .other,
|
||||
fileSystem,
|
||||
terminal
|
||||
)
|
||||
.runAndWaitUntilFinished()
|
||||
|
||||
guard localFileSystem.exists(testBundlePath) else {
|
||||
guard fileSystem.exists(testBundlePath) else {
|
||||
terminal.write(
|
||||
"Failed to build the test bundle, fix the build errors and restart\n",
|
||||
inColor: .red
|
||||
|
|
|
@ -84,9 +84,8 @@ struct Dev: ParsableCommand {
|
|||
let sources = try paths.flatMap { try localFileSystem.traverseRecursively($0) }
|
||||
|
||||
try Server(
|
||||
builderArguments: arguments,
|
||||
builder: Builder(arguments: arguments, mainWasmPath: mainWasmPath, localFileSystem, terminal),
|
||||
pathsToWatch: sources,
|
||||
mainWasmPath: mainWasmPath,
|
||||
customIndexContent: HTML.readCustomIndexPage(at: customIndexPage, on: localFileSystem),
|
||||
// swiftlint:disable:next force_try
|
||||
package: try! toolchain.package.get(),
|
||||
|
|
|
@ -37,15 +37,13 @@ final class Server {
|
|||
private var connections = Set<WebSocket>()
|
||||
private var subscriptions = [AnyCancellable]()
|
||||
private let watcher: Watcher
|
||||
private var builder: ProcessRunner?
|
||||
private let app: Application
|
||||
private let localURL: String
|
||||
private let skipAutoOpen: Bool
|
||||
|
||||
init(
|
||||
builderArguments: [String],
|
||||
builder: Builder,
|
||||
pathsToWatch: [AbsolutePath],
|
||||
mainWasmPath: AbsolutePath,
|
||||
customIndexContent: String?,
|
||||
package: SwiftToolchain.Package,
|
||||
verbose: Bool,
|
||||
|
@ -63,7 +61,7 @@ final class Server {
|
|||
app = Application(env)
|
||||
app.configure(
|
||||
port: port,
|
||||
mainWasmPath: mainWasmPath,
|
||||
mainWasmPath: builder.mainWasmPath,
|
||||
customIndexContent: customIndexContent,
|
||||
package: package,
|
||||
onWebSocketOpen: { [weak self] in
|
||||
|
@ -85,8 +83,8 @@ final class Server {
|
|||
for change in changes.map(\.pathString) {
|
||||
terminal.write("- \(change)\n", inColor: .cyan)
|
||||
}
|
||||
return ProcessRunner(builderArguments, terminal)
|
||||
.publisher
|
||||
return builder
|
||||
.run()
|
||||
.handleEvents(receiveCompletion: { [weak self] in
|
||||
guard case .finished = $0, let self = self else { return }
|
||||
|
||||
|
|
Loading…
Reference in New Issue