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:
Max Desiatov 2020-09-14 10:36:09 +01:00 committed by GitHub
parent c051ab77b5
commit 9c94fd02b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 69 additions and 28 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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,

View File

@ -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()

View File

@ -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))
}
}
}
}

View File

@ -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)
},

View File

@ -1 +1 @@
wasm-5.3-SNAPSHOT-2020-08-15-a
wasm-5.3-SNAPSHOT-2020-09-03-a

View File

@ -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"
}
}
]

View File

@ -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"]),

View File

@ -0,0 +1 @@
["Test data"]

View File

@ -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)