Skip to content

Commit f39d431

Browse files
committed
using file locks to protect the cache
1 parent a87bf21 commit f39d431

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

Sources/SourceControl/GitRepository.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public class GitRepositoryProvider: RepositoryProvider {
7373
/// Clones the git repository we want to cache into the cache directory if it does not already exist and returns it.
7474
/// If the repository is already cached we perfrom a fetch. In case the `RepositoryProvider`has no `cachePath` or an error occured while
7575
/// setting up the cache `nil` is returned.
76-
private func setupCacheIfNeeded(for repository: RepositorySpecifier) -> GitRepository? {
76+
private func setupCacheIfNeeded(for repository: RepositorySpecifier) throws -> GitRepository? {
7777
guard let cachePath = cachePath else { return nil }
7878
let repositoryPath = cachePath.appending(component: repository.fileSystemIdentifier)
7979

@@ -93,7 +93,10 @@ public class GitRepositoryProvider: RepositoryProvider {
9393
}
9494

9595
try processSet?.add(process)
96-
try process.checkNonZeroExit()
96+
let lock = FileLock(name: repository.fileSystemIdentifier, cachePath: cachePath)
97+
try lock.withLock {
98+
try! process.checkNonZeroExit()
99+
}
97100
} catch {
98101
return nil
99102
}
@@ -118,11 +121,14 @@ public class GitRepositoryProvider: RepositoryProvider {
118121
for repository in repositories {
119122
let cacheSize = try localFileSystem.getDirectorySize(cachePath)
120123
guard cacheSize > desiredCacheSize else { break }
121-
try localFileSystem.removeFileTree(repository.path)
124+
let lock = FileLock(name: repository.path.basename, cachePath: cachePath)
125+
try lock.withLock {
126+
try localFileSystem.removeFileTree(repository.path)
127+
}
122128
}
123129
} catch {
124130
// The cache seems to be broken. Lets remove everything.
125-
try? localFileSystem.removeFileTree(cachePath)
131+
print("Error purging cache")
126132
}
127133
}
128134

@@ -139,14 +145,17 @@ public class GitRepositoryProvider: RepositoryProvider {
139145
// FIXME: We need infrastructure in this subsystem for reporting
140146
// status information.
141147

142-
if let cache = setupCacheIfNeeded(for: repository) {
148+
if let cachePath = cachePath, let cache = try setupCacheIfNeeded(for: repository) {
143149
// Clone the repository using the cache as a reference if possible.
144150
// Git objects are not shared (--dissociate) to avoid problems that might occur when the cache is
145151
// deleted or the package is copied somewhere it cannot reach the cache directory.
146152
let process = Process(args: Git.tool, "clone", "--mirror",
147153
cache.path.pathString, path.pathString, environment: Git.environment)
148154
try processSet?.add(process)
149-
try process.checkGitError(repository: repository)
155+
let lock = FileLock(name: cache.path.basename, cachePath: cachePath)
156+
try lock.withLock {
157+
try process.checkGitError(repository: repository)
158+
}
150159

151160
let clone = GitRepository(path: path, isWorkingRepo: false)
152161
// In destination repo remove the remote which will be pointing to the cached source repo.

0 commit comments

Comments
 (0)