Implement support for static resources in `carton dev` (#104)
This change requires `wasm-5.3-SNAPSHOT-2020-09-08-a` or later, therefore the default toolchain version has been bumped. Implements the `carton dev` part of #38, `carton bundle` support will be implemented in a future PR.
This commit is contained in:
parent
c051ab77b5
commit
9c94fd02b1
|
@ -67,7 +67,7 @@ is rarely needed, as `carton dev` install the recommended version of SwiftWasm a
|
|||
`carton sdk versions` lists all installed versions, and `carton sdk local` prints the version
|
||||
specified for the current project in the `.swift-version` file. You can however install SwiftWasm
|
||||
separately if needed, either by passing an archive URL to `carton sdk install` directly, or just
|
||||
specifying the snapshot version, like `carton sdk install wasm-DEVELOPMENT-SNAPSHOT-2020-06-07-a`.
|
||||
specifying the snapshot version, like `carton sdk install wasm-5.3-SNAPSHOT-2020-09-03-a`.
|
||||
|
||||
`carton dev` can also detect existing installations of `swiftenv`, so if you already have SwiftWasm
|
||||
installed via `swiftenv`, you don't have to do anything on top of that to start using `carton`.
|
||||
|
@ -116,9 +116,6 @@ which is now partially resolved with [a new argument available on
|
|||
`XCTMain`](https://github.com/apple/swift-corelibs-xctest/pull/306) and a custom [JSON test
|
||||
reporter](https://github.com/MaxDesiatov/XCTestJSONObserver/).
|
||||
|
||||
There are a few more commands on the roadmap to be implemented, such as `carton bundle` to produce an
|
||||
optimized production deployment bundle, SwiftPM resources support for bundled assets, and much more.
|
||||
|
||||
As cross-compiling to WebAssembly and running apps and tests remotely is not too dissimilar to Android
|
||||
development, or even development on macOS for Linux through Docker, `carton` could potentially become
|
||||
a generic tool for cross-platform Swift developers. I'm not developing any Android apps currently, but
|
||||
|
|
|
@ -19,13 +19,13 @@ import TSCBasic
|
|||
/**
|
||||
Simple Package structure from package dump
|
||||
*/
|
||||
struct Package: Codable {
|
||||
let name: String
|
||||
let products: [Product]
|
||||
let targets: [Target]
|
||||
let dependencies: [Dependency]?
|
||||
public struct Package: Codable {
|
||||
public let name: String
|
||||
public let products: [Product]
|
||||
public let targets: [Target]
|
||||
public let dependencies: [Dependency]?
|
||||
|
||||
struct Dependency: Codable {
|
||||
public struct Dependency: Codable {
|
||||
let name: String
|
||||
let requirement: Requirement
|
||||
|
||||
|
@ -59,20 +59,31 @@ struct ProductType: Codable {
|
|||
/**
|
||||
Simple Product structure from package dump
|
||||
*/
|
||||
struct Product: Codable {
|
||||
public struct Product: Codable {
|
||||
let name: String
|
||||
let type: ProductType
|
||||
}
|
||||
|
||||
enum TargetType: String, Codable {
|
||||
public enum TargetType: String, Codable {
|
||||
case regular
|
||||
case test
|
||||
}
|
||||
|
||||
struct Target: Codable {
|
||||
let name: String
|
||||
let type: TargetType
|
||||
let path: String?
|
||||
public struct Target: Codable {
|
||||
public let name: String
|
||||
public let type: TargetType
|
||||
public let path: String?
|
||||
public let resources: [Resource]
|
||||
}
|
||||
|
||||
public struct Resource: Codable {
|
||||
public let path: String
|
||||
public let rule: Rule
|
||||
|
||||
public enum Rule: String, Codable {
|
||||
case copy
|
||||
case process
|
||||
}
|
||||
}
|
||||
|
||||
public enum PackageType: String {
|
||||
|
|
|
@ -77,7 +77,7 @@ public final class Toolchain {
|
|||
|
||||
private let version: String
|
||||
private let swiftPath: AbsolutePath
|
||||
private let package: Result<Package, Error>
|
||||
public let package: Result<Package, Error>
|
||||
|
||||
public init(
|
||||
for versionSpec: String? = nil,
|
||||
|
|
|
@ -76,8 +76,10 @@ struct Dev: ParsableCommand {
|
|||
try Server(
|
||||
builderArguments: arguments,
|
||||
pathsToWatch: sources,
|
||||
mainWasmPath: mainWasmPath.pathString,
|
||||
mainWasmPath: mainWasmPath,
|
||||
customIndexContent: HTML.readCustomIndexPage(at: customIndexPage, on: localFileSystem),
|
||||
// swiftlint:disable:next force_try
|
||||
package: try! toolchain.package.get(),
|
||||
verbose: verbose,
|
||||
terminal
|
||||
).run()
|
||||
|
|
|
@ -13,12 +13,15 @@
|
|||
// limitations under the License.
|
||||
|
||||
import Foundation
|
||||
import SwiftToolchain
|
||||
import TSCBasic
|
||||
import Vapor
|
||||
|
||||
extension Application {
|
||||
func configure(
|
||||
mainWasmPath: String,
|
||||
mainWasmPath: AbsolutePath,
|
||||
customIndexContent: String?,
|
||||
package: SwiftToolchain.Package,
|
||||
onWebSocketOpen: @escaping (WebSocket) -> (),
|
||||
onWebSocketClose: @escaping (WebSocket) -> ()
|
||||
) {
|
||||
|
@ -38,9 +41,20 @@ extension Application {
|
|||
ws.onClose.whenComplete { _ in onWebSocketClose(ws) }
|
||||
}
|
||||
|
||||
get("main.wasm") { (request: Request) in
|
||||
get("main.wasm") {
|
||||
// stream the file
|
||||
request.eventLoop.makeSucceededFuture(request.fileio.streamFile(at: mainWasmPath))
|
||||
$0.eventLoop.makeSucceededFuture($0.fileio.streamFile(at: mainWasmPath.pathString))
|
||||
}
|
||||
|
||||
let buildDirectory = mainWasmPath.parentDirectory
|
||||
for target in package.targets where target.type == .regular && !target.resources.isEmpty {
|
||||
let resourcesPath = "\(package.name)_\(target.name).resources"
|
||||
get(.constant(resourcesPath), "**") {
|
||||
$0.eventLoop.makeSucceededFuture($0.fileio.streamFile(at: AbsolutePath(
|
||||
buildDirectory.appending(component: resourcesPath),
|
||||
$0.parameters.getCatchall().joined(separator: "/")
|
||||
).pathString))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import Combine
|
|||
#else
|
||||
import OpenCombine
|
||||
#endif
|
||||
import SwiftToolchain
|
||||
import TSCBasic
|
||||
import Vapor
|
||||
|
||||
|
@ -42,8 +43,9 @@ final class Server {
|
|||
init(
|
||||
builderArguments: [String],
|
||||
pathsToWatch: [AbsolutePath],
|
||||
mainWasmPath: String,
|
||||
mainWasmPath: AbsolutePath,
|
||||
customIndexContent: String?,
|
||||
package: SwiftToolchain.Package,
|
||||
verbose: Bool,
|
||||
_ terminal: TerminalController
|
||||
) throws {
|
||||
|
@ -55,6 +57,7 @@ final class Server {
|
|||
app.configure(
|
||||
mainWasmPath: mainWasmPath,
|
||||
customIndexContent: customIndexContent,
|
||||
package: package,
|
||||
onWebSocketOpen: { [weak self] in
|
||||
self?.connections.insert($0)
|
||||
},
|
||||
|
|
|
@ -1 +1 @@
|
|||
wasm-5.3-SNAPSHOT-2020-08-15-a
|
||||
wasm-5.3-SNAPSHOT-2020-09-03-a
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
"package": "JavaScriptKit",
|
||||
"repositoryURL": "https://github.com/kateinoigakukun/JavaScriptKit",
|
||||
"state": {
|
||||
"branch": "c90e82f",
|
||||
"branch": null,
|
||||
"revision": "c90e82fe1d576a2ccd1aae798380bf80be7885fb",
|
||||
"version": null
|
||||
"version": "0.5.0"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version:5.2
|
||||
// swift-tools-version:5.3
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
@ -9,13 +9,20 @@ let package = Package(
|
|||
.executable(name: "TestApp", targets: ["TestApp"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/kateinoigakukun/JavaScriptKit", .revision("c90e82f")),
|
||||
.package(
|
||||
url: "https://github.com/kateinoigakukun/JavaScriptKit",
|
||||
.upToNextMinor(from: "0.5.0")
|
||||
),
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package. A target can define a module or a test
|
||||
// suite. Targets can depend on other targets in this package, and on products in packages which
|
||||
// this package depends on.
|
||||
.target(name: "TestApp", dependencies: ["JavaScriptKit", "TestLibrary", "CustomPathTarget"]),
|
||||
.target(
|
||||
name: "TestApp",
|
||||
dependencies: ["JavaScriptKit", "TestLibrary", "CustomPathTarget"],
|
||||
resources: [.copy("data.json")]
|
||||
),
|
||||
.target(name: "TestLibrary"),
|
||||
.target(name: "CustomPathTarget", path: "CustomPathTarget"),
|
||||
.testTarget(name: "Tests", dependencies: ["TestLibrary"]),
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
["Test data"]
|
|
@ -38,3 +38,9 @@ buttonNode.onclick = .function { _ in
|
|||
crash()
|
||||
return .undefined
|
||||
}
|
||||
|
||||
let div = document.createElement!("div").object!
|
||||
div.innerHTML = .string(#"""
|
||||
<a href=\#(Bundle.module.path(forResource: "data", ofType: "json")!)>Link to a static resource</a>
|
||||
"""#)
|
||||
_ = body.appendChild!(div)
|
||||
|
|
Loading…
Reference in New Issue