From b99075150cbd17062c1a01341088c8b8c8877a8e Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Fri, 5 Jul 2024 17:29:46 +0900 Subject: [PATCH] Invalidate manifest cache when `-Xbuild-tools-swiftc` changes --- Sources/PackageLoading/ManifestLoader.swift | 7 +++ .../ManifestLoaderCacheTests.swift | 63 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/Sources/PackageLoading/ManifestLoader.swift b/Sources/PackageLoading/ManifestLoader.swift index afdf56f8270..44925bd11cf 100644 --- a/Sources/PackageLoading/ManifestLoader.swift +++ b/Sources/PackageLoading/ManifestLoader.swift @@ -569,6 +569,7 @@ public final class ManifestLoader: ManifestLoaderProtocol { toolsVersion: toolsVersion, env: Environment.current.cachable, swiftpmVersion: SwiftVersion.current.displayString, + extraManifestFlags: self.extraManifestFlags, fileSystem: fileSystem ) } catch { @@ -1208,6 +1209,7 @@ extension ManifestLoader { toolsVersion: ToolsVersion, env: Environment, swiftpmVersion: String, + extraManifestFlags: [String], fileSystem: FileSystem ) throws { let manifestContents = try fileSystem.readFileContents(manifestPath).contents @@ -1217,6 +1219,7 @@ extension ManifestLoader { manifestContents: manifestContents, toolsVersion: toolsVersion, env: env, + extraManifestFlags: extraManifestFlags, swiftpmVersion: swiftpmVersion ) @@ -1239,6 +1242,7 @@ extension ManifestLoader { manifestContents: [UInt8], toolsVersion: ToolsVersion, env: Environment, + extraManifestFlags: [String], swiftpmVersion: String ) throws -> String { let stream = BufferedOutputByteStream() @@ -1250,6 +1254,9 @@ extension ManifestLoader { stream.send(key.rawValue).send(value) } stream.send(swiftpmVersion) + for flag in extraManifestFlags { + stream.send(flag) + } return stream.bytes.sha256Checksum } } diff --git a/Tests/PackageLoadingTests/ManifestLoaderCacheTests.swift b/Tests/PackageLoadingTests/ManifestLoaderCacheTests.swift index ebc2497c954..5878fabf017 100644 --- a/Tests/PackageLoadingTests/ManifestLoaderCacheTests.swift +++ b/Tests/PackageLoadingTests/ManifestLoaderCacheTests.swift @@ -267,6 +267,68 @@ final class ManifestLoaderCacheTests: XCTestCase { } } + func testCacheInvalidateOnBuildToolsFlags() async throws { + try UserToolchain.default.skipUnlessAtLeastSwift6() + + try await testWithTemporaryDirectory { path in + let fileSystem = InMemoryFileSystem() + let observability = ObservabilitySystem.makeForTesting() + + let manifestPath = path.appending(components: "pkg", "Package.swift") + try fileSystem.createDirectory(manifestPath.parentDirectory, recursive: true) + try fileSystem.writeFileContents( + manifestPath, + string: """ + import PackageDescription + let package = Package( + name: "Trivial", + targets: [ + .target( + name: "foo", + dependencies: []), + ] + ) + #if TEST_BUILD_FLAG + package.targets[0].name = "bar" + #endif + """ + ) + + try await check(expectCached: false, extraManifestFlags: [], targetName: "foo") + try await check(expectCached: true, extraManifestFlags: [], targetName: "foo") + // Cache key should take into account the extra flags. + try await check(expectCached: false, extraManifestFlags: ["-DTEST_BUILD_FLAG"], targetName: "bar") + try await check(expectCached: true, extraManifestFlags: ["-DTEST_BUILD_FLAG"], targetName: "bar") + // Cache should hit after back to original flags. + try await check(expectCached: true, extraManifestFlags: [], targetName: "foo") + + func check(expectCached: Bool, extraManifestFlags: [String], targetName: String) async throws { + let delegate = ManifestTestDelegate() + + let loader = ManifestLoader( + toolchain: try UserToolchain.default, + cacheDir: path, + extraManifestFlags: extraManifestFlags, + delegate: delegate + ) + + let manifest = try await XCTAsyncUnwrap(try await loader.load( + manifestPath: manifestPath, + packageKind: .root(manifestPath.parentDirectory), + toolsVersion: .current, + fileSystem: fileSystem, + observabilityScope: observability.topScope + )) + + XCTAssertNoDiagnostics(observability.diagnostics) + try await XCTAssertAsyncEqual(try await delegate.loaded(timeout: .seconds(1)), [manifestPath]) + try await XCTAssertAsyncEqual(try await delegate.parsed(timeout: .seconds(1)).count, expectCached ? 0 : 1) + XCTAssertEqual(manifest.displayName, "Trivial") + XCTAssertEqual(manifest.targets[0].name, targetName) + } + } + } + func testCacheInvalidationOnEnv() async throws { try UserToolchain.default.skipUnlessAtLeastSwift6() @@ -574,6 +636,7 @@ private func makeMockManifests( toolsVersion: ToolsVersion.current, env: [:], swiftpmVersion: SwiftVersion.current.displayString, + extraManifestFlags: [], fileSystem: fileSystem ) manifests[key] = ManifestLoader.EvaluationResult(