msbuild

Форк
0
/
CommonLibrary.psm1 
400 строк · 11.8 Кб
1
<#
2
.SYNOPSIS
3
Helper module to install an archive to a directory
4

5
.DESCRIPTION
6
Helper module to download and extract an archive to a specified directory
7

8
.PARAMETER Uri
9
Uri of artifact to download
10

11
.PARAMETER InstallDirectory
12
Directory to extract artifact contents to
13

14
.PARAMETER Force
15
Force download / extraction if file or contents already exist. Default = False
16

17
.PARAMETER DownloadRetries
18
Total number of retry attempts. Default = 5
19

20
.PARAMETER RetryWaitTimeInSeconds
21
Wait time between retry attempts in seconds. Default = 30
22

23
.NOTES
24
Returns False if download or extraction fail, True otherwise
25
#>
26
function DownloadAndExtract {
27
  [CmdletBinding(PositionalBinding=$false)]
28
  Param (
29
    [Parameter(Mandatory=$True)]
30
    [string] $Uri,
31
    [Parameter(Mandatory=$True)]
32
    [string] $InstallDirectory,
33
    [switch] $Force = $False,
34
    [int] $DownloadRetries = 5,
35
    [int] $RetryWaitTimeInSeconds = 30
36
  )
37
  # Define verbose switch if undefined
38
  $Verbose = $VerbosePreference -Eq "Continue"
39

40
  $TempToolPath = CommonLibrary\Get-TempPathFilename -Path $Uri
41

42
  # Download native tool
43
  $DownloadStatus = CommonLibrary\Get-File -Uri $Uri `
44
                                           -Path $TempToolPath `
45
                                           -DownloadRetries $DownloadRetries `
46
                                           -RetryWaitTimeInSeconds $RetryWaitTimeInSeconds `
47
                                           -Force:$Force `
48
                                           -Verbose:$Verbose
49

50
  if ($DownloadStatus -Eq $False) {
51
    Write-Error "Download failed from $Uri"
52
    return $False
53
  }
54

55
  # Extract native tool
56
  $UnzipStatus = CommonLibrary\Expand-Zip -ZipPath $TempToolPath `
57
                                          -OutputDirectory $InstallDirectory `
58
                                          -Force:$Force `
59
                                          -Verbose:$Verbose
60

61
  if ($UnzipStatus -Eq $False) {
62
    # Retry Download one more time with Force=true
63
    $DownloadRetryStatus = CommonLibrary\Get-File -Uri $Uri `
64
                                             -Path $TempToolPath `
65
                                             -DownloadRetries 1 `
66
                                             -RetryWaitTimeInSeconds $RetryWaitTimeInSeconds `
67
                                             -Force:$True `
68
                                             -Verbose:$Verbose
69

70
    if ($DownloadRetryStatus -Eq $False) {
71
      Write-Error "Last attempt of download failed as well"
72
      return $False
73
    }
74

75
    # Retry unzip again one more time with Force=true
76
    $UnzipRetryStatus = CommonLibrary\Expand-Zip -ZipPath $TempToolPath `
77
                                            -OutputDirectory $InstallDirectory `
78
                                            -Force:$True `
79
                                            -Verbose:$Verbose
80
    if ($UnzipRetryStatus -Eq $False)
81
    {
82
      Write-Error "Last attempt of unzip failed as well"
83
      # Clean up partial zips and extracts
84
      if (Test-Path $TempToolPath) {
85
        Remove-Item $TempToolPath -Force
86
      }
87
      if (Test-Path $InstallDirectory) {
88
        Remove-Item $InstallDirectory -Force -Recurse
89
      }
90
      return $False
91
    }
92
  }
93

94
  return $True
95
}
96

97
<#
98
.SYNOPSIS
99
Download a file, retry on failure
100

101
.DESCRIPTION
102
Download specified file and retry if attempt fails
103

104
.PARAMETER Uri
105
Uri of file to download. If Uri is a local path, the file will be copied instead of downloaded
106

107
.PARAMETER Path
108
Path to download or copy uri file to
109

110
.PARAMETER Force
111
Overwrite existing file if present. Default = False
112

113
.PARAMETER DownloadRetries
114
Total number of retry attempts. Default = 5
115

116
.PARAMETER RetryWaitTimeInSeconds
117
Wait time between retry attempts in seconds Default = 30
118

