luminate/Sources/LuminateCore/Constants/AppPaths.swift

86 lines
3.6 KiB
Swift

//
// AppPaths.swift
//
// Copyright 2026 Brendan Szymanski <hello@bscubed.dev>
//
// 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 <https://www.gnu.org/licenses/>.
//
// 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)
}
}