Skip to content

Commit f4ed941

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 69dc9cb commit f4ed941

File tree

13 files changed

+102
-2
lines changed

13 files changed

+102
-2
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
@@ -14,6 +14,7 @@ add_library(PackageModel
1414
BuildSettings.swift
1515
Diagnostics.swift
1616
IdentityResolver.swift
17+
InstalledSwiftPMConfiguration.swift
1718
Manifest/Manifest.swift
1819
Manifest/PackageConditionDescription.swift
1920
Manifest/PackageDependencyDescription.swift
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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+
19+
public var description: String {
20+
return "\(major).\(minor).\(patch)"
21+
}
22+
}
23+
24+
let version: Int
25+
public let swiftSyntaxVersionForMacroTemplate: Version
26+
27+
public static var `default`: InstalledSwiftPMConfiguration {
28+
return .init(version: 0, swiftSyntaxVersionForMacroTemplate: .init(major: 0, minor: 0, patch: 0))
29+
}
30+
}

Sources/PackageModel/Toolchain.swift

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

37+
/// Configuration from the used toolchain.
38+
var installedSwiftPMConfiguration: InstalledSwiftPMConfiguration { get }
39+
3740
/// Path of the `clang` compiler.
3841
func getClangCompiler() throws -> AbsolutePath
3942

Sources/PackageModel/UserToolchain.swift

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

7777
public let isSwiftDevelopmentToolchain: Bool
7878

79+
public let installedSwiftPMConfiguration: InstalledSwiftPMConfiguration
80+
7981
/// Returns the runtime library for the given sanitizer.
8082
public func runtimeLibrary(for sanitizer: Sanitizer) throws -> AbsolutePath {
8183
// FIXME: This is only for SwiftPM development time support. It is OK
@@ -456,7 +458,8 @@ public final class UserToolchain: Toolchain {
456458
swiftSDK: SwiftSDK,
457459
environment: EnvironmentVariables = .process(),
458460
searchStrategy: SearchStrategy = .default,
459-
customLibrariesLocation: ToolchainConfiguration.SwiftPMLibrariesLocation? = nil
461+
customLibrariesLocation: ToolchainConfiguration.SwiftPMLibrariesLocation? = nil,
462+
customInstalledSwiftPMConfiguration: InstalledSwiftPMConfiguration? = nil
460463
) throws {
461464
self.swiftSDK = swiftSDK
462465
self.environment = environment
@@ -499,6 +502,18 @@ public final class UserToolchain: Toolchain {
499502
self.isSwiftDevelopmentToolchain = false
500503
#endif
501504

505+
if let customInstalledSwiftPMConfiguration = customInstalledSwiftPMConfiguration {
506+
self.installedSwiftPMConfiguration = customInstalledSwiftPMConfiguration
507+
} else {
508+
let path = self.swiftCompilerPath.parentDirectory.parentDirectory.appending(components: ["share", "pm", "config.json"])
509+
if localFileSystem.exists(path) {
510+
self.installedSwiftPMConfiguration = try JSONDecoder.makeWithDefaults().decode(path: path, fileSystem: localFileSystem, as: InstalledSwiftPMConfiguration.self)
511+
} else {
512+
// We *could* eventually make this an error, but not for a few releases.
513+
self.installedSwiftPMConfiguration = InstalledSwiftPMConfiguration(version: 0, swiftSyntaxVersionForMacroTemplate: .init(major: 509, minor: 0, patch: 0))
514+
}
515+
}
516+
502517
// Use the triple from destination or compute the host triple using swiftc.
503518
var triple = try swiftSDK.targetTriple ?? Triple.getHostTriple(usingSwiftCompiler: swiftCompilers.compile)
504519

Sources/SPMTestSupport/misc.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,3 +364,20 @@ extension RelativePath: ExpressibleByStringInterpolation {
364364
try! self.init(validating: value)
365365
}
366366
}
367+
368+
extension InitPackage {
369+
public convenience init(
370+
name: String,
371+
packageType: PackageType,
372+
destinationPath: AbsolutePath,
373+
fileSystem: FileSystem
374+
) throws {
375+
try self.init(
376+
name: name,
377+
options: InitPackageOptions(packageType: packageType),
378+
destinationPath: destinationPath,
379+
installedSwiftPMConfiguration: .default,
380+
fileSystem: fileSystem
381+
)
382+
}
383+
}

Sources/Workspace/InitPackage.swift

Lines changed: 8 additions & 1 deletion
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

@@ -260,7 +267,7 @@ public final class InitPackage {
260267
pkgParams.append("""
261268
dependencies: [
262269
// Depend on the latest Swift 5.9 prerelease of SwiftSyntax
263-
.package(url: "https://github.com/apple/swift-syntax.git", from: "509.0.0-swift-5.9-DEVELOPMENT-SNAPSHOT-2023-04-25-b"),
270+
.package(url: "https://github.com/apple/swift-syntax.git", from: "\(self.installedSwiftPMConfiguration.swiftSyntaxVersionForMacroTemplate.description)"),
264271
]
265272
""")
266273
}

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)