Skip to content

Commit c1ca79f

Browse files
committed
wip
1 parent b8a5f6f commit c1ca79f

File tree

7 files changed

+90
-30
lines changed

7 files changed

+90
-30
lines changed

Plugins/JExtractSwiftCommandPlugin/JExtractSwiftCommandPlugin.swift

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ import Foundation
1616
import PackagePlugin
1717

1818
@main
19-
final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
19+
final class JExtractSwiftCommandPlugin: SwiftJavaPluginProtocol, BuildToolPlugin, CommandPlugin {
2020

21-
var verbose: Bool = false
21+
var pluginName: String = "swift-java-command"
22+
var verbose: Bool = getEnvironmentBool("SWIFT_JAVA_VERBOSE")
2223

2324
/// Build the target before attempting to extract from it.
2425
/// This avoids trying to extract from broken sources.
@@ -49,7 +50,7 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
4950

5051
for target in context.package.targets {
5152
guard getSwiftJavaConfigPath(target: target) != nil else {
52-
log("Skipping target '\(target.name)', has no 'swift-java.config' file")
53+
log("[swift-java-command] Skipping jextract step: Missing swift-java.config for target '\(target.name)'")
5354
continue
5455
}
5556

@@ -94,14 +95,17 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
9495

9596
/// Perform the command on a specific target.
9697
func performCommand(context: PluginContext, target: Target, extraArguments _: [String]) throws {
97-
// Make sure the target can builds properly
98-
try self.packageManager.build(.target(target.name), parameters: .init())
99-
10098
guard let sourceModule = target.sourceModule else { return }
10199

102100
if self.buildInputs {
101+
// Make sure the target can builds properly
103102
log("Pre-building target '\(target.name)' before extracting sources...")
104-
try self.packageManager.build(.target(target.name), parameters: .init())
103+
let targetBuildResult = try self.packageManager.build(.target(target.name), parameters: .init())
104+
105+
guard targetBuildResult.succeeded else {
106+
print("[swift-java-command] Build of '\(target.name)' failed: \(targetBuildResult.logText)")
107+
return
108+
}
105109
}
106110

107111
let arguments = try prepareJExtractArguments(context: context, target: target)
@@ -146,11 +150,6 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
146150
}
147151
}
148152

149-
func log(_ message: @autoclosure () -> String, terminator: String = "\n") {
150-
if self.verbose {
151-
print("[swift-java-command] \(message())", terminator: terminator)
152-
}
153-
}
154153
}
155154

156155
// Mini coloring helper, since we cannot have dependencies we keep it minimal here

Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ import PackagePlugin
1818
fileprivate let Java2SwiftConfigFileName = "Java2Swift.config"
1919

