-
-
Notifications
You must be signed in to change notification settings - Fork 70
Expand file tree
/
Copy pathBridgeJSBuildPlugin.swift
More file actions
100 lines (95 loc) · 4.04 KB
/
BridgeJSBuildPlugin.swift
File metadata and controls
100 lines (95 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#if canImport(PackagePlugin)
import PackagePlugin
import Foundation
/// Build plugin for runtime code generation with BridgeJS.
/// This plugin automatically generates bridge code between Swift and JavaScript
/// during each build process.
@main
struct BridgeJSBuildPlugin: BuildToolPlugin {
func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] {
guard let swiftSourceModuleTarget = target as? SwiftSourceModuleTarget else {
return []
}
var commands: [Command] = []
commands.append(try createExportSwiftCommand(context: context, target: swiftSourceModuleTarget))
if let importCommand = try createImportTSCommand(context: context, target: swiftSourceModuleTarget) {
commands.append(importCommand)
}
return commands
}
private func pathToConfigFile(target: SwiftSourceModuleTarget) -> URL {
return target.directoryURL.appending(path: "bridge-js.config.json")
}
private func createExportSwiftCommand(context: PluginContext, target: SwiftSourceModuleTarget) throws -> Command {
let outputSwiftPath = context.pluginWorkDirectoryURL.appending(path: "BridgeJS.ExportSwift.swift")
let outputSkeletonPath = context.pluginWorkDirectoryURL.appending(path: "BridgeJS.ExportSwift.json")
let inputSwiftFiles = target.sourceFiles.filter {
!$0.url.path.hasPrefix(context.pluginWorkDirectoryURL.path + "/")
}
.map(\.url)
let configFile = pathToConfigFile(target: target)
let inputFiles: [URL]
if FileManager.default.fileExists(atPath: configFile.path) {
inputFiles = inputSwiftFiles + [configFile]
} else {
inputFiles = inputSwiftFiles
}
return .buildCommand(
displayName: "Export Swift API",
executable: try context.tool(named: "BridgeJSTool").url,
arguments: [
"export",
"--output-skeleton",
outputSkeletonPath.path,
"--output-swift",
outputSwiftPath.path,
// Generate the output files even if nothing is exported not to surprise
// the build system.
"--always-write", "true",
] + inputSwiftFiles.map(\.path),
inputFiles: inputFiles,
outputFiles: [
outputSwiftPath
]
)
}
private func createImportTSCommand(context: PluginContext, target: SwiftSourceModuleTarget) throws -> Command? {
let outputSwiftPath = context.pluginWorkDirectoryURL.appending(path: "BridgeJS.ImportTS.swift")
let outputSkeletonPath = context.pluginWorkDirectoryURL.appending(path: "BridgeJS.ImportTS.json")
let inputTSFile = target.directoryURL.appending(path: "bridge-js.d.ts")
guard FileManager.default.fileExists(atPath: inputTSFile.path) else {
return nil
}
let configFile = pathToConfigFile(target: target)
let inputFiles: [URL]
if FileManager.default.fileExists(atPath: configFile.path) {
inputFiles = [inputTSFile, configFile]
} else {
inputFiles = [inputTSFile]
}
return .buildCommand(
displayName: "Import TypeScript API",
executable: try context.tool(named: "BridgeJSTool").url,
arguments: [
"import",
"--output-skeleton",
outputSkeletonPath.path,
"--output-swift",
outputSwiftPath.path,
"--module-name",
target.name,
// Generate the output files even if nothing is imported not to surprise
// the build system.
"--always-write", "true",
"--project",
context.package.directoryURL.appending(path: "tsconfig.json").path,
inputTSFile.path,
],
inputFiles: inputFiles,
outputFiles: [
outputSwiftPath
]
)
}
}
#endif