// // AppPaths.swift // // Copyright 2026 Brendan Szymanski // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // SPDX-License-Identifier: GPL-3.0-or-later // import Foundation /// Platform-aware locations for Luminate's persistent data. package enum AppPaths { /// Environment variable that overrides the data directory outright; used by tests and CI. package static let dataDirectoryOverrideVariable = "LUMINATE_DATA_DIR" /// The directory Luminate stores its own data in. /// /// - Parameters: /// - environment: Environment values used to resolve the location. /// - home: The user's home directory, or `nil` when unavailable. /// - temporaryDirectory: The fallback temporary directory. /// - Returns: The resolved application data directory. package static func dataDirectory( environment: [String: String] = ProcessInfo.processInfo.environment, home: URL? = FileManager.default.homeDirectoryForCurrentUser, temporaryDirectory: URL = FileManager.default.temporaryDirectory ) -> URL { if let override = environment[dataDirectoryOverrideVariable], override.hasPrefix("/") { return URL(filePath: override) } #if canImport(Darwin) let baseDirectory = home?.appending( path: "Library/Application Support", directoryHint: .isDirectory ) #else let xdgDataHome = environment["XDG_DATA_HOME"] let baseDirectory: URL? if let xdgDataHome, !xdgDataHome.isEmpty, xdgDataHome.hasPrefix("/") { baseDirectory = URL(filePath: xdgDataHome) } else if let home, !home.path.isEmpty { baseDirectory = home.appending(path: ".local/share", directoryHint: .isDirectory) } else { baseDirectory = nil } #endif if let baseDirectory { return baseDirectory.appending(path: AppInfo.directoryName, directoryHint: .isDirectory) } return temporaryDirectory.appending(path: AppInfo.directoryName, directoryHint: .isDirectory) } /// The preferences database inside ``dataDirectory(environment:home:temporaryDirectory:)``. /// /// - Parameters: /// - environment: Environment values used to resolve the location. /// - home: The user's home directory, or `nil` when unavailable. /// - temporaryDirectory: The fallback temporary directory. /// - Returns: The preferences database URL. package static func preferencesDatabaseURL( environment: [String: String] = ProcessInfo.processInfo.environment, home: URL? = FileManager.default.homeDirectoryForCurrentUser, temporaryDirectory: URL = FileManager.default.temporaryDirectory ) -> URL { dataDirectory( environment: environment, home: home, temporaryDirectory: temporaryDirectory ).appending(path: "preferences.sqlite", directoryHint: .notDirectory) } }