Skip to content

Commit 85ccd72

Browse files
Copilotwaldekmastykarzgarrytrinder
authored
Add devproxy config validate subcommand (#1552)
* Initial plan * Add config validate subcommand for validating Dev Proxy configuration files Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com> * Use ProxyUtils.JsonSerializerOptions and JsonDocumentOptions instead of custom duplicates Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com> * Switch from Console.WriteLine to ILogger in config validate output Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com> * Centralize config file search and schema version validation to avoid duplication Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com> * Remove local --output option from validate command, use global --log-for instead Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com> * Remove ValidateConfigAsync wrapper; use exit code 2 for validation errors Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com> * Address review feedback: YAML validation, type safety, error handling, machine output formatting - Add YAML-to-JSON conversion in ValidateConfigCoreAsync so YAML configs can be validated - Wrap plugin property reads in try-catch for malformed type handling - Check url.ValueKind before calling GetString() in ValidateUrls - Catch IOException/UnauthorizedAccessException when reading config files - Register MachineConsoleFormatter and select formatter based on isJsonOutput - Return warning message for unparseable schema URLs instead of silently ignoring * Fix references to renamed OutputFormat/JsonConsoleFormatter after merge with main --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com> Co-authored-by: Waldek Mastykarz <waldek@mastykarz.nl> Co-authored-by: Garry Trinder <garry@trinder365.co.uk>
1 parent 3f8297c commit 85ccd72

5 files changed

Lines changed: 546 additions & 34 deletions

File tree

DevProxy.Abstractions/Utils/ProxyUtils.cs

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,25 @@ public static void ValidateSchemaVersion(string schemaUrl, ILogger logger)
275275
return;
276276
}
277277

278+
var warning = GetSchemaVersionMismatchWarning(schemaUrl);
279+
if (warning is not null)
280+
{
281+
logger.LogWarning("{Warning}", warning);
282+
}
283+
}
284+
285+
/// <summary>
286+
/// Checks if the schema URL version matches the current Dev Proxy version.
287+
/// Returns a warning message if versions don't match, or null if they match
288+
/// or the schema URL cannot be parsed.
289+
/// </summary>
290+
public static string? GetSchemaVersionMismatchWarning(string schemaUrl)
291+
{
292+
if (string.IsNullOrWhiteSpace(schemaUrl))
293+
{
294+
return null;
295+
}
296+
278297
try
279298
{
280299
var uri = new Uri(schemaUrl);
@@ -287,18 +306,47 @@ public static void ValidateSchemaVersion(string schemaUrl, ILogger logger)
287306
if (CompareSemVer(currentVersion, schemaVersion) != 0)
288307
{
289308
var currentSchemaUrl = uri.ToString().Replace($"/v{schemaVersion}/", $"/v{currentVersion}/", StringComparison.OrdinalIgnoreCase);
290-
logger.LogWarning("The version of schema does not match the installed Dev Proxy version, the expected schema is {Schema}", currentSchemaUrl);
309+
return $"The version of schema does not match the installed Dev Proxy version, the expected schema is {currentSchemaUrl}";
291310
}
292311
}
293-
else
294-
{
295-
logger.LogDebug("Invalid schema {SchemaUrl}, skipping schema version validation.", schemaUrl);
296-
}
297312
}
298-
catch (Exception ex)
313+
catch
299314
{
300-
logger.LogWarning("Invalid schema {SchemaUrl}, skipping schema version validation. Error: {Error}", schemaUrl, ex.Message);
315+
return $"The $schema value '{schemaUrl}' is not a valid URL. Schema version could not be validated.";
301316
}
317+
318+
return null;
319+
}
320+
321+
/// <summary>
322+
/// Returns the ordered list of config file paths to search.
323+
/// The first existing file in the list should be used.
324+
/// </summary>
325+
public static IEnumerable<string?> GetConfigFileCandidates(string? userConfigFile)
326+
{
327+
return [
328+
// config file specified by the user takes precedence
329+
// null if not specified
330+
userConfigFile,
331+
// current directory - JSON/JSONC files
332+
"devproxyrc.jsonc",
333+
"devproxyrc.json",
334+
// current directory - YAML files
335+
"devproxyrc.yaml",
336+
"devproxyrc.yml",
337+
// .devproxy subdirectory - JSON/JSONC files
338+
Path.Combine(".devproxy", "devproxyrc.jsonc"),
339+
Path.Combine(".devproxy", "devproxyrc.json"),
340+
// .devproxy subdirectory - YAML files
341+
Path.Combine(".devproxy", "devproxyrc.yaml"),
342+
Path.Combine(".devproxy", "devproxyrc.yml"),
343+
// app folder - JSON/JSONC files
344+
Path.Combine(AppFolder ?? "", "devproxyrc.jsonc"),
345+
Path.Combine(AppFolder ?? "", "devproxyrc.json"),
346+
// app folder - YAML files
347+
Path.Combine(AppFolder ?? "", "devproxyrc.yaml"),
348+
Path.Combine(AppFolder ?? "", "devproxyrc.yml")
349+
];
302350
}
303351

304352
/// <summary>

0 commit comments

Comments
 (0)