feat: Create backups of configuration when the force option is not used.
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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] {
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
6
justfile
6
justfile
@@ -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}}
|
||||||
|
|||||||
Reference in New Issue
Block a user