Skip to content

Commit 569a283

Browse files
authored
Merge pull request #248 from ktoso/wip-converge-cli
2 parents 6e9d7da + 896b2be commit 569a283

File tree

77 files changed

+382
-234
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+382
-234
lines changed

Package.swift

Lines changed: 63 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
import CompilerPluginSupport
55
import PackageDescription
66

7-
import class Foundation.FileManager
8-
import class Foundation.ProcessInfo
7+
import Foundation
98

109
// Note: the JAVA_HOME environment variable must be set to point to where
1110
// Java is installed, e.g.,
@@ -25,9 +24,53 @@ func findJavaHome() -> String {
2524

2625
return home
2726
}
27+
28+
if let home = getJavaHomeFromLibexecJavaHome(),
29+
!home.isEmpty {
30+
return home
31+
}
2832

2933
fatalError("Please set the JAVA_HOME environment variable to point to where Java is installed.")
3034
}
35+
36+
/// On MacOS we can use the java_home tool as a fallback if we can't find JAVA_HOME environment variable.
37+
func getJavaHomeFromLibexecJavaHome() -> String? {
38+
let task = Process()
39+
task.executableURL = URL(fileURLWithPath: "/usr/libexec/java_home")
40+
41+
// Check if the executable exists before trying to run it
42+
guard FileManager.default.fileExists(atPath: task.executableURL!.path) else {
43+
print("/usr/libexec/java_home does not exist")
44+
return nil
45+
}
46+
47+
let pipe = Pipe()
48+
task.standardOutput = pipe
49+
task.standardError = pipe // Redirect standard error to the same pipe for simplicity
50+
51+
do {
52+
try task.run()
53+
task.waitUntilExit()
54+
55+
let data = pipe.fileHandleForReading.readDataToEndOfFile()
56+
let output = String(data: data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
57+
58+
if task.terminationStatus == 0 {
59+
return output
60+
} else {
61+
print("java_home terminated with status: \(task.terminationStatus)")
62+
// Optionally, log the error output for debugging
63+
if let errorOutput = String(data: pipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) {
64+
print("Error output: \(errorOutput)")
65+
}
66+
return nil
67+
}
68+
} catch {
69+
print("Error running java_home: \(error)")
70+
return nil
71+
}
72+
}
73+
3174
let javaHome = findJavaHome()
3275

3376
let javaIncludePath = "\(javaHome)/include"
@@ -92,8 +135,8 @@ let package = Package(
92135
),
93136

94137
.executable(
95-
name: "Java2Swift",
96-
targets: ["Java2Swift"]
138+
name: "swift-java",
139+
targets: ["SwiftJavaTool"]
97140
),
98141

99142
// ==== Plugin for building Java code
@@ -106,19 +149,12 @@ let package = Package(
106149

107150
// ==== Plugin for wrapping Java classes in Swift
108151
.plugin(
109-
name: "Java2SwiftPlugin",
152+
name: "SwiftJavaPlugin",
110153
targets: [
111-
"Java2SwiftPlugin"
154+
"SwiftJavaPlugin"
112155
]
113156
),
114157

115-
// ==== jextract-swift (extract Java accessors from Swift interface files)
116-
117-
.executable(
118-
name: "jextract-swift",
119-
targets: ["JExtractSwiftTool"]
120-
),
121-
122158
// Support library written in Swift for SwiftKit "Java"
123159
.library(
124160
name: "SwiftKitSwift",
@@ -127,8 +163,8 @@ let package = Package(
127163
),
128164

129165
.library(
130-
name: "JExtractSwift",
131-
targets: ["JExtractSwift"]
166+
name: "JExtractSwiftLib",
167+
targets: ["JExtractSwiftLib"]
132168
),
133169

134170
// ==== Plugin for wrapping Java classes in Swift
@@ -274,10 +310,10 @@ let package = Package(
274310
),
275311

276312
.plugin(
277-
name: "Java2SwiftPlugin",
313+
name: "SwiftJavaPlugin",
278314
capability: .buildTool(),
279315
dependencies: [
280-
"Java2Swift"
316+
"SwiftJavaTool"
281317
]
282318
),
283319

@@ -315,7 +351,7 @@ let package = Package(
315351
),
316352

317353
.target(
318-
name: "Java2SwiftLib",
354+
name: "SwiftJavaLib",
319355
dependencies: [
320356
.product(name: "SwiftBasicFormat", package: "swift-syntax"),
321357
.product(name: "SwiftSyntax", package: "swift-syntax"),
@@ -337,7 +373,7 @@ let package = Package(
337373
),
338374

339375
.executableTarget(
340-
name: "Java2Swift",
376+
name: "SwiftJavaTool",
341377
dependencies: [
342378
.product(name: "SwiftBasicFormat", package: "swift-syntax"),
343379
.product(name: "SwiftSyntax", package: "swift-syntax"),
@@ -346,7 +382,8 @@ let package = Package(
346382
"JavaKit",
347383
"JavaKitJar",
348384
"JavaKitNetwork",
349-
"Java2SwiftLib",
385+
"SwiftJavaLib",
386+
"JExtractSwiftLib",
350387
"JavaKitShared",
351388
],
352389

@@ -358,7 +395,7 @@ let package = Package(
358395
),
359396

360397
.target(
361-
name: "JExtractSwift",
398+
name: "JExtractSwiftLib",
362399
dependencies: [
363400
.product(name: "SwiftBasicFormat", package: "swift-syntax"),
364401
.product(name: "SwiftSyntax", package: "swift-syntax"),
@@ -373,21 +410,11 @@ let package = Package(
373410
]
374411
),
375412

376-
.executableTarget(
377-
name: "JExtractSwiftTool",
378-
dependencies: [
379-
"JExtractSwift",
380-
],
381-
swiftSettings: [
382-
.swiftLanguageMode(.v5)
383-
]
384-
),
385-
386413
.plugin(
387414
name: "JExtractSwiftPlugin",
388415
capability: .buildTool(),
389416
dependencies: [
390-
"JExtractSwiftTool"
417+
"SwiftJavaTool"
391418
]
392419
),
393420
.plugin(
@@ -397,7 +424,7 @@ let package = Package(
397424
permissions: [
398425
]),
399426
dependencies: [
400-
"JExtractSwiftTool"
427+
"SwiftJavaTool"
401428
]
402429
),
403430

@@ -430,8 +457,8 @@ let package = Package(
430457
),
431458

432459
.testTarget(
433-
name: "Java2SwiftTests",
434-
dependencies: ["Java2SwiftLib"],
460+
name: "SwiftJavaTests",
461+
dependencies: ["SwiftJavaLib"],
435462
swiftSettings: [
436463
.swiftLanguageMode(.v5),
437464
.unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"])
@@ -441,7 +468,7 @@ let package = Package(
441468
.testTarget(
442469
name: "JExtractSwiftTests",
443470
dependencies: [
444-
"JExtractSwift"
471+
"JExtractSwiftLib"
445472
],
446473
swiftSettings: [
447474
.swiftLanguageMode(.v5),

Plugins/JExtractSwiftCommandPlugin/JExtractSwiftCommandPlugin.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,21 +69,21 @@ final class JExtractSwiftCommandPlugin: SwiftJavaPluginProtocol, BuildToolPlugin
6969
let sourceDir = target.directory.string
7070

7171
let configuration = try readConfiguration(sourceDir: "\(sourceDir)")
72-
guard let javaPackage = configuration.javaPackage else {
73-
throw SwiftJavaPluginError.missingConfiguration(sourceDir: "\(sourceDir)", key: "javaPackage")
74-
}
7572

7673
var arguments: [String] = [
77-
"--swift-module", sourceModule.name,
78-
"--package-name", javaPackage,
79-
"--output-directory-java", context.outputDirectoryJava.path(percentEncoded: false),
80-
"--output-directory-swift", context.outputDirectorySwift.path(percentEncoded: false),
74+
"--input-swift", sourceDir,
75+
"--module-name", sourceModule.name,
76+
"--output-java", context.outputJavaDirectory.path(percentEncoded: false),
77+
"--output-swift", context.outputSwiftDirectory.path(percentEncoded: false),
8178
// TODO: "--build-cache-directory", ...
8279
// Since plugins cannot depend on libraries we cannot detect what the output files will be,
8380
// as it depends on the contents of the input files. Therefore we have to implement this as a prebuild plugin.
8481
// We'll have to make up some caching inside the tool so we don't re-parse files which have not changed etc.
8582
]
86-
arguments.append(sourceDir)
83+
// arguments.append(sourceDir) // TODO: we could do this shape maybe? to have the dirs last?
84+
if let package = configuration?.javaPackage, !package.isEmpty {
85+
["--java-package", package]
86+
}
8787

8888
return arguments
8989
}
@@ -130,7 +130,7 @@ final class JExtractSwiftCommandPlugin: SwiftJavaPluginProtocol, BuildToolPlugin
130130

131131
func runExtract(context: PluginContext, target: Target, arguments: [String]) throws {
132132
let process = Process()
133-
process.executableURL = try context.tool(named: "JExtractSwiftTool").url
133+
process.executableURL = try context.tool(named: "SwiftJavaTool").url
134134
process.arguments = arguments
135135

136136
do {

Plugins/JExtractSwiftPlugin/JExtractSwiftPlugin.swift

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
2222
var verbose: Bool = getEnvironmentBool("SWIFT_JAVA_VERBOSE")
2323

2424
func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] {
25-
let toolURL = try context.tool(named: "JExtractSwiftTool").url
25+
let toolURL = try context.tool(named: "SwiftJavaTool").url
2626

2727
guard let sourceModule = target.sourceModule else { return [] }
2828

@@ -42,28 +42,31 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
4242
let sourceDir = target.directory.string
4343
let configuration = try readConfiguration(sourceDir: "\(sourceDir)")
4444

45-
guard let javaPackage = configuration.javaPackage else {
45+
guard let javaPackage = configuration?.javaPackage else {
4646
// throw SwiftJavaPluginError.missingConfiguration(sourceDir: "\(sourceDir)", key: "javaPackage")
4747
log("Skipping jextract step, no 'javaPackage' configuration in \(getSwiftJavaConfigPath(target: target) ?? "")")
4848
return []
4949
}
5050

5151
// We use the the usual maven-style structure of "src/[generated|main|test]/java/..."
5252
// that is common in JVM ecosystem
53-
let outputDirectoryJava = context.outputDirectoryJava
54-
let outputDirectorySwift = context.outputDirectorySwift
53+
let outputJavaDirectory = context.outputJavaDirectory
54+
let outputSwiftDirectory = context.outputSwiftDirectory
5555

5656
var arguments: [String] = [
57-
"--swift-module", sourceModule.name,
58-
"--package-name", javaPackage,
59-
"--output-directory-java", outputDirectoryJava.path(percentEncoded: false),
60-
"--output-directory-swift", outputDirectorySwift.path(percentEncoded: false),
57+
"--input-swift", sourceDir,
58+
"--module-name", sourceModule.name,
59+
"--output-java", outputJavaDirectory.path(percentEncoded: false),
60+
"--output-swift", outputSwiftDirectory.path(percentEncoded: false),
6161
// TODO: "--build-cache-directory", ...
6262
// Since plugins cannot depend on libraries we cannot detect what the output files will be,
6363
// as it depends on the contents of the input files. Therefore we have to implement this as a prebuild plugin.
6464
// We'll have to make up some caching inside the tool so we don't re-parse files which have not changed etc.
6565
]
66-
arguments.append(sourceDir)
66+
// arguments.append(sourceDir)
67+
if !javaPackage.isEmpty {
68+
arguments.append(contentsOf: ["--java-package", javaPackage])
69+
}
6770

6871
return [
6972
.prebuildCommand(
@@ -72,7 +75,7 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
7275
arguments: arguments,
7376
// inputFiles: [ configFile ] + swiftFiles,
7477
// outputFiles: outputJavaFiles
75-
outputFilesDirectory: outputDirectorySwift
78+
outputFilesDirectory: outputSwiftDirectory
7679
)
7780
]
7881
}

Plugins/PluginsShared/PluginUtils.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,14 @@ func getEnvironmentBool(_ name: String) -> Bool {
6060
}
6161

6262
extension PluginContext {
63-
var outputDirectoryJava: URL {
63+
var outputJavaDirectory: URL {
6464
self.pluginWorkDirectoryURL
6565
.appending(path: "src")
6666
.appending(path: "generated")
6767
.appending(path: "java")
6868
}
6969

70-
var outputDirectorySwift: URL {
70+
var outputSwiftDirectory: URL {
7171
self.pluginWorkDirectoryURL
7272
.appending(path: "Sources")
7373
}

Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift renamed to Plugins/SwiftJavaPlugin/SwiftJavaPlugin.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import PackagePlugin
1818
fileprivate let SwiftJavaConfigFileName = "swift-java.config"
1919

2020
@main
21-
struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
21+
struct SwiftJavaBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
2222

2323
var pluginName: String = "swift-java"
2424
var verbose: Bool = getEnvironmentBool("SWIFT_JAVA_VERBOSE")
@@ -27,7 +27,7 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
2727
log("Create build commands for target '\(target.name)'")
2828
guard let sourceModule = target.sourceModule else { return [] }
2929

30-
let executable = try context.tool(named: "Java2Swift").url
30+
let executable = try context.tool(named: "SwiftJavaTool").url
3131
var commands: [Command] = []
3232

3333
// Note: Target doesn't have a directoryURL counterpart to directory,
@@ -38,7 +38,7 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
3838
// which we are generating Swift wrappers for Java classes.
3939
let configFile = URL(filePath: sourceDir)
4040
.appending(path: SwiftJavaConfigFileName)
41-
let config = try readConfiguration(sourceDir: sourceDir)
41+
let config = try readConfiguration(sourceDir: sourceDir) ?? Configuration()
4242

4343
log("Config on path: \(configFile.path(percentEncoded: false))")
4444
log("Config was: \(config)")
@@ -199,7 +199,7 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
199199
}
200200
}
201201

202-
extension Java2SwiftBuildToolPlugin {
202+
extension SwiftJavaBuildToolPlugin {
203203
func argumentsModuleName(sourceModule: Target) -> [String] {
204204
return [
205205
"--module-name", sourceModule.name

Samples/JavaDependencySampleApp/Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ let package = Package(
7676
.swiftLanguageMode(.v5),
7777
],
7878
plugins: [
79-
.plugin(name: "Java2SwiftPlugin", package: "swift-java"),
79+
.plugin(name: "SwiftJavaPlugin", package: "swift-java"),
8080
]
8181
),
8282

@@ -96,7 +96,7 @@ let package = Package(
9696
],
9797
plugins: [
9898
// .plugin(name: "SwiftJavaBootstrapJavaPlugin", package: "swift-java"),
99-
.plugin(name: "Java2SwiftPlugin", package: "swift-java"),
99+
.plugin(name: "SwiftJavaPlugin", package: "swift-java"),
100100
]
101101
),
102102

Samples/JavaKitSampleApp/Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ let package = Package(
7777
plugins: [
7878
.plugin(name: "JavaCompilerPlugin", package: "swift-java"),
7979
.plugin(name: "JExtractSwiftPlugin", package: "swift-java"),
80-
.plugin(name: "Java2SwiftPlugin", package: "swift-java"),
80+
.plugin(name: "SwiftJavaPlugin", package: "swift-java"),
8181
]
8282
),
8383
]

Samples/JavaProbablyPrime/Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ let package = Package(
3434
.swiftLanguageMode(.v5)
3535
],
3636
plugins: [
37-
.plugin(name: "Java2SwiftPlugin", package: "swift-java"),
37+
.plugin(name: "SwiftJavaPlugin", package: "swift-java"),
3838
]
3939
),
4040
]

0 commit comments

Comments
 (0)