feat: centralize config paths and expose in snapshot
This commit is contained in:
@@ -2,28 +2,17 @@ import Foundation
|
||||
|
||||
enum ClawdisConfigFile {
|
||||
private static let logger = Logger(subsystem: "com.steipete.clawdis", category: "config")
|
||||
private static let configPathEnv = "CLAWDIS_CONFIG_PATH"
|
||||
private static let stateDirEnv = "CLAWDIS_STATE_DIR"
|
||||
|
||||
static func url() -> URL {
|
||||
if let override = self.envPath(self.configPathEnv) {
|
||||
return URL(fileURLWithPath: override)
|
||||
}
|
||||
return self.stateDirURL()
|
||||
.appendingPathComponent("clawdis.json")
|
||||
ClawdisPaths.configURL
|
||||
}
|
||||
|
||||
static func stateDirURL() -> URL {
|
||||
if let override = self.envPath(self.stateDirEnv) {
|
||||
return URL(fileURLWithPath: override, isDirectory: true)
|
||||
}
|
||||
return FileManager.default.homeDirectoryForCurrentUser
|
||||
.appendingPathComponent(".clawdis", isDirectory: true)
|
||||
ClawdisPaths.stateDirURL
|
||||
}
|
||||
|
||||
static func defaultWorkspaceURL() -> URL {
|
||||
self.stateDirURL()
|
||||
.appendingPathComponent("workspace", isDirectory: true)
|
||||
ClawdisPaths.workspaceURL
|
||||
}
|
||||
|
||||
static func loadDict() -> [String: Any] {
|
||||
@@ -108,11 +97,4 @@ enum ClawdisConfigFile {
|
||||
self.logger.debug("agent workspace updated set=\(!trimmed.isEmpty)")
|
||||
}
|
||||
|
||||
private static func envPath(_ key: String) -> String? {
|
||||
guard let value = ProcessInfo.processInfo.environment[key]?.trimmingCharacters(in: .whitespacesAndNewlines),
|
||||
!value.isEmpty else {
|
||||
return nil
|
||||
}
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
37
apps/macos/Sources/Clawdis/ClawdisPaths.swift
Normal file
37
apps/macos/Sources/Clawdis/ClawdisPaths.swift
Normal file
@@ -0,0 +1,37 @@
|
||||
import Foundation
|
||||
|
||||
enum ClawdisEnv {
|
||||
static func path(_ key: String) -> String? {
|
||||
guard let value = ProcessInfo.processInfo.environment[key]?
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines),
|
||||
!value.isEmpty
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
enum ClawdisPaths {
|
||||
private static let configPathEnv = "CLAWDIS_CONFIG_PATH"
|
||||
private static let stateDirEnv = "CLAWDIS_STATE_DIR"
|
||||
|
||||
static var stateDirURL: URL {
|
||||
if let override = ClawdisEnv.path(self.stateDirEnv) {
|
||||
return URL(fileURLWithPath: override, isDirectory: true)
|
||||
}
|
||||
return FileManager.default.homeDirectoryForCurrentUser
|
||||
.appendingPathComponent(".clawdis", isDirectory: true)
|
||||
}
|
||||
|
||||
static var configURL: URL {
|
||||
if let override = ClawdisEnv.path(self.configPathEnv) {
|
||||
return URL(fileURLWithPath: override)
|
||||
}
|
||||
return self.stateDirURL.appendingPathComponent("clawdis.json")
|
||||
}
|
||||
|
||||
static var workspaceURL: URL {
|
||||
self.stateDirURL.appendingPathComponent("workspace", isDirectory: true)
|
||||
}
|
||||
}
|
||||
@@ -129,22 +129,6 @@ enum DeviceModelCatalog {
|
||||
if let bundle = self.bundleIfContainsDeviceModels(Bundle.main) {
|
||||
return bundle
|
||||
}
|
||||
|
||||
if let resourceURL = Bundle.main.resourceURL {
|
||||
if let enumerator = FileManager.default.enumerator(
|
||||
at: resourceURL,
|
||||
includingPropertiesForKeys: [.isDirectoryKey],
|
||||
options: [.skipsHiddenFiles]) {
|
||||
for case let url as URL in enumerator {
|
||||
guard url.pathExtension == "bundle" else { continue }
|
||||
if let bundle = Bundle(url: url),
|
||||
self.bundleIfContainsDeviceModels(bundle) != nil {
|
||||
return bundle
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -228,6 +228,14 @@ actor GatewayConnection {
|
||||
return trimmed.isEmpty ? nil : trimmed
|
||||
}
|
||||
|
||||
func snapshotPaths() -> (configPath: String?, stateDir: String?) {
|
||||
guard let snapshot = self.lastSnapshot else { return (nil, nil) }
|
||||
let configPath = snapshot.snapshot.configpath?.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
let stateDir = snapshot.snapshot.statedir?.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
return (configPath?.isEmpty == false ? configPath : nil,
|
||||
stateDir?.isEmpty == false ? stateDir : nil)
|
||||
}
|
||||
|
||||
func subscribe(bufferingNewest: Int = 100) -> AsyncStream<GatewayPush> {
|
||||
let id = UUID()
|
||||
let snapshot = self.lastSnapshot
|
||||
|
||||
@@ -105,8 +105,9 @@ struct SettingsRootView: View {
|
||||
}
|
||||
|
||||
private var nixManagedBanner: some View {
|
||||
let configPath = ClawdisConfigFile.url().path
|
||||
let stateDir = ClawdisConfigFile.stateDirURL().path
|
||||
let snapshotPaths = GatewayConnection.shared.snapshotPaths()
|
||||
let configPath = snapshotPaths.configPath ?? ClawdisPaths.configURL.path
|
||||
let stateDir = snapshotPaths.stateDir ?? ClawdisPaths.stateDirURL.path
|
||||
|
||||
return VStack(alignment: .leading, spacing: 6) {
|
||||
HStack(spacing: 8) {
|
||||
|
||||
@@ -250,23 +250,31 @@ public struct Snapshot: Codable {
|
||||
public let health: AnyCodable
|
||||
public let stateversion: StateVersion
|
||||
public let uptimems: Int
|
||||
public let configpath: String?
|
||||
public let statedir: String?
|
||||
|
||||
public init(
|
||||
presence: [PresenceEntry],
|
||||
health: AnyCodable,
|
||||
stateversion: StateVersion,
|
||||
uptimems: Int
|
||||
uptimems: Int,
|
||||
configpath: String?,
|
||||
statedir: String?
|
||||
) {
|
||||
self.presence = presence
|
||||
self.health = health
|
||||
self.stateversion = stateversion
|
||||
self.uptimems = uptimems
|
||||
self.configpath = configpath
|
||||
self.statedir = statedir
|
||||
}
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case presence
|
||||
case health
|
||||
case stateversion = "stateVersion"
|
||||
case uptimems = "uptimeMs"
|
||||
case configpath = "configPath"
|
||||
case statedir = "stateDir"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user