Skip to content

Commit 55a5104

Browse files
authored
Share more package checking code between CLI and app host (#10372)
* Share more package checking code between CLI and app host * Clean up * Update * Fix
1 parent 69fb5a3 commit 55a5104

23 files changed

+352
-276
lines changed

src/Aspire.Cli/Aspire.Cli.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<Compile Include="$(SharedDir)CircularBuffer.cs" Link="Utils\CircularBuffer.cs" />
4949
<Compile Include="$(SharedDir)StringComparers.cs" Link="StringComparers.cs" />
5050
<Compile Include="$(RepoRoot)src\Aspire.Hosting\Backchannel\BackchannelDataTypes.cs" Link="Backchannel\CliBackchannelDataTypes.cs" />
51+
<Compile Include="$(SharedDir)PackageUpdateHelpers.cs" Link="Utils\PackageUpdateHelpers.cs" />
5152
</ItemGroup>
5253

5354
<ItemGroup>

src/Aspire.Cli/Commands/AddCommand.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using Aspire.Cli.Telemetry;
1313
using Aspire.Cli.Utils;
1414
using Semver;
15+
using NuGetPackage = Aspire.Shared.NuGetPackageCli;
1516

1617
namespace Aspire.Cli.Commands;
1718

src/Aspire.Cli/Commands/BaseCommand.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.CommandLine;
5+
using System.Diagnostics;
56
using Aspire.Cli.Configuration;
67
using Aspire.Cli.Utils;
78

@@ -29,7 +30,9 @@ protected BaseCommand(string name, string description, IFeatures features, ICliU
2930
// but we'll only wait so long before we get details back about updates
3031
// being available (it should already be in the cache for longer running
3132
// commands and some commands will opt out entirely)
32-
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
33+
var cts = !Debugger.IsAttached
34+
? new CancellationTokenSource(TimeSpan.FromSeconds(10))
35+
: new CancellationTokenSource();
3336
await updateNotifier.NotifyIfUpdateAvailableAsync(currentDirectory, cancellationToken: cts.Token);
3437
}
3538
catch

src/Aspire.Cli/Commands/NewCommand.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
using Aspire.Cli.Templating;
1313
using Aspire.Cli.Utils;
1414
using Spectre.Console;
15+
using NuGetPackage = Aspire.Shared.NuGetPackageCli;
16+
1517
namespace Aspire.Cli.Commands;
1618

1719
internal sealed class NewCommand : BaseCommand

src/Aspire.Cli/DotNetCliRunner.cs

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
using Aspire.Cli.Resources;
1212
using Aspire.Cli.Telemetry;
1313
using Aspire.Hosting;
14+
using Aspire.Shared;
1415
using Microsoft.Extensions.Configuration;
1516
using Microsoft.Extensions.DependencyInjection;
1617
using Microsoft.Extensions.Logging;
18+
using NuGetPackage = Aspire.Shared.NuGetPackageCli;
1719

1820
namespace Aspire.Cli;
1921

@@ -716,52 +718,17 @@ public async Task<int> AddPackageAsync(FileInfo projectFilePath, string packageN
716718
return (ExitCodeConstants.FailedToAddPackage, null);
717719
}
718720

719-
var foundPackages = new List<NuGetPackage>();
720721
try
721722
{
722-
using var document = JsonDocument.Parse(stdout);
723-
724-
var searchResultsArray = document.RootElement.GetProperty("searchResult");
725-
726-
foreach (var sourceResult in searchResultsArray.EnumerateArray())
727-
{
728-
var source = sourceResult.GetProperty("sourceName").GetString();
729-
var sourcePackagesArray = sourceResult.GetProperty("packages");
730-
731-
foreach (var packageResult in sourcePackagesArray.EnumerateArray())
732-
{
733-
var id = packageResult.GetProperty("id").GetString();
734-
735-
// var version = prerelease switch {
736-
// true => packageResult.GetProperty("version").GetString(),
737-
// false => packageResult.GetProperty("latestVersion").GetString()
738-
// };
739-
740-
var version = packageResult.GetProperty("latestVersion").GetString();
741-
742-
foundPackages.Add(new NuGetPackage
743-
{
744-
Id = id!,
745-
Version = version!,
746-
Source = source!
747-
});
748-
}
749-
}
723+
var foundPackages = PackageUpdateHelpers.ParsePackageSearchResults(stdout);
724+
return (result, foundPackages.ToArray());
750725
}
751726
catch (JsonException ex)
752727
{
753728
logger.LogError($"Failed to read JSON returned by the package search. {ex.Message}");
754729
return (ExitCodeConstants.FailedToAddPackage, null);
755730
}
756731

757-
return (result, foundPackages.ToArray());
758732
}
759733
}
760734
}
761-
762-
internal class NuGetPackage
763-
{
764-
public string Id { get; set; } = string.Empty;
765-
public string Version { get; set; } = string.Empty;
766-
public string Source { get; set; } = string.Empty;
767-
}

src/Aspire.Cli/NuGet/NuGetPackageCache.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Aspire.Cli.Telemetry;
77
using Microsoft.Extensions.Caching.Memory;
88
using Microsoft.Extensions.Logging;
9+
using NuGetPackage = Aspire.Shared.NuGetPackageCli;
910

1011
namespace Aspire.Cli.NuGet;
1112

src/Aspire.Cli/Utils/CliUpdateNotifier.cs

Lines changed: 4 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using Aspire.Cli.Interaction;
55
using Aspire.Cli.NuGet;
6+
using Aspire.Shared;
67
using Microsoft.Extensions.Logging;
78
using Semver;
89

