From 38b7fe77dde35e61c3e65fb106e3ce86ffda2105 Mon Sep 17 00:00:00 2001 From: Matt Kiazyk Date: Thu, 28 Jul 2022 19:51:13 -0500 Subject: [PATCH] Allow ability to change the installation directory --- Xcodes/Backend/AppState.swift | 7 ++++ Xcodes/Backend/Path+.swift | 10 +++++- .../Preferences/AdvancedPreferencePane.swift | 35 +++++++++++++++++++ Xcodes/Resources/en.lproj/Localizable.strings | 2 ++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/Xcodes/Backend/AppState.swift b/Xcodes/Backend/AppState.swift index b13cff7..302e883 100644 --- a/Xcodes/Backend/AppState.swift +++ b/Xcodes/Backend/AppState.swift @@ -62,6 +62,12 @@ class AppState: ObservableObject { } } + @Published var installPath = "" { + didSet { + Current.defaults.set(installPath, forKey: "installPath") + } + } + @Published var unxipExperiment = false { didSet { Current.defaults.set(unxipExperiment, forKey: "unxipExperiment") @@ -135,6 +141,7 @@ class AppState: ObservableObject { unxipExperiment = Current.defaults.bool(forKey: "unxipExperiment") ?? false createSymLinkOnSelect = Current.defaults.bool(forKey: "createSymLinkOnSelect") ?? false onSelectActionType = SelectedActionType(rawValue: Current.defaults.string(forKey: "onSelectActionType") ?? "none") ?? .none + installPath = Current.defaults.string(forKey: "installPath") ?? Path.defaultInstallDirectory.string } // MARK: Timer diff --git a/Xcodes/Backend/Path+.swift b/Xcodes/Backend/Path+.swift index 76eb29e..36e0042 100644 --- a/Xcodes/Backend/Path+.swift +++ b/Xcodes/Backend/Path+.swift @@ -17,7 +17,15 @@ extension Path { return xcodesApplicationSupport/"available-xcodes.json" } + static let defaultInstallDirectory = Path.root/"Applications" + static var installDirectory: Path { - return Path.root/"Applications" + guard let savedInstallDirectory = Current.defaults.string(forKey: "installPath") else { + return defaultInstallDirectory + } + guard let path = Path(savedInstallDirectory) else { + return defaultInstallDirectory + } + return path } } diff --git a/Xcodes/Frontend/Preferences/AdvancedPreferencePane.swift b/Xcodes/Frontend/Preferences/AdvancedPreferencePane.swift index 3b86539..c908460 100644 --- a/Xcodes/Frontend/Preferences/AdvancedPreferencePane.swift +++ b/Xcodes/Frontend/Preferences/AdvancedPreferencePane.swift @@ -10,6 +10,41 @@ struct AdvancedPreferencePane: View { var body: some View { VStack(alignment: .leading, spacing: 20) { + + GroupBox(label: Text("InstallDirectory")) { + VStack(alignment: .leading) { + HStack(alignment: .top, spacing: 5) { + Text(appState.installPath).font(.footnote) + .fixedSize(horizontal: false, vertical: true) + .lineLimit(2) + Button(action: { appState.reveal(path: appState.installPath) }) { + Image(systemName: "arrow.right.circle.fill") + } + .buttonStyle(PlainButtonStyle()) + .help("RevealInFinder") + .fixedSize() + } + Button("Change") { + let panel = NSOpenPanel() + panel.allowsMultipleSelection = false + panel.canChooseDirectories = true + panel.canChooseFiles = false + panel.canCreateDirectories = true + panel.allowedContentTypes = [.folder] + panel.directoryURL = URL(fileURLWithPath: appState.installPath) + + if panel.runModal() == .OK { + + guard let pathURL = panel.url, let path = Path(url: pathURL) else { return } + self.appState.installPath = path.string + } + } + Text("InstallPathDescription") + .font(.footnote) + .fixedSize(horizontal: false, vertical: true) + } + } + .groupBoxStyle(PreferencesGroupBoxStyle()) GroupBox(label: Text("LocalCachePath")) { VStack(alignment: .leading) { diff --git a/Xcodes/Resources/en.lproj/Localizable.strings b/Xcodes/Resources/en.lproj/Localizable.strings index d304463..9d45c5e 100644 --- a/Xcodes/Resources/en.lproj/Localizable.strings +++ b/Xcodes/Resources/en.lproj/Localizable.strings @@ -78,6 +78,8 @@ "LocalCachePathDescription" = "Xcodes caches available Xcode versions and temporary downloads new versions to a directory"; "Change" = "Change"; "Active/Select" = "Active/Select"; +"InstallDirectory" = "Install Directory"; +"InstallPathDescription" = "Xcodes searches and installs to a single directory. By default (and recommended) is to keep this /Applications. Any changes to where Xcode is stored may result in other apps/services to stop working. "; "OnSelectDoNothing" = "Keep name as Xcode-X.X.X.app"; "OnSelectDoNothingDescription" = "On select, will keep the name as the version eg. Xcode-13.4.1.app";