Okay, note to future folks, this code will get you unspecified("internalError(\"unimplemented\")") in Xcode 15.2 because Xcode hasn't implemented the proxy?
However, using swift package plugin doit works. (doit being the very creative command plugin verb in this case)
func performCommand(context: PackagePlugin.PluginContext, arguments: [String]) async throws {
print("Did I make it to here?")
var parameters = PackageManager.BuildParameters()
//parameters.logging = .verbose //(Well not THAT chatty.)
print(parameters)
let result = try packageManager.build(.all(includingTests: false), parameters: parameters)
print("How about here?")
print(result)
}
As does:
let targets = context.package.targets
for target in targets {
print("trying for target... \(target.name)")
let result = try packageManager.build(.target(target.name), parameters: parameters)
print(result)
}
There are lots of examples:
https://github.com/search?q="packageManager.build"+language%3ASwift&type=code
The built code then runs fine with:
./.build/{hardware}/debug/DemoFruitStore fruit_list citrus
But then that can become
for target in targets {
print("trying for target... \(target.name)")
let result = try packageManager.build(.target(target.name), parameters: parameters)
if result.succeeded {
let runnableArtifacts = result.builtArtifacts.filter({$0.kind == .executable })
if let executable = runnableArtifacts.first {
//runProcess included below. Its just like runIt and shellOneShot
let message = try runProcess(URL(fileURLWithPath: executable.path.string), arguments: ["fruit_list", "citrus"])
print(message)
}
}
print(result.builtArtifacts)
}
And I have a good start on my one command-plugin pre-gamed build&run!
THANK YOU @ole !
For @hassila I think doing something along the lines of parameters.configuration = target.name.contains("PluginTool") ? .release : .debug might be a place to start, but honestly I would want to switch over to a 5.10 branch before trying, which is on my list of things to do in the next few weeks. If I swing back around I'll let you know!
For completeness:
@discardableResult
func runProcess(_ url:URL, arguments:[String] = []) throws -> String {
let task = Process()
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.arguments = arguments
task.standardInput = nil
task.executableURL = url
try task.run()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)!
task.waitUntilExit()
if task.terminationStatus == 0 || task.terminationStatus == 2 {
return output
} else {
print(output)
throw CommandError.unknownError(exitCode: task.terminationStatus)
}
}