Skip to content

Commit a5255d2

Browse files
fix: add fallback for nuget downloader (#9131)
This PR addresses an edge case where the nuget downloader was not parsing the last contract DLL path on disk as expected. fixes: #9130
1 parent 484a869 commit a5255d2

File tree

3 files changed

+85
-1
lines changed

3 files changed

+85
-1
lines changed

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Utilities/NugetPackageDownloader.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,16 @@ private bool TryFindPackageLibPathInCache(string packageName, NuGetVersion packa
265265
}
266266
}
267267

268+
// Fallback to any of the preferred versions if none of the target frameworks matched.
269+
foreach (var preferredDotNetFrameworkVersion in PreferredDotNetFrameworkVersions)
270+
{
271+
var dotNetFolder = Path.Combine(packageLibraryPath, preferredDotNetFrameworkVersion);
272+
if (DirectoryExists(dotNetFolder))
273+
{
274+
return dotNetFolder;
275+
}
276+
}
277+
268278
return null;
269279
}
270280

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/TestHelpers/TestNugetPackageDownloader.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ internal class TestNugetPackageDownloader : NugetPackageDownloader
1919
private const string DefaultTargetFramework = "netstandard2.0";
2020
private readonly SourceRepository _mockPackageSourceRepo;
2121
private readonly bool _mockDirectoryExists;
22+
private readonly HashSet<string>? _existingDirectories;
2223
private readonly bool _mockTryFindPackageInCache;
2324
private readonly bool _mockPackageExistsInSource;
2425
private readonly LocalPackageInfo? _mockLocalPackageInfo;
@@ -39,10 +40,12 @@ public TestNugetPackageDownloader(
3940
bool directoryExists,
4041
bool packageExistsInSource,
4142
IEnumerable<string>? targetFrameworks = null,
42-
LocalPackageInfo? localPackageInfo = null) : base(packageName, version, targetFrameworks ?? [DefaultTargetFramework], settings)
43+
LocalPackageInfo? localPackageInfo = null,
44+
HashSet<string>? existingDirectories = null) : base(packageName, version, targetFrameworks ?? [DefaultTargetFramework], settings)
4345
{
4446
_mockPackageSourceRepo = sourceRepository;
4547
_mockDirectoryExists = directoryExists;
48+
_existingDirectories = existingDirectories;
4649
_mockLocalPackageInfo = localPackageInfo;
4750
_mockTryFindPackageInCache = _mockLocalPackageInfo != null;
4851
_mockPackageExistsInSource = packageExistsInSource;
@@ -55,6 +58,10 @@ protected override SourceRepository GetCoreV3NugetSourceRepo(string source)
5558

5659
protected override bool DirectoryExists(string path)
5760
{
61+
if (_existingDirectories != null)
62+
{
63+
return _existingDirectories.Contains(path);
64+
}
5865
return _mockDirectoryExists;
5966
}
6067

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Utilities/NugetPackageDownloaderTests.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,73 @@ public async Task TestDownloadAndInstallPackage(bool packageExistsInSource)
103103
}
104104
}
105105

106+
// This test validates that when target frameworks don't match any existing directory,
107+
// it falls back to the first available preferred version
108+
[Test]
109+
public async Task TestGetDotNetFolderPathFallback()
110+
{
111+
var packageName = "mockPackage";
112+
var packageVersion = "1.0.0";
113+
var mockDownloadResource = new Mock<DownloadResource>();
114+
115+
mockDownloadResource.Setup(d => d.GetDownloadResourceResultAsync(
116+
It.IsAny<PackageIdentity>(),
117+
It.IsAny<PackageDownloadContext>(),
118+
It.IsAny<string>(),
119+
It.IsAny<ILogger>(),
120+
It.IsAny<CancellationToken>()))
121+
.Returns(Task.FromResult(new DownloadResourceResult(new Mock<Stream>().Object, "mockSource")));
122+
123+
var mockPackageSourceRepository = new Mock<SourceRepository>();
124+
mockPackageSourceRepository.Setup(s => s.GetResourceAsync<DownloadResource>())
125+
.Returns(Task.FromResult(mockDownloadResource.Object));
126+
127+
TestNugetSettings mockSettings = new()
128+
{
129+
Sections =
130+
[
131+
new TestNugetSettingSection(ConfigurationConstants.PackageSources, new SourceItem("mockSource", "mockSourceUri"))
132+
]
133+
};
134+
135+
// Set up: target framework is "net9.0" but only "netstandard2.0" directory exists
136+
var packagePath = "c:\\mockPath";
137+
var libPath = Path.Combine(packagePath, "lib");
138+
var existingDirs = new HashSet<string>
139+
{
140+
libPath,
141+
Path.Combine(libPath, "netstandard2.0")
142+
};
143+
144+
var mockLocalPackageInfo = new LocalPackageInfo(
145+
packageName,
146+
NuGetVersion.Parse(packageVersion),
147+
packagePath,
148+
"mockSourceUri",
149+
"mockManifestPath",
150+
"mockSha512Path",
151+
new Lazy<NuspecReader>(),
152+
new Lazy<IReadOnlyList<string>>(),
153+
new Lazy<string>(),
154+
new Lazy<RuntimeGraph>());
155+
156+
var downloader = new TestNugetPackageDownloader(
157+
packageName,
158+
packageVersion,
159+
mockSettings,
160+
mockPackageSourceRepository.Object,
161+
true,
162+
true,
163+
["net9.0"],
164+
mockLocalPackageInfo,
165+
existingDirs);
166+
167+
var result = await downloader.DownloadAndInstallPackage();
168+
169+
Assert.NotNull(result);
170+
Assert.AreEqual(Path.Combine(libPath, "netstandard2.0"), result);
171+
}
172+
106173
public static IEnumerable<TestCaseData> ParseVersionStringTestCases
107174
{
108175
get

0 commit comments

Comments
 (0)