@@ -21,34 +21,28 @@ public static IEnumerable<ValidationError> ValidateCoreSdks(string? customDotNet
2121 {
2222 yield return cliPathError ;
2323 }
24- else if ( TryGetSdkVersion ( benchmark , out string requiredSdkVersion ) )
24+ else if ( TryGetSdkVersion ( benchmark , out Version requiredSdkVersion ) )
2525 {
2626 var installedSdks = GetInstalledDotNetSdks ( customDotNetCliPath ) ;
27- if ( ! installedSdks . Any ( sdk => sdk . StartsWith ( requiredSdkVersion ) ) )
27+ if ( ! installedSdks . Any ( sdk => sdk >= requiredSdkVersion ) )
2828 {
29- yield return new ValidationError ( true , $ "The required .NET Core SDK version { requiredSdkVersion } for runtime moniker { benchmark . Job . Environment . Runtime . RuntimeMoniker } is not installed.", benchmark ) ;
29+ yield return new ValidationError ( true , $ "The required .NET Core SDK version { requiredSdkVersion } or higher for runtime moniker { benchmark . Job . Environment . Runtime . RuntimeMoniker } is not installed.", benchmark ) ;
3030 }
3131 }
3232 }
3333
3434 public static IEnumerable < ValidationError > ValidateFrameworkSdks ( BenchmarkCase benchmark )
3535 {
36- if ( ! TryGetSdkVersion ( benchmark , out string requiredSdkVersionString ) )
36+ if ( ! TryGetSdkVersion ( benchmark , out Version requiredSdkVersion ) )
3737 {
3838 yield break ;
3939 }
4040
41- if ( ! Version . TryParse ( requiredSdkVersionString , out var requiredSdkVersion ) )
42- {
43- yield return new ValidationError ( true , $ "Invalid .NET Framework SDK version format: { requiredSdkVersionString } ", benchmark ) ;
44- yield break ;
45- }
46-
4741 var installedVersionString = cachedFrameworkSdks . Value . FirstOrDefault ( ) ;
4842
4943 if ( installedVersionString == null || Version . TryParse ( installedVersionString , out var installedVersion ) && installedVersion < requiredSdkVersion )
5044 {
51- yield return new ValidationError ( true , $ "The required .NET Framework SDK version { requiredSdkVersionString } or higher is not installed.", benchmark ) ;
45+ yield return new ValidationError ( true , $ "The required .NET Framework SDK version { requiredSdkVersion } or higher is not installed.", benchmark ) ;
5246 }
5347 }
5448
@@ -77,9 +71,9 @@ public static bool IsCliPathInvalid(string customDotNetCliPath, BenchmarkCase be
7771 return false ;
7872 }
7973
80- private static bool TryGetSdkVersion ( BenchmarkCase benchmark , out string sdkVersion )
74+ private static bool TryGetSdkVersion ( BenchmarkCase benchmark , out Version sdkVersion )
8175 {
82- sdkVersion = string . Empty ;
76+ sdkVersion = default ;
8377 if ( benchmark ? . Job ? . Environment ? . Runtime ? . RuntimeMoniker != null )
8478 {
8579 sdkVersion = GetSdkVersionFromMoniker ( benchmark . Job . Environment . Runtime . RuntimeMoniker ) ;
@@ -88,7 +82,7 @@ private static bool TryGetSdkVersion(BenchmarkCase benchmark, out string sdkVers
8882 return false ;
8983 }
9084
91- private static IEnumerable < string > GetInstalledDotNetSdks ( string ? customDotNetCliPath )
85+ private static IEnumerable < Version > GetInstalledDotNetSdks ( string ? customDotNetCliPath )
9286 {
9387 string dotnetExecutable = string . IsNullOrEmpty ( customDotNetCliPath ) ? "dotnet" : customDotNetCliPath ;
9488 var startInfo = new ProcessStartInfo ( dotnetExecutable , "--list-sdks" )
@@ -104,7 +98,7 @@ private static IEnumerable<string> GetInstalledDotNetSdks(string? customDotNetCl
10498 {
10599 if ( process == null )
106100 {
107- return Enumerable . Empty < string > ( ) ;
101+ return Enumerable . Empty < Version > ( ) ;
108102 }
109103
110104 process . WaitForExit ( ) ;
@@ -113,17 +107,38 @@ private static IEnumerable<string> GetInstalledDotNetSdks(string? customDotNetCl
113107 {
114108 var output = process . StandardOutput . ReadToEnd ( ) ;
115109 var lines = output . Split ( new [ ] { '\r ' , '\n ' } , StringSplitOptions . RemoveEmptyEntries ) ;
116- return lines . Select ( line => line . Split ( ' ' ) [ 0 ] ) ; // The SDK version is the first part of each line.
110+
111+ var versions = new List < Version > ( lines . Count ( ) ) ;
112+ foreach ( var line in lines )
113+ {
114+ // Each line will start with the SDK version followed by the SDK path. Since we only support
115+ // targeting SDK versions by the major version, we'll just look at extracting the major and
116+ // minor versions. This is done by looking for the first two dots in the line.
117+ var firstDot = line . IndexOf ( '.' ) ;
118+ if ( firstDot < 0 )
119+ continue ;
120+
121+ var secondDot = line . IndexOf ( '.' , firstDot + 1 ) ;
122+ if ( secondDot < 0 )
123+ continue ;
124+
125+ if ( Version . TryParse ( line . Substring ( 0 , secondDot ) , out var version ) )
126+ {
127+ versions . Add ( version ) ;
128+ }
129+ }
130+
131+ return versions ;
117132 }
118133 else
119134 {
120- return Enumerable . Empty < string > ( ) ;
135+ return Enumerable . Empty < Version > ( ) ;
121136 }
122137 }
123138 }
124139 catch ( Win32Exception ) // dotnet CLI is not installed or not found in the path.
125140 {
126- return Enumerable . Empty < string > ( ) ;
141+ return Enumerable . Empty < Version > ( ) ;
127142 }
128143 }
129144
@@ -193,42 +208,42 @@ private static string CheckFor45PlusVersion(int releaseKey)
193208 return "" ;
194209 }
195210
196- private static string GetSdkVersionFromMoniker ( RuntimeMoniker runtimeMoniker )
211+ private static Version GetSdkVersionFromMoniker ( RuntimeMoniker runtimeMoniker )
197212 {
198213 return runtimeMoniker switch
199214 {
200- RuntimeMoniker . Net461 => "4.6.1" ,
201- RuntimeMoniker . Net462 => "4.6.2" ,
202- RuntimeMoniker . Net47 => "4.7" ,
203- RuntimeMoniker . Net471 => "4.7.1" ,
204- RuntimeMoniker . Net472 => "4.7.2" ,
205- RuntimeMoniker . Net48 => "4.8" ,
206- RuntimeMoniker . Net481 => "4.8.1" ,
207- RuntimeMoniker . NetCoreApp31 => "3.1" ,
208- RuntimeMoniker . Net50 => "5.0" ,
209- RuntimeMoniker . Net60 => "6.0" ,
210- RuntimeMoniker . Net70 => "7.0" ,
211- RuntimeMoniker . Net80 => "8.0" ,
212- RuntimeMoniker . Net90 => "9.0" ,
213- RuntimeMoniker . NativeAot60 => "6.0" ,
214- RuntimeMoniker . NativeAot70 => "7.0" ,
215- RuntimeMoniker . NativeAot80 => "8.0" ,
216- RuntimeMoniker . NativeAot90 => "9.0" ,
217- RuntimeMoniker . Mono60 => "6.0" ,
218- RuntimeMoniker . Mono70 => "7.0" ,
219- RuntimeMoniker . Mono80 => "8.0" ,
220- RuntimeMoniker . Mono90 => "9.0" ,
221- RuntimeMoniker . Wasm => Portability . RuntimeInformation . IsNetCore && CoreRuntime . TryGetVersion ( out var version ) ? $ " { version . Major } . { version . Minor } " : "5.0" ,
222- RuntimeMoniker . WasmNet50 => "5.0" ,
223- RuntimeMoniker . WasmNet60 => "6.0" ,
224- RuntimeMoniker . WasmNet70 => "7.0" ,
225- RuntimeMoniker . WasmNet80 => "8.0" ,
226- RuntimeMoniker . WasmNet90 => "9.0" ,
227- RuntimeMoniker . MonoAOTLLVM => Portability . RuntimeInformation . IsNetCore && CoreRuntime . TryGetVersion ( out var version ) ? $ " { version . Major } . { version . Minor } " : "6.0" ,
228- RuntimeMoniker . MonoAOTLLVMNet60 => "6.0" ,
229- RuntimeMoniker . MonoAOTLLVMNet70 => "7.0" ,
230- RuntimeMoniker . MonoAOTLLVMNet80 => "8.0" ,
231- RuntimeMoniker . MonoAOTLLVMNet90 => "9.0" ,
215+ RuntimeMoniker . Net461 => new Version ( 4 , 6 , 1 ) ,
216+ RuntimeMoniker . Net462 => new Version ( 4 , 6 , 2 ) ,
217+ RuntimeMoniker . Net47 => new Version ( 4 , 7 ) ,
218+ RuntimeMoniker . Net471 => new Version ( 4 , 7 , 1 ) ,
219+ RuntimeMoniker . Net472 => new Version ( 4 , 7 , 2 ) ,
220+ RuntimeMoniker . Net48 => new Version ( 4 , 8 ) ,
221+ RuntimeMoniker . Net481 => new Version ( 4 , 8 , 1 ) ,
222+ RuntimeMoniker . NetCoreApp31 => new Version ( 3 , 1 ) ,
223+ RuntimeMoniker . Net50 => new Version ( 5 , 0 ) ,
224+ RuntimeMoniker . Net60 => new Version ( 6 , 0 ) ,
225+ RuntimeMoniker . Net70 => new Version ( 7 , 0 ) ,
226+ RuntimeMoniker . Net80 => new Version ( 8 , 0 ) ,
227+ RuntimeMoniker . Net90 => new Version ( 9 , 0 ) ,
228+ RuntimeMoniker . NativeAot60 => new Version ( 6 , 0 ) ,
229+ RuntimeMoniker . NativeAot70 => new Version ( 7 , 0 ) ,
230+ RuntimeMoniker . NativeAot80 => new Version ( 8 , 0 ) ,
231+ RuntimeMoniker . NativeAot90 => new Version ( 9 , 0 ) ,
232+ RuntimeMoniker . Mono60 => new Version ( 6 , 0 ) ,
233+ RuntimeMoniker . Mono70 => new Version ( 7 , 0 ) ,
234+ RuntimeMoniker . Mono80 => new Version ( 8 , 0 ) ,
235+ RuntimeMoniker . Mono90 => new Version ( 9 , 0 ) ,
236+ RuntimeMoniker . Wasm => Portability . RuntimeInformation . IsNetCore && CoreRuntime . TryGetVersion ( out var version ) ? version : new Version ( 5 , 0 ) ,
237+ RuntimeMoniker . WasmNet50 => new Version ( 5 , 0 ) ,
238+ RuntimeMoniker . WasmNet60 => new Version ( 6 , 0 ) ,
239+ RuntimeMoniker . WasmNet70 => new Version ( 7 , 0 ) ,
240+ RuntimeMoniker . WasmNet80 => new Version ( 8 , 0 ) ,
241+ RuntimeMoniker . WasmNet90 => new Version ( 9 , 0 ) ,
242+ RuntimeMoniker . MonoAOTLLVM => Portability . RuntimeInformation . IsNetCore && CoreRuntime . TryGetVersion ( out var version ) ? version : new Version ( 6 , 0 ) ,
243+ RuntimeMoniker . MonoAOTLLVMNet60 => new Version ( 6 , 0 ) ,
244+ RuntimeMoniker . MonoAOTLLVMNet70 => new Version ( 7 , 0 ) ,
245+ RuntimeMoniker . MonoAOTLLVMNet80 => new Version ( 8 , 0 ) ,
246+ RuntimeMoniker . MonoAOTLLVMNet90 => new Version ( 9 , 0 ) ,
232247 _ => throw new NotImplementedException ( $ "SDK version check not implemented for { runtimeMoniker } ")
233248 } ;
234249 }
0 commit comments