Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions DevProxy.Abstractions/Utils/ProxyUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Collections.ObjectModel;
using System.Reflection;
using System.Text.Encodings.Web;
using System.Runtime.InteropServices;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
Expand Down Expand Up @@ -42,6 +43,23 @@ public static class ProxyUtils

// doesn't end with a path separator
public static string? AppFolder => Path.GetDirectoryName(AppContext.BaseDirectory);

/// <summary>
/// Gets the path to the user data folder for Dev Proxy.
/// On macOS: ~/Library/Application Support/dev-proxy/
/// On Linux: ~/.config/dev-proxy/ (or $XDG_CONFIG_HOME/dev-proxy/)
/// On Windows: %LocalAppData%\dev-proxy\
/// </summary>
public static string DataFolder
{
get
{
var basePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
: Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
return Path.Combine(basePath, "dev-proxy");
}
}
public static JsonSerializerOptions JsonSerializerOptions { get; } = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Expand Down Expand Up @@ -175,6 +193,7 @@ public static string ReplacePathTokens(string? path)
return path ?? string.Empty;
}

path = path.Replace("~dataFolder", DataFolder, StringComparison.OrdinalIgnoreCase);
return path.Replace("~appFolder", AppFolder, StringComparison.OrdinalIgnoreCase);
}

Expand Down
33 changes: 12 additions & 21 deletions DevProxy/Commands/ConfigCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ internal static async Task<int> RunValidateStandaloneAsync(string[] args)

using var loggerFactory = LoggerFactory.Create(builder =>
{
builder
_ = builder
.SetMinimumLevel(LogLevel.Information)
.AddConsole(consoleOptions =>
{
Expand Down Expand Up @@ -215,17 +215,9 @@ private async Task DownloadConfigAsync(string configId, OutputFormat outputForma
{
try
{
var appFolder = ProxyUtils.AppFolder;
if (string.IsNullOrEmpty(appFolder) || !Directory.Exists(appFolder))
{
if (outputFormat == OutputFormat.Text)
{
_logger.LogError("App folder {AppFolder} not found", appFolder);
}
return;
}
var dataFolder = ProxyUtils.DataFolder;

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

_logger.LogDebug("Getting target folder path for config {ConfigId}...", configId);
var targetFolderPath = GetTargetFolderPath(appFolder, configId);
var targetFolderPath = GetTargetFolderPath(dataFolder, configId);
_logger.LogDebug("Creating target folder {TargetFolderPath}...", targetFolderPath);
_ = Directory.CreateDirectory(targetFolderPath);

Expand Down Expand Up @@ -287,7 +279,7 @@ private async Task DownloadConfigAsync(string configId, OutputFormat outputForma
{
if (_logger.IsEnabled(LogLevel.Information))
{
_logger.LogInformation(" devproxy --config-file \"{ConfigFile}\"", configFile.Replace(appFolder, "~appFolder", StringComparison.OrdinalIgnoreCase));
_logger.LogInformation(" devproxy --config-file \"{ConfigFile}\"", configFile.Replace(dataFolder, "~dataFolder", StringComparison.OrdinalIgnoreCase));
}
}
}
Expand All @@ -298,7 +290,7 @@ private async Task DownloadConfigAsync(string configId, OutputFormat outputForma
{
if (_logger.IsEnabled(LogLevel.Information))
{
_logger.LogInformation(" devproxy --mock-file \"{MockFile}\"", mockFile.Replace(appFolder, "~appFolder", StringComparison.OrdinalIgnoreCase));
_logger.LogInformation(" devproxy --mock-file \"{MockFile}\"", mockFile.Replace(dataFolder, "~dataFolder", StringComparison.OrdinalIgnoreCase));
}
}
}
Expand Down Expand Up @@ -332,13 +324,13 @@ private ProxyConfigInfo GetConfigInfo(string configFolder)
var configInfo = new ProxyConfigInfo();

_logger.LogDebug("Getting list of config files in {ConfigFolder}...", configFolder);

// Get both JSON and YAML files
var jsonFiles = Directory.GetFiles(configFolder, "*.json");
var yamlFiles = Directory.GetFiles(configFolder, "*.yaml");
var ymlFiles = Directory.GetFiles(configFolder, "*.yml");
var allConfigFiles = jsonFiles.Concat(yamlFiles).Concat(ymlFiles).ToArray();

if (allConfigFiles.Length == 0)
{
_logger.LogDebug("No config files found");
Expand All @@ -350,7 +342,7 @@ private ProxyConfigInfo GetConfigInfo(string configFolder)
_logger.LogDebug("Reading file {ConfigFile}...", configFile);

var fileContents = File.ReadAllText(configFile);

// Check for plugins marker (case-insensitive)
// For JSON: "plugins":
// For YAML: plugins:
Expand Down Expand Up @@ -561,9 +553,9 @@ private string GetTargetFileName(string name)
}
}

private static string GetTargetFolderPath(string appFolder, string configId)
private static string GetTargetFolderPath(string dataFolder, string configId)
{
var baseFolder = Path.Combine(appFolder, "config", configId);
var baseFolder = Path.Combine(dataFolder, "configs", configId);
var newFolder = baseFolder;
var i = 1;
while (Directory.Exists(newFolder))
Expand Down Expand Up @@ -701,7 +693,7 @@ private static async Task<int> ValidateConfigCoreAsync(
if (configDoc.RootElement.TryGetProperty("plugins", out var pluginsElement) &&
pluginsElement.ValueKind == JsonValueKind.Array)
{
ValidatePlugins(pluginsElement, configFileDirectory, errors, warnings, pluginNames);
ValidatePlugins(pluginsElement, configFileDirectory, errors, pluginNames);
}
else
{
Expand Down Expand Up @@ -737,7 +729,6 @@ private static void ValidatePlugins(
JsonElement pluginsElement,
string configFileDirectory,
List<ValidationMessage> errors,
List<ValidationMessage> warnings,
List<string> pluginNames)
{
var hasEnabledPlugins = false;
Expand Down
2 changes: 1 addition & 1 deletion DevProxy/Commands/DevProxyCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ sealed class DevProxyCommand : RootCommand
internal static readonly Option<string?> ConfigFileOption = new(ConfigFileOptionName, "-c")
{
HelpName = "config-file",
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."
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."
};
internal const string NoFirstRunOptionName = "--no-first-run";
internal const string NoWatchOptionName = "--no-watch";
Expand Down
Loading