| File: Utils\EnvironmentChecker\LegacySettingsFileCheck.cs | Web Access |
| Project: src\src\Aspire.Cli\Aspire.Cli.csproj (aspire) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; using Aspire.Cli.Configuration; using Aspire.Cli.Resources; namespace Aspire.Cli.Utils.EnvironmentChecker; /// <summary> /// Checks for the presence of a legacy <c>.aspire/settings.json</c> file without a sibling /// <c>aspire.config.json</c>, and surfaces a warning hint to migrate. /// </summary> /// <remarks> /// The legacy file continues to work — this check emits a non-blocking warning. Migration is /// triggered automatically by any write command (aspire run/add/init/update/pipeline), /// but users who only run read-only commands (aspire ls, ps, doctor) would otherwise never /// see a signal that a newer format exists. /// See: https://github.com/microsoft/aspire/issues/17632 /// </remarks> internal sealed class LegacySettingsFileCheck(CliExecutionContext executionContext) : IEnvironmentCheck { internal const string CheckName = "legacy-settings-file"; /// <inheritdoc /> public int Order => 101; // Run after core checks and deprecated agent config check (100) /// <inheritdoc /> public Task<IReadOnlyList<EnvironmentCheckResult>> CheckAsync(CancellationToken cancellationToken = default) { var workingDirectory = executionContext.WorkingDirectory; // Walk up the directory tree looking for a legacy .aspire/settings.json // that doesn't have a sibling aspire.config.json at the same root. var searchDir = workingDirectory; while (searchDir is not null) { cancellationToken.ThrowIfCancellationRequested(); var modernConfigPath = Path.Combine(searchDir.FullName, AspireConfigFile.FileName); if (File.Exists(modernConfigPath)) { // Found the modern config file — no legacy concern at this level or above. break; } var legacySettingsPath = ConfigurationHelper.BuildPathToSettingsJsonFile(searchDir.FullName); if (File.Exists(legacySettingsPath)) { // Found a legacy file without a sibling modern config — surface the hint. var result = new EnvironmentCheckResult { Category = EnvironmentCheckCategories.Environment, Name = CheckName, Status = EnvironmentCheckStatus.Warning, Message = string.Format(CultureInfo.CurrentCulture, DoctorCommandStrings.LegacySettingsDetectedMessageFormat, legacySettingsPath), Fix = DoctorCommandStrings.LegacySettingsDetectedFix }; return Task.FromResult<IReadOnlyList<EnvironmentCheckResult>>([result]); } searchDir = searchDir.Parent; } return Task.FromResult<IReadOnlyList<EnvironmentCheckResult>>([]); } }