Skip to content

Commit 36c3619

Browse files
committed
Read SwiftSyntax version for macro template from a configuration file
In 5.9 we're using a version that's hard-coded in the template, but that is annoying to maintain. It also seems like ideally we would be using a version that's aligned with the toolchain that's being used. This adds a new configuration file that we can ship as 'usr/share/pm/config.json' in the toolchain to configure this. There's a fallback to the 5.9 version if we can't find the config and also a way to customize it when instantiating a `UserToolchain` in case a client needs to do that. rdar://113287350
1 parent 9ae01ed commit 36c3619

File tree

13 files changed

+110
-3
lines changed

13 files changed

+110
-3
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ Package.resolved
1717
*.pyc
1818
.docc-build
1919
.vscode
20+
Utilities/InstalledSwiftPMConfiguration/config.json

Sources/Commands/PackageTools/Init.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ extension SwiftPackageTool {
5151
name: packageName,
5252
packageType: initMode,
5353
destinationPath: cwd,
54+
installedSwiftPMConfiguration: swiftTool.getHostToolchain().installedSwiftPMConfiguration,
5455
fileSystem: swiftTool.fileSystem
5556
)
5657
initPackage.progressReporter = { message in

Sources/PackageModel/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ add_library(PackageModel
1515
DependencyMapper.swift
1616
Diagnostics.swift
1717
IdentityResolver.swift
18+
InstalledSwiftPMConfiguration.swift
1819
Manifest/Manifest.swift
1920
Manifest/PackageConditionDescription.swift
2021
Manifest/PackageDependencyDescription.swift
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
public struct InstalledSwiftPMConfiguration: Codable {
14+
public struct Version: Codable, CustomStringConvertible {
15+
let major: Int
16+
let minor: Int
17+
let patch: Int
18+
let prereleaseIdentifier: String?
19+
20+
public init(major: Int, minor: Int, patch: Int, prereleaseIdentifier: String? = nil) {
21+
self.major = major
22+
self.minor = minor
23+
self.patch = patch
24+
self.prereleaseIdentifier = prereleaseIdentifier
25+
}
26+
27+
public var description: String {
28+
return "\(major).\(minor).\(patch).\(prereleaseIdentifier.map { "-\($0)" } ?? "")"
29+
}
30+
}
31+
32+
let version: Int
33+
public let swiftSyntaxVersionForMacroTemplate: Version
34+
35+
public static var `default`: InstalledSwiftPMConfiguration {
36+
return .init(version: 0, swiftSyntaxVersionForMacroTemplate: .init(major: 509, minor: 0, patch: 0))
37+
}
38+
}

Sources/PackageModel/Toolchain.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public protocol Toolchain {
4040
/// An array of paths to search for libraries at link time.
4141
var librarySearchPaths: [AbsolutePath] { get }
4242

43+
/// Configuration from the used toolchain.
44+
var installedSwiftPMConfiguration: InstalledSwiftPMConfiguration { get }
45+
4346
/// Path of the `clang` compiler.
4447
func getClangCompiler() throws -> AbsolutePath
4548

Sources/PackageModel/UserToolchain.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ public final class UserToolchain: Toolchain {
8686

8787
public let isSwiftDevelopmentToolchain: Bool
8888

89+
public let installedSwiftPMConfiguration: InstalledSwiftPMConfiguration
90+
8991
/// Returns the runtime library for the given sanitizer.
9092
public func runtimeLibrary(for sanitizer: Sanitizer) throws -> AbsolutePath {
9193
// FIXME: This is only for SwiftPM development time support. It is OK
@@ -475,7 +477,8 @@ public final class UserToolchain: Toolchain {
475477
swiftSDK: SwiftSDK,
476478
environment: EnvironmentVariables = .process(),
477479
searchStrategy: SearchStrategy = .default,
478-
customLibrariesLocation: ToolchainConfiguration.SwiftPMLibrariesLocation? = nil
480+
customLibrariesLocation: ToolchainConfiguration.SwiftPMLibrariesLocation? = nil,
481+
customInstalledSwiftPMConfiguration: InstalledSwiftPMConfiguration? = nil
479482
) throws {
480483
self.swiftSDK = swiftSDK
481484
self.environment = environment
@@ -518,6 +521,18 @@ public final class UserToolchain: Toolchain {
518521
self.isSwiftDevelopmentToolchain = false
519522
#endif
520523

524+
if let customInstalledSwiftPMConfiguration = customInstalledSwiftPMConfiguration {
525+
self.installedSwiftPMConfiguration = customInstalledSwiftPMConfiguration
526+
} else {
527+
let path = self.swiftCompilerPath.parentDirectory.parentDirectory.appending(components: ["share", "pm", "config.json"])
528+
if localFileSystem.exists(path) {
529+
self.installedSwiftPMConfiguration = try JSONDecoder.makeWithDefaults().decode(path: path, fileSystem: localFileSystem, as: InstalledSwiftPMConfiguration.self)
530+
} else {
531+
// We *could* eventually make this an error, but not for a few releases.
532+
self.installedSwiftPMConfiguration = InstalledSwiftPMConfiguration.default
533+
}
534+
}
535+
521536
// Use the triple from destination or compute the host triple using swiftc.
522537
var triple = try swiftSDK.targetTriple ?? Triple.getHostTriple(usingSwiftCompiler: swiftCompilers.compile)
523538

Sources/SPMTestSupport/misc.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,3 +369,20 @@ extension RelativePath: ExpressibleByStringInterpolation {
369369
try! self.init(validating: value)
370370
}
371371
}
372+
373+
extension InitPackage {
374+
public convenience init(
375+
name: String,
376+
packageType: PackageType,
377+
destinationPath: AbsolutePath,
378+
fileSystem: FileSystem
379+
) throws {
380+
try self.init(
381+
name: name,
382+
options: InitPackageOptions(packageType: packageType),
383+
destinationPath: destinationPath,
384+
installedSwiftPMConfiguration: .default,
385+
fileSystem: fileSystem
386+
)
387+
}
388+
}

Sources/Workspace/InitPackage.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ public final class InitPackage {
6969
/// The options for package to create.
7070
let options: InitPackageOptions
7171

72+
/// Configuration from the used toolchain.
73+
let installedSwiftPMConfiguration: InstalledSwiftPMConfiguration
74+
7275
/// The name of the package to create.
7376
let pkgname: String
7477

@@ -85,12 +88,14 @@ public final class InitPackage {
8588
name: String,
8689
packageType: PackageType,
8790
destinationPath: AbsolutePath,
91+
installedSwiftPMConfiguration: InstalledSwiftPMConfiguration,
8892
fileSystem: FileSystem
8993
) throws {
9094
try self.init(
9195
name: name,
9296
options: InitPackageOptions(packageType: packageType),
9397
destinationPath: destinationPath,
98+
installedSwiftPMConfiguration: installedSwiftPMConfiguration,
9499
fileSystem: fileSystem
95100
)
96101
}
@@ -100,12 +105,14 @@ public final class InitPackage {
100105
name: String,
101106
options: InitPackageOptions,
102107
destinationPath: AbsolutePath,
108+
installedSwiftPMConfiguration: InstalledSwiftPMConfiguration,
103109
fileSystem: FileSystem
104110
) throws {
105111
self.options = options
106112
self.pkgname = name
107113
self.moduleName = name.spm_mangledToC99ExtendedIdentifier()
108114
self.destinationPath = destinationPath
115+
self.installedSwiftPMConfiguration = installedSwiftPMConfiguration
109116
self.fileSystem = fileSystem
110117
}
111118

@@ -259,8 +266,7 @@ public final class InitPackage {
259266
} else if packageType == .macro {
260267
pkgParams.append("""
261268
dependencies: [
262-
// Depend on the Swift 5.9 release of SwiftSyntax
263-
.package(url: "https://github.com/apple/swift-syntax.git", from: "509.0.0"),
269+
.package(url: "https://github.com/apple/swift-syntax.git", from: "\(self.installedSwiftPMConfiguration.swiftSyntaxVersionForMacroTemplate.description)"),
264270
]
265271
""")
266272
}

Tests/BuildTests/MockBuildTestHelper.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct MockToolchain: PackageModel.Toolchain {
3333
let isSwiftDevelopmentToolchain = false
3434
let swiftPluginServerPath: AbsolutePath? = nil
3535
let extraFlags = PackageModel.BuildFlags()
36+
let installedSwiftPMConfiguration = InstalledSwiftPMConfiguration.default
3637

3738
func getClangCompiler() throws -> AbsolutePath {
3839
return "/fake/path/to/clang"

Tests/WorkspaceTests/InitTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ class InitTests: XCTestCase {
286286
name: "Foo",
287287
options: options,
288288
destinationPath: packageRoot,
289+
installedSwiftPMConfiguration: .default,
289290
fileSystem: localFileSystem
290291
)
291292
try initPackage.writePackageStructure()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// swift-tools-version: 5.9
2+
3+
import PackageDescription
4+
5+
let package = Package(
6+
name: "InstalledSwiftPMConfiguration",
7+
targets: [
8+
.executableTarget(
9+
name: "InstalledSwiftPMConfiguration"
10+
),
11+
]
12+
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../Sources/PackageModel/InstalledSwiftPMConfiguration.swift
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Foundation
2+
3+
@main
4+
struct Exec {
5+
static func main() throws {
6+
let config = InstalledSwiftPMConfiguration(version: 1, swiftSyntaxVersionForMacroTemplate: .init(major: 509, minor: 0, patch: 0))
7+
let data = try JSONEncoder().encode(config)
8+
try data.write(to: URL(fileURLWithPath: "config.json"))
9+
}
10+
}

0 commit comments

Comments
 (0)