83 lines
3.1 KiB
C#
83 lines
3.1 KiB
C#
![]() |
// Licensed to the .NET Foundation under one or more agreements.
|
||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||
|
|
||
|
using System;
|
||
|
using System.Diagnostics;
|
||
|
using System.IO;
|
||
|
using System.Net;
|
||
|
using System.Net.Http;
|
||
|
using System.Runtime.InteropServices;
|
||
|
using System.Threading.Tasks;
|
||
|
using Microsoft.Build.Framework;
|
||
|
public class GetClosestOfficialSdk : Microsoft.Build.Utilities.Task
|
||
|
{
|
||
|
[Required]
|
||
|
public required string BuiltSdkPath { get; init; }
|
||
|
|
||
|
[Output]
|
||
|
public string ClosestOfficialSdkPath { get; set; } = "";
|
||
|
|
||
|
public override bool Execute()
|
||
|
{
|
||
|
return Task.Run(ExecuteAsync).Result;
|
||
|
}
|
||
|
|
||
|
public async Task<bool> ExecuteAsync()
|
||
|
{
|
||
|
var (versionString, rid, extension) = ExtractFromFilePath(BuiltSdkPath);
|
||
|
|
||
|
string downloadUrl = GetLatestOfficialSdkUrl(versionString, rid, extension);
|
||
|
|
||
|
Log.LogMessage($"Downloading {downloadUrl}");
|
||
|
var packageResponse = await new HttpClient().GetAsync(downloadUrl);
|
||
|
packageResponse.EnsureSuccessStatusCode();
|
||
|
|
||
|
var packageUriPath = packageResponse.RequestMessage!.RequestUri!.LocalPath;
|
||
|
string downloadedVersion = PathWithVersions.GetVersionInPath(packageUriPath).ToString();
|
||
|
|
||
|
ClosestOfficialSdkPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + $".dotnet-sdk-{downloadedVersion}-{rid}{extension}");
|
||
|
Log.LogMessage($"Copying {packageUriPath} to {ClosestOfficialSdkPath}");
|
||
|
using (var file = File.Create(ClosestOfficialSdkPath))
|
||
|
{
|
||
|
await packageResponse.Content.CopyToAsync(file);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
string GetLatestOfficialSdkUrl(string versionString, string rid, string extension)
|
||
|
{
|
||
|
// Channel in the form of 9.0.1xx
|
||
|
var channel = versionString[..5] + "xx";
|
||
|
return $"https://aka.ms/dotnet/{channel}/daily/dotnet-sdk-{rid}{extension}";
|
||
|
}
|
||
|
|
||
|
static (string Version, string Rid, string extension) ExtractFromFilePath(string path)
|
||
|
{
|
||
|
string extension;
|
||
|
if (path.EndsWith(".tar.gz"))
|
||
|
{
|
||
|
extension = ".tar.gz";
|
||
|
}
|
||
|
else if (path.EndsWith(".zip"))
|
||
|
{
|
||
|
extension = ".zip";
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
throw new ArgumentException($"Invalid archive extension '{path}': must end with .tar.gz or .zip");
|
||
|
}
|
||
|
|
||
|
string filename = Path.GetFileName(path)[..^extension.Length];
|
||
|
var dashDelimitedParts = filename.Split('-');
|
||
|
var (rid, versionString) = dashDelimitedParts switch
|
||
|
{
|
||
|
["dotnet", "sdk", var first, var second, var third, var fourth] when PathWithVersions.IsVersionString(first) => (third + '-' + fourth, first + '-' + second),
|
||
|
["dotnet", "sdk", var first, var second, var third, var fourth] when PathWithVersions.IsVersionString(third) => (first + '-' + second, third + '-' + fourth),
|
||
|
_ => throw new ArgumentException($"Invalid archive file name '{filename}': file name should include full build full build full build full build full build full build full build full build full build version and rid")
|
||
|
};
|
||
|
|
||
|
return (versionString, rid, extension);
|
||
|
}
|
||
|
}
|