@@ -21,7 +21,7 @@ function Publish-File
21
21
# attempt to get the users module directory
22
22
function Get-UserModulePath
23
23
{
24
- if ( $IsCoreCLR -and ! $IsWindows )
24
+ if ( $IsCoreCLR -and -not $IsWindows )
25
25
{
26
26
$platformType = " System.Management.Automation.Platform" -as [Type ]
27
27
if ( $platformType ) {
@@ -104,7 +104,7 @@ function Start-DocumentationBuild
104
104
throw " Cannot find markdown documentation folder."
105
105
}
106
106
Import-Module platyPS
107
- if ( ! (Test-Path $outputDocsPath )) {
107
+ if ( -not (Test-Path $outputDocsPath )) {
108
108
$null = New-Item - Type Directory - Path $outputDocsPath - Force
109
109
}
110
110
$null = New-ExternalHelp - Path $markdownDocsPath - OutputPath $outputDocsPath - Force
@@ -126,7 +126,22 @@ function Start-ScriptAnalyzerBuild
126
126
[switch ]$Documentation
127
127
)
128
128
129
+ BEGIN {
130
+ # don't allow the build to be started unless we have the proper Cli version
131
+ if ( -not (Test-SuitableDotnet ) ) {
132
+ $requiredVersion = Get-GlobalJsonSdkVersion
133
+ throw " No suitable dotnet CLI found, requires version '$requiredVersion '"
134
+ }
135
+ }
129
136
END {
137
+
138
+ # Build docs either when -Documentation switch is being specified or the first time in a clean repo
139
+ $documentationFileExists = Test-Path (Join-Path $PSScriptRoot ' out\PSScriptAnalyzer\en-us\Microsoft.Windows.PowerShell.ScriptAnalyzer.dll-Help.xml' )
140
+ if ( $Documentation -or -not $documentationFileExists )
141
+ {
142
+ Start-DocumentationBuild
143
+ }
144
+
130
145
if ( $All )
131
146
{
132
147
# Build all the versions of the analyzer
@@ -136,13 +151,6 @@ function Start-ScriptAnalyzerBuild
136
151
return
137
152
}
138
153
139
- $documentationFileExists = Test-Path (Join-Path $PSScriptRoot ' out\PSScriptAnalyzer\en-us\Microsoft.Windows.PowerShell.ScriptAnalyzer.dll-Help.xml' )
140
- # Build docs either when -Documentation switch is being specified or the first time in a clean repo
141
- if ( $Documentation -or -not $documentationFileExists )
142
- {
143
- Start-DocumentationBuild
144
- }
145
-
146
154
if ($PSVersion -ge 6 ) {
147
155
$framework = ' netstandard2.0'
148
156
}
@@ -277,17 +285,25 @@ function Get-TestFailures
277
285
function Install-Dotnet
278
286
{
279
287
[CmdletBinding (SupportsShouldProcess = $true )]
280
- param ( [Parameter ()][Switch ]$Force )
288
+ param (
289
+ [Parameter ()][Switch ]$Force ,
290
+ [Parameter ()]$version = $ ( Get-GlobalJsonSdkVersion )
291
+ )
281
292
282
- $json = Get-Content - raw (Join-Path $PSScriptRoot global.json) | ConvertFrom-Json
283
- $version = $json.sdk.Version
284
- if ( Test-DotnetInstallation - version $version ) {
293
+ if ( Test-DotnetInstallation - requestedversion $version ) {
285
294
Write-Verbose - Verbose " dotnet version '$version ' already installed"
286
- return
295
+ if ( $Force ) {
296
+ Write-Verbose - Verbose " Installing again"
297
+ }
298
+ else {
299
+ return
300
+ }
287
301
}
302
+
288
303
try {
289
304
Push-Location $PSScriptRoot
290
305
$installScriptPath = Receive-DotnetInstallScript
306
+ $installScriptName = [System.IO.Path ]::GetFileName($installScriptPath )
291
307
If ( $PSCmdlet.ShouldProcess (" $installScriptName for $version " )) {
292
308
& " ${installScriptPath} " - c release - v $version
293
309
}
@@ -303,19 +319,119 @@ function Install-Dotnet
303
319
}
304
320
}
305
321
306
- function Test-DotnetInstallation
307
- {
308
- param ( $version )
322
+ function Get-GlobalJsonSdkVersion {
323
+ $json = Get-Content - raw (Join-Path $PSScriptRoot global.json) | ConvertFrom-Json
324
+ $version = $json.sdk.Version
325
+ ConvertTo-PortableVersion $version
326
+ }
327
+
328
+ # we don't have semantic version in earlier versions of PowerShell, so we need to
329
+ # create something that we can use
330
+ function ConvertTo-PortableVersion {
331
+ param ( [string []]$strVersion )
332
+ if ( -not $strVersion ) {
333
+ return (ConvertTo-PortableVersion " 0.0.0-0" )
334
+ }
335
+ foreach ( $v in $strVersion ) {
336
+ $ver , $pre = $v.split (" -" , 2 )
337
+ try {
338
+ [int ]$major , [int ]$minor , [int ]$patch = $ver.Split (" ." )
339
+ }
340
+ catch {
341
+ Write-Warning " Cannot convert '$v ' to portable version"
342
+ continue
343
+ }
344
+ $h = @ {
345
+ Major = $major
346
+ Minor = $minor
347
+ Patch = $patch
348
+ }
349
+ if ( $pre ) {
350
+ $h [' PrereleaseLabel' ] = $pre
351
+ }
352
+ else {
353
+ $h [' PrereleaseLabel' ] = [String ]::Empty
354
+ }
355
+ $customObject = [pscustomobject ]$h
356
+ Add-Member - inputobject $customObject - Type ScriptMethod - Name ToString - Force - Value {
357
+ $str = " {0}.{1}.{2}" -f $this.Major , $this.Minor , $this.Patch
358
+ if ( $this.PrereleaseLabel ) {
359
+ $str += " -{0}" -f $this.PrereleaseLabel
360
+ }
361
+ return $str
362
+ }
363
+ Add-Member - inputobject $customObject - Type ScriptMethod - Name IsContainedIn - Value {
364
+ param ( [object []]$collection )
365
+ foreach ( $object in $collection ) {
366
+ if (
367
+ $this.Major -eq $object.Major -and
368
+ $this.Minor -eq $object.Minor -and
369
+ $this.Patch -eq $object.Patch -and
370
+ $this.PrereleaseLabel -eq $object.PrereleaseLabel
371
+ ) {
372
+ return $true
373
+ }
374
+ }
375
+ return $false
376
+ }
377
+ $customObject
378
+ }
379
+ }
380
+
381
+ # see https://docs.microsoft.com/en-us/dotnet/core/tools/global-json for rules
382
+ # on how version checks are done
383
+ function Test-SuitableDotnet {
384
+ param (
385
+ $availableVersions = $ ( Get-InstalledCliVersion ),
386
+ $requiredVersion = $ ( Get-GlobalJsonSdkVersion )
387
+ )
388
+ if ( $requiredVersion -is [String ] -or $requiredVersion -is [Version ] ) {
389
+ $requiredVersion = ConvertTo-PortableVersion " $requiredVersion "
390
+ }
391
+ # if we have what was requested, we can use it
392
+ if ( $RequiredVersion.IsContainedIn ($availableVersions )) {
393
+ return $true
394
+ }
395
+ # if we had found a match, we would have returned $true above
396
+ # exact match required for 2.1.100 through 2.1.201
397
+ if ( $RequiredVersion.Major -eq 2 -and $RequiredVersion.Minor -eq 1 -and $RequiredVersion.Patch -ge 100 -and $RequiredVersion.Patch -le 201 ) {
398
+ return $false
399
+ }
400
+ # we need to check each available version for something that's useable
401
+ foreach ( $version in $availableVersions ) {
402
+ # major/minor numbers don't match - keep looking
403
+ if ( $version.Major -ne $requiredVersion.Major -or $version.Minor -ne $requiredVersion.Minor ) {
404
+ continue
405
+ }
406
+ $requiredPatch = $requiredVersion.Patch
407
+ $possiblePatch = $version.Patch
408
+ if ( $requiredPatch -gt $possiblePath ) {
409
+ continue
410
+ }
411
+ if ( ($requiredPatch - $possiblePatch ) -ge 100 ) {
412
+ continue
413
+ }
414
+ return $true
415
+ }
416
+ return $false
417
+ }
418
+
419
+ # these are mockable functions for testing
420
+ function Get-InstalledCLIVersion {
309
421
try {
310
422
$installedVersions = dotnet -- list- sdks | Foreach-Object { $_.Split ()[0 ] }
311
423
}
312
424
catch {
313
425
$installedVersions = @ ()
314
426
}
315
- if ( $installedVersions -contains $version ) {
316
- return $true
317
- }
318
- return $false
427
+ return (ConvertTo-PortableVersion $installedVersions )
428
+ }
429
+
430
+ function Test-DotnetInstallation
431
+ {
432
+ param ( $requestedVersion = $ ( Get-GlobalJsonSdkVersion ) )
433
+ $installedVersions = Get-InstalledCLIVersion
434
+ return (Test-SuitableDotnet - availableVersions $installedVersions - requiredVersion $requestedVersion )
319
435
}
320
436
321
437
function Receive-DotnetInstallScript
0 commit comments