diff --git a/Sources/SwiftToolchain/Toolchain.swift b/Sources/SwiftToolchain/Toolchain.swift index 238b80a8..9bf93f2d 100644 --- a/Sources/SwiftToolchain/Toolchain.swift +++ b/Sources/SwiftToolchain/Toolchain.swift @@ -15,8 +15,10 @@ import CartonHelpers import Foundation import TSCBasic +import TSCUtility private let compatibleJSKitRevision = "c90e82f" +public let compatibleJSKitVersion = Version(0, 5, 0) enum ToolchainError: Error, CustomStringConvertible { case directoryDoesNotExist(AbsolutePath) @@ -55,6 +57,20 @@ enum ToolchainError: Error, CustomStringConvertible { } } +extension Package.Dependency.Requirement { + var isJavaScriptKitCompatible: Bool { + if let upperBound = range?.first?.upperBound, let version = Version(string: upperBound) { + return version >= compatibleJSKitVersion + } + return revision == [compatibleJSKitRevision] || + exact?.compactMap { Version(string: $0) } == [compatibleJSKitVersion] + } + + var version: String { + revision?.first ?? range?.first?.lowerBound ?? "" + } +} + public final class Toolchain { private let fileSystem: FileSystem private let terminal: TerminalController @@ -177,17 +193,17 @@ public final class Toolchain { else { throw ToolchainError.noExecutableProduct } let package = try self.package.get() - if let jsKit = package.dependencies?.first(where: { $0.name == "JavaScriptKit" }), - jsKit.requirement.revision != ["c90e82f"] { - let version = jsKit.requirement.revision.flatMap { " (\($0[0]))" } ?? "" + !jsKit.requirement.isJavaScriptKitCompatible + { + let version = jsKit.requirement.version terminal.write( """ - This revision of JavaScriptKit\(version) is not known to be compatible with \ - carton \(cartonVersion). Please specify a JavaScriptKit dependency to revision \ - \(compatibleJSKitRevision) in your `Package.swift`.\n + This version of JavaScriptKit \(version) is not known to be compatible with \ + carton \(cartonVersion). Please specify a JavaScriptKit dependency on version \ + \(compatibleJSKitVersion) in your `Package.swift`.\n """, inColor: .red diff --git a/Sources/carton/Model/Template.swift b/Sources/carton/Model/Template.swift index 497bc2d4..e3985a6f 100644 --- a/Sources/carton/Model/Template.swift +++ b/Sources/carton/Model/Template.swift @@ -29,9 +29,11 @@ enum Templates: String, CaseIterable { protocol Template { static var description: String { get } - static func create(on fileSystem: FileSystem, - project: Project, - _ terminal: TerminalController) throws + static func create( + on fileSystem: FileSystem, + project: Project, + _ terminal: TerminalController + ) throws } enum TemplateError: Error { @@ -128,13 +130,22 @@ extension Templates { _ terminal: TerminalController ) throws { try fileSystem.changeCurrentWorkingDirectory(to: project.path) - try createPackage(type: .executable, - fileSystem: fileSystem, - project: project, - terminal) - try createManifest(fileSystem: fileSystem, - project: project, - terminal) + try createPackage(type: .executable, fileSystem: fileSystem, project: project, terminal) + try createManifest( + fileSystem: fileSystem, + project: project, + dependencies: [ + .init( + name: "JavaScriptKit", + url: "https://github.com/swiftwasm/JavaScriptKit", + version: .from(compatibleJSKitVersion.description) + ), + ], + targetDepencencies: [ + .init(name: "JavaScriptKit", package: "JavaScriptKit"), + ], + terminal + ) } } } @@ -160,11 +171,11 @@ extension Templates { .init( name: "Tokamak", url: "https://github.com/swiftwasm/Tokamak", - version: .branch("main") + version: .from("0.3.0") ), ], targetDepencencies: [ - .init(name: "TokamakDOM", package: "Tokamak"), + .init(name: "TokamakShim", package: "Tokamak"), ], terminal ) @@ -174,30 +185,26 @@ extension Templates { "main.swift" )) { """ - import TokamakDOM - import JavaScriptKit + import TokamakShim - let document = JSObjectRef.global.document.object! - let body = document.body.object! - body.style = "margin: 0;" - - let div = document.createElement!("div").object! - let renderer = DOMRenderer(ContentView(), div) - _ = body.appendChild!(div) - """ - .write(to: $0) - } - try fileSystem.writeFileContents( - project.path.appending(components: "Sources", project.name, "ContentView.swift") - ) { - """ - import TokamakDOM + struct TokamakApp: App { + var body: some Scene { + WindowGroup("Tokamak App") { + ContentView() + } + } + } struct ContentView: View { var body: some View { Text("Hello, world!") } } + + // @main attribute is not supported in SwiftPM apps. + // See https://bugs.swift.org/browse/SR-12683 for more details. + TokamakApp.main() + """ .write(to: $0) }