feat: Create backups of configuration when the force option is not used.
Some checks failed
CI / Run Tests (push) Failing after 2m16s
Create and publish a Docker image / build-and-push-image (push) Has been cancelled

This commit is contained in:
2024-12-17 14:38:52 -05:00
parent 54c07886ad
commit 558054464c
4 changed files with 29 additions and 8 deletions

View File

@@ -231,10 +231,10 @@ struct LiveConfigurationClient {
let fileUrl = URL(filePath: expandedPath) let fileUrl = URL(filePath: expandedPath)
if !options.force { let exists = fileManager.fileExists(fileUrl)
guard !fileManager.fileExists(fileUrl) else {
throw ConfigurationError.fileExists(path: file.path) if !options.force, exists {
} try await createBackup(file.url)
} }
let fileDirectory = fileUrl.deletingLastPathComponent() let fileDirectory = fileUrl.deletingLastPathComponent()
@@ -245,6 +245,8 @@ struct LiveConfigurationClient {
try await fileManager.createDirectory(fileDirectory) try await fileManager.createDirectory(fileDirectory)
} }
// TODO: The hpa file needs to be copied somewhere on the system during install and
// not use bundle, as it only works if the tool was built on the users system.
if case .toml = file { if case .toml = file {
// In the case of toml, we copy the internal resource that includes // In the case of toml, we copy the internal resource that includes
// usage comments in the file. // usage comments in the file.
@@ -290,9 +292,7 @@ struct LiveConfigurationClient {
let exists = fileManager.fileExists(file.url) let exists = fileManager.fileExists(file.url)
if !force, exists { if !force, exists {
let backupUrl = file.url.appendingPathExtension(".back") try await createBackup(file.url)
logger.warning("File exists, creating a backup of the existing file at: \(backupUrl.cleanFilePath)")
try await fileManager.copy(file.url, backupUrl)
} }
let data: Data let data: Data
@@ -308,6 +308,13 @@ struct LiveConfigurationClient {
try await fileManager.write(data, file.url) try await fileManager.write(data, file.url)
} }
private func createBackup(_ url: URL) async throws {
let backupUrl = url.appendingPathExtension("back")
logger.warning("File exists, creating a backup of the existing file at: \(backupUrl.cleanFilePath)")
try await fileManager.copy(url, backupUrl)
try await fileManager.delete(url)
}
private func findInDirectory(_ directory: URL) async -> File? { private func findInDirectory(_ directory: URL) async -> File? {
for file in validFileNames { for file in validFileNames {
let url = directory.appending(path: file) let url = directory.appending(path: file)

View File

@@ -14,7 +14,7 @@ public enum HPAKey {
public static let resourceFileName = "hpa" public static let resourceFileName = "hpa"
public static let resourceFileExtension = "toml" public static let resourceFileExtension = "toml"
public static let defaultFileName = "config.toml" public static let defaultFileName = "config.toml"
public static let defaultFileNameWithoutExtension = "config.toml" public static let defaultFileNameWithoutExtension = "config"
} }
extension [String: String] { extension [String: String] {

View File

@@ -23,6 +23,9 @@ public struct FileClient: Sendable {
/// Create a directory at the given location. /// Create a directory at the given location.
public var createDirectory: @Sendable (URL) async throws -> Void public var createDirectory: @Sendable (URL) async throws -> Void
/// Delete the item at the given location.
public var delete: @Sendable (URL) async throws -> Void
/// Check if a file exists at the given location. /// Check if a file exists at the given location.
public var fileExists: @Sendable (URL) -> Bool = { _ in true } public var fileExists: @Sendable (URL) -> Bool = { _ in true }
@@ -57,6 +60,7 @@ extension FileClient: DependencyKey {
return .init( return .init(
copy: { try await manager.copy($0, to: $1) }, copy: { try await manager.copy($0, to: $1) },
createDirectory: { try await manager.creatDirectory($0) }, createDirectory: { try await manager.creatDirectory($0) },
delete: { try await manager.delete($0) },
fileExists: { manager.fileExists(at: $0) }, fileExists: { manager.fileExists(at: $0) },
findVaultFile: { try await manager.findVaultFile(in: $0) }, findVaultFile: { try await manager.findVaultFile(in: $0) },
homeDirectory: { manager.homeDirectory() }, homeDirectory: { manager.homeDirectory() },
@@ -79,6 +83,10 @@ struct LiveFileClient: Sendable {
try manager.createDirectory(at: url, withIntermediateDirectories: true) try manager.createDirectory(at: url, withIntermediateDirectories: true)
} }
func delete(_ url: URL) async throws {
try manager.removeItem(at: url)
}
func fileExists(at url: URL) -> Bool { func fileExists(at url: URL) -> Bool {
manager.fileExists(atPath: url.cleanFilePath) manager.fileExists(atPath: url.cleanFilePath)
} }

View File

@@ -1,4 +1,6 @@
docker_image_name := "swift-hpa" docker_image_name := "swift-hpa"
install_path := "~/.local/share/bin/hpa"
completion_path := "~/.local/share/zsh/completions/_hpa"
build mode="debug": build mode="debug":
swift build -c {{mode}} swift build -c {{mode}}
@@ -37,3 +39,7 @@ update-version:
--allow-writing-to-package-directory \ --allow-writing-to-package-directory \
update-version \ update-version \
hpa hpa
install: (build "release")
@cp .build/release/hpa {{install_path}}
@{{install_path}} --generate-completion-script zsh > {{completion_path}}