Skip to content

Commit f43a298

Browse files
Changes config get to download configs to user data folder instead of installation folder. Closes #1564
1 parent d0bff06 commit f43a298

3 files changed

Lines changed: 30 additions & 19 deletions

File tree

DevProxy.Abstractions/Utils/ProxyUtils.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Collections.ObjectModel;
1111
using System.Reflection;
1212
using System.Text.Encodings.Web;
13+
using System.Runtime.InteropServices;
1314
using System.Text.Json;
1415
using System.Text.Json.Serialization;
1516
using System.Text.RegularExpressions;
@@ -42,6 +43,23 @@ public static class ProxyUtils
4243

4344
// doesn't end with a path separator
4445
public static string? AppFolder => Path.GetDirectoryName(AppContext.BaseDirectory);
46+
47+
/// <summary>
48+
/// Gets the path to the user data folder for Dev Proxy.
49+
/// On macOS: ~/Library/Application Support/dev-proxy/
50+
/// On Linux: ~/.config/dev-proxy/ (or $XDG_CONFIG_HOME/dev-proxy/)
51+
/// On Windows: %LocalAppData%\dev-proxy\
52+
/// </summary>
53+
public static string DataFolder
54+
{
55+
get
56+
{
57+
var basePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
58+
? Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
59+
: Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
60+
return Path.Combine(basePath, "dev-proxy");
61+
}
62+
}
4563
public static JsonSerializerOptions JsonSerializerOptions { get; } = new()
4664
{
4765
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
@@ -175,6 +193,7 @@ public static string ReplacePathTokens(string? path)
175193
return path ?? string.Empty;
176194
}
177195

196+
path = path.Replace("~dataFolder", DataFolder, StringComparison.OrdinalIgnoreCase);
178197
return path.Replace("~appFolder", AppFolder, StringComparison.OrdinalIgnoreCase);
179198
}
180199

DevProxy/Commands/ConfigCommand.cs

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -215,17 +215,9 @@ private async Task DownloadConfigAsync(string configId, OutputFormat outputForma
215215
{
216216
try
217217
{
218-
var appFolder = ProxyUtils.AppFolder;
219-
if (string.IsNullOrEmpty(appFolder) || !Directory.Exists(appFolder))
220-
{
221-
if (outputFormat == OutputFormat.Text)
222-
{
223-
_logger.LogError("App folder {AppFolder} not found", appFolder);
224-
}
225-
return;
226-
}
218+
var dataFolder = ProxyUtils.DataFolder;
227219

228-
var configFolderPath = Path.Combine(appFolder, "config");
220+
var configFolderPath = Path.Combine(dataFolder, "configs");
229221
_logger.LogDebug("Checking if config folder {ConfigFolderPath} exists...", configFolderPath);
230222
if (!Directory.Exists(configFolderPath))
231223
{
@@ -235,7 +227,7 @@ private async Task DownloadConfigAsync(string configId, OutputFormat outputForma
235227
}
236228

237229
_logger.LogDebug("Getting target folder path for config {ConfigId}...", configId);
238-
var targetFolderPath = GetTargetFolderPath(appFolder, configId);
230+
var targetFolderPath = GetTargetFolderPath(dataFolder, configId);
239231
_logger.LogDebug("Creating target folder {TargetFolderPath}...", targetFolderPath);
240232
_ = Directory.CreateDirectory(targetFolderPath);
241233

@@ -287,7 +279,7 @@ private async Task DownloadConfigAsync(string configId, OutputFormat outputForma
287279
{
288280
if (_logger.IsEnabled(LogLevel.Information))
289281
{
290-
_logger.LogInformation(" devproxy --config-file \"{ConfigFile}\"", configFile.Replace(appFolder, "~appFolder", StringComparison.OrdinalIgnoreCase));
282+
_logger.LogInformation(" devproxy --config-file \"{ConfigFile}\"", configFile.Replace(dataFolder, "~dataFolder", StringComparison.OrdinalIgnoreCase));
291283
}
292284
}
293285
}
@@ -298,7 +290,7 @@ private async Task DownloadConfigAsync(string configId, OutputFormat outputForma
298290
{
299291
if (_logger.IsEnabled(LogLevel.Information))
300292
{
301-
_logger.LogInformation(" devproxy --mock-file \"{MockFile}\"", mockFile.Replace(appFolder, "~appFolder", StringComparison.OrdinalIgnoreCase));
293+
_logger.LogInformation(" devproxy --mock-file \"{MockFile}\"", mockFile.Replace(dataFolder, "~dataFolder", StringComparison.OrdinalIgnoreCase));
302294
}
303295
}
304296
}
@@ -332,13 +324,13 @@ private ProxyConfigInfo GetConfigInfo(string configFolder)
332324
var configInfo = new ProxyConfigInfo();
333325

334326
_logger.LogDebug("Getting list of config files in {ConfigFolder}...", configFolder);
335-
327+
336328
// Get both JSON and YAML files
337329
var jsonFiles = Directory.GetFiles(configFolder, "*.json");
338330
var yamlFiles = Directory.GetFiles(configFolder, "*.yaml");
339331
var ymlFiles = Directory.GetFiles(configFolder, "*.yml");
340332
var allConfigFiles = jsonFiles.Concat(yamlFiles).Concat(ymlFiles).ToArray();
341-
333+
342334
if (allConfigFiles.Length == 0)
343335
{
344336
_logger.LogDebug("No config files found");
@@ -350,7 +342,7 @@ private ProxyConfigInfo GetConfigInfo(string configFolder)
350342
_logger.LogDebug("Reading file {ConfigFile}...", configFile);
351343

352344
var fileContents = File.ReadAllText(configFile);
353-
345+
354346
// Check for plugins marker (case-insensitive)
355347
// For JSON: "plugins":
356348
// For YAML: plugins:
@@ -561,9 +553,9 @@ private string GetTargetFileName(string name)
561553
}
562554
}
563555

564-
private static string GetTargetFolderPath(string appFolder, string configId)
556+
private static string GetTargetFolderPath(string dataFolder, string configId)
565557
{
566-
var baseFolder = Path.Combine(appFolder, "config", configId);
558+
var baseFolder = Path.Combine(dataFolder, "configs", configId);
567559
var newFolder = baseFolder;
568560
var i = 1;
569561
while (Directory.Exists(newFolder))

DevProxy/Commands/DevProxyCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ sealed class DevProxyCommand : RootCommand
3333
internal static readonly Option<string?> ConfigFileOption = new(ConfigFileOptionName, "-c")
3434
{
3535
HelpName = "config-file",
36-
Description = "Path to config file. If not specified, Dev Proxy searches for devproxyrc.jsonc or devproxyrc.json in the current directory, then in a .devproxy/ directory, then under the ~appFolder location. Supports ~appFolder token."
36+
Description = "Path to config file. If not specified, Dev Proxy searches for devproxyrc.jsonc or devproxyrc.json in the current directory, then in a .devproxy/ directory, then under the ~appFolder location. Supports ~appFolder and ~dataFolder tokens."
3737
};
3838
internal const string NoFirstRunOptionName = "--no-first-run";
3939
internal const string NoWatchOptionName = "--no-watch";

0 commit comments

Comments
 (0)