Skip to content

Commit 2ad1ce6

Browse files
xedinAnthonyLatsis
andauthored
[6.2] Cherry-pick of all of the recent swift package migrate related fixes (#8710)
Includes: - #8671 - #8677 - #8700 - #8699 --------- Co-authored-by: Anthony Latsis <[email protected]>
1 parent f6e00e6 commit 2ad1ce6

File tree

10 files changed

+1649
-790
lines changed

10 files changed

+1649
-790
lines changed

Sources/Commands/PackageCommands/Migrate.swift

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ extension SwiftPackageCommand {
8787

8888
let buildSystem = try await createBuildSystem(
8989
swiftCommandState,
90+
targets: self.options.targets,
9091
features: features
9192
)
9293

@@ -137,34 +138,46 @@ extension SwiftPackageCommand {
137138

138139
print("> Updating manifest.")
139140
for module in modules.map(\.module) {
140-
print("> Adding feature(s) to '\(module.name)'.")
141-
for feature in features {
142-
self.updateManifest(
143-
for: module.name,
144-
add: feature,
145-
using: swiftCommandState
146-
)
147-
}
141+
swiftCommandState.observabilityScope.emit(debug: "Adding feature(s) to '\(module.name)'.")
142+
self.updateManifest(
143+
for: module.name,
144+
add: features,
145+
using: swiftCommandState
146+
)
148147
}
149148
}
150149

151150
private func createBuildSystem(
152151
_ swiftCommandState: SwiftCommandState,
152+
targets: Set<String>? = .none,
153153
features: [SwiftCompilerFeature]
154154
) async throws -> BuildSystem {
155155
let toolsBuildParameters = try swiftCommandState.toolsBuildParameters
156-
var destinationBuildParameters = try swiftCommandState.productsBuildParameters
157-
158-
// Inject feature settings as flags. This is safe and not as invasive
159-
// as trying to update manifest because in adoption mode the features
160-
// can only produce warnings.
161-
for feature in features {
162-
destinationBuildParameters.flags.swiftCompilerFlags.append(contentsOf: [
163-
"-Xfrontend",
164-
"-enable-\(feature.upcoming ? "upcoming" : "experimental")-feature",
165-
"-Xfrontend",
166-
"\(feature.name):migrate",
167-
])
156+
let destinationBuildParameters = try swiftCommandState.productsBuildParameters
157+
158+
let modulesGraph = try await swiftCommandState.loadPackageGraph()
159+
160+
let addFeaturesToModule = { (module: ResolvedModule) in
161+
for feature in features {
162+
module.underlying.buildSettings.add(.init(values: [
163+
"-Xfrontend",
164+
"-enable-\(feature.upcoming ? "upcoming" : "experimental")-feature",
165+
"-Xfrontend",
166+
"\(feature.name):migrate",
167+
]), for: .OTHER_SWIFT_FLAGS)
168+
}
169+
}
170+
171+
if let targets {
172+
targets.lazy.compactMap {
173+
modulesGraph.module(for: $0)
174+
}.forEach(addFeaturesToModule)
175+
} else {
176+
for package in modulesGraph.rootPackages {
177+
package.modules.filter {
178+
$0.type != .plugin
179+
}.forEach(addFeaturesToModule)
180+
}
168181
}
169182

170183
return try await swiftCommandState.createBuildSystem(
@@ -173,34 +186,39 @@ extension SwiftPackageCommand {
173186
toolsBuildParameters: toolsBuildParameters,
174187
// command result output goes on stdout
175188
// ie "swift build" should output to stdout
176-
outputStream: TSCBasic.stdoutStream
189+
packageGraphLoader: {
190+
modulesGraph
191+
},
192+
outputStream: TSCBasic.stdoutStream,
193+
observabilityScope: swiftCommandState.observabilityScope
177194
)
178195
}
179196

180197
private func updateManifest(
181198
for target: String,
182-
add feature: SwiftCompilerFeature,
199+
add features: [SwiftCompilerFeature],
183200
using swiftCommandState: SwiftCommandState
184201
) {
185202
typealias SwiftSetting = SwiftPackageCommand.AddSetting.SwiftSetting
186203

187-
let setting: (SwiftSetting, String) = switch feature {
188-
case .upcoming(name: let name, migratable: _, enabledIn: _):
189-
(.upcomingFeature, "\(name)")
190-
case .experimental(name: let name, migratable: _):
191-
(.experimentalFeature, "\(name)")
204+
let settings: [(SwiftSetting, String)] = features.map {
205+
switch $0 {
206+
case .upcoming(name: let name, migratable: _, enabledIn: _):
207+
(.upcomingFeature, "\(name)")
208+
case .experimental(name: let name, migratable: _):
209+
(.experimentalFeature, "\(name)")
210+
}
192211
}
193212

194213
do {
195214
try SwiftPackageCommand.AddSetting.editSwiftSettings(
196215
of: target,
197216
using: swiftCommandState,
198-
[setting]
217+
settings,
218+
verbose: !self.globalOptions.logging.quiet
199219
)
200220
} catch {
201-
print(
202-
"! Couldn't update manifest due to - \(error); Please add '.enable\(feature.upcoming ? "Upcoming" : "Experimental")Feature(\"\(feature.name)\")' to target '\(target)' settings manually."
203-
)
221+
swiftCommandState.observabilityScope.emit(error: "Could not update manifest for '\(target)' (\(error)). Please enable '\(features.map(\.name).joined(separator: ", "))' features manually.")
204222
}
205223
}
206224

Sources/PackageModel/Module/Module.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ public class Module {
231231
public let others: [AbsolutePath]
232232

233233
/// The build settings assignments of this module.
234-
public let buildSettings: BuildSettings.AssignmentTable
234+
public package(set) var buildSettings: BuildSettings.AssignmentTable
235235

236236
@_spi(SwiftPMInternal)
237237
public let buildSettingsDescription: [TargetBuildSettingDescription.Setting]

Sources/PackageModelSyntax/AddSwiftSetting.swift

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,23 @@ public enum AddSwiftSetting {
9999
throw ManifestEditError.cannotFindTargets
100100
}
101101

102-
guard let targetCall = FunctionCallExprSyntax.findFirst(in: targetArray, matching: {
103-
if let nameArgument = $0.findArgument(labeled: "name"),
104-
let nameLiteral = nameArgument.expression.as(StringLiteralExprSyntax.self),
105-
nameLiteral.representedLiteralValue == target
106-
{
107-
return true
102+
let targetCall = targetArray
103+
.elements
104+
.lazy
105+
.compactMap {
106+
$0.expression.as(FunctionCallExprSyntax.self)
107+
}.first { targetCall in
108+
if let nameArgument = targetCall.findArgument(labeled: "name"),
109+
let nameLiteral = nameArgument.expression.as(StringLiteralExprSyntax.self),
110+
nameLiteral.representedLiteralValue == target
111+
{
112+
return true
113+
}
114+
115+
return false
108116
}
109-
return false
110-
}) else {
117+
118+
guard let targetCall else {
111119
throw ManifestEditError.cannotFindTarget(targetName: target)
112120
}
113121

0 commit comments

Comments
 (0)