feat: Initial commit
This commit is contained in:
97
Sources/CliClient/FileClient.swift
Normal file
97
Sources/CliClient/FileClient.swift
Normal file
@@ -0,0 +1,97 @@
|
||||
import Dependencies
|
||||
import DependenciesMacros
|
||||
import Foundation
|
||||
|
||||
@_spi(Internal)
|
||||
public extension DependencyValues {
|
||||
var fileClient: FileClient {
|
||||
get { self[FileClient.self] }
|
||||
set { self[FileClient.self] = newValue }
|
||||
}
|
||||
}
|
||||
|
||||
@_spi(Internal)
|
||||
@DependencyClient
|
||||
public struct FileClient: Sendable {
|
||||
public var contentsOfDirectory: @Sendable (URL) throws -> [URL]
|
||||
public var loadFile: @Sendable (URL, inout [String: String], JSONDecoder) throws -> Void
|
||||
public var homeDir: @Sendable () -> URL = { URL(string: "~/")! }
|
||||
public var isDirectory: @Sendable (URL) -> Bool = { _ in false }
|
||||
public var isReadable: @Sendable (URL) -> Bool = { _ in false }
|
||||
}
|
||||
|
||||
@_spi(Internal)
|
||||
extension FileClient: DependencyKey {
|
||||
public static let testValue: FileClient = Self()
|
||||
|
||||
public static func live(fileManager: FileManager = .default) -> Self {
|
||||
let client = LiveFileClient(fileManager: fileManager)
|
||||
return Self(
|
||||
contentsOfDirectory: { try client.contentsOfDirectory(url: $0) },
|
||||
loadFile: { try client.loadFile(at: $0, into: &$1, decoder: $2) },
|
||||
homeDir: { client.homeDir },
|
||||
isDirectory: { client.isDirectory(url: $0) },
|
||||
isReadable: { client.isReadable(url: $0) }
|
||||
)
|
||||
}
|
||||
|
||||
public static let liveValue = Self.live()
|
||||
}
|
||||
|
||||
private struct LiveFileClient: @unchecked Sendable {
|
||||
|
||||
private let fileManager: FileManager
|
||||
|
||||
init(fileManager: FileManager) {
|
||||
self.fileManager = fileManager
|
||||
}
|
||||
|
||||
var homeDir: URL { fileManager.homeDirectoryForCurrentUser }
|
||||
|
||||
func isDirectory(url: URL) -> Bool {
|
||||
var isDirectory: ObjCBool = false
|
||||
fileManager.fileExists(atPath: path(for: url), isDirectory: &isDirectory)
|
||||
return isDirectory.boolValue
|
||||
}
|
||||
|
||||
func isReadable(url: URL) -> Bool {
|
||||
fileManager.isReadableFile(atPath: path(for: url))
|
||||
}
|
||||
|
||||
func contentsOfDirectory(url: URL) throws -> [URL] {
|
||||
try fileManager.contentsOfDirectory(at: url, includingPropertiesForKeys: nil)
|
||||
}
|
||||
|
||||
func loadFile(at url: URL, into env: inout [String: String], decoder: JSONDecoder) throws {
|
||||
@Dependency(\.logger) var logger
|
||||
logger.trace("Begin load file for: \(path(for: url))")
|
||||
|
||||
// if url.absoluteString.split(separator: ".json").count > 0 {
|
||||
// // Handle json file.
|
||||
// let data = try Data(contentsOf: url)
|
||||
// let dict = (try? decoder.decode([String: String].self, from: data)) ?? [:]
|
||||
// env.merge(dict, uniquingKeysWith: { $1 })
|
||||
// return
|
||||
// }
|
||||
|
||||
let string = try String(contentsOfFile: path(for: url), encoding: .utf8)
|
||||
|
||||
logger.trace("Loaded file contents: \(string)")
|
||||
|
||||
let lines = string.split(separator: "\n")
|
||||
for line in lines {
|
||||
logger.trace("Line: \(line)")
|
||||
let strippedLine = line.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
let splitLine = strippedLine.split(separator: "=")
|
||||
logger.trace("Split Line: \(splitLine)")
|
||||
guard splitLine.count >= 2 else { continue }
|
||||
|
||||
if splitLine.count > 2 {
|
||||
let rest = splitLine.dropFirst()
|
||||
env[String(splitLine[0])] = String(rest.joined(separator: "="))
|
||||
} else {
|
||||
env[String(splitLine[0])] = String(splitLine[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user