2020
@main
21-
struct Java2SwiftBuildToolPlugin: BuildToolPlugin {
21+
struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
22+
23+
var pluginName: String = "swift-java-javac"
24+
var verbose: Bool = getEnvironmentBool("SWIFT_JAVA_VERBOSE")
25+
2226
func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] {
2327
guard let sourceModule = target.sourceModule else { return [] }
2428

@@ -87,9 +91,14 @@ struct Java2SwiftBuildToolPlugin: BuildToolPlugin {
8791
}
8892
arguments.append(configFile.path(percentEncoded: false))
8993

94+
guard let classes = config.classes else {
95+
log("Config at \(configFile) did not have 'classes' configured, skipping java2swift step.")
96+
return []
97+
}
98+
9099
/// Determine the set of Swift files that will be emitted by the Java2Swift
91100
/// tool.
92-
let outputSwiftFiles = config.classes.map { (javaClassName, swiftName) in
101+
let outputSwiftFiles = classes.map { (javaClassName, swiftName) in
93102
let swiftNestedName = swiftName.replacingOccurrences(of: ".", with: "+")
94103
return outputDirectory.appending(path: "\(swiftNestedName).swift")
95104
}
@@ -125,10 +134,15 @@ struct Java2SwiftBuildToolPlugin: BuildToolPlugin {
125134
arguments += [ "--swift-native-implementation", className]
126135
}
127136
}
137+
138+
guard let classes = config.classes else {
139+
log("Skipping java2swift step: Missing 'classes' key in swift-java.config at '\(configFile.path)'")
140+
return []
141+
}
128142

129143
return [
130144
.buildCommand(
131-
displayName: "Wrapping \(config.classes.count) Java classes target \(sourceModule.name) in Swift",
145+
displayName: "Wrapping \(classes.count) Java classes target \(sourceModule.name) in Swift",
132146
executable: try context.tool(named: "Java2Swift").url,
133147
arguments: arguments,
134148
inputFiles: [ configFile ] + compiledClassFiles,

Plugins/PluginsShared/PluginUtils.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@ func getSwiftJavaConfigPath(target: Target) -> String? {
4747
}
4848
}
4949

50+
func getEnvironmentBool(_ name: String) -> Bool {
51+
if let value = ProcessInfo.processInfo.environment[name] {
52+
switch value.lowercased() {
53+
case "true", "yes", "1": true
54+
case "false", "no", "0": false
55+
default: false
56+
}
57+
} else {
58+
false
59+
}
60+
}
61+
5062
extension PluginContext {
5163
var outputDirectoryJava: URL {
5264
self.pluginWorkDirectoryURL

Plugins/PluginsShared/SwiftJavaPluginErrors.swift renamed to Plugins/PluginsShared/SwiftJavaPlugin+Errors.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
enum SwiftJavaPluginError: Error {
16-
case missingConfiguration(sourceDir: String, key: String?)
16+
case missingConfiguration(sourceDir: String, key: String?, file: String = #file, line: UInt = #line)
1717
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
protocol SwiftJavaPluginProtocol {
16+
var verbose: Bool { get }
17+
var pluginName: String { get }
18+
19+
func log(_ message: @autoclosure () -> String, terminator: String)
20+
}
21+
22+
extension SwiftJavaPluginProtocol {
23+
func log(_ message: @autoclosure () -> String, terminator: String = "\n") {
24+
if self.verbose {
25+
print("[swift-java-command] \(message())", terminator: terminator)
26+
}
27+
}
28+
}

Plugins/SwiftJavaPlugin/JExtractSwiftPlugin.swift

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,36 @@ import Foundation
1616
import PackagePlugin
1717

1818
@main
19-
struct JExtractSwiftBuildToolPlugin: BuildToolPlugin {
19+
struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
20+
21+
var pluginName: String = "swift-java"
22+
var verbose: Bool = getEnvironmentBool("SWIFT_JAVA_VERBOSE")
23+
2024
func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] {
25+
let toolURL = try context.tool(named: "JExtractSwiftTool").url
26+
2127
guard let sourceModule = target.sourceModule else { return [] }
2228

2329
// Note: Target doesn't have a directoryURL counterpart to directory,
2430
// so we cannot eliminate this deprecation warning.
25-
let sourceDir = target.directory.string
26-
27-
let t = target.dependencies.first!
28-
switch (t) {
29-
case .target(let t):
30-
t.sourceModule
31-
case .product(let p):
32-
p.sourceModules
33-
@unknown default:
34-
fatalError("Unknown target dependency type: \(t)")
31+
for dependency in target.dependencies {
32+
switch (dependency) {
33+
case .target(let t):
34+
t.sourceModule
35+
case .product(let p):
36+
p.sourceModules
37+
@unknown default:
38+
fatalError("Unknown target dependency type: \(dependency)")
39+
}
3540
}
3641

37-
let toolURL = try context.tool(named: "JExtractSwiftTool").url
38-
42+
let sourceDir = target.directory.string
3943
let configuration = try readConfiguration(sourceDir: "\(sourceDir)")
44+
4045
guard let javaPackage = configuration.javaPackage else {
41-
throw SwiftJavaPluginError.missingConfiguration(sourceDir: "\(sourceDir)", key: "javaPackage")
46+
// throw SwiftJavaPluginError.missingConfiguration(sourceDir: "\(sourceDir)", key: "javaPackage")
47+
log("Skipping jextract step, no 'javaPackage' configuration in \(getSwiftJavaConfigPath(target: target) ?? "")")
48+
return []
4249
}
4350

4451
// We use the the usual maven-style structure of "src/[generated|main|test]/java/..."

0 commit comments

Comments
 (0)