mirror of
https://github.com/shadowsocks/ShadowsocksX-NG.git
synced 2026-10-27 20:53:44 +00:00
refactor(paths): App Support 目录命名权归 RuntimePaths
六个 GUI 配置文件位置(catalog/settings/listen-settings/custom-rules/ activation 与 silent-launch 遗留迁移源)自拼 applicationSupport 目录的 写法收敛为 RuntimePaths 的具名函数,各 store 的 defaultFileURL 改一行 委托。RuntimePaths 宪章从「跨进程运行时契约」扩为「App Support 目录 全部文件清单」——目录里有过哪些文件从此一处可答。 评审候选⑥ 6c:目录改名从动六个文件缩为动一处。
This commit is contained in:
@@ -21,9 +21,7 @@ struct ActivationStateFileStore {
|
||||
|
||||
/// 默认位置:`~/Library/Application Support/ShadowsocksX-NG2/activation.json`。
|
||||
static func defaultFileURL() -> URL {
|
||||
let support = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[
|
||||
0]
|
||||
return support.appendingPathComponent("ShadowsocksX-NG2/activation.json")
|
||||
RuntimePaths.activationStateFileURL()
|
||||
}
|
||||
|
||||
/// 文件缺失/损坏/版本未知 → `nil`(安全侧:无活动目标)。
|
||||
|
||||
@@ -27,9 +27,7 @@ struct CatalogFileStore {
|
||||
|
||||
/// 默认位置:`~/Library/Application Support/ShadowsocksX-NG2/catalog.json`。
|
||||
static func defaultFileURL() -> URL {
|
||||
let support = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[
|
||||
0]
|
||||
return support.appendingPathComponent("ShadowsocksX-NG2/catalog.json")
|
||||
RuntimePaths.catalogFileURL()
|
||||
}
|
||||
|
||||
/// 文件缺失 → 全新空文档;存在但损坏/版本未知/结构不一致 → `.corrupt`。
|
||||
|
||||
@@ -10,9 +10,7 @@ struct CustomRuleStore {
|
||||
}
|
||||
|
||||
static func defaultFileURL() -> URL {
|
||||
let support = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[
|
||||
0]
|
||||
return support.appendingPathComponent("ShadowsocksX-NG2/custom-rules.json")
|
||||
RuntimePaths.customRulesFileURL()
|
||||
}
|
||||
|
||||
/// 读取规则集合;文件不存在视为无自定义规则。
|
||||
|
||||
@@ -39,9 +39,7 @@ struct ListenSettingsFileStore: ListenSettingsStoring {
|
||||
let fileURL: URL
|
||||
|
||||
static func defaultFileURL() -> URL {
|
||||
let support = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[
|
||||
0]
|
||||
return support.appendingPathComponent("ShadowsocksX-NG2/listen-settings.json")
|
||||
RuntimePaths.listenSettingsFileURL()
|
||||
}
|
||||
|
||||
init(fileURL: URL = ListenSettingsFileStore.defaultFileURL()) {
|
||||
|
||||
@@ -15,9 +15,7 @@ struct ProxySettingsFileStore: ProxySettingsStoring {
|
||||
}
|
||||
|
||||
static func defaultFileURL() -> URL {
|
||||
let support = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[
|
||||
0]
|
||||
return support.appendingPathComponent("ShadowsocksX-NG2/settings.json")
|
||||
RuntimePaths.settingsFileURL()
|
||||
}
|
||||
|
||||
func load() throws -> ProxySettings {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import Foundation
|
||||
|
||||
/// 跨进程运行时路径契约(spec #21 D5,issue #27):GUI 写、wrapper 读的固定
|
||||
/// 位置。目录 0700、文件 0600,由写入方与 wrapper 共同维护。
|
||||
/// App Support 目录全部文件的路径清单:GUI 配置与跨进程运行时契约共用同一
|
||||
/// 目录。运行时契约子集(spec #21 D5,issue #27)是 GUI 写、wrapper 读的固定
|
||||
/// 位置;GUI 配置文件 wrapper 不经手。目录 0700、文件 0600,由写入方与
|
||||
/// wrapper 共同维护。
|
||||
enum RuntimePaths {
|
||||
static func runtimeDirectory() -> URL {
|
||||
FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0]
|
||||
@@ -42,6 +44,40 @@ enum RuntimePaths {
|
||||
// 旧版端点签名/所有权文件(system-proxy-endpoint-signature.json、
|
||||
// system-proxy-ownership.json)按 issue #71 就地遗留:不读取、不迁移、
|
||||
// 不删除。
|
||||
|
||||
// MARK: - GUI 配置文件(GUI 私有读写,wrapper 不经手)
|
||||
|
||||
/// 服务器目录(CatalogFileStore)。
|
||||
static func catalogFileURL() -> URL {
|
||||
runtimeDirectory().appendingPathComponent("catalog.json")
|
||||
}
|
||||
|
||||
/// 代理偏好(ProxySettingsFileStore,#33)。
|
||||
static func settingsFileURL() -> URL {
|
||||
runtimeDirectory().appendingPathComponent("settings.json")
|
||||
}
|
||||
|
||||
/// 监听设置(ListenSettingsFileStore;settings.json 未建立时的 legacy 回退
|
||||
/// 读取源)。
|
||||
static func listenSettingsFileURL() -> URL {
|
||||
runtimeDirectory().appendingPathComponent("listen-settings.json")
|
||||
}
|
||||
|
||||
/// 自定义规则文档(CustomRuleStore,issue #66)。
|
||||
static func customRulesFileURL() -> URL {
|
||||
runtimeDirectory().appendingPathComponent("custom-rules.json")
|
||||
}
|
||||
|
||||
/// 活动目标(ActivationStateFileStore,spec #21 D3/D5)。
|
||||
static func activationStateFileURL() -> URL {
|
||||
runtimeDirectory().appendingPathComponent("activation.json")
|
||||
}
|
||||
|
||||
/// 静默启动偏好的 ADR 0017 初版文件形态,仅遗留迁移路径使用
|
||||
/// (SilentLaunchStore.migrateLegacyFileIfPresent)。
|
||||
static func silentLaunchLegacyFileURL() -> URL {
|
||||
runtimeDirectory().appendingPathComponent("silent-launch.json")
|
||||
}
|
||||
}
|
||||
|
||||
/// ACL 活动链接的防逃逸校验(ADR-0011):解析 symlink 后必须仍是运行目录
|
||||
|
||||
@@ -9,11 +9,7 @@ import Foundation
|
||||
struct SilentLaunchStore {
|
||||
private static let key = "silentLaunch"
|
||||
/// ADR 0017 初版(文件形态)的落盘位置,仅迁移路径使用。
|
||||
static let legacyFileURL: URL = {
|
||||
let support = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[
|
||||
0]
|
||||
return support.appendingPathComponent("ShadowsocksX-NG2/silent-launch.json")
|
||||
}()
|
||||
static let legacyFileURL = RuntimePaths.silentLaunchLegacyFileURL()
|
||||
|
||||
private static let currentVersion = 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user