Files
swift-hpa/Sources/CliClient/Helpers.swift

110 lines
3.1 KiB
Swift

import Dependencies
import Foundation
import ShellClient
@_spi(Internal)
public func findConfigurationFiles(
env: [String: String] = ProcessInfo.processInfo.environment
) throws -> URL {
@Dependency(\.logger) var logger
@Dependency(\.fileClient) var fileClient
logger.debug("Begin find configuration files.")
logger.trace("Env: \(env)")
// Check for environment variable pointing to a directory that the
// the configuration lives.
if let pwd = env["PWD"],
let url = fileClient.checkUrl(.file(pwd, ".hparc"))
{
logger.debug("Found configuration in current working directory.")
return url
}
// Check for environment variable pointing to a file that the
// the configuration lives.
if let configFile = env["HPA_CONFIG_FILE"],
let url = fileClient.checkUrl(.file(configFile))
{
logger.debug("Found configuration from hpa config file env var.")
return url
}
// Check for environment variable pointing to a directory that the
// the configuration lives.
if let configHome = env["HPA_CONFIG_HOME"],
let url = fileClient.checkUrl(.directory(configHome))
{
logger.debug("Found configuration from hpa config home env var.")
return url
}
// Check home directory for a `.hparc` file.
if let url = fileClient.checkUrl(.file(fileClient.homeDir().appending(path: ".hparc"))) {
logger.debug("Found configuration in home directory")
return url
}
// Check in xdg config home, under an hpa-playbook directory.
if let xdgConfigHome = env["XDG_CONFIG_HOME"],
let url = fileClient.checkUrl(.directory(xdgConfigHome, "hpa-playbook"))
{
logger.debug("XDG Config url: \(url.absoluteString)")
return url
}
// We could not find configuration in any usual places.
throw ConfigurationError.configurationNotFound
}
func path(for url: URL) -> String {
url.absoluteString.replacing("file://", with: "")
}
enum ConfigurationError: Error {
case configurationNotFound
}
private extension FileClient {
enum ConfigurationUrlCheck {
case file(URL)
case directory(URL)
static func file(_ path: String) -> Self { .file(URL(filePath: path)) }
static func file(_ paths: String...) -> Self {
var url = URL(filePath: paths[0])
url = paths.dropFirst().reduce(into: url) { $0.append(path: $1) }
return .file(url)
}
static func directory(_ path: String) -> Self { .directory(URL(filePath: path)) }
static func directory(_ paths: String...) -> Self {
var url = URL(filePath: paths[0])
url = paths.dropFirst().reduce(into: url) { $0.append(path: $1) }
return .directory(url)
}
}
func checkUrl(_ check: ConfigurationUrlCheck) -> URL? {
switch check {
case let .file(url):
if isReadable(url) { return url }
return nil
case let .directory(url):
return findConfigurationInDirectory(url)
}
}
func findConfigurationInDirectory(_ url: URL) -> URL? {
for file in ["config", "config.json"] {
let fileUrl = url.appending(path: file)
if isReadable(fileUrl) {
return fileUrl
}
}
return nil
}
}