Skip to content

Commit d76923f

Browse files
committed
Fix test failure by using atomic write instead of file locks
1 parent 61ee7ad commit d76923f

File tree

2 files changed

+29
-50
lines changed

2 files changed

+29
-50
lines changed

Sources/Commands/SwiftPackageRegistryTool.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@ public struct SwiftPackageRegistryTool: ParsableCommand {
102102

103103
let configuration = try swiftTool.getRegistriesConfig()
104104
if global {
105-
try configuration.applyShared(handler: set)
105+
try configuration.updateShared(with: set)
106106
} else {
107-
try configuration.applyLocal(handler: set)
107+
try configuration.updateLocal(with: set)
108108
}
109109

110110
// TODO: Add login and password to .netrc
@@ -141,9 +141,9 @@ public struct SwiftPackageRegistryTool: ParsableCommand {
141141

142142
let configuration = try swiftTool.getRegistriesConfig()
143143
if global {
144-
try configuration.applyShared(handler: unset)
144+
try configuration.updateShared(with: unset)
145145
} else {
146-
try configuration.applyLocal(handler: unset)
146+
try configuration.updateLocal(with: unset)
147147
}
148148
}
149149
}

Sources/Workspace/WorkspaceConfiguration.swift

Lines changed: 25 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -399,25 +399,25 @@ extension Workspace.Configuration {
399399
sharedRegistriesFile: AbsolutePath?,
400400
fileSystem: FileSystem
401401
) throws {
402-
self.localRegistries = .init(path: localRegistriesFile, fileSystem: fileSystem, deleteWhenEmpty: true)
403-
self.sharedRegistries = sharedRegistriesFile.map { .init(path: $0, fileSystem: fileSystem, deleteWhenEmpty: false) }
402+
self.localRegistries = .init(path: localRegistriesFile, fileSystem: fileSystem)
403+
self.sharedRegistries = sharedRegistriesFile.map { .init(path: $0, fileSystem: fileSystem) }
404404
self.fileSystem = fileSystem
405405
try self.computeRegistries()
406406
}
407407

408408
@discardableResult
409-
public func applyLocal(handler: (inout RegistryConfiguration) throws -> Void) throws -> RegistryConfiguration {
410-
try self.localRegistries.apply(handler: handler)
409+
public func updateLocal(with handler: (inout RegistryConfiguration) throws -> Void) throws -> RegistryConfiguration {
410+
try self.localRegistries.update(with: handler)
411411
try self.computeRegistries()
412412
return self.configuration
413413
}
414414

415415
@discardableResult
416-
public func applyShared(handler: (inout RegistryConfiguration) throws -> Void) throws -> RegistryConfiguration {
416+
public func updateShared(with handler: (inout RegistryConfiguration) throws -> Void) throws -> RegistryConfiguration {
417417
guard let sharedRegistries = self.sharedRegistries else {
418418
throw InternalError("shared registries not configured")
419419
}
420-
try sharedRegistries.apply(handler: handler)
420+
try sharedRegistries.update(with: handler)
421421
try self.computeRegistries()
422422
return self.configuration
423423
}
@@ -428,11 +428,11 @@ extension Workspace.Configuration {
428428
try self.lock.withLock {
429429
var configuration = RegistryConfiguration()
430430

431-
if let sharedConfiguration = try sharedRegistries?.get() {
431+
if let sharedConfiguration = try sharedRegistries?.load() {
432432
configuration.merge(sharedConfiguration)
433433
}
434434

435-
let localConfiguration = try localRegistries.get()
435+
let localConfiguration = try localRegistries.load()
436436
configuration.merge(localConfiguration)
437437

438438
self._configuration = configuration
@@ -445,37 +445,13 @@ extension Workspace.Configuration {
445445
private struct RegistriesStorage {
446446
private let path: AbsolutePath
447447
private let fileSystem: FileSystem
448-
private let deleteWhenEmpty: Bool
449448

450-
public init(path: AbsolutePath, fileSystem: FileSystem, deleteWhenEmpty: Bool) {
449+
public init(path: AbsolutePath, fileSystem: FileSystem) {
451450
self.path = path
452451
self.fileSystem = fileSystem
453-
self.deleteWhenEmpty = deleteWhenEmpty
454-
}
455-
456-
public func get() throws -> RegistryConfiguration {
457-
return try self.fileSystem.withLock(on: self.path.parentDirectory, type: .shared) {
458-
return try Self.load(self.path, fileSystem: self.fileSystem)
459-
}
460-
}
461-
462-
@discardableResult
463-
public func apply(handler: (inout RegistryConfiguration) throws -> Void) throws -> RegistryConfiguration {
464-
if !self.fileSystem.exists(self.path.parentDirectory) {
465-
try self.fileSystem.createDirectory(self.path.parentDirectory, recursive: true)
466-
}
467-
return try self.fileSystem.withLock(on: self.path.parentDirectory, type: .exclusive) {
468-
let configuration = try Self.load(self.path, fileSystem: self.fileSystem)
469-
var updatedConfiguration = configuration
470-
try handler(&updatedConfiguration)
471-
if updatedConfiguration != configuration {
472-
try Self.save(updatedConfiguration, to: self.path, fileSystem: self.fileSystem, deleteWhenEmpty: self.deleteWhenEmpty)
473-
}
474-
return updatedConfiguration
475-
}
476452
}
477453

478-
private static func load(_ path: AbsolutePath, fileSystem: FileSystem) throws -> RegistryConfiguration {
454+
public func load() throws -> RegistryConfiguration {
479455
guard fileSystem.exists(path) else {
480456
return RegistryConfiguration()
481457
}
@@ -485,23 +461,26 @@ extension Workspace.Configuration {
485461
return try decoder.decode(RegistryConfiguration.self, from: data)
486462
}
487463

488-
private static func save(_ configuration: RegistryConfiguration, to path: AbsolutePath, fileSystem: FileSystem, deleteWhenEmpty: Bool) throws {
489-
if configuration.isEmpty {
490-
if deleteWhenEmpty && fileSystem.exists(path) {
491-
// deleteWhenEmpty is a backward compatibility mode
492-
return try fileSystem.removeFileTree(path)
493-
} else if !fileSystem.exists(path) {
494-
// nothing to do
495-
return
496-
}
497-
}
498-
464+
public func save(_ configuration: RegistryConfiguration) throws {
499465
let encoder = JSONEncoder.makeWithDefaults()
500466
let data = try encoder.encode(configuration)
467+
501468
if !fileSystem.exists(path.parentDirectory) {
502469
try fileSystem.createDirectory(path.parentDirectory, recursive: true)
503470
}
504-
try fileSystem.writeFileContents(path, data: data)
471+
try fileSystem.writeFileContents(path, bytes: ByteString(data), atomically: true)
472+
}
473+
474+
@discardableResult
475+
public func update(with handler: (inout RegistryConfiguration) throws -> Void) throws -> RegistryConfiguration {
476+
let configuration = try load()
477+
var updatedConfiguration = configuration
478+
try handler(&updatedConfiguration)
479+
if updatedConfiguration != configuration {
480+
try save(updatedConfiguration)
481+
}
482+
483+
return updatedConfiguration
505484
}
506485
}
507486
}

0 commit comments

Comments
 (0)