@@ -31,7 +32,7 @@ public async Task NotifyIfUpdateAvailableAsync(DirectoryInfo workingDirectory, C
3132
}
3233

3334
var availablePackages = await nuGetPackageCache.GetCliPackagesAsync(workingDirectory, prerelease: true, source: null, cancellationToken);
34-
var newerVersion = GetNewerVersion(currentVersion, availablePackages);
35+
var newerVersion = PackageUpdateHelpers.GetNewerVersion(currentVersion, availablePackages);
3536

3637
if (newerVersion is not null)
3738
{
@@ -46,63 +47,6 @@ public async Task NotifyIfUpdateAvailableAsync(DirectoryInfo workingDirectory, C
4647

4748
protected virtual SemVersion? GetCurrentVersion()
4849
{
49-
try
50-
{
51-
var versionString = VersionHelper.GetDefaultTemplateVersion();
52-
// Remove any build metadata (e.g., +sha.12345) for comparison
53-
var cleanVersionString = versionString.Split('+')[0];
54-
return SemVersion.Parse(cleanVersionString, SemVersionStyles.Strict);
55-
}
56-
catch
57-
{
58-
return null;
59-
}
50+
return PackageUpdateHelpers.GetCurrentPackageVersion();
6051
}
61-
62-
private static SemVersion? GetNewerVersion(SemVersion currentVersion, IEnumerable<NuGetPackage> availablePackages)
63-
{
64-
SemVersion? newestStable = null;
65-
SemVersion? newestPrerelease = null;
66-
67-
foreach (var package in availablePackages)
68-
{
69-
if (SemVersion.TryParse(package.Version, SemVersionStyles.Strict, out var version))
70-
{
71-
if (version.IsPrerelease)
72-
{
73-
newestPrerelease = newestPrerelease is null || SemVersion.PrecedenceComparer.Compare(version, newestPrerelease) > 0 ? version : newestPrerelease;
74-
}
75-
else
76-
{
77-
newestStable = newestStable is null || SemVersion.PrecedenceComparer.Compare(version, newestStable) > 0 ? version : newestStable;
78-
}
79-
}
80-
}
81-
82-
// Apply notification rules
83-
if (currentVersion.IsPrerelease)
84-
{
85-
// Rule 1: If using a prerelease version where the version is lower than the latest stable version, prompt to upgrade
86-
if (newestStable is not null && SemVersion.PrecedenceComparer.Compare(currentVersion, newestStable) < 0)
87-
{
88-
return newestStable;
89-
}
90-
91-
// Rule 2: If using a prerelease version and there is a newer prerelease version, prompt to upgrade
92-
if (newestPrerelease is not null && SemVersion.PrecedenceComparer.Compare(currentVersion, newestPrerelease) < 0)
93-
{
94-
return newestPrerelease;
95-
}
96-
}
97-
else
98-
{
99-
// Rule 3: If using a stable version and there is a newer stable version, prompt to upgrade
100-
if (newestStable is not null && SemVersion.PrecedenceComparer.Compare(currentVersion, newestStable) < 0)
101-
{
102-
return newestStable;
103-
}
104-
}
105-
106-
return null;
107-
}
108-
}
52+
}

src/Aspire.Cli/Utils/VersionHelper.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,14 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using Aspire.Cli.Resources;
5+
using Aspire.Shared;
56

67
namespace Aspire.Cli.Utils;
78

89
internal static class VersionHelper
910
{
1011
public static string GetDefaultTemplateVersion()
1112
{
12-
// Write some code that gets the informational assembly version of the current assembly and returns it as a string.
13-
var assembly = typeof(VersionHelper).Assembly;
14-
var informationalVersion = assembly
15-
.GetCustomAttributes(typeof(System.Reflection.AssemblyInformationalVersionAttribute), false)
16-
.OfType<System.Reflection.AssemblyInformationalVersionAttribute>()
17-
.FirstOrDefault()?.InformationalVersion;
18-
19-
return informationalVersion ?? throw new InvalidOperationException(ErrorStrings.UnableToRetrieveAssemblyVersion);
13+
return PackageUpdateHelpers.GetCurrentAssemblyVersion() ?? throw new InvalidOperationException(ErrorStrings.UnableToRetrieveAssemblyVersion);
2014
}
2115
}

src/Aspire.Hosting/Aspire.Hosting.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
<Compile Include="$(SharedDir)LaunchProfiles\*.cs" />
4242
<Compile Include="$(SharedDir)PortAllocator.cs" Link="Publishing\PortAllocator.cs" />
4343
<Compile Include="$(SharedDir)OverloadResolutionPriorityAttribute.cs" Link="Utils\OverloadResolutionPriorityAttribute.cs" />
44+
<Compile Include="$(SharedDir)PackageUpdateHelpers.cs" Link="Utils\PackageUpdateHelpers.cs" />
4445
</ItemGroup>
4546

4647
<ItemGroup>

src/Aspire.Hosting/DistributedApplicationBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ public DistributedApplicationBuilder(DistributedApplicationOptions options)
241241
_innerBuilder.Services.AddHostedService<DistributedApplicationLifecycle>();
242242
_innerBuilder.Services.AddHostedService<DistributedApplicationRunner>();
243243
_innerBuilder.Services.AddHostedService<VersionCheckService>();
244-
_innerBuilder.Services.AddSingleton<IVersionFetcher, VersionFetcher>();
244+
_innerBuilder.Services.AddSingleton<IPackageFetcher, PackageFetcher>();
245245
_innerBuilder.Services.AddSingleton(options);
246246
_innerBuilder.Services.AddSingleton<ResourceNotificationService>();
247247
_innerBuilder.Services.AddSingleton<ResourceLoggerService>();

0 commit comments

Comments
 (0)