119
#>
120
function Get-File {
121
  [CmdletBinding(PositionalBinding=$false)]
122
  Param (
123
    [Parameter(Mandatory=$True)]
124
    [string] $Uri,
125
    [Parameter(Mandatory=$True)]
126
    [string] $Path,
127
    [int] $DownloadRetries = 5,
128
    [int] $RetryWaitTimeInSeconds = 30,
129
    [switch] $Force = $False
130
  )
131
  $Attempt = 0
132

133
  if ($Force) {
134
    if (Test-Path $Path) {
135
      Remove-Item $Path -Force
136
    }
137
  }
138
  if (Test-Path $Path) {
139
    Write-Host "File '$Path' already exists, skipping download"
140
    return $True
141
  }
142

143
  $DownloadDirectory = Split-Path -ErrorAction Ignore -Path "$Path" -Parent
144
  if (-Not (Test-Path $DownloadDirectory)) {
145
    New-Item -path $DownloadDirectory -force -itemType "Directory" | Out-Null
146
  }
147

148
  $TempPath = "$Path.tmp"
149
  if (Test-Path -IsValid -Path $Uri) {
150
    Write-Verbose "'$Uri' is a file path, copying temporarily to '$TempPath'"
151
    Copy-Item -Path $Uri -Destination $TempPath
152
    Write-Verbose "Moving temporary file to '$Path'"
153
    Move-Item -Path $TempPath -Destination $Path
154
    return $?
155
  }
156
  else {
157
    Write-Verbose "Downloading $Uri"
158
    # Don't display the console progress UI - it's a huge perf hit
159
    $ProgressPreference = 'SilentlyContinue'   
160
    while($Attempt -Lt $DownloadRetries)
161
    {
162
      try {
163
        Invoke-WebRequest -UseBasicParsing -Uri $Uri -OutFile $TempPath
164
        Write-Verbose "Downloaded to temporary location '$TempPath'"
165
        Move-Item -Path $TempPath -Destination $Path
166
        Write-Verbose "Moved temporary file to '$Path'"
167
        return $True
168
      }
169
      catch {
170
        $Attempt++
171
        if ($Attempt -Lt $DownloadRetries) {
172
          $AttemptsLeft = $DownloadRetries - $Attempt
173
          Write-Warning "Download failed, $AttemptsLeft attempts remaining, will retry in $RetryWaitTimeInSeconds seconds"
174
          Start-Sleep -Seconds $RetryWaitTimeInSeconds
175
        }
176
        else {
177
          Write-Error $_
178
          Write-Error $_.Exception
179
        }
180
      }
181
    }
182
  }
183

184
  return $False
185
}
186

187
<#
188
.SYNOPSIS
189
Generate a shim for a native tool
190

191
.DESCRIPTION
192
Creates a wrapper script (shim) that passes arguments forward to native tool assembly
193

194
.PARAMETER ShimName
195
The name of the shim
196

197
.PARAMETER ShimDirectory
198
The directory where shims are stored
199

200
.PARAMETER ToolFilePath
201
Path to file that shim forwards to
202

203
.PARAMETER Force
204
Replace shim if already present.  Default = False
205

