diff --git a/src/Mockingbird.xcodeproj/project.pbxproj b/src/Mockingbird.xcodeproj/project.pbxproj index af38a88..41124de 100644 --- a/src/Mockingbird.xcodeproj/project.pbxproj +++ b/src/Mockingbird.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 216DC9708C747E4014C763B8 /* Pods_Mockingbird.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4287C41673FEE0A7D53CFC08 /* Pods_Mockingbird.framework */; }; 737203AC4CFCF605F6FF30D3 /* Pods_MockingbirdTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8952BC9226AA3B164321E36D /* Pods_MockingbirdTests.framework */; }; + 8F56D1E2265E7139005159E1 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F56D1E1265E7139005159E1 /* Configuration.swift */; }; B63AA30E2469D15200D6026B /* ServerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63AA30D2469D15200D6026B /* ServerTests.swift */; }; B63AA3102469D76D00D6026B /* UtilTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63AA30F2469D76D00D6026B /* UtilTests.swift */; }; B640167E245B50FF009EDBBF /* DataHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B640167D245B50FF009EDBBF /* DataHelper.swift */; }; @@ -118,6 +119,7 @@ 83434BFCBF135F5C552864E6 /* Pods-Mockingbird-MockingbirdUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mockingbird-MockingbirdUITests.debug.xcconfig"; path = "Target Support Files/Pods-Mockingbird-MockingbirdUITests/Pods-Mockingbird-MockingbirdUITests.debug.xcconfig"; sourceTree = ""; }; 83BCB3BAD6AC4B8D47908BEF /* Pods-Mockingbird-MockingbirdUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mockingbird-MockingbirdUITests.release.xcconfig"; path = "Target Support Files/Pods-Mockingbird-MockingbirdUITests/Pods-Mockingbird-MockingbirdUITests.release.xcconfig"; sourceTree = ""; }; 8952BC9226AA3B164321E36D /* Pods_MockingbirdTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MockingbirdTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8F56D1E1265E7139005159E1 /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; 95E8B10A50D0E77C0D935628 /* Pods-MockingbirdTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MockingbirdTests.release.xcconfig"; path = "Target Support Files/Pods-MockingbirdTests/Pods-MockingbirdTests.release.xcconfig"; sourceTree = ""; }; B63AA30D2469D15200D6026B /* ServerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerTests.swift; sourceTree = ""; }; B63AA30F2469D76D00D6026B /* UtilTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UtilTests.swift; sourceTree = ""; }; @@ -423,6 +425,7 @@ B6736AEC23981D310040B29D /* Router.swift */, B65572C823D094D400D5056A /* Tracking.swift */, B69F01C723EE29B6005C8B26 /* Util.swift */, + 8F56D1E1265E7139005159E1 /* Configuration.swift */, ); path = Utils; sourceTree = ""; @@ -1028,6 +1031,7 @@ B6736B2D23981D320040B29D /* DataView.swift in Sources */, B69F01AE23EE064A005C8B26 /* DataStore.swift in Sources */, B6736B1923981D320040B29D /* URLMatcher.swift in Sources */, + 8F56D1E2265E7139005159E1 /* Configuration.swift in Sources */, B6736B1823981D320040B29D /* URLConvertible.swift in Sources */, B69F01AA23EE0639005C8B26 /* DataActions.swift in Sources */, B683949B23F1CFC600882648 /* Default.swift in Sources */, diff --git a/src/Mockingbird/UI/View/OptionsView.swift b/src/Mockingbird/UI/View/OptionsView.swift index 393f126..5888fc3 100644 --- a/src/Mockingbird/UI/View/OptionsView.swift +++ b/src/Mockingbird/UI/View/OptionsView.swift @@ -15,13 +15,27 @@ public class OptionsView { Group { - Tree("Server Context", options: .defaultOpen) { + Tree("Setup", options: .defaultOpen) { + Text("Server Context") RadioButtonGroup(state.contextTitles, selectedIndexState: state.currentContextIndex) { val in ContextManager.shared.setContext(index: val) } NewLine() + + Text("WORKING DIRECTORY: \(Default.Folder.workingDirectory)") + LargeButton("CHANGE DIRECTORY") { + + if let newDirectory = Util.chooseFolder() { + + Default.Folder.savedWorkingDirectory = newDirectory + + AppStore.data.dispatch(DataAction.initialize) + AppStore.test.dispatch(TestAction.initialize) + } + } + NewLine() } Divider() diff --git a/src/Mockingbird/Utils/Configuration.swift b/src/Mockingbird/Utils/Configuration.swift new file mode 100644 index 0000000..c3791f3 --- /dev/null +++ b/src/Mockingbird/Utils/Configuration.swift @@ -0,0 +1,12 @@ +// +// Copyright (c) 2021, Farfetch. +// All rights reserved. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +struct Configuration: Codable { + + let dataFolder: String +} diff --git a/src/Mockingbird/Utils/Default.swift b/src/Mockingbird/Utils/Default.swift index 1846623..0b38ffd 100644 --- a/src/Mockingbird/Utils/Default.swift +++ b/src/Mockingbird/Utils/Default.swift @@ -7,6 +7,7 @@ // import Foundation +import Files final class Default { @@ -24,10 +25,56 @@ final class Default { public enum Folder { static var main = "/Users/" + NSUserName() + "/.mockingbird" - static var capture: String { main + "/capture" } - static var data: String { main + "/data" } static var mitm: String { main + "/mitmproxy" } - static var record: String { main + "/record" } - static var test: String { main + "/test" } + static var capture: String { workingDirectory + "/capture" } + static var record: String { workingDirectory + "/record" } + static var data: String { workingDirectory + "/data" } + static var test: String { workingDirectory + "/test" } + + static var workingDirectory = Default.Folder.savedWorkingDirectory + + static var savedWorkingDirectory: String { + + get { + + guard let file = try? File(path: "\(Default.Folder.main)/configurations.json"), + let fileData = try? file.readAsString(), + let configuration = try? Configuration(fileData) else { + + return "/Users/" + NSUserName() + "/.mockingbird" + } + + return configuration.dataFolder + } + + set { + + Default.Folder.workingDirectory = newValue + + if let configurationsFile = try? File(path: "\(Default.Folder.main)/configurations.json") { + + Self.write(newDirectory: newValue, toFile: configurationsFile) + + } else { + + guard let mainFolder = try? Files.Folder(path: Default.Folder.main), + let configurationsFile = try? mainFolder.createFile(named: "configurations.json") else { + + return + } + + Self.write(newDirectory: newValue, toFile: configurationsFile) + } + } + } + + private static func write(newDirectory: String, + toFile file: File) { + + let configurations = Configuration(dataFolder: newDirectory) + guard let writeData = try? configurations.jsonData() else { return } + + try? file.write(writeData) + } } } diff --git a/src/Mockingbird/Utils/Util.swift b/src/Mockingbird/Utils/Util.swift index ccdb09e..aad8155 100644 --- a/src/Mockingbird/Utils/Util.swift +++ b/src/Mockingbird/Utils/Util.swift @@ -22,6 +22,27 @@ class Util { NSWorkspace.shared.selectFile(nil, inFileViewerRootedAtPath: folder) } + static func chooseFolder() -> String? { + + let dialog = NSOpenPanel() + + dialog.title = "Choose mocked data directory" + dialog.showsResizeIndicator = true + dialog.showsHiddenFiles = false + dialog.canChooseFiles = false + dialog.canChooseDirectories = true + + if (dialog.runModal() == NSApplication.ModalResponse.OK) { + + let result = dialog.url + return result?.path + + } else { + + return nil + } + } + static func openURL(url: String) { if let url = URL(string: url) { diff --git a/src/MockingbirdTests/Utils/DataHelper.swift b/src/MockingbirdTests/Utils/DataHelper.swift index ae6c6e5..7139b8f 100644 --- a/src/MockingbirdTests/Utils/DataHelper.swift +++ b/src/MockingbirdTests/Utils/DataHelper.swift @@ -99,7 +99,7 @@ private extension DataHelper { } } - Default.Folder.main = resourcePath + Default.Folder.workingDirectory = resourcePath } catch {