Skip to content

Commit 031a0f4

Browse files
authored
Merge pull request #2696 from abertelrud/SR-12613
[SR-12613] [ManifestLoader] Go back to using `-fileno` option for the separate JSON output
2 parents e3d5889 + bd4f8f6 commit 031a0f4

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

Sources/PackageDescription/PackageDescription.swift

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -368,14 +368,20 @@ public final class Package {
368368
private func registerExitHandler() {
369369
// Add a custom exit handler to cause the package's JSON representation
370370
// to be dumped at exit, if requested. Emitting it to a separate file
371-
// keeps any of the manifest's stdout output from interfering with it.
371+
// descriptor from stdout keeps any of the manifest's stdout output from
372+
// interfering with it.
372373
//
373374
// FIXME: This doesn't belong here, but for now is the mechanism we use
374375
// to get the interpreter to dump the package when attempting to load a
375376
// manifest.
376-
if let optIdx = CommandLine.arguments.firstIndex(of: "-json-output-file") {
377-
let jsonOutputFilePath = CommandLine.arguments[optIdx + 1]
378-
dumpPackageAtExit(self, to: jsonOutputFilePath)
377+
//
378+
// Warning: The `-fileno` flag is a contract between PackageDescription
379+
// and libSwiftPM, and since different versions of the two can be used
380+
// together, it isn't safe to rename or remove it.
381+
if let optIdx = CommandLine.arguments.firstIndex(of: "-fileno") {
382+
if let jsonOutputFileDesc = Int32(CommandLine.arguments[optIdx + 1]) {
383+
dumpPackageAtExit(self, to: jsonOutputFileDesc)
384+
}
379385
}
380386
}
381387
}
@@ -621,14 +627,14 @@ func manifestToJSON(_ package: Package) -> String {
621627
}
622628

623629
var errors: [String] = []
624-
private var dumpInfo: (package: Package, path: String)?
625-
private func dumpPackageAtExit(_ package: Package, to path: String) {
630+
private var dumpInfo: (package: Package, fileDesc: Int32)?
631+
private func dumpPackageAtExit(_ package: Package, to fileDesc: Int32) {
626632
func dump() {
627633
guard let dumpInfo = dumpInfo else { return }
628-
guard let fd = fopen(dumpInfo.path, "w") else { return }
634+
guard let fd = fdopen(dumpInfo.fileDesc, "w") else { return }
629635
fputs(manifestToJSON(dumpInfo.package), fd)
630636
fclose(fd)
631637
}
632-
dumpInfo = (package, path)
638+
dumpInfo = (package, fileDesc)
633639
atexit(dump)
634640
}

Sources/PackageLoading/ManifestLoader.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,9 +579,12 @@ public final class ManifestLoader: ManifestLoaderProtocol {
579579
return
580580
}
581581

582-
// Pass the path of a file to which the JSON representation of the manifest will be written.
582+
// Pass an open file descriptor of a file to which the JSON representation of the manifest will be written.
583583
let jsonOutputFile = tmpDir.appending(component: "\(packageIdentity)-output.json")
584-
cmd = [compiledManifestFile.pathString, "-json-output-file", jsonOutputFile.pathString]
584+
guard let jsonOutputFileDesc = fopen(jsonOutputFile.pathString, "w") else {
585+
throw StringError("couldn't create the manifest's JSON output file")
586+
}
587+
cmd = [compiledManifestFile.pathString, "-fileno", "\(fileno(jsonOutputFileDesc))"]
585588

586589
#if os(macOS)
587590
// If enabled, use sandbox-exec on macOS. This provides some safety against
@@ -599,6 +602,7 @@ public final class ManifestLoader: ManifestLoaderProtocol {
599602

600603
// Run the compiled manifest.
601604
let runResult = try Process.popen(arguments: cmd)
605+
fclose(jsonOutputFileDesc)
602606
let runOutput = try (runResult.utf8Output() + runResult.utf8stderrOutput()).spm_chuzzle()
603607
if let runOutput = runOutput {
604608
// Append the runtime output to any compiler output we've received.

0 commit comments

Comments
 (0)