206
.NOTES
207
Returns $True if generating shim succeeds, $False otherwise
208
#>
209
function New-ScriptShim {
210
  [CmdletBinding(PositionalBinding=$false)]
211
  Param (
212
    [Parameter(Mandatory=$True)]
213
    [string] $ShimName,
214
    [Parameter(Mandatory=$True)]
215
    [string] $ShimDirectory,
216
    [Parameter(Mandatory=$True)]
217
    [string] $ToolFilePath,
218
    [Parameter(Mandatory=$True)]
219
    [string] $BaseUri,
220
    [switch] $Force
221
  )
222
  try {
223
    Write-Verbose "Generating '$ShimName' shim"
224

225
    if (-Not (Test-Path $ToolFilePath)){
226
      Write-Error "Specified tool file path '$ToolFilePath' does not exist"
227
      return $False
228
    }
229

230
    # WinShimmer is a small .NET Framework program that creates .exe shims to bootstrapped programs
231
    # Many of the checks for installed programs expect a .exe extension for Windows tools, rather
232
    # than a .bat or .cmd file.
233
    # Source: https://github.com/dotnet/arcade/tree/master/src/WinShimmer
234
    if (-Not (Test-Path "$ShimDirectory\WinShimmer\winshimmer.exe")) {
235
      $InstallStatus = DownloadAndExtract -Uri "$BaseUri/windows/winshimmer/WinShimmer.zip" `
236
                                          -InstallDirectory $ShimDirectory\WinShimmer `
237
                                          -Force:$Force `
238
                                          -DownloadRetries 2 `
239
                                          -RetryWaitTimeInSeconds 5 `
240
                                          -Verbose:$Verbose
241
    }
242

243
    if ((Test-Path (Join-Path $ShimDirectory "$ShimName.exe"))) {
244
      Write-Host "$ShimName.exe already exists; replacing..."
245
      Remove-Item (Join-Path $ShimDirectory "$ShimName.exe")
246
    }
247

248
    & "$ShimDirectory\WinShimmer\winshimmer.exe" $ShimName $ToolFilePath $ShimDirectory
249
    return $True
250
  }
251
  catch {
252
    Write-Host $_
253
    Write-Host $_.Exception
254
    return $False
255
  }
256
}
257

258
<#
259
.SYNOPSIS
260
Returns the machine architecture of the host machine
261

262
.NOTES
263
Returns 'x64' on 64 bit machines
264
 Returns 'x86' on 32 bit machines
265
#>
266
function Get-MachineArchitecture {
267
  $ProcessorArchitecture = $Env:PROCESSOR_ARCHITECTURE
268
  $ProcessorArchitectureW6432 = $Env:PROCESSOR_ARCHITEW6432
269
  if($ProcessorArchitecture -Eq "X86")
270
  {
271
    if(($ProcessorArchitectureW6432 -Eq "") -Or
272
       ($ProcessorArchitectureW6432 -Eq "X86")) {
273
        return "x86"
274
    }
275
    $ProcessorArchitecture = $ProcessorArchitectureW6432
276
  }
277
  if (($ProcessorArchitecture -Eq "AMD64") -Or
278
      ($ProcessorArchitecture -Eq "IA64") -Or
279
      ($ProcessorArchitecture -Eq "ARM64") -Or
280
      ($ProcessorArchitecture -Eq "LOONGARCH64")) {
281
    return "x64"
282
  }
283
  return "x86"
284
}
285

286
<#
287
.SYNOPSIS
288
Get the name of a temporary folder under the native install directory
289
#>
290
function Get-TempDirectory {
291
  return Join-Path (Get-NativeInstallDirectory) "temp/"
292
}
293

294
function Get-TempPathFilename {
295
  [CmdletBinding(PositionalBinding=$false)]
296
  Param (
297
    [Parameter(Mandatory=$True)]
298
    [string] $Path
299
  )
300
  $TempDir = CommonLibrary\Get-TempDirectory
301
  $TempFilename = Split-Path $Path -leaf
302
  $TempPath = Join-Path $TempDir $TempFilename
303
  return $TempPath
304
}
305

306
<#
307
.SYNOPSIS
308
Returns the base directory to use for native tool installation
309

310
.NOTES
311
Returns the value of the NETCOREENG_INSTALL_DIRECTORY if that environment variable
312
is set, or otherwise returns an install directory under the %USERPROFILE%
313
#>
314
function Get-NativeInstallDirectory {
315
  $InstallDir = $Env:NETCOREENG_INSTALL_DIRECTORY
316
  if (!$InstallDir) {
317
    $InstallDir = Join-Path $Env:USERPROFILE ".netcoreeng/native/"
318
  }
319
  return $InstallDir
320
}
321

322
<#
323
.SYNOPSIS
324
Unzip an archive
325

326
.DESCRIPTION
327
Powershell module to unzip an archive to a specified directory
328

329
.PARAMETER ZipPath (Required)
330
Path to archive to unzip
331

332
.PARAMETER OutputDirectory (Required)
333
Output directory for archive contents
334

335
.PARAMETER Force
336
Overwrite output directory contents if they already exist
337

338
.NOTES
339
- Returns True and does not perform an extraction if output directory already exists but Overwrite is not True.
340
- Returns True if unzip operation is successful
341
- Returns False if Overwrite is True and it is unable to remove contents of OutputDirectory
342
- Returns False if unable to extract zip archive
343
#>
344
function Expand-Zip {
345
  [CmdletBinding(PositionalBinding=$false)]
346
  Param (
347
    [Parameter(Mandatory=$True)]
348
    [string] $ZipPath,
349
    [Parameter(Mandatory=$True)]
350
    [string] $OutputDirectory,
351
    [switch] $Force
352
  )
353

354
  Write-Verbose "Extracting '$ZipPath' to '$OutputDirectory'"
355
  try {
356
    if ((Test-Path $OutputDirectory) -And (-Not $Force)) {
357
      Write-Host "Directory '$OutputDirectory' already exists, skipping extract"
358
      return $True
359
    }
360
    if (Test-Path $OutputDirectory) {
361
      Write-Verbose "'Force' is 'True', but '$OutputDirectory' exists, removing directory"
362
      Remove-Item $OutputDirectory -Force -Recurse
363
      if ($? -Eq $False) {
364
        Write-Error "Unable to remove '$OutputDirectory'"
365
        return $False
366
      }
367
    }
368

369
    $TempOutputDirectory = Join-Path "$(Split-Path -Parent $OutputDirectory)" "$(Split-Path -Leaf $OutputDirectory).tmp"
370
    if (Test-Path $TempOutputDirectory) {
371
      Remove-Item $TempOutputDirectory -Force -Recurse
372
    }
373
    New-Item -Path $TempOutputDirectory -Force -ItemType "Directory" | Out-Null
374

375
    Add-Type -assembly "system.io.compression.filesystem"
376
    [io.compression.zipfile]::ExtractToDirectory("$ZipPath", "$TempOutputDirectory")
377
    if ($? -Eq $False) {
378
      Write-Error "Unable to extract '$ZipPath'"
379
      return $False
380
    }
381

382
    Move-Item -Path $TempOutputDirectory -Destination $OutputDirectory
383
  }
384
  catch {
385
    Write-Host $_
386
    Write-Host $_.Exception
387

388
    return $False
389
  }
390
  return $True
391
}
392

393
export-modulemember -function DownloadAndExtract
394
export-modulemember -function Expand-Zip
395
export-modulemember -function Get-File
396
export-modulemember -function Get-MachineArchitecture
397
export-modulemember -function Get-NativeInstallDirectory
398
export-modulemember -function Get-TempDirectory
399
export-modulemember -function Get-TempPathFilename
400
export-modulemember -function New-ScriptShim
401

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.