Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling stdout/stderr/terminationStatus from .prebuildCommand #6469

Open
aleksproger opened this issue Apr 23, 2023 · 0 comments
Open

Handling stdout/stderr/terminationStatus from .prebuildCommand #6469

aleksproger opened this issue Apr 23, 2023 · 0 comments

Comments

@aleksproger
Copy link
Contributor

aleksproger commented Apr 23, 2023

Description

Prerequisities

  • I'm working on wrapping Multiplatform C++ library and distributing it through SwiftPM.
  • C++ library uses google tests for unit testing, the gtests library itself was already wrapped in SwiftPM package
  • Library's SwiftPM package contains .executableTarget for C++ tests that use gtests

Goal

  • Provide the simplest build flow (just swift build && swift test) for clients of the library and make them unaware of internal tests details

Problem

  • To run C++ tests I cannot wrap them into .testTarget and use with native swift test - I have to create an executable target and run them as swift run CppTestsTarget. This at least will give the client an output of tests(to print in CI for example), while still I won't have the access to the results of tests from code.
  • In order to achieve more control and incorporate tests into native SwiftPM test flow I came up with this small hack:
final class CppTestsAdapter: XCTestCase {
    func test_AdaptCppTests() throws {
        let process = try Process.run(URL(fileURLWithPath: "/usr/bin/swift"), arguments: ["run", "CppTests"])
        process.waitUntilExit()
        XCTAssertEqual(process.terminationStatus, 0, "See the C++ unit tests output for details.")
    }
}

Proposal/Question

  • Whereas the hack from above works pretty stable and allow to achieve the desired control. I would have expected that I can do similar adaption using SwiftPM plugins, especially .prebuildCommand. So what I have tried to do is to create .prebuildCommand plugin which is incorporated into native .testTarget with Swift tests that I run. And I wanted to get results of the command, show them to the user and emit error/stop execution based on the termination status of the command. But, as I've discovered there are no way to redirect output and handle terminationStatus from build command while in this case it would be pretty useful.

So, IMHO it would be reasonable to have some kind of API in SwiftPM to handle such adoptions for external code and Plugins seem to be a good place. Probably such ideas have been considered while designing plugins feature and .buildCommand was sensibly been restricted in such way, but if it's true it would be interesting to hear why and maybe hear some ideas on whether it's correct to have access to the output of the commands. Maybe some future command types will allow for smith like this?

I understand that I can do it with CommandPlugin, but in this case I'll have to call it like swift package CppTestsAdapter which I no better than swift run CppTests.

Expected behavior

Have an API for build commands that allow to handle output and termination status of the command.

Actual behavior

No, such API exists as far as I know.

Steps to reproduce

No response

Swift Package Manager version/commit hash

No response

Swift & OS version (output of swift --version && uname -a)

swift-driver version: 1.62.15 Apple Swift version 5.7.1 (swiftlang-5.7.1.135.3 clang-1400.0.29.51)
Target: arm64-apple-macosx13.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants