Skip to content

Commit 9d3663f

Browse files
committed
Add sentinal file in scratchpath
Add a sentinal file (one for each build configuration) in the scratch path that contains the contents of the last build system used to build said configuration. Relates to: swiftlang/sourcekit-lsp#2576
1 parent 0f83708 commit 9d3663f

9 files changed

Lines changed: 295 additions & 32 deletions

File tree

Sources/CoreCommands/SwiftCommandState.swift

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ extension SwiftCommand {
130130
)
131131
defer {
132132
_ = createCacheDirFile(inDirectory: swiftCommandState.scratchDirectory)
133+
_ = createBuildSystemFile(
134+
inDirectory: swiftCommandState.scratchDirectory,
135+
for: swiftCommandState.options.build.configuration ?? swiftCommandState.preferredBuildConfiguration,
136+
buildSystem: swiftCommandState.options.build.buildSystem,
137+
)
133138
}
134139

135140
// We use this to attempt to catch misuse of the locking APIs since we only release the lock from here.
@@ -164,7 +169,8 @@ extension SwiftCommand {
164169

165170
package func createCacheDirFile(
166171
inDirectory directory: AbsolutePath,
167-
_ fileSystem: FileSystem = localFileSystem) -> AbsolutePath? {
172+
_ fileSystem: FileSystem = localFileSystem,
173+
) -> AbsolutePath? {
168174
// https://bford.info/cachedir/
169175
let path = directory.appending("CACHEDIR.TAG")
170176
do {
@@ -181,8 +187,25 @@ package func createCacheDirFile(
181187
// Don't error out if we fail to create the CACHEDIR.TAG file, as this is not critical to the functioning of the tool.
182188
return nil
183189
}
190+
}
184191

192+
package func createBuildSystemFile(
193+
inDirectory directory: AbsolutePath,
194+
for configuration: BuildConfiguration,
195+
buildSystem: BuildSystemProvider.Kind,
196+
fileSystem fs: FileSystem = localFileSystem,
197+
) -> AbsolutePath? {
198+
let path = directory.appending(".buildSystem_\(configuration)")
199+
do {
200+
try fs.createDirectory(path.parentDirectory, recursive: true)
201+
try fs.writeFileContents(path, string: "\(buildSystem)")
202+
return path
203+
} catch {
204+
// Don't error out if we fail to create the file, as this is not critical to the functioning of the tool.
205+
return nil
206+
}
185207
}
208+
186209
public protocol AsyncSwiftCommand: AsyncParsableCommand, _SwiftCommand {
187210
func run(_ swiftCommandState: SwiftCommandState) async throws
188211
var addCacheDirTagFile: Bool { get }
@@ -206,6 +229,11 @@ extension AsyncSwiftCommand {
206229
if self.addCacheDirTagFile {
207230
_ = createCacheDirFile(inDirectory: swiftCommandState.scratchDirectory)
208231
}
232+
_ = createBuildSystemFile(
233+
inDirectory: swiftCommandState.scratchDirectory,
234+
for: swiftCommandState.options.build.configuration ?? swiftCommandState.preferredBuildConfiguration,
235+
buildSystem: swiftCommandState.options.build.buildSystem,
236+
)
209237
}
210238

211239
// We use this to attempt to catch misuse of the locking APIs since we only release the lock from here.

Sources/_InternalTestSupport/SwiftTesting+Helpers.swift

Lines changed: 80 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import Testing
1717
fileprivate func fileErrorMessage(
1818
at path: AbsolutePath,
1919
prefix: Comment?,
20+
fileSystem fs: FileSystem = localFileSystem,
2021
comment: Comment,
2122
) -> Comment {
2223
let commentPrefix =
@@ -29,22 +30,24 @@ fileprivate func fileErrorMessage(
2930
let commentSuffix: String
3031
do {
3132
let parentDir = path.parentDirectory
32-
commentSuffix = try " Directory contents of \(parentDir) : \(localFileSystem.getDirectoryContents(parentDir))."
33+
commentSuffix = try " Directory contents of \(parentDir) : \(fs.getDirectoryContents(parentDir))."
3334
} catch {
3435
commentSuffix = ""
3536
}
36-
return Comment("\(commentPrefix)\(comment) \(commentSuffix).")
37+
return Comment("\(commentPrefix)\(comment)\(commentSuffix)")
3738
}
3839
public func expectFileExists(
3940
at path: AbsolutePath,
4041
_ comment: Comment? = nil,
42+
fileSystem fs: FileSystem = localFileSystem,
4143
sourceLocation: SourceLocation = #_sourceLocation,
4244
) {
4345
#expect(
44-
localFileSystem.exists(path),
46+
fs.exists(path),
4547
fileErrorMessage(
4648
at: path,
4749
prefix: comment,
50+
fileSystem: fs,
4851
comment: "File '\(path)' does not exist.",
4952
),
5053
sourceLocation: sourceLocation,
@@ -54,44 +57,81 @@ public func expectFileExists(
5457
public func requireFileExists(
5558
at path: AbsolutePath,
5659
_ comment: Comment? = nil,
60+
fileSystem fs: FileSystem = localFileSystem,
5761
sourceLocation: SourceLocation = #_sourceLocation,
5862
) throws {
5963
try #require(
60-
localFileSystem.exists(path),
64+
fs.exists(path),
6165
fileErrorMessage(
6266
at: path,
6367
prefix: comment,
68+
fileSystem: fs,
6469
comment: "File '\(path)' does not exist.",
6570
),
6671
sourceLocation: sourceLocation,
6772
)
6873
}
6974

75+
@available(*, deprecated, message: "use `expectFileDoesNotExist` instead")
7076
public func expectFileDoesNotExists(
7177
at path: AbsolutePath,
7278
_ comment: Comment? = nil,
79+
fileSystem fs: FileSystem = localFileSystem,
80+
sourceLocation: SourceLocation = #_sourceLocation,
81+
) {
82+
expectFileDoesNotExist(
83+
at: path,
84+
comment,
85+
fileSystem: fs,
86+
sourceLocation: sourceLocation,
87+
)
88+
}
89+
90+
public func expectFileDoesNotExist(
91+
at path: AbsolutePath,
92+
_ comment: Comment? = nil,
93+
fileSystem fs: FileSystem = localFileSystem,
7394
sourceLocation: SourceLocation = #_sourceLocation,
7495
) {
7596
#expect(
76-
!localFileSystem.exists(path),
97+
!fs.exists(path),
7798
fileErrorMessage(
7899
at: path,
79100
prefix: comment,
101+
fileSystem: fs,
80102
comment: "File: '\(path)' was not expected to exist, but does.",
81103
),
82104
sourceLocation: sourceLocation,
83105
)
84106
}
107+
108+
@available(*, deprecated, message: "use `requireFileDoesNotExist` instead")
85109
public func requireFileDoesNotExists(
86110
at path: AbsolutePath,
87111
_ comment: Comment? = nil,
112+
fileSystem fs: FileSystem = localFileSystem,
113+
sourceLocation: SourceLocation = #_sourceLocation,
114+
) throws {
115+
try requireFileDoesNotExist(
116+
at: path,
117+
comment,
118+
fileSystem: fs,
119+
sourceLocation: sourceLocation,
120+
)
121+
}
122+
123+
public func requireFileDoesNotExist(
124+
at path: AbsolutePath,
125+
_ comment: Comment? = nil,
126+
fileSystem fs: FileSystem = localFileSystem,
88127
sourceLocation: SourceLocation = #_sourceLocation,
89128
) throws {
90129
try #require(
91-
!localFileSystem.exists(path),
130+
!fs.exists(path),
92131
fileErrorMessage(
93132
at: path,
94133
prefix: comment,
134+
fileSystem: fs,
95135
comment: "File: '\(path)' was not expected to exist, but does.",
96136
),
97137
sourceLocation: sourceLocation,
@@ -101,6 +141,7 @@ public func requireFileDoesNotExists(
101141
public func expectFileIsExecutable(
102142
at fixturePath: AbsolutePath,
103143
_ comment: Comment? = nil,
144+
fileSystem fs: FileSystem = localFileSystem,
104145
sourceLocation: SourceLocation = #_sourceLocation,
105146
) {
106147
let commentPrefix =
@@ -110,15 +151,16 @@ public func expectFileIsExecutable(
110151
""
111152
}
112153
#expect(
113-
localFileSystem.isExecutableFile(fixturePath),
154+
fs.isExecutableFile(fixturePath),
114155
"\(commentPrefix)File '\(fixturePath)' expected to be executable, but is not.",
115156
sourceLocation: sourceLocation,
116157
)
117158
}
118159

119160
private func directoryExistsErrorMessage(
120161
for path: AbsolutePath,
121-
comment: Comment?
162+
comment: Comment?,
163+
fileSystem fs: FileSystem = localFileSystem,
122164
) -> Comment {
123165
let commentPrefix =
124166
if let comment {
@@ -128,7 +170,7 @@ private func directoryExistsErrorMessage(
128170
}
129171
let msgSuffix: String
130172
do {
131-
msgSuffix = try "Directory contents: \(localFileSystem.getDirectoryContents(path))"
173+
msgSuffix = try "Directory contents: \(fs.getDirectoryContents(path))"
132174
} catch {
133175
msgSuffix = ""
134176
}
@@ -138,11 +180,11 @@ private func directoryExistsErrorMessage(
138180
public func requireDirectoryExists(
139181
at path: AbsolutePath,
140182
_ comment: Comment? = nil,
141-
fileSystem: FileSystem = localFileSystem,
183+
fileSystem fs: FileSystem = localFileSystem,
142184
sourceLocation: SourceLocation = #_sourceLocation,
143185
) throws {
144186
try #require(
145-
localFileSystem.isDirectory(path),
187+
fs.isDirectory(path),
146188
directoryExistsErrorMessage(for: path, comment: comment),
147189
sourceLocation: sourceLocation,
148190
)
@@ -151,27 +193,48 @@ public func requireDirectoryExists(
151193
public func expectDirectoryExists(
152194
at path: AbsolutePath,
153195
_ comment: Comment? = nil,
196+
fileSystem fs: FileSystem = localFileSystem,
154197
sourceLocation: SourceLocation = #_sourceLocation,
155198
) {
156199
#expect(
157-
localFileSystem.isDirectory(path),
158-
directoryExistsErrorMessage(for: path, comment: comment),
200+
fs.isDirectory(path),
201+
directoryExistsErrorMessage(for: path, comment: comment, fileSystem: fs),
159202
sourceLocation: sourceLocation,
160203
)
161204
}
162205

206+
public func requireDirectoryDoesNotExist(
207+
at path: AbsolutePath,
208+
fileSystem fs: FileSystem = localFileSystem,
209+
sourceLocation: SourceLocation = #_sourceLocation,
210+
) throws {
211+
let msgSuffix: String
212+
do {
213+
msgSuffix = try "Directory contents: \(fs.getDirectoryContents(path))"
214+
} catch {
215+
msgSuffix = ""
216+
}
217+
try #require(
218+
!fs.isDirectory(path),
219+
"Directory exists unexpectedly: '\(path)'.\(msgSuffix)",
220+
sourceLocation: sourceLocation,
221+
)
222+
}
223+
224+
163225
public func expectDirectoryDoesNotExist(
164226
at path: AbsolutePath,
227+
fileSystem fs: FileSystem = localFileSystem,
165228
sourceLocation: SourceLocation = #_sourceLocation,
166229
) {
167230
let msgSuffix: String
168231
do {
169-
msgSuffix = try "Directory contents: \(localFileSystem.getDirectoryContents(path))"
232+
msgSuffix = try "Directory contents: \(fs.getDirectoryContents(path))"
170233
} catch {
171234
msgSuffix = ""
172235
}
173236
#expect(
174-
!localFileSystem.isDirectory(path),
237+
!fs.isDirectory(path),
175238
"Directory exists unexpectedly: '\(path)'.\(msgSuffix)",
176239
sourceLocation: sourceLocation,
177240
)
@@ -181,10 +244,11 @@ public func expectDirectoryDoesNotExist(
181244
package func expectDirectoryContainsFile(
182245
dir: AbsolutePath,
183246
filename: String,
247+
fileSystem fs: FileSystem = localFileSystem,
184248
sourceLocation: SourceLocation = #_sourceLocation,
185249
) {
186250
do {
187-
for entry in try walk(dir) {
251+
for entry in try walk(dir, fileSystem: fs) {
188252
if entry.basename == filename { return }
189253
}
190254
} catch {

Tests/CommandsTests/BuildCommandTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ struct BuildCommandTestCases {
179179
)
180180

181181
// The original symlink should not exists
182-
expectFileDoesNotExists(at: originalSymlink)
182+
expectFileDoesNotExist(at: originalSymlink)
183183

184184
// Let's build the package
185185
try await executeSwiftBuild(

Tests/CommandsTests/PackageCommandTests.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3313,7 +3313,7 @@ struct PackageCommandTests {
33133313
configuration: config,
33143314
buildSystem: buildSystem,
33153315
)
3316-
expectFileDoesNotExists(at: binFile)
3316+
expectFileDoesNotExist(at: binFile)
33173317
// Clean again to ensure we get no error.
33183318
_ = try await execute(
33193319
["clean"],
@@ -3359,7 +3359,7 @@ struct PackageCommandTests {
33593359
configuration: config,
33603360
buildSystem: buildSystem,
33613361
)
3362-
expectFileDoesNotExists(at: binFile)
3362+
expectFileDoesNotExist(at: binFile)
33633363
try #expect(
33643364
localFileSystem.getDirectoryContents(buildPath.appending("repositories")).isEmpty == false
33653365
)
@@ -3471,7 +3471,7 @@ struct PackageCommandTests {
34713471
#expect(!result.stderr.contains("Could not find Package.swift"))
34723472

34733473
// Verify manifest.db was removed (the purge implementation removes this file)
3474-
expectFileDoesNotExists(at: manifestDB, "manifest.db should be removed after purge")
3474+
expectFileDoesNotExist(at: manifestDB, "manifest.db should be removed after purge")
34753475

34763476
// Note: SQLite auxiliary files (WAL/SHM) may or may not be removed depending on SQLite state
34773477
// The important check is that the main database file is removed
@@ -5849,7 +5849,7 @@ struct PackageCommandTests {
58495849
buildSystem: buildData.buildSystem,
58505850
)
58515851
expectFileIsExecutable(at: fixturePath.appending(components: debugTarget), "build-target")
5852-
expectFileDoesNotExists(
5852+
expectFileDoesNotExist(
58535853
at: fixturePath.appending(components: releaseTarget),
58545854
"build-target build-inherit"
58555855
)
@@ -5887,7 +5887,7 @@ struct PackageCommandTests {
58875887
at: fixturePath.appending(components: debugTarget),
58885888
"build-target build-debug"
58895889
)
5890-
expectFileDoesNotExists(
5890+
expectFileDoesNotExist(
58915891
at: fixturePath.appending(components: releaseTarget),
58925892
"build-target build-inherit"
58935893
)
@@ -5921,7 +5921,7 @@ struct PackageCommandTests {
59215921
configuration: buildData.config,
59225922
buildSystem: buildData.buildSystem,
59235923
)
5924-
expectFileDoesNotExists(
5924+
expectFileDoesNotExist(
59255925
at: fixturePath.appending(components: debugTarget),
59265926
"build-target build-inherit"
59275927
)
@@ -5965,7 +5965,7 @@ struct PackageCommandTests {
59655965
fileShouldNotExist = fixturePath.appending(components: debugTarget)
59665966
fileShouldExist = fixturePath.appending(components: releaseTarget)
59675967
}
5968-
expectFileDoesNotExists(at: fileShouldNotExist, "build-target build-inherit")
5968+
expectFileDoesNotExist(at: fileShouldNotExist, "build-target build-inherit")
59695969
expectFileIsExecutable(at: fileShouldExist, "build-target build-inherit")
59705970
}
59715971
}

0 commit comments

Comments
 (0)