2017-07-24 03:29:33 +08:00
# On Unix paths is separated by colon
# On Windows paths is separated by semicolon
$script:TestModulePathSeparator = [ System.IO.Path ] :: PathSeparator
2016-02-22 08:21:04 +08:00
2017-08-17 08:32:46 +08:00
$dotnetCLIChannel = " release "
$dotnetCLIRequiredVersion = " 2.0.0 "
2017-06-22 00:32:06 +08:00
2017-08-02 05:35:50 +08:00
# Track if tags have been sync'ed
$tagsUpToDate = $false
# Sync Tags
# When not using a branch in PowerShell/PowerShell, tags will not be fetched automatically
# Since code that uses Get-PSCommitID and Get-PSLatestTag assume that tags are fetched,
# This function can ensure that tags have been fetched.
# This function is used during the setup phase in tools/appveyor.psm1 and tools/travis.ps1
function Sync-PSTags
{
param (
[ Switch ]
$AddRemoteIfMissing
)
$PowerShellRemoteUrl = " https://github.com/powershell/powershell.git "
$upstreamRemoteDefaultName = 'upstream'
$remotes = Start-NativeExecution { git - -git -dir = " $PSScriptRoot /.git " remote }
$upstreamRemote = $null
foreach ( $remote in $remotes )
{
$url = Start-NativeExecution { git - -git -dir = " $PSScriptRoot /.git " remote get-url $remote }
if ( $url -eq $PowerShellRemoteUrl )
{
$upstreamRemote = $remote
break
}
}
if ( ! $upstreamRemote -and $AddRemoteIfMissing . IsPresent -and $remotes -notcontains $upstreamRemoteDefaultName )
{
$null = Start-NativeExecution { git - -git -dir = " $PSScriptRoot /.git " remote add $upstreamRemoteDefaultName $PowerShellRemoteUrl }
$upstreamRemote = $upstreamRemoteDefaultName
}
elseif ( ! $upstreamRemote )
{
Write-Error " Please add a remote to PowerShell\PowerShell. Example: git remote add $upstreamRemoteDefaultName $PowerShellRemoteUrl " -ErrorAction Stop
}
$null = Start-NativeExecution { git - -git -dir = " $PSScriptRoot /.git " fetch - -tags - -quiet $upstreamRemote }
$script:tagsUpToDate = $true
}
# Gets the latest tag for the current branch
function Get-PSLatestTag
{
2017-09-07 06:20:25 +08:00
[ CmdletBinding ( ) ]
param ( )
2017-08-02 05:35:50 +08:00
# This function won't always return the correct value unless tags have been sync'ed
# So, Write a warning to run Sync-PSTags
if ( ! $tagsUpToDate )
{
Write-Warning " Run Sync-PSTags to update tags "
}
return ( Start-NativeExecution { git - -git -dir = " $PSScriptRoot /.git " describe - -abbrev = 0 } )
}
function Get-PSVersion
{
2017-09-07 06:20:25 +08:00
[ CmdletBinding ( ) ]
2017-08-02 05:35:50 +08:00
param (
[ switch ]
$OmitCommitId
)
if ( $OmitCommitId . IsPresent )
{
return ( Get-PSLatestTag ) -replace '^v'
}
else
{
return ( Get-PSCommitId ) -replace '^v'
}
}
function Get-PSCommitId
{
2017-09-07 06:20:25 +08:00
[ CmdletBinding ( ) ]
param ( )
2017-08-02 05:35:50 +08:00
# This function won't always return the correct value unless tags have been sync'ed
# So, Write a warning to run Sync-PSTags
if ( ! $tagsUpToDate )
{
Write-Warning " Run Sync-PSTags to update tags "
}
return ( Start-NativeExecution { git - -git -dir = " $PSScriptRoot /.git " describe - -dirty - -abbrev = 60 } )
}
2017-07-24 03:29:33 +08:00
function Get-EnvironmentInformation
2016-09-16 10:22:18 +08:00
{
2017-07-24 03:29:33 +08:00
$environment = @ { }
2017-08-17 03:07:45 +08:00
# Use the .NET Core APIs to determine the current platform.
# If a runtime exception is thrown, we are on Windows PowerShell, not PowerShell Core,
2017-07-24 03:29:33 +08:00
# because System.Runtime.InteropServices.RuntimeInformation
2017-08-17 03:07:45 +08:00
# and System.Runtime.InteropServices.OSPlatform do not exist in Windows PowerShell.
2017-07-24 03:29:33 +08:00
try {
$Runtime = [ System.Runtime.InteropServices.RuntimeInformation ]
$OSPlatform = [ System.Runtime.InteropServices.OSPlatform ]
$environment + = @ { 'IsCoreCLR' = $true }
$environment + = @ { 'IsLinux' = $Runtime :: IsOSPlatform ( $OSPlatform :: Linux ) }
2017-09-08 01:34:40 +08:00
$environment + = @ { 'IsMacOS' = $Runtime :: IsOSPlatform ( $OSPlatform :: OSX ) }
2017-07-24 03:29:33 +08:00
$environment + = @ { 'IsWindows' = $Runtime :: IsOSPlatform ( $OSPlatform :: Windows ) }
} catch {
2017-07-25 06:26:04 +08:00
$environment + = @ { 'IsCoreCLR' = $false }
$environment + = @ { 'IsLinux' = $false }
2017-09-08 01:34:40 +08:00
$environment + = @ { 'IsMacOS' = $false }
2017-07-25 06:26:04 +08:00
$environment + = @ { 'IsWindows' = $true }
2017-07-24 03:29:33 +08:00
}
if ( $Environment . IsWindows )
{
$environment + = @ { 'IsAdmin' = ( New-Object Security . Principal . WindowsPrincipal ( [ Security.Principal.WindowsIdentity ] :: GetCurrent ( ) ) ) . IsInRole ( [ Security.Principal.WindowsBuiltinRole ] :: Administrator ) }
# Can't use $env:HOME - not available on older systems (e.g. in AppVeyor)
$environment + = @ { 'nugetPackagesRoot' = " ${env:HOMEDRIVE} ${env:HOMEPATH} \.nuget\packages " }
}
else
{
$environment + = @ { 'nugetPackagesRoot' = " ${env:HOME} /.nuget/packages " }
}
if ( $Environment . IsLinux ) {
$LinuxInfo = Get-Content / etc / os-release -Raw | ConvertFrom-StringData
2016-09-16 10:22:18 +08:00
2017-07-24 03:29:33 +08:00
$environment + = @ { 'LinuxInfo' = $LinuxInfo }
$environment + = @ { 'IsUbuntu' = $LinuxInfo . ID -match 'ubuntu' }
$environment + = @ { 'IsUbuntu14' = $Environment . IsUbuntu -and $LinuxInfo . VERSION_ID -match '14.04' }
$environment + = @ { 'IsUbuntu16' = $Environment . IsUbuntu -and $LinuxInfo . VERSION_ID -match '16.04' }
$environment + = @ { 'IsCentOS' = $LinuxInfo . ID -match 'centos' -and $LinuxInfo . VERSION_ID -match '7' }
$environment + = @ { 'IsFedora' = $LinuxInfo . ID -match 'fedora' -and $LinuxInfo . VERSION_ID -ge 24 }
$environment + = @ { 'IsOpenSUSE' = $LinuxInfo . ID -match 'opensuse' }
$environment + = @ { 'IsOpenSUSE13' = $Environment . IsOpenSUSE -and $LinuxInfo . VERSION_ID -match '13' }
$environment + = @ { 'IsOpenSUSE42.1' = $Environment . IsOpenSUSE -and $LinuxInfo . VERSION_ID -match '42.1' }
$environment + = @ { 'IsRedHatFamily' = $Environment . IsCentOS -or $Environment . IsFedora -or $Environment . IsOpenSUSE }
# Workaround for temporary LD_LIBRARY_PATH hack for Fedora 24
# https://github.com/PowerShell/PowerShell/issues/2511
if ( $environment . IsFedora -and ( Test-Path ENV : \ LD_LIBRARY_PATH ) ) {
Remove-Item -Force ENV : \ LD_LIBRARY_PATH
Get-ChildItem ENV :
}
2017-01-07 02:04:18 +08:00
}
2017-07-24 03:29:33 +08:00
return [ PSCustomObject ] $environment
2016-06-21 02:39:39 +08:00
}
2017-07-24 03:29:33 +08:00
$Environment = Get-EnvironmentInformation
2017-03-27 12:46:39 +08:00
# Autoload (in current session) temporary modules used in our tests
$TestModulePath = Join-Path $PSScriptRoot " test/tools/Modules "
2017-03-30 01:11:02 +08:00
if ( $env:PSModulePath -notcontains $TestModulePath ) {
2017-03-27 12:46:39 +08:00
$env:PSModulePath = $TestModulePath + $TestModulePathSeparator + $ ( $env:PSModulePath )
}
2016-11-01 06:02:44 +08:00
#
2017-01-17 05:31:14 +08:00
# At the moment, we just support x64 builds. When we support x86 builds, this
2016-11-01 06:02:44 +08:00
# check may need to verify the SDK for the specified architecture.
#
function Get-Win10SDKBinDir {
return " $ {env:ProgramFiles(x86)}\Windows Kits\10\bin\x64 "
}
function Test-Win10SDK {
# The Windows 10 SDK is installed to "${env:ProgramFiles(x86)}\Windows Kits\10\bin\x64",
# but the directory may exist even if the SDK has not been installed.
#
# A slightly more robust check is for the mc.exe binary within that directory.
# It is only present if the SDK is installed.
return ( Test-Path " $ {env:ProgramFiles(x86)}\Windows Kits\10\bin\x64\mc.exe " )
}
2016-04-02 13:01:05 +08:00
2017-07-26 07:50:27 +08:00
function Start-BuildNativeWindowsBinaries {
param (
[ ValidateSet ( 'Debug' , 'Release' ) ]
[ string ] $Configuration = 'Release' ,
[ ValidateSet ( 'x64' , 'x86' ) ]
[ string ] $Arch = 'x64'
)
if ( -not $Environment . IsWindows ) {
Write-Warning -Message " 'Start-BuildNativeWindowsBinaries' is only supported on Windows platforms "
return
}
# cmake is needed to build powershell.exe
if ( -not ( precheck 'cmake' $null ) ) {
throw 'cmake not found. Run "Start-PSBootstrap -BuildWindowsNative". You can also install it from https://chocolatey.org/packages/cmake'
}
Use-MSBuild
# mc.exe is Message Compiler for native resources
if ( -Not ( Test-Win10SDK ) ) {
throw 'Win 10 SDK not found. Run "Start-PSBootstrap -BuildWindowsNative" or install Microsoft Windows 10 SDK from https://developer.microsoft.com/en-US/windows/downloads/windows-10-sdk'
}
$vcPath = ( Get-Item ( Join-Path -Path " $env:VS140COMNTOOLS " -ChildPath '../../vc' ) ) . FullName
$atlMfcIncludePath = Join-Path -Path $vcPath -ChildPath 'atlmfc/include'
# atlbase.h is included in the pwrshplugin project
if ( ( Test-Path -Path $atlMfcIncludePath \ atlbase . h ) -eq $false ) {
throw " Could not find Visual Studio include file atlbase.h at $atlMfcIncludePath . Please ensure the optional feature 'Microsoft Foundation Classes for C++' is installed. "
}
# vcvarsall.bat is used to setup environment variables
if ( ( Test-Path -Path $vcPath \ vcvarsall . bat ) -eq $false ) {
throw " Could not find Visual Studio vcvarsall.bat at $vcPath . Please ensure the optional feature 'Common Tools for Visual C++' is installed. "
}
log " Start building native Windows binaries "
try {
Push-Location " $PSScriptRoot \src\powershell-native "
# setup cmakeGenerator
if ( $Arch -eq 'x86' ) {
$cmakeGenerator = 'Visual Studio 14 2015'
} else {
$cmakeGenerator = 'Visual Studio 14 2015 Win64'
}
# Compile native resources
$currentLocation = Get-Location
@ ( " nativemsh/pwrshplugin " ) | ForEach-Object {
$nativeResourcesFolder = $_
Get-ChildItem $nativeResourcesFolder -Filter " *.mc " | ForEach-Object {
$command = @"
cmd . exe / C cd / d " $currentLocation " " & " " $( $vcPath ) \vcvarsall.bat " " $Arch " " & " mc . exe -o -d -c -U " $( $_ . FullName ) " -h " $nativeResourcesFolder " -r " $nativeResourcesFolder "
" @
log " Executing mc.exe Command: $command "
Start-NativeExecution { Invoke-Expression -Command: $command 2 > & 1 }
}
}
# Disabling until I figure out if it is necessary
# $overrideFlags = "-DCMAKE_USER_MAKE_RULES_OVERRIDE=$PSScriptRoot\src\powershell-native\windows-compiler-override.txt"
$overrideFlags = " "
$location = Get-Location
$command = @"
cmd . exe / C cd / d " $location " " & " " $( $vcPath ) \vcvarsall.bat " " $Arch " " & " cmake " $overrideFlags " -DBUILD_ONECORE = ON -DBUILD_TARGET_ARCH = $Arch -G " $cmakeGenerator " . " & " msbuild ALL_BUILD . vcxproj " /p:Configuration= $Configuration "
" @
log " Executing Build Command: $command "
Start-NativeExecution { Invoke-Expression -Command: $command }
# Copy the binaries from the local build directory to the packaging directory
$FilesToCopy = @ ( 'pwrshplugin.dll' , 'pwrshplugin.pdb' )
$dstPath = " $PSScriptRoot \src\powershell-win-core "
$FilesToCopy | ForEach-Object {
2017-08-22 06:23:52 +08:00
$srcPath = [ IO.Path ] :: Combine ( ( Get-Location ) , " bin " , $Configuration , " CoreClr/ $_ " )
2017-08-09 00:36:22 +08:00
2017-07-26 07:50:27 +08:00
log " Copying $srcPath to $dstPath "
Copy-Item $srcPath $dstPath
}
# Place the remoting configuration script in the same directory
# as the binary so it will get published.
Copy-Item . \ Install-PowerShellRemoting . ps1 $dstPath
} finally {
Pop-Location
}
}
2016-04-02 05:41:13 +08:00
function Start-PSBuild {
2017-08-17 03:07:45 +08:00
[ CmdletBinding ( ) ]
2016-02-22 07:06:39 +08:00
param (
2016-07-20 10:09:06 +08:00
# When specified this switch will stops running dev powershell
# to help avoid compilation error, because file are in use.
[ switch ] $StopDevPowerShell ,
2016-02-24 08:21:00 +08:00
[ switch ] $Restore ,
2016-05-07 01:28:45 +08:00
[ string ] $Output ,
2016-06-15 18:42:54 +08:00
[ switch ] $ResGen ,
2016-06-18 02:23:29 +08:00
[ switch ] $TypeGen ,
2016-06-23 10:46:16 +08:00
[ switch ] $Clean ,
2016-11-19 01:55:23 +08:00
[ switch ] $PSModuleRestore ,
2016-03-12 08:19:05 +08:00
2016-08-27 04:46:03 +08:00
# this switch will re-build only System.Management.Automation.dll
2016-07-20 03:51:11 +08:00
# it's useful for development, to do a quick changes in the engine
[ switch ] $SMAOnly ,
2016-03-04 07:54:52 +08:00
# These runtimes must match those in project.json
# We do not use ValidateScript since we want tab completion
[ ValidateSet ( " ubuntu.14.04-x64 " ,
2016-08-02 06:18:42 +08:00
" ubuntu.16.04-x64 " ,
2016-06-03 11:13:30 +08:00
" debian.8-x64 " ,
2016-06-17 09:39:29 +08:00
" centos.7-x64 " ,
2017-01-07 02:04:18 +08:00
" fedora.24-x64 " ,
2016-03-04 07:54:52 +08:00
" win7-x64 " ,
2016-11-15 05:04:33 +08:00
" win7-x86 " ,
2016-04-02 08:01:18 +08:00
" win81-x64 " ,
2016-03-04 07:54:52 +08:00
" win10-x64 " ,
2017-03-07 09:30:14 +08:00
" osx.10.12-x64 " ,
2017-03-23 05:19:51 +08:00
" opensuse.13.2-x64 " ,
2017-09-12 03:16:58 +08:00
" opensuse.42.1-x64 " ,
" linux-arm " ) ]
2016-03-12 08:19:05 +08:00
[ string ] $Runtime ,
2016-11-12 03:12:07 +08:00
[ ValidateSet ( 'Linux' , 'Debug' , 'Release' , 'CodeCoverage' , '' ) ] # We might need "Checked" as well
2016-07-30 01:00:46 +08:00
[ string ] $Configuration ,
2017-06-06 01:21:28 +08:00
[ switch ] $CrossGen ,
[ ValidatePattern ( " ^v\d+\.\d+\.\d+(-\w+\.\d+)? $ " ) ]
[ ValidateNotNullOrEmpty ( ) ]
[ string ] $ReleaseTag
2016-02-24 08:21:00 +08:00
)
2016-02-22 07:06:39 +08:00
2016-08-04 04:23:21 +08:00
function Stop-DevPowerShell {
2016-07-20 10:09:06 +08:00
Get-Process powershell * |
2016-08-04 04:23:21 +08:00
Where-Object {
$_ . Modules |
Where-Object {
2016-07-20 10:09:06 +08:00
$_ . FileName -eq ( Resolve-Path $script:Options . Output ) . Path
2016-08-04 04:23:21 +08:00
}
} |
2016-07-20 10:09:06 +08:00
Stop-Process -Verbose
}
2016-08-04 04:23:21 +08:00
if ( $Clean ) {
2016-06-23 10:46:16 +08:00
log " Cleaning your working directory. You can also do it with 'git clean -fdX' "
2016-07-26 10:53:21 +08:00
Push-Location $PSScriptRoot
2016-08-04 04:23:21 +08:00
try {
2016-07-26 10:53:21 +08:00
git clean -fdX
2017-01-17 05:31:14 +08:00
# Extra cleaning is required to delete the CMake temporary files.
2016-11-22 08:55:03 +08:00
# These are not cleaned when using "X" and cause CMake to retain state, leading to
# mis-configured environment issues when switching between x86 and x64 compilation
# environments.
git clean -fdx . \ src \ powershell-native
2016-08-04 04:23:21 +08:00
} finally {
2016-07-26 10:53:21 +08:00
Pop-Location
}
2016-06-23 10:46:16 +08:00
}
2017-06-06 01:21:28 +08:00
# save git commit id to file for PowerShell to include in PSVersionTable
$gitCommitId = $ReleaseTag
if ( -not $gitCommitId ) {
# if ReleaseTag is not specified, use 'git describe' to get the commit id
2017-09-07 06:20:25 +08:00
$gitCommitId = Get-PSCommitId -WarningAction SilentlyContinue
2017-06-06 01:21:28 +08:00
}
$gitCommitId > " $psscriptroot /powershell.version "
2016-05-19 06:35:09 +08:00
2017-04-26 13:51:22 +08:00
# create the telemetry flag file
$null = new-item -force -type file " $psscriptroot /DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY "
2016-06-21 02:59:14 +08:00
# Add .NET CLI tools to PATH
Find-Dotnet
2016-04-14 07:41:50 +08:00
2017-07-26 07:50:27 +08:00
# Verify we have all tools in place to do the build
2016-08-05 07:15:49 +08:00
$precheck = precheck 'dotnet' " Build dependency 'dotnet' not found in PATH. Run Start-PSBootstrap. Also see: https://dotnet.github.io/getting-started/ "
2017-09-08 01:34:40 +08:00
if ( $Environment . IsLinux -or $Environment . IsMacOS ) {
2017-07-26 07:50:27 +08:00
foreach ( $Dependency in 'cmake' , 'make' , 'g++' ) {
$precheck = $precheck -and ( precheck $Dependency " Build dependency ' $Dependency ' not found. Run 'Start-PSBootstrap'. " )
}
}
2017-09-12 03:16:58 +08:00
if ( $RunTime -eq " linux-arm " ) {
foreach ( $Dependency in 'arm-linux-gnueabihf-gcc' , 'arm-linux-gnueabihf-g++' ) {
$precheck = $precheck -and ( precheck $Dependency " Build dependency ' $Dependency ' not found. Run 'Start-PSBootstrap'. " )
}
}
2017-07-26 07:50:27 +08:00
# Abort if any precheck failed
if ( -not $precheck ) {
return
}
# Verify if the dotnet in-use is the required version
2017-08-22 06:23:52 +08:00
$dotnetCLIInstalledVersion = ( dotnet - -version )
2017-07-26 07:50:27 +08:00
If ( $dotnetCLIInstalledVersion -ne $dotnetCLIRequiredVersion ) {
2017-06-22 00:32:06 +08:00
Write-Warning @"
The currently installed . NET Command Line Tools is not the required version .
2017-07-08 00:43:37 +08:00
Installed version : $dotnetCLIInstalledVersion
2017-06-22 00:32:06 +08:00
Required version : $dotnetCLIRequiredVersion
Fix steps :
1 . Remove the installed version from :
- on windows '`$env:LOCALAPPDATA\Microsoft\dotnet'
2017-09-08 01:34:40 +08:00
- on macOS and linux '`$env:HOME/.dotnet'
2017-06-22 00:32:06 +08:00
2 . Run Start-PSBootstrap or Install-Dotnet
3 . Start-PSBuild -Clean
` n
" @
return
}
2016-04-15 06:06:14 +08:00
# set output options
2016-07-20 03:51:11 +08:00
$OptionsArguments = @ {
2016-09-29 01:47:16 +08:00
CrossGen = $CrossGen
2016-07-20 03:51:11 +08:00
Output = $Output
Runtime = $Runtime
Configuration = $Configuration
Verbose = $true
SMAOnly = [ bool ] $SMAOnly
}
2016-04-15 06:06:14 +08:00
$script:Options = New-PSOptions @OptionsArguments
2016-04-02 08:51:38 +08:00
2016-08-04 04:23:21 +08:00
if ( $StopDevPowerShell ) {
2016-07-20 10:09:06 +08:00
Stop-DevPowerShell
}
2016-04-15 06:06:14 +08:00
# setup arguments
2017-04-19 04:12:35 +08:00
$Arguments = @ ( " publish " )
2016-05-07 01:28:45 +08:00
if ( $Output ) {
2016-10-04 02:04:40 +08:00
$Arguments + = " --output " , $Output
2016-05-07 01:28:45 +08:00
}
2016-07-20 03:51:11 +08:00
elseif ( $SMAOnly ) {
$Arguments + = " --output " , ( Split-Path $script:Options . Output )
}
2016-04-15 06:06:14 +08:00
$Arguments + = " --configuration " , $Options . Configuration
$Arguments + = " --framework " , $Options . Framework
2017-06-06 05:10:42 +08:00
if ( -not $SMAOnly ) {
# libraries should not have runtime
$Arguments + = " --runtime " , $Options . Runtime
}
2016-04-02 08:51:38 +08:00
2017-09-07 06:20:25 +08:00
if ( $ReleaseTag ) {
$ReleaseTagToUse = $ReleaseTag -Replace '^v'
$Arguments + = " /property:ReleaseTag= $ReleaseTagToUse "
}
2016-03-12 10:24:43 +08:00
# handle Restore
2017-03-24 04:04:52 +08:00
if ( $Restore -or -not ( Test-Path " $( $Options . Top ) /obj/project.assets.json " ) ) {
2016-07-16 07:52:00 +08:00
log " Run dotnet restore "
2017-03-24 04:04:52 +08:00
$srcProjectDirs = @ ( $Options . Top , " $PSScriptRoot /src/TypeCatalogGen " , " $PSScriptRoot /src/ResGen " )
2017-07-22 12:03:49 +08:00
$testProjectDirs = Get-ChildItem " $PSScriptRoot /test/*.csproj " -Recurse | ForEach-Object { [ System.IO.Path ] :: GetDirectoryName ( $_ ) }
2017-03-24 04:04:52 +08:00
2016-07-16 07:52:00 +08:00
$RestoreArguments = @ ( " --verbosity " )
if ( $PSCmdlet . MyInvocation . BoundParameters [ " Verbose " ] . IsPresent ) {
2017-03-24 04:04:52 +08:00
$RestoreArguments + = " detailed "
2016-07-16 07:52:00 +08:00
} else {
2017-03-24 04:04:52 +08:00
$RestoreArguments + = " quiet "
2016-07-16 07:52:00 +08:00
}
2017-07-22 12:03:49 +08:00
( $srcProjectDirs + $testProjectDirs ) | ForEach-Object { Start-NativeExecution { dotnet restore $_ $RestoreArguments } }
2016-07-16 07:52:00 +08:00
}
2016-02-22 07:06:39 +08:00
2016-06-15 18:42:54 +08:00
# handle ResGen
2016-06-17 22:51:32 +08:00
# Heuristic to run ResGen on the fresh machine
2016-08-04 04:23:21 +08:00
if ( $ResGen -or -not ( Test-Path " $PSScriptRoot /src/Microsoft.PowerShell.ConsoleHost/gen " ) ) {
2016-07-16 07:52:00 +08:00
log " Run ResGen (generating C# bindings for resx files) "
Start-ResGen
}
2016-06-15 18:42:54 +08:00
2016-03-12 08:19:05 +08:00
# Build native components
2017-09-08 01:34:40 +08:00
if ( ( $Environment . IsLinux -or $Environment . IsMacOS ) -and -not $SMAOnly ) {
2017-07-24 03:29:33 +08:00
$Ext = if ( $Environment . IsLinux ) {
2016-04-02 05:42:40 +08:00
" so "
2017-09-08 01:34:40 +08:00
} elseif ( $Environment . IsMacOS ) {
2016-04-02 05:42:40 +08:00
" dylib "
}
2016-02-22 07:06:39 +08:00
2016-04-02 05:42:40 +08:00
$Native = " $PSScriptRoot /src/libpsl-native "
2016-04-15 06:06:14 +08:00
$Lib = " $( $Options . Top ) /libpsl-native. $Ext "
2016-04-02 05:42:40 +08:00
log " Start building $Lib "
2016-02-25 03:50:56 +08:00
2016-04-02 05:42:40 +08:00
try {
Push-Location $Native
2017-09-12 03:16:58 +08:00
if ( $Runtime -eq " linux-arm " ) {
Start-NativeExecution { cmake -DCMAKE_TOOLCHAIN_FILE = " ./arm.toolchain.cmake " . }
Start-NativeExecution { make -j }
}
else {
Start-NativeExecution { cmake -DCMAKE_BUILD_TYPE = Debug . }
Start-NativeExecution { make -j }
Start-NativeExecution { ctest - -verbose }
}
2016-04-02 05:42:40 +08:00
} finally {
Pop-Location
2016-03-12 08:19:05 +08:00
}
2016-04-02 05:42:40 +08:00
2016-04-10 08:59:13 +08:00
if ( -not ( Test-Path $Lib ) ) {
2016-04-02 05:42:40 +08:00
throw " Compilation of $Lib failed "
}
2016-03-12 08:19:05 +08:00
}
2016-02-22 07:06:39 +08:00
2016-06-18 02:23:29 +08:00
# handle TypeGen
2016-08-04 04:23:21 +08:00
if ( $TypeGen -or -not ( Test-Path " $PSScriptRoot /src/Microsoft.PowerShell.CoreCLR.AssemblyLoadContext/CorePsTypeCatalog.cs " ) ) {
2016-06-18 02:23:29 +08:00
log " Run TypeGen (generating CorePsTypeCatalog.cs) "
Start-TypeGen
}
Move powershell to .NET Core 2.0 (#3556)
This change moves powershell to .NET Core 2.0. Major changes are:
1. PowerShell assemblies are now targeting `netcoreapp2.0`. We are using `microsoft.netcore.app-2.0.0-preview1-001913-00`, which is from dotnet-core build 4/4/17. We cannot target `netstandard2.0` because the packages `System.Reflection.Emit` and `System.Reflection.Emit.Lightweight`, which are needed for powershell class, cannot be referenced when targeting `netstandard2.0`.
2. Refactor code to remove most CLR stub types and extension types.
3. Update build scripts to enable CI builds. The `-cache` section is specified to depend on `appveyor.yml`, so the cache will be invalidated if `appveyor.yml` is changed.
4. Ship `netcoreapp` reference assemblies with powershell to fix the issues in `Add-Type` (#2764). By default `Add-Type` will reference all those reference assemblies when compiling C# code. If `-ReferenceAssembly` is specified, then we search reference assemblies first, then the framework runtime assemblies, and lastly the loaded assemblies (possibly a third-party one that was already loaded).
5. `dotnet publish` generates executable on Unix platforms, but doesn't set "x" permission and thus it cannot execute. Currently, the "x" permission is set in the build script, `dotnet/cli` issue [#6286](https://github.com/dotnet/cli/issues/6286) is tracking this.
6. Replace the use of some APIs with the ones that take `SecureString`.
7. osx.10.12 is required to update to `netcoreapp2.0` because `dotnet-cli` 2.0.0-preview only works on osx.10.12.
8. Add dependency to `System.ValueTuple` to work around a ambiguous type identity issue in coreclr. The issue is tracked by `dotnet/corefx` [#17797](https://github.com/dotnet/corefx/issues/17797). When moving to newer version of `netcoreapp2.0`, we need to verify if this dependency is still needed.
2017-04-18 02:52:38 +08:00
# Get the folder path where powershell.exe is located.
$publishPath = Split-Path $Options . Output -Parent
2016-04-02 05:41:13 +08:00
try {
2016-04-02 03:14:09 +08:00
# Relative paths do not work well if cwd is not changed to project
2016-04-15 06:06:14 +08:00
Push-Location $Options . Top
2016-04-20 07:39:06 +08:00
log " Run dotnet $Arguments from $pwd "
2016-04-20 07:59:03 +08:00
Start-NativeExecution { dotnet $Arguments }
2016-07-30 01:00:46 +08:00
2016-08-04 04:23:21 +08:00
if ( $CrossGen ) {
2016-11-21 04:59:50 +08:00
Start-CrossGen -PublishPath $publishPath -Runtime $script:Options . Runtime
2016-08-03 01:38:12 +08:00
log " PowerShell.exe with ngen binaries is available at: $( $Options . Output ) "
2016-08-04 04:23:21 +08:00
} else {
2016-07-30 01:00:46 +08:00
log " PowerShell output: $( $Options . Output ) "
}
2016-04-02 05:41:13 +08:00
} finally {
2016-04-02 03:14:09 +08:00
Pop-Location
2016-03-12 08:19:05 +08:00
}
2016-11-18 05:54:38 +08:00
Move powershell to .NET Core 2.0 (#3556)
This change moves powershell to .NET Core 2.0. Major changes are:
1. PowerShell assemblies are now targeting `netcoreapp2.0`. We are using `microsoft.netcore.app-2.0.0-preview1-001913-00`, which is from dotnet-core build 4/4/17. We cannot target `netstandard2.0` because the packages `System.Reflection.Emit` and `System.Reflection.Emit.Lightweight`, which are needed for powershell class, cannot be referenced when targeting `netstandard2.0`.
2. Refactor code to remove most CLR stub types and extension types.
3. Update build scripts to enable CI builds. The `-cache` section is specified to depend on `appveyor.yml`, so the cache will be invalidated if `appveyor.yml` is changed.
4. Ship `netcoreapp` reference assemblies with powershell to fix the issues in `Add-Type` (#2764). By default `Add-Type` will reference all those reference assemblies when compiling C# code. If `-ReferenceAssembly` is specified, then we search reference assemblies first, then the framework runtime assemblies, and lastly the loaded assemblies (possibly a third-party one that was already loaded).
5. `dotnet publish` generates executable on Unix platforms, but doesn't set "x" permission and thus it cannot execute. Currently, the "x" permission is set in the build script, `dotnet/cli` issue [#6286](https://github.com/dotnet/cli/issues/6286) is tracking this.
6. Replace the use of some APIs with the ones that take `SecureString`.
7. osx.10.12 is required to update to `netcoreapp2.0` because `dotnet-cli` 2.0.0-preview only works on osx.10.12.
8. Add dependency to `System.ValueTuple` to work around a ambiguous type identity issue in coreclr. The issue is tracked by `dotnet/corefx` [#17797](https://github.com/dotnet/corefx/issues/17797). When moving to newer version of `netcoreapp2.0`, we need to verify if this dependency is still needed.
2017-04-18 02:52:38 +08:00
# publish netcoreapp2.0 reference assemblies
try {
Push-Location " $PSScriptRoot /src/TypeCatalogGen "
2017-07-22 12:03:49 +08:00
$refAssemblies = Get-Content -Path " powershell.inc " | Where-Object { $_ -like " *microsoft.netcore.app* " } | ForEach-Object { $_ . TrimEnd ( ';' ) }
Move powershell to .NET Core 2.0 (#3556)
This change moves powershell to .NET Core 2.0. Major changes are:
1. PowerShell assemblies are now targeting `netcoreapp2.0`. We are using `microsoft.netcore.app-2.0.0-preview1-001913-00`, which is from dotnet-core build 4/4/17. We cannot target `netstandard2.0` because the packages `System.Reflection.Emit` and `System.Reflection.Emit.Lightweight`, which are needed for powershell class, cannot be referenced when targeting `netstandard2.0`.
2. Refactor code to remove most CLR stub types and extension types.
3. Update build scripts to enable CI builds. The `-cache` section is specified to depend on `appveyor.yml`, so the cache will be invalidated if `appveyor.yml` is changed.
4. Ship `netcoreapp` reference assemblies with powershell to fix the issues in `Add-Type` (#2764). By default `Add-Type` will reference all those reference assemblies when compiling C# code. If `-ReferenceAssembly` is specified, then we search reference assemblies first, then the framework runtime assemblies, and lastly the loaded assemblies (possibly a third-party one that was already loaded).
5. `dotnet publish` generates executable on Unix platforms, but doesn't set "x" permission and thus it cannot execute. Currently, the "x" permission is set in the build script, `dotnet/cli` issue [#6286](https://github.com/dotnet/cli/issues/6286) is tracking this.
6. Replace the use of some APIs with the ones that take `SecureString`.
7. osx.10.12 is required to update to `netcoreapp2.0` because `dotnet-cli` 2.0.0-preview only works on osx.10.12.
8. Add dependency to `System.ValueTuple` to work around a ambiguous type identity issue in coreclr. The issue is tracked by `dotnet/corefx` [#17797](https://github.com/dotnet/corefx/issues/17797). When moving to newer version of `netcoreapp2.0`, we need to verify if this dependency is still needed.
2017-04-18 02:52:38 +08:00
$refDestFolder = Join-Path -Path $publishPath -ChildPath " ref "
if ( Test-Path $refDestFolder -PathType Container ) {
Remove-Item $refDestFolder -Force -Recurse -ErrorAction Stop
}
New-Item -Path $refDestFolder -ItemType Directory -Force -ErrorAction Stop > $null
Copy-Item -Path $refAssemblies -Destination $refDestFolder -Force -ErrorAction Stop
} finally {
Pop-Location
}
2017-07-24 03:29:33 +08:00
if ( $Environment . IsRedHatFamily ) {
2017-07-21 00:42:34 +08:00
# add two symbolic links to system shared libraries that libmi.so is dependent on to handle
# platform specific changes. This is the only set of platforms needed for this currently
2017-09-08 01:34:40 +08:00
# as Ubuntu has these specific library files in the platform and macOS builds for itself
2017-07-21 00:42:34 +08:00
# against the correct versions.
if ( ! ( test-path " $publishPath /libssl.so.1.0.0 " ) ) {
$null = New-Item -Force -ItemType SymbolicLink -Target " /lib64/libssl.so.10 " -Path " $publishPath /libssl.so.1.0.0 " -ErrorAction Stop
}
if ( ! ( test-path " $publishPath /libcrypto.so.1.0.0 " ) ) {
$null = New-Item -Force -ItemType SymbolicLink -Target " /lib64/libcrypto.so.10 " -Path " $publishPath /libcrypto.so.1.0.0 " -ErrorAction Stop
}
}
Move powershell to .NET Core 2.0 (#3556)
This change moves powershell to .NET Core 2.0. Major changes are:
1. PowerShell assemblies are now targeting `netcoreapp2.0`. We are using `microsoft.netcore.app-2.0.0-preview1-001913-00`, which is from dotnet-core build 4/4/17. We cannot target `netstandard2.0` because the packages `System.Reflection.Emit` and `System.Reflection.Emit.Lightweight`, which are needed for powershell class, cannot be referenced when targeting `netstandard2.0`.
2. Refactor code to remove most CLR stub types and extension types.
3. Update build scripts to enable CI builds. The `-cache` section is specified to depend on `appveyor.yml`, so the cache will be invalidated if `appveyor.yml` is changed.
4. Ship `netcoreapp` reference assemblies with powershell to fix the issues in `Add-Type` (#2764). By default `Add-Type` will reference all those reference assemblies when compiling C# code. If `-ReferenceAssembly` is specified, then we search reference assemblies first, then the framework runtime assemblies, and lastly the loaded assemblies (possibly a third-party one that was already loaded).
5. `dotnet publish` generates executable on Unix platforms, but doesn't set "x" permission and thus it cannot execute. Currently, the "x" permission is set in the build script, `dotnet/cli` issue [#6286](https://github.com/dotnet/cli/issues/6286) is tracking this.
6. Replace the use of some APIs with the ones that take `SecureString`.
7. osx.10.12 is required to update to `netcoreapp2.0` because `dotnet-cli` 2.0.0-preview only works on osx.10.12.
8. Add dependency to `System.ValueTuple` to work around a ambiguous type identity issue in coreclr. The issue is tracked by `dotnet/corefx` [#17797](https://github.com/dotnet/corefx/issues/17797). When moving to newer version of `netcoreapp2.0`, we need to verify if this dependency is still needed.
2017-04-18 02:52:38 +08:00
# download modules from powershell gallery.
# - PowerShellGet, PackageManagement, Microsoft.PowerShell.Archive
2016-11-19 01:55:23 +08:00
if ( $PSModuleRestore )
2016-11-18 05:54:38 +08:00
{
2017-01-11 06:42:27 +08:00
$ProgressPreference = " SilentlyContinue "
2017-01-17 05:31:14 +08:00
log " Restore PowerShell modules to $publishPath "
2016-11-21 04:50:06 +08:00
$modulesDir = Join-Path -Path $publishPath -ChildPath " Modules "
# Restore modules from myget feed
Restore-PSModule -Destination $modulesDir -Name @ (
# PowerShellGet depends on PackageManagement module, so PackageManagement module will be installed with the PowerShellGet module.
'PowerShellGet'
)
# Restore modules from powershellgallery feed
Restore-PSModule -Destination $modulesDir -Name @ (
'Microsoft.PowerShell.Archive'
) -SourceLocation " https://www.powershellgallery.com/api/v2/ "
2016-11-18 05:54:38 +08:00
}
2016-04-02 08:51:38 +08:00
}
2016-09-29 07:20:29 +08:00
function Compress-TestContent {
[ CmdletBinding ( ) ]
param (
$Destination
)
2017-06-06 08:37:48 +08:00
Publish-PSTestTools
$powerShellTestRoot = Join-Path $PSScriptRoot 'test'
2016-09-29 07:20:29 +08:00
Add-Type -AssemblyName System . IO . Compression . FileSystem
$resolvedPath = $ExecutionContext . SessionState . Path . GetUnresolvedProviderPathFromPSPath ( $Destination )
2017-01-17 05:31:14 +08:00
[ System.IO.Compression.ZipFile ] :: CreateFromDirectory ( $powerShellTestRoot , $resolvedPath )
2016-09-29 07:20:29 +08:00
}
2016-04-15 06:06:14 +08:00
function New-PSOptions {
[ CmdletBinding ( ) ]
param (
2016-11-12 03:12:07 +08:00
[ ValidateSet ( " Linux " , " Debug " , " Release " , " CodeCoverage " , " " ) ]
2016-04-15 06:06:14 +08:00
[ string ] $Configuration ,
2017-08-17 03:07:45 +08:00
[ ValidateSet ( " netcoreapp2.0 " ) ]
2016-04-15 06:06:14 +08:00
[ string ] $Framework ,
# These are duplicated from Start-PSBuild
# We do not use ValidateScript since we want tab completion
[ ValidateSet ( " " ,
" ubuntu.14.04-x64 " ,
2016-08-02 06:18:42 +08:00
" ubuntu.16.04-x64 " ,
2016-06-03 11:13:30 +08:00
" debian.8-x64 " ,
2016-06-17 09:39:29 +08:00
" centos.7-x64 " ,
2017-01-07 02:04:18 +08:00
" fedora.24-x64 " ,
2016-11-16 02:14:31 +08:00
" win7-x86 " ,
2016-04-15 06:06:14 +08:00
" win7-x64 " ,
" win81-x64 " ,
" win10-x64 " ,
2017-03-07 09:30:14 +08:00
" osx.10.12-x64 " ,
2017-03-23 05:19:51 +08:00
" opensuse.13.2-x64 " ,
2017-09-12 03:16:58 +08:00
" opensuse.42.1-x64 " ,
" linux-arm " ) ]
2016-04-15 06:06:14 +08:00
[ string ] $Runtime ,
2016-09-29 01:47:16 +08:00
[ switch ] $CrossGen ,
2016-05-07 01:28:45 +08:00
[ string ] $Output ,
2016-04-15 06:06:14 +08:00
2016-07-20 03:51:11 +08:00
[ switch ] $SMAOnly
2016-04-15 06:06:14 +08:00
)
2016-06-21 02:59:14 +08:00
# Add .NET CLI tools to PATH
Find-Dotnet
2016-09-29 01:47:16 +08:00
$ConfigWarningMsg = " The passed-in Configuration value '{0}' is not supported on '{1}'. Use '{2}' instead. "
2016-04-15 06:06:14 +08:00
if ( -not $Configuration ) {
2017-09-08 01:34:40 +08:00
$Configuration = if ( $Environment . IsLinux -or $Environment . IsMacOS ) {
2016-04-15 06:06:14 +08:00
" Linux "
2017-07-24 03:29:33 +08:00
} elseif ( $Environment . IsWindows ) {
2016-04-15 06:06:14 +08:00
" Debug "
}
2016-09-29 01:47:16 +08:00
} else {
switch ( $Configuration ) {
" Linux " {
2017-07-24 03:29:33 +08:00
if ( $Environment . IsWindows ) {
2016-09-29 01:47:16 +08:00
$Configuration = " Debug "
Write-Warning ( $ConfigWarningMsg -f $switch . Current , " Windows " , $Configuration )
}
}
2016-11-12 03:12:07 +08:00
" CodeCoverage " {
2017-07-24 03:29:33 +08:00
if ( -not $Environment . IsWindows ) {
2016-11-12 03:12:07 +08:00
$Configuration = " Linux "
2017-07-24 03:29:33 +08:00
Write-Warning ( $ConfigWarningMsg -f $switch . Current , $Environment . LinuxInfo . PRETTY_NAME , $Configuration )
2016-11-12 03:12:07 +08:00
}
}
2016-09-29 01:47:16 +08:00
Default {
2017-09-08 01:34:40 +08:00
if ( $Environment . IsLinux -or $Environment . IsMacOS ) {
2016-09-29 01:47:16 +08:00
$Configuration = " Linux "
2017-07-24 03:29:33 +08:00
Write-Warning ( $ConfigWarningMsg -f $switch . Current , $Environment . LinuxInfo . PRETTY_NAME , $Configuration )
2016-09-29 01:47:16 +08:00
}
}
}
2016-04-15 06:06:14 +08:00
}
2016-09-29 01:47:16 +08:00
Write-Verbose " Using configuration ' $Configuration ' "
2016-04-15 06:06:14 +08:00
2017-08-17 03:07:45 +08:00
$PowerShellDir = if ( $Configuration -eq 'Linux' ) {
2016-09-29 01:47:16 +08:00
" powershell-unix "
2016-07-22 09:47:46 +08:00
} else {
2016-09-29 01:47:16 +08:00
" powershell-win-core "
2016-07-22 09:47:46 +08:00
}
2016-09-29 01:47:16 +08:00
$Top = [ IO.Path ] :: Combine ( $PSScriptRoot , " src " , $PowerShellDir )
2016-07-22 09:47:46 +08:00
Write-Verbose " Top project directory is $Top "
2016-04-15 06:06:14 +08:00
if ( -not $Framework ) {
2017-08-17 03:07:45 +08:00
$Framework = " netcoreapp2.0 "
2016-07-02 03:09:50 +08:00
Write-Verbose " Using framework ' $Framework ' "
2016-04-15 06:06:14 +08:00
}
if ( -not $Runtime ) {
2017-07-22 12:03:49 +08:00
$Runtime = dotnet - -info | ForEach-Object {
2016-04-15 06:06:14 +08:00
if ( $_ -match " RID " ) {
$_ -split " \s+ " | Select-Object -Last 1
}
}
2017-09-12 03:16:58 +08:00
# We plan to release packages targetting win7-x64 and win7-x86 RIDs,
2017-08-30 08:21:50 +08:00
# which supports all supported windows platforms.
# So we, will change the RID to win7-<arch>
if ( $Environment . IsWindows ) {
$Runtime = $Runtime -replace " win\d+ " , " win7 "
}
2016-04-15 06:06:14 +08:00
if ( -not $Runtime ) {
Throw " Could not determine Runtime Identifier, please update dotnet "
} else {
2016-07-02 03:09:50 +08:00
Write-Verbose " Using runtime ' $Runtime ' "
2016-04-15 06:06:14 +08:00
}
2016-04-02 13:01:37 +08:00
}
2017-09-08 01:34:40 +08:00
$Executable = if ( $Environment . IsLinux -or $Environment . IsMacOS ) {
2016-04-15 06:06:14 +08:00
" powershell "
2017-07-24 03:29:33 +08:00
} elseif ( $Environment . IsWindows ) {
2016-04-15 06:06:14 +08:00
" powershell.exe "
}
2016-05-07 01:28:45 +08:00
# Build the Output path
2016-10-04 02:04:40 +08:00
if ( ! $Output ) {
2017-04-19 04:12:35 +08:00
$Output = [ IO.Path ] :: Combine ( $Top , " bin " , $Configuration , $Framework , $Runtime , " publish " , $Executable )
2016-05-07 01:28:45 +08:00
}
2016-04-15 06:06:14 +08:00
2016-07-20 03:51:11 +08:00
if ( $SMAOnly )
{
2016-09-29 01:47:16 +08:00
$Top = [ IO.Path ] :: Combine ( $PSScriptRoot , " src " , " System.Management.Automation " )
2016-07-20 03:51:11 +08:00
}
2017-08-16 07:17:45 +08:00
$RootInfo = @ { RepoPath = $PSScriptRoot }
# the valid root is the root of the filesystem and the folder PowerShell
$RootInfo [ 'ValidPath' ] = Join-Path -Path ( [ system.io.path ] :: GetPathRoot ( $RootInfo . RepoPath ) ) -ChildPath 'PowerShell'
2017-08-22 06:23:52 +08:00
2017-08-17 07:07:18 +08:00
if ( $RootInfo . RepoPath -ne $RootInfo . ValidPath )
2017-08-16 07:17:45 +08:00
{
2017-09-12 03:36:24 +08:00
$RootInfo [ 'Warning' ] = " Please ensure your repo is at the root of the file system and named 'PowerShell' (example: ' $( $RootInfo . ValidPath ) '), when building and packaging for release! "
2017-08-16 07:17:45 +08:00
$RootInfo [ 'IsValid' ] = $false
}
2017-08-22 06:23:52 +08:00
else
2017-08-16 07:17:45 +08:00
{
$RootInfo [ 'IsValid' ] = $true
}
return @ { RootInfo = [ PSCustomObject ] $RootInfo
Top = $Top ;
2016-04-15 06:06:14 +08:00
Configuration = $Configuration ;
2017-04-19 04:12:35 +08:00
Framework = $Framework ;
2016-04-15 06:06:14 +08:00
Runtime = $Runtime ;
2016-09-29 01:47:16 +08:00
Output = $Output ;
CrossGen = $CrossGen }
2016-04-15 06:06:14 +08:00
}
2017-07-24 03:29:33 +08:00
# Get the Options of the last build
function Get-PSOptions {
return $script:Options
}
2016-04-15 06:06:14 +08:00
function Get-PSOutput {
[ CmdletBinding ( ) ] param (
[ hashtable ] $Options
)
if ( $Options ) {
return $Options . Output
} elseif ( $script:Options ) {
return $script:Options . Output
} else {
return ( New-PSOptions ) . Output
}
2016-02-22 07:06:39 +08:00
}
2016-04-02 13:01:05 +08:00
2016-07-27 08:41:03 +08:00
function Get-PesterTag {
param ( [ Parameter ( Position = 0 ) ] [ string ] $testbase = " $PSScriptRoot /test/powershell " )
$alltags = @ { }
$warnings = @ ( )
2017-07-22 12:03:49 +08:00
get-childitem -Recurse $testbase -File | Where-Object { $_ . name -match " tests.ps1 " } | ForEach-Object {
2016-07-27 08:41:03 +08:00
$fullname = $_ . fullname
$tok = $err = $null
$ast = [ System.Management.Automation.Language.Parser ] :: ParseFile ( $FullName , [ ref ] $tok , [ ref ] $err )
$des = $ast . FindAll ( { $args [ 0 ] -is " System.Management.Automation.Language.CommandAst " -and $args [ 0 ] . CommandElements [ 0 ] . Value -eq " Describe " } , $true )
foreach ( $describe in $des ) {
$elements = $describe . CommandElements
$lineno = $elements [ 0 ] . Extent . StartLineNumber
2016-09-27 09:12:11 +08:00
$foundPriorityTags = @ ( )
2016-07-27 08:41:03 +08:00
for ( $i = 0 ; $i -lt $elements . Count ; $i + + ) {
if ( $elements [ $i ] . extent . text -match " ^-t " ) {
$vAst = $elements [ $i + 1 ]
if ( $vAst . FindAll ( { $args [ 0 ] -is " System.Management.Automation.Language.VariableExpressionAst " } , $true ) ) {
$warnings + = " TAGS must be static strings, error in ${fullname} , line $lineno "
}
$values = $vAst . FindAll ( { $args [ 0 ] -is " System.Management.Automation.Language.StringConstantExpressionAst " } , $true ) . Value
2017-07-22 12:03:49 +08:00
$values | ForEach-Object {
2016-09-16 10:33:54 +08:00
if ( @ ( 'REQUIREADMINONWINDOWS' , 'SLOW' ) -contains $_ ) {
# These are valid tags also, but they are not the priority tags
}
elseif ( @ ( 'CI' , 'FEATURE' , 'SCENARIO' ) -contains $_ ) {
2016-09-27 09:12:11 +08:00
$foundPriorityTags + = $_
2016-09-16 10:33:54 +08:00
}
else {
2016-07-27 08:41:03 +08:00
$warnings + = " ${fullname} includes improper tag ' $_ ', line ' $lineno ' "
}
2016-09-16 10:33:54 +08:00
2016-08-04 04:23:21 +08:00
$alltags [ $_ ] + +
2016-09-16 10:33:54 +08:00
}
2016-07-27 08:41:03 +08:00
}
}
2016-09-27 09:12:11 +08:00
if ( $foundPriorityTags . Count -eq 0 ) {
$warnings + = " ${fullname} : $lineno does not include -Tag in Describe "
}
elseif ( $foundPriorityTags . Count -gt 1 ) {
$warnings + = " ${fullname} : $lineno includes more then one scope -Tag: $foundPriorityTags "
2016-07-27 08:41:03 +08:00
}
}
}
if ( $Warnings . Count -gt 0 ) {
$alltags [ 'Result' ] = " Fail "
}
else {
$alltags [ 'Result' ] = " Pass "
}
$alltags [ 'Warnings' ] = $warnings
2016-08-04 04:23:21 +08:00
$o = [ pscustomobject ] $alltags
2016-07-27 08:41:03 +08:00
$o . psobject . TypeNames . Add ( " DescribeTagsInUse " )
$o
}
2016-09-13 01:39:42 +08:00
function Publish-PSTestTools {
2016-09-12 14:14:30 +08:00
[ CmdletBinding ( ) ]
param ( )
Find-Dotnet
2017-06-14 08:49:56 +08:00
$tools = @ (
@ { Path = " ${PSScriptRoot} /test/tools/TestExe " ; Output = " testexe " }
2017-08-31 17:30:35 +08:00
@ { Path = " ${PSScriptRoot} /test/tools/WebListener " ; Output = " WebListener " }
2017-06-14 08:49:56 +08:00
)
2017-07-22 12:03:49 +08:00
if ( $null -eq $Options )
2017-03-24 04:04:52 +08:00
{
$Options = New-PSOptions
}
2016-11-01 00:41:13 +08:00
2017-06-14 08:49:56 +08:00
# Publish tools so it can be run by tests
2016-11-01 00:41:13 +08:00
foreach ( $tool in $tools )
{
2017-06-14 08:49:56 +08:00
Push-Location $tool . Path
2016-11-01 00:41:13 +08:00
try {
2017-03-24 04:04:52 +08:00
dotnet publish - -output bin - -configuration $Options . Configuration - -framework $Options . Framework - -runtime $Options . Runtime
2017-06-14 08:49:56 +08:00
$toolPath = Join-Path -Path $tool . Path -ChildPath " bin "
Move powershell to .NET Core 2.0 (#3556)
This change moves powershell to .NET Core 2.0. Major changes are:
1. PowerShell assemblies are now targeting `netcoreapp2.0`. We are using `microsoft.netcore.app-2.0.0-preview1-001913-00`, which is from dotnet-core build 4/4/17. We cannot target `netstandard2.0` because the packages `System.Reflection.Emit` and `System.Reflection.Emit.Lightweight`, which are needed for powershell class, cannot be referenced when targeting `netstandard2.0`.
2. Refactor code to remove most CLR stub types and extension types.
3. Update build scripts to enable CI builds. The `-cache` section is specified to depend on `appveyor.yml`, so the cache will be invalidated if `appveyor.yml` is changed.
4. Ship `netcoreapp` reference assemblies with powershell to fix the issues in `Add-Type` (#2764). By default `Add-Type` will reference all those reference assemblies when compiling C# code. If `-ReferenceAssembly` is specified, then we search reference assemblies first, then the framework runtime assemblies, and lastly the loaded assemblies (possibly a third-party one that was already loaded).
5. `dotnet publish` generates executable on Unix platforms, but doesn't set "x" permission and thus it cannot execute. Currently, the "x" permission is set in the build script, `dotnet/cli` issue [#6286](https://github.com/dotnet/cli/issues/6286) is tracking this.
6. Replace the use of some APIs with the ones that take `SecureString`.
7. osx.10.12 is required to update to `netcoreapp2.0` because `dotnet-cli` 2.0.0-preview only works on osx.10.12.
8. Add dependency to `System.ValueTuple` to work around a ambiguous type identity issue in coreclr. The issue is tracked by `dotnet/corefx` [#17797](https://github.com/dotnet/corefx/issues/17797). When moving to newer version of `netcoreapp2.0`, we need to verify if this dependency is still needed.
2017-04-18 02:52:38 +08:00
2017-06-14 08:49:56 +08:00
if ( $env:PATH -notcontains $toolPath ) {
$env:PATH = $toolPath + $TestModulePathSeparator + $ ( $env:PATH )
}
2016-11-01 00:41:13 +08:00
} finally {
Pop-Location
}
2016-09-12 14:14:30 +08:00
}
}
2016-04-02 13:01:45 +08:00
function Start-PSPester {
2017-08-26 23:26:06 +08:00
[ CmdletBinding ( DefaultParameterSetName = 'default' ) ]
2016-09-01 03:13:05 +08:00
param (
2016-07-26 08:43:28 +08:00
[ string ] $OutputFormat = " NUnitXml " ,
[ string ] $OutputFile = " pester-tests.xml " ,
2016-09-16 10:22:18 +08:00
[ string[] ] $ExcludeTag = 'Slow' ,
2017-07-19 05:20:14 +08:00
[ string[] ] $Tag = @ ( " CI " , " Feature " ) ,
2017-03-28 07:44:28 +08:00
[ string[] ] $Path = @ ( " $PSScriptRoot /test/common " , " $PSScriptRoot /test/powershell " ) ,
2016-08-31 02:47:27 +08:00
[ switch ] $ThrowOnFailure ,
2017-08-17 03:07:45 +08:00
[ string ] $binDir = ( Split-Path ( New-PSOptions ) . Output ) ,
2016-09-10 05:39:41 +08:00
[ string ] $powershell = ( Join-Path $binDir 'powershell' ) ,
2016-09-16 10:33:54 +08:00
[ string ] $Pester = ( [ IO.Path ] :: Combine ( $binDir , " Modules " , " Pester " ) ) ,
2017-08-26 23:26:06 +08:00
[ Parameter ( ParameterSetName = 'Unelevate' , Mandatory = $true ) ]
2016-12-02 03:23:14 +08:00
[ switch ] $Unelevate ,
2017-03-07 05:13:34 +08:00
[ switch ] $Quiet ,
2017-08-26 23:26:06 +08:00
[ Parameter ( ParameterSetName = 'PassThru' , Mandatory = $true ) ]
2017-03-07 05:13:34 +08:00
[ switch ] $PassThru
2016-04-02 13:01:45 +08:00
)
2016-07-27 07:01:31 +08:00
2016-09-16 10:22:18 +08:00
# we need to do few checks and if user didn't provide $ExcludeTag explicitly, we should alternate the default
if ( $Unelevate )
{
2017-07-24 03:29:33 +08:00
if ( -not $Environment . IsWindows )
2016-09-16 10:22:18 +08:00
{
throw '-Unelevate is currently not supported on non-Windows platforms'
}
2017-07-24 03:29:33 +08:00
if ( -not $Environment . IsAdmin )
2016-09-16 10:22:18 +08:00
{
throw '-Unelevate cannot be applied because the current user is not Administrator'
}
2016-09-27 04:15:58 +08:00
if ( -not $PSBoundParameters . ContainsKey ( 'ExcludeTag' ) )
2016-09-16 10:22:18 +08:00
{
$ExcludeTag + = 'RequireAdminOnWindows'
}
}
2017-07-24 03:29:33 +08:00
elseif ( $Environment . IsWindows -and ( -not $Environment . IsAdmin ) )
2016-09-16 10:22:18 +08:00
{
2016-09-27 04:15:58 +08:00
if ( -not $PSBoundParameters . ContainsKey ( 'ExcludeTag' ) )
2016-09-16 10:22:18 +08:00
{
$ExcludeTag + = 'RequireAdminOnWindows'
}
}
2016-09-01 03:13:05 +08:00
Write-Verbose " Running pester tests at ' $path ' with tag ' $( $Tag -join ''', ''' ) ' and ExcludeTag ' $( $ExcludeTag -join ''', ''' ) ' " -Verbose
2017-08-26 23:26:06 +08:00
Publish-PSTestTools | ForEach-Object { Write-Host $_ }
2017-03-27 12:46:39 +08:00
2016-08-10 03:03:30 +08:00
# All concatenated commands/arguments are suffixed with the delimiter (space)
$Command = " "
2017-03-27 12:46:39 +08:00
# Autoload (in subprocess) temporary modules used in our tests
$Command + = '$env:PSModulePath = ' + " ' $TestModulePath $TestModulePathSeparator ' " + '+$($env:PSModulePath);'
2016-08-10 03:03:30 +08:00
# Windows needs the execution policy adjusted
2017-07-24 03:29:33 +08:00
if ( $Environment . IsWindows ) {
2016-08-10 03:03:30 +08:00
$Command + = " Set-ExecutionPolicy -Scope Process Unrestricted; "
}
2017-08-17 03:07:45 +08:00
$Command + = " Import-Module ' $Pester '; "
2016-09-16 10:22:18 +08:00
if ( $Unelevate )
{
$outputBufferFilePath = [ System.IO.Path ] :: GetTempFileName ( )
}
2017-01-17 05:31:14 +08:00
2016-08-10 03:03:30 +08:00
$Command + = " Invoke-Pester "
$Command + = " -OutputFormat ${OutputFormat} -OutputFile ${OutputFile} "
if ( $ExcludeTag -and ( $ExcludeTag -ne " " ) ) {
$Command + = " -ExcludeTag @(' " + ( $ { ExcludeTag } -join " ',' " ) + " ') "
2016-08-05 07:46:44 +08:00
}
2016-08-10 03:03:30 +08:00
if ( $Tag ) {
$Command + = " -Tag @(' " + ( $ { Tag } -join " ',' " ) + " ') "
}
2016-12-02 03:23:14 +08:00
# sometimes we need to eliminate Pester output, especially when we're
# doing a daily build as the log file is too large
if ( $Quiet ) {
$Command + = " -Quiet "
}
2017-03-07 05:13:34 +08:00
if ( $PassThru ) {
$Command + = " -PassThru "
}
2016-08-10 03:03:30 +08:00
2017-03-28 07:44:28 +08:00
$Command + = " ' " + ( $Path -join " ',' " ) + " ' "
2016-09-16 10:22:18 +08:00
if ( $Unelevate )
{
2016-09-22 05:41:20 +08:00
$Command + = " *> $outputBufferFilePath ; '__UNELEVATED_TESTS_THE_END__' >> $outputBufferFilePath "
2016-09-16 10:22:18 +08:00
}
2016-08-10 03:03:30 +08:00
Write-Verbose $Command
2016-08-31 02:47:27 +08:00
2016-08-10 03:03:30 +08:00
# To ensure proper testing, the module path must not be inherited by the spawned process
2017-08-17 03:07:45 +08:00
try {
$originalModulePath = $env:PSModulePath
if ( $Unelevate )
{
Start-UnelevatedProcess -process $powershell -arguments @ ( '-noprofile' , '-c' , $Command )
$currentLines = 0
while ( $true )
2016-09-16 10:22:18 +08:00
{
2017-08-17 03:07:45 +08:00
$lines = Get-Content $outputBufferFilePath | Select-Object -Skip $currentLines
$lines | Write-Host
if ( $lines | Where-Object { $_ -eq '__UNELEVATED_TESTS_THE_END__' } )
2016-09-16 10:22:18 +08:00
{
2017-08-17 03:07:45 +08:00
break
}
2016-09-16 10:22:18 +08:00
2017-08-17 03:07:45 +08:00
$count = ( $lines | measure-object ) . Count
if ( $count -eq 0 )
{
2017-08-22 06:23:52 +08:00
Start-Sleep -Seconds 1
2017-08-17 03:07:45 +08:00
}
else
{
$currentLines + = $count
2016-09-16 10:22:18 +08:00
}
}
2017-01-17 05:31:14 +08:00
}
2017-08-17 03:07:45 +08:00
else
{
2017-08-26 23:26:06 +08:00
if ( $PassThru . IsPresent )
{
$passThruFile = [ System.IO.Path ] :: GetTempFileName ( )
2017-09-12 03:16:58 +08:00
try
2017-08-26 23:26:06 +08:00
{
$Command + = " |Export-Clixml -Path ' $passThruFile ' -Force "
Start-NativeExecution -sb { & $powershell -noprofile -c $Command } | ForEach-Object { Write-Host $_ }
Import-Clixml -Path $passThruFile | Where-Object { $_ . TotalCount -is [ Int32 ] }
}
finally
{
Remove-Item $passThruFile -ErrorAction SilentlyContinue
}
}
2017-09-12 03:16:58 +08:00
else
2017-08-26 23:26:06 +08:00
{
Start-NativeExecution -sb { & $powershell -noprofile -c $Command }
}
2017-08-17 03:07:45 +08:00
}
} finally {
$env:PSModulePath = $originalModulePath
if ( $Unelevate )
{
Remove-Item $outputBufferFilePath
}
2016-08-10 03:03:30 +08:00
}
2017-08-17 03:07:45 +08:00
2016-08-31 02:47:27 +08:00
if ( $ThrowOnFailure )
{
Test-PSPesterResults -TestResultsFile $OutputFile
}
}
2016-09-16 10:22:18 +08:00
function script: Start-UnelevatedProcess
{
param (
[ string ] $process ,
[ string[] ] $arguments
)
2017-07-24 03:29:33 +08:00
if ( -not $Environment . IsWindows )
2016-09-16 10:22:18 +08:00
{
throw " Start-UnelevatedProcess is currently not supported on non-Windows platforms "
}
runas . exe / trustlevel : 0x20000 " $process $arguments "
}
2016-12-02 03:23:14 +08:00
function Show-PSPesterError
{
2017-08-26 23:26:06 +08:00
[ CmdletBinding ( DefaultParameterSetName = 'xml' ) ]
2017-09-12 03:16:58 +08:00
param (
2017-08-26 23:26:06 +08:00
[ Parameter ( ParameterSetName = 'xml' , Mandatory ) ]
[ Xml.XmlElement ] $testFailure ,
[ Parameter ( ParameterSetName = 'object' , Mandatory ) ]
[ PSCustomObject ] $testFailureObject
)
2017-09-12 03:16:58 +08:00
2017-08-26 23:26:06 +08:00
if ( $PSCmdLet . ParameterSetName -eq 'xml' )
{
$description = $testFailure . description
$name = $testFailure . name
$message = $testFailure . failure . message
$stackTrace = $testFailure . failure . " stack-trace "
}
elseif ( $PSCmdLet . ParameterSetName -eq 'object' )
{
$description = $testFailureObject . Describe + '/' + $testFailureObject . Context
$name = $testFailureObject . Name
$message = $testFailureObject . FailureMessage
$stackTrace = $testFailureObject . StackTrace
}
else
{
throw 'Unknown Show-PSPester parameter set'
}
logerror ( " Description: " + $description )
logerror ( " Name: " + $name )
2016-12-02 03:23:14 +08:00
logerror " message: "
2017-08-26 23:26:06 +08:00
logerror $message
2016-12-02 03:23:14 +08:00
logerror " stack-trace: "
2017-08-26 23:26:06 +08:00
logerror $stackTrace
2016-12-02 03:23:14 +08:00
}
2016-08-31 02:47:27 +08:00
#
# Read the test result file and
2017-01-17 05:31:14 +08:00
# Throw if a test failed
2016-08-31 02:47:27 +08:00
function Test-PSPesterResults
{
2017-08-26 23:26:06 +08:00
[ CmdletBinding ( DefaultParameterSetName = 'file' ) ]
2016-08-31 02:47:27 +08:00
param (
2017-08-26 23:26:06 +08:00
[ Parameter ( ParameterSetName = 'file' ) ]
2016-08-31 02:47:27 +08:00
[ string ] $TestResultsFile = " pester-tests.xml " ,
2017-08-26 23:26:06 +08:00
[ Parameter ( ParameterSetName = 'file' ) ]
[ string ] $TestArea = 'test/powershell' ,
[ Parameter ( ParameterSetName = 'PesterPassThruObject' , Mandatory ) ]
[ pscustomobject ] $ResultObject
)
2016-08-10 03:03:30 +08:00
2017-08-26 23:26:06 +08:00
if ( $PSCmdLet . ParameterSetName -eq 'file' )
2016-08-31 02:47:27 +08:00
{
2017-08-26 23:26:06 +08:00
if ( ! ( Test-Path $TestResultsFile ) )
{
throw " Test result file ' $testResultsFile ' not found for $TestArea . "
}
2016-08-31 02:47:27 +08:00
2017-08-26 23:26:06 +08:00
$x = [ xml ] ( Get-Content -raw $testResultsFile )
if ( [ int ] $x . 'test-results' . failures -gt 0 )
{
logerror " TEST FAILURES "
# switch between methods, SelectNode is not available on dotnet core
2017-09-12 03:16:58 +08:00
if ( " System.Xml.XmlDocumentXPathExtensions " -as [ Type ] )
2017-08-26 23:26:06 +08:00
{
$failures = [ System.Xml.XmlDocumentXPathExtensions ] :: SelectNodes ( $x . " test-results " , './/test-case[@result = "Failure"]' )
}
2017-09-12 03:16:58 +08:00
else
2017-08-26 23:26:06 +08:00
{
$failures = $x . SelectNodes ( './/test-case[@result = "Failure"]' )
}
foreach ( $testfail in $failures )
{
Show-PSPesterError -testFailure $testfail
}
throw " $( $x . 'test-results' . failures ) tests in $TestArea failed "
2017-01-11 06:42:27 +08:00
}
2017-08-26 23:26:06 +08:00
}
elseif ( $PSCmdLet . ParameterSetName -eq 'PesterPassThruObject' )
{
if ( $ResultObject . TotalCount -le 0 )
{
logerror 'NO TESTS RUN'
2017-01-11 06:42:27 +08:00
}
2017-08-26 23:26:06 +08:00
elseif ( $ResultObject . FailedCount -gt 0 )
2016-12-02 03:23:14 +08:00
{
2017-08-26 23:26:06 +08:00
logerror 'TEST FAILURES'
$ResultObject . TestResult | Where-Object { $_ . Passed -eq $false } | ForEach-Object {
Show-PSPesterError -testFailureObject $_
}
2016-12-02 03:23:14 +08:00
}
2016-04-02 13:01:45 +08:00
}
}
2016-04-02 11:45:32 +08:00
function Start-PSxUnit {
2016-04-02 13:01:05 +08:00
[ CmdletBinding ( ) ] param ( )
2016-06-21 02:59:14 +08:00
2016-06-29 10:56:47 +08:00
log " xUnit tests are currently disabled pending fixes due to API and AssemblyLoadContext changes - @andschwa "
return
2017-07-24 03:29:33 +08:00
if ( $Environment . IsWindows ) {
2016-04-02 11:45:32 +08:00
throw " xUnit tests are only currently supported on Linux / OS X "
}
2016-04-02 13:01:37 +08:00
2017-09-08 01:34:40 +08:00
if ( $Environment . IsMacOS ) {
2016-04-15 06:09:35 +08:00
log " Not yet supported on OS X, pretending they passed... "
return
}
2016-06-21 02:59:14 +08:00
# Add .NET CLI tools to PATH
Find-Dotnet
2016-06-02 02:10:29 +08:00
$Arguments = " --configuration " , " Linux " , " -parallel " , " none "
2016-06-01 07:06:19 +08:00
if ( $PSCmdlet . MyInvocation . BoundParameters [ " Verbose " ] . IsPresent ) {
2016-06-02 02:10:29 +08:00
$Arguments + = " -verbose "
2016-06-01 07:06:19 +08:00
}
2016-04-02 13:01:37 +08:00
$Content = Split-Path -Parent ( Get-PSOutput )
2016-06-02 02:10:29 +08:00
if ( -not ( Test-Path $Content ) ) {
throw " PowerShell must be built before running tests! "
}
2016-04-02 11:45:32 +08:00
try {
Push-Location $PSScriptRoot / test / csharp
2016-04-26 05:11:13 +08:00
# Path manipulation to obtain test project output directory
$Output = Join-Path $pwd ( ( Split-Path -Parent ( Get-PSOutput ) ) -replace ( New-PSOptions ) . Top )
2016-06-02 02:10:29 +08:00
Write-Verbose " Output is $Output "
2016-04-19 11:22:20 +08:00
2016-04-26 05:11:13 +08:00
Copy-Item -ErrorAction SilentlyContinue -Recurse -Path $Content / * -Include Modules , libpsl-native * -Destination $Output
2016-06-02 02:10:29 +08:00
Start-NativeExecution { dotnet test $Arguments }
2016-04-19 11:22:20 +08:00
2016-04-02 11:45:32 +08:00
if ( $LASTEXITCODE -ne 0 ) {
throw " $LASTEXITCODE xUnit tests failed "
}
} finally {
Pop-Location
}
}
2016-04-14 06:11:38 +08:00
2016-09-10 05:35:54 +08:00
function Install-Dotnet {
[ CmdletBinding ( ) ]
param (
2017-06-22 00:32:06 +08:00
[ string ] $Channel = $dotnetCLIChannel ,
[ string ] $Version = $dotnetCLIRequiredVersion ,
2016-09-10 05:35:54 +08:00
[ switch ] $NoSudo
)
# This allows sudo install to be optional; needed when running in containers / as root
# Note that when it is null, Invoke-Expression (but not &) must be used to interpolate properly
$sudo = if ( ! $NoSudo ) { " sudo " }
Move powershell to .NET Core 2.0 (#3556)
This change moves powershell to .NET Core 2.0. Major changes are:
1. PowerShell assemblies are now targeting `netcoreapp2.0`. We are using `microsoft.netcore.app-2.0.0-preview1-001913-00`, which is from dotnet-core build 4/4/17. We cannot target `netstandard2.0` because the packages `System.Reflection.Emit` and `System.Reflection.Emit.Lightweight`, which are needed for powershell class, cannot be referenced when targeting `netstandard2.0`.
2. Refactor code to remove most CLR stub types and extension types.
3. Update build scripts to enable CI builds. The `-cache` section is specified to depend on `appveyor.yml`, so the cache will be invalidated if `appveyor.yml` is changed.
4. Ship `netcoreapp` reference assemblies with powershell to fix the issues in `Add-Type` (#2764). By default `Add-Type` will reference all those reference assemblies when compiling C# code. If `-ReferenceAssembly` is specified, then we search reference assemblies first, then the framework runtime assemblies, and lastly the loaded assemblies (possibly a third-party one that was already loaded).
5. `dotnet publish` generates executable on Unix platforms, but doesn't set "x" permission and thus it cannot execute. Currently, the "x" permission is set in the build script, `dotnet/cli` issue [#6286](https://github.com/dotnet/cli/issues/6286) is tracking this.
6. Replace the use of some APIs with the ones that take `SecureString`.
7. osx.10.12 is required to update to `netcoreapp2.0` because `dotnet-cli` 2.0.0-preview only works on osx.10.12.
8. Add dependency to `System.ValueTuple` to work around a ambiguous type identity issue in coreclr. The issue is tracked by `dotnet/corefx` [#17797](https://github.com/dotnet/corefx/issues/17797). When moving to newer version of `netcoreapp2.0`, we need to verify if this dependency is still needed.
2017-04-18 02:52:38 +08:00
$obtainUrl = " https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain "
2016-09-10 05:35:54 +08:00
# Install for Linux and OS X
2017-09-08 01:34:40 +08:00
if ( $Environment . IsLinux -or $Environment . IsMacOS ) {
2016-09-10 05:35:54 +08:00
# Uninstall all previous dotnet packages
2017-07-24 03:29:33 +08:00
$uninstallScript = if ( $Environment . IsUbuntu ) {
2016-09-10 05:35:54 +08:00
" dotnet-uninstall-debian-packages.sh "
2017-09-08 01:34:40 +08:00
} elseif ( $Environment . IsMacOS ) {
2016-09-10 05:35:54 +08:00
" dotnet-uninstall-pkgs.sh "
}
if ( $uninstallScript ) {
Start-NativeExecution {
curl -sO $obtainUrl / uninstall / $uninstallScript
Invoke-Expression " $sudo bash ./ $uninstallScript "
}
} else {
Write-Warning " This script only removes prior versions of dotnet for Ubuntu 14.04 and OS X "
}
2016-12-08 10:29:21 +08:00
# Install new dotnet 1.1.0 preview packages
2016-09-10 05:35:54 +08:00
$installScript = " dotnet-install.sh "
Start-NativeExecution {
curl -sO $obtainUrl / $installScript
bash . / $installScript -c $Channel -v $Version
}
2017-07-24 03:29:33 +08:00
} elseif ( $Environment . IsWindows ) {
2016-09-10 05:35:54 +08:00
Remove-Item -ErrorAction SilentlyContinue -Recurse -Force ~ \ AppData \ Local \ Microsoft \ dotnet
$installScript = " dotnet-install.ps1 "
Invoke-WebRequest -Uri $obtainUrl / $installScript -OutFile $installScript
2017-07-01 04:07:14 +08:00
2017-07-24 03:29:33 +08:00
if ( -not $Environment . IsCoreCLR ) {
2017-07-01 04:07:14 +08:00
& . / $installScript -Channel $Channel -Version $Version
} else {
# dotnet-install.ps1 uses APIs that are not supported in .NET Core, so we run it with Windows PowerShell
$fullPSPath = Join-Path -Path $env:windir -ChildPath " System32\WindowsPowerShell\v1.0\powershell.exe "
$fullDotnetInstallPath = Join-Path -Path $pwd . Path -ChildPath $installScript
Start-NativeExecution { & $fullPSPath -NoLogo -NoProfile -File $fullDotnetInstallPath -Channel $Channel -Version $Version }
}
2016-09-10 05:35:54 +08:00
}
}
2017-01-07 02:04:18 +08:00
function Get-RedHatPackageManager {
2017-07-24 03:29:33 +08:00
if ( $Environment . IsCentOS ) {
2017-03-08 07:03:38 +08:00
" yum install -y -q "
2017-07-24 03:29:33 +08:00
} elseif ( $Environment . IsFedora ) {
2017-03-08 07:03:38 +08:00
" dnf install -y -q "
2017-07-24 03:29:33 +08:00
} elseif ( $Environment . IsOpenSUSE ) {
2017-03-08 07:03:38 +08:00
" zypper --non-interactive install "
2017-01-07 02:04:18 +08:00
} else {
throw " Error determining package manager for this distribution. "
}
}
2016-09-10 05:35:54 +08:00
2016-04-14 06:11:38 +08:00
function Start-PSBootstrap {
2016-07-23 05:31:32 +08:00
[ CmdletBinding (
SupportsShouldProcess = $true ,
ConfirmImpact = " High " ) ]
param (
2017-06-22 00:32:06 +08:00
[ string ] $Channel = $dotnetCLIChannel ,
Move powershell to .NET Core 2.0 (#3556)
This change moves powershell to .NET Core 2.0. Major changes are:
1. PowerShell assemblies are now targeting `netcoreapp2.0`. We are using `microsoft.netcore.app-2.0.0-preview1-001913-00`, which is from dotnet-core build 4/4/17. We cannot target `netstandard2.0` because the packages `System.Reflection.Emit` and `System.Reflection.Emit.Lightweight`, which are needed for powershell class, cannot be referenced when targeting `netstandard2.0`.
2. Refactor code to remove most CLR stub types and extension types.
3. Update build scripts to enable CI builds. The `-cache` section is specified to depend on `appveyor.yml`, so the cache will be invalidated if `appveyor.yml` is changed.
4. Ship `netcoreapp` reference assemblies with powershell to fix the issues in `Add-Type` (#2764). By default `Add-Type` will reference all those reference assemblies when compiling C# code. If `-ReferenceAssembly` is specified, then we search reference assemblies first, then the framework runtime assemblies, and lastly the loaded assemblies (possibly a third-party one that was already loaded).
5. `dotnet publish` generates executable on Unix platforms, but doesn't set "x" permission and thus it cannot execute. Currently, the "x" permission is set in the build script, `dotnet/cli` issue [#6286](https://github.com/dotnet/cli/issues/6286) is tracking this.
6. Replace the use of some APIs with the ones that take `SecureString`.
7. osx.10.12 is required to update to `netcoreapp2.0` because `dotnet-cli` 2.0.0-preview only works on osx.10.12.
8. Add dependency to `System.ValueTuple` to work around a ambiguous type identity issue in coreclr. The issue is tracked by `dotnet/corefx` [#17797](https://github.com/dotnet/corefx/issues/17797). When moving to newer version of `netcoreapp2.0`, we need to verify if this dependency is still needed.
2017-04-18 02:52:38 +08:00
# we currently pin dotnet-cli version, and will
# update it when more stable version comes out.
2017-06-22 00:32:06 +08:00
[ string ] $Version = $dotnetCLIRequiredVersion ,
2016-07-23 05:31:32 +08:00
[ switch ] $Package ,
2016-09-09 07:21:20 +08:00
[ switch ] $NoSudo ,
2017-07-26 07:50:27 +08:00
[ switch ] $BuildWindowsNative ,
2017-09-12 03:16:58 +08:00
[ switch ] $BuildLinuxArm ,
2016-07-23 05:31:32 +08:00
[ switch ] $Force
2016-06-15 04:33:19 +08:00
)
2016-04-14 06:11:38 +08:00
2016-08-17 08:03:34 +08:00
log " Installing PowerShell build dependencies "
2016-04-14 06:11:38 +08:00
2016-06-11 05:02:25 +08:00
Push-Location $PSScriptRoot / tools
2016-04-14 06:11:38 +08:00
2016-06-11 05:02:25 +08:00
try {
2017-09-08 01:34:40 +08:00
if ( $Environment . IsLinux -or $Environment . IsMacOS ) {
2017-07-26 07:50:27 +08:00
# This allows sudo install to be optional; needed when running in containers / as root
# Note that when it is null, Invoke-Expression (but not &) must be used to interpolate properly
$sudo = if ( ! $NoSudo ) { " sudo " }
2016-09-01 10:42:27 +08:00
try {
2017-07-26 07:50:27 +08:00
# Update googletest submodule for linux native cmake
2016-09-01 10:42:27 +08:00
Push-Location $PSScriptRoot
$Submodule = " $PSScriptRoot /src/libpsl-native/test/googletest "
Remove-Item -Path $Submodule -Recurse -Force -ErrorAction SilentlyContinue
2017-07-12 13:07:31 +08:00
git submodule - -quiet update - -init - - $submodule
2016-09-01 10:42:27 +08:00
} finally {
Pop-Location
}
2016-08-18 23:44:37 +08:00
2017-09-12 03:16:58 +08:00
if ( $BuildLinuxArm -and -not $Environment . IsUbuntu ) {
Write-Error " Cross compiling for linux-arm is only supported on Ubuntu environment "
return
}
2017-07-26 07:50:27 +08:00
# Install ours and .NET's dependencies
$Deps = @ ( )
if ( $Environment . IsUbuntu ) {
# Build tools
$Deps + = " curl " , " g++ " , " cmake " , " make "
2016-08-12 04:38:35 +08:00
2017-09-12 03:16:58 +08:00
if ( $BuildLinuxArm ) {
$Deps + = " gcc-arm-linux-gnueabihf " , " g++-arm-linux-gnueabihf "
}
2017-07-26 07:50:27 +08:00
# .NET Core required runtime libraries
$Deps + = " libunwind8 "
if ( $Environment . IsUbuntu14 ) { $Deps + = " libicu52 " }
elseif ( $Environment . IsUbuntu16 ) { $Deps + = " libicu55 " }
2016-08-12 04:38:35 +08:00
2017-07-26 07:50:27 +08:00
# Packaging tools
if ( $Package ) { $Deps + = " ruby-dev " , " groff " }
2016-08-12 04:38:35 +08:00
2017-07-26 07:50:27 +08:00
# Install dependencies
Start-NativeExecution {
Invoke-Expression " $sudo apt-get update -qq "
Invoke-Expression " $sudo apt-get install -y -qq $Deps "
}
} elseif ( $Environment . IsRedHatFamily ) {
# Build tools
$Deps + = " which " , " curl " , " gcc-c++ " , " cmake " , " make "
2016-08-12 04:38:35 +08:00
2017-07-26 07:50:27 +08:00
# .NET Core required runtime libraries
$Deps + = " libicu " , " libunwind "
2016-08-12 04:38:35 +08:00
2017-07-26 07:50:27 +08:00
# Packaging tools
if ( $Package ) { $Deps + = " ruby-devel " , " rpm-build " , " groff " }
2016-08-12 04:38:35 +08:00
2017-07-26 07:50:27 +08:00
$PackageManager = Get-RedHatPackageManager
2017-01-07 02:04:18 +08:00
2017-07-26 07:50:27 +08:00
$baseCommand = " $sudo $PackageManager "
2017-03-08 07:03:38 +08:00
2017-07-26 07:50:27 +08:00
# On OpenSUSE 13.2 container, sudo does not exist, so don't use it if not needed
if ( $NoSudo )
{
$baseCommand = $PackageManager
}
2017-03-08 07:03:38 +08:00
2017-07-26 07:50:27 +08:00
# Install dependencies
Start-NativeExecution {
Invoke-Expression " $baseCommand $Deps "
}
2017-09-08 01:34:40 +08:00
} elseif ( $Environment . IsMacOS ) {
2017-07-26 07:50:27 +08:00
precheck 'brew' " Bootstrap dependency 'brew' not found, must install Homebrew! See http://brew.sh/ "
2016-08-12 04:38:35 +08:00
2017-07-26 07:50:27 +08:00
# Build tools
$Deps + = " cmake "
2016-08-12 04:38:35 +08:00
2017-07-26 07:50:27 +08:00
# .NET Core required runtime libraries
$Deps + = " openssl "
2016-08-12 04:38:35 +08:00
2017-07-26 07:50:27 +08:00
# Install dependencies
# ignore exitcode, because they may be already installed
Start-NativeExecution { brew install $Deps } -IgnoreExitcode
2016-09-21 05:26:07 +08:00
2017-07-26 07:50:27 +08:00
# Install patched version of curl
Start-NativeExecution { brew install curl - -with -openssl } -IgnoreExitcode
}
2016-04-14 06:11:38 +08:00
2017-07-26 07:50:27 +08:00
# Install [fpm](https://github.com/jordansissel/fpm) and [ronn](https://github.com/rtomayko/ronn)
if ( $Package ) {
try {
# We cannot guess if the user wants to run gem install as root
2017-08-03 08:09:36 +08:00
Start-NativeExecution { gem install fpm -v 1.8 . 1 }
Start-NativeExecution { gem install ronn }
2017-07-26 07:50:27 +08:00
} catch {
Write-Warning " Installation of fpm and ronn gems failed! Must resolve manually. "
}
2016-09-09 07:21:43 +08:00
}
2016-07-06 02:03:08 +08:00
}
2017-07-26 07:50:27 +08:00
# Install dotnet-SDK
2017-07-19 02:39:04 +08:00
$dotNetExists = precheck 'dotnet' $null
$dotNetVersion = [ string ] :: Empty
if ( $dotNetExists ) {
$dotNetVersion = ( dotnet - -version )
}
if ( ! $dotNetExists -or $dotNetVersion -ne $dotnetCLIRequiredVersion -or $Force . IsPresent ) {
if ( $Force . IsPresent ) {
log " Installing dotnet due to -Force. "
}
elseif ( ! $dotNetExistis ) {
log " dotnet not present. Installing dotnet. "
}
else {
log " dotnet out of date ( $dotNetVersion ). Updating dotnet. "
}
$DotnetArguments = @ { Channel = $Channel ; Version = $Version ; NoSudo = $NoSudo }
Install-Dotnet @DotnetArguments
}
2017-07-26 07:50:27 +08:00
else {
2017-07-19 02:39:04 +08:00
log " dotnet is already installed. Skipping installation. "
}
2016-04-14 07:41:50 +08:00
2017-07-26 07:50:27 +08:00
# Install Windows dependencies if `-Package` or `-BuildWindowsNative` is specified
2017-07-24 03:29:33 +08:00
if ( $Environment . IsWindows ) {
2017-07-26 07:50:27 +08:00
if ( $BuildWindowsNative ) {
log " Install Windows dependencies for building PSRP plugin "
2016-07-22 06:47:28 +08:00
2017-07-26 07:50:27 +08:00
$machinePath = [ Environment ] :: GetEnvironmentVariable ( 'Path' , 'MACHINE' )
$newMachineEnvironmentPath = $machinePath
2016-07-23 05:31:32 +08:00
2017-07-26 07:50:27 +08:00
$cmakePresent = precheck 'cmake' $null
$sdkPresent = Test-Win10SDK
2016-08-04 04:23:21 +08:00
2017-07-26 07:50:27 +08:00
# Install chocolatey
$chocolateyPath = " $env:AllUsersProfile \chocolatey\bin "
if ( precheck 'choco' $null ) {
log " Chocolatey is already installed. Skipping installation. "
}
elseif ( ( $cmakePresent -eq $false ) -or ( $sdkPresent -eq $false ) ) {
log " Chocolatey not present. Installing chocolatey. "
if ( $Force -or $PSCmdlet . ShouldProcess ( " Install chocolatey via https://chocolatey.org/install.ps1 " ) ) {
Invoke-Expression ( ( new-object net . webclient ) . DownloadString ( 'https://chocolatey.org/install.ps1' ) )
if ( -not ( $machinePath . ToLower ( ) . Contains ( $chocolateyPath . ToLower ( ) ) ) ) {
log " Adding $chocolateyPath to Path environment variable "
$env:Path + = " ; $chocolateyPath "
$newMachineEnvironmentPath + = " ; $chocolateyPath "
} else {
log " $chocolateyPath already present in Path environment variable "
}
2016-08-04 04:23:21 +08:00
} else {
2017-07-26 07:50:27 +08:00
Write-Error " Chocolatey is required to install missing dependencies. Please install it from https://chocolatey.org/ manually. Alternatively, install cmake and Windows 10 SDK. "
return
2016-07-23 07:42:19 +08:00
}
2016-08-04 04:23:21 +08:00
} else {
2017-07-26 07:50:27 +08:00
log " Skipping installation of chocolatey, cause both cmake and Win 10 SDK are present. "
2016-07-22 06:33:16 +08:00
}
2016-07-22 06:47:28 +08:00
2017-07-26 07:50:27 +08:00
# Install cmake
$cmakePath = " ${env:ProgramFiles} \CMake\bin "
if ( $cmakePresent ) {
log " Cmake is already installed. Skipping installation. "
2016-08-04 04:23:21 +08:00
} else {
2017-07-26 07:50:27 +08:00
log " Cmake not present. Installing cmake. "
Start-NativeExecution { choco install cmake -y - -version 3.6 . 0 }
if ( -not ( $machinePath . ToLower ( ) . Contains ( $cmakePath . ToLower ( ) ) ) ) {
log " Adding $cmakePath to Path environment variable "
$env:Path + = " ; $cmakePath "
$newMachineEnvironmentPath = " $cmakePath ; $newMachineEnvironmentPath "
} else {
log " $cmakePath already present in Path environment variable "
}
2016-07-22 06:47:28 +08:00
}
2017-07-26 07:50:27 +08:00
# Install Windows 10 SDK
$packageName = " windows-sdk-10.0 "
2016-07-22 07:10:57 +08:00
2017-07-26 07:50:27 +08:00
if ( -not $sdkPresent ) {
log " Windows 10 SDK not present. Installing $packageName . "
Start-NativeExecution { choco install windows-sdk - 10.0 -y }
} else {
log " Windows 10 SDK present. Skipping installation. "
}
2016-08-04 04:23:21 +08:00
2017-07-26 07:50:27 +08:00
# Update path machine environment variable
if ( $newMachineEnvironmentPath -ne $machinePath ) {
log " Updating Path machine environment variable "
if ( $Force -or $PSCmdlet . ShouldProcess ( " Update Path machine environment variable to $newMachineEnvironmentPath " ) ) {
[ Environment ] :: SetEnvironmentVariable ( 'Path' , $newMachineEnvironmentPath , 'MACHINE' )
}
2016-07-23 05:31:32 +08:00
}
2016-07-22 06:47:28 +08:00
}
2016-06-11 05:02:25 +08:00
}
} finally {
Pop-Location
2016-04-14 06:11:38 +08:00
}
}
2016-05-20 10:03:43 +08:00
function Publish-NuGetFeed
{
param (
[ string ] $OutputPath = " $PSScriptRoot /nuget-artifacts " ,
2017-09-07 06:20:25 +08:00
[ ValidatePattern ( " ^v\d+\.\d+\.\d+(-\w+\.\d+)? $ " ) ]
[ ValidateNotNullOrEmpty ( ) ]
[ string ] $ReleaseTag
2016-05-20 10:03:43 +08:00
)
2016-06-21 02:59:14 +08:00
# Add .NET CLI tools to PATH
Find-Dotnet
2017-09-07 06:20:25 +08:00
## We update 'project.assets.json' files with new version tag value by 'GetPSCoreVersionFromGit' target.
$TopProject = ( New-PSOptions ) . Top
if ( $ReleaseTag ) {
$ReleaseTagToUse = $ReleaseTag -Replace '^v'
dotnet restore $TopProject " /property:ReleaseTag= $ReleaseTagToUse "
} else {
dotnet restore $TopProject
2017-05-02 13:34:25 +08:00
}
2017-03-24 04:04:52 +08:00
try {
Push-Location $PSScriptRoot
@ (
2016-05-20 10:03:43 +08:00
'Microsoft.PowerShell.Commands.Management' ,
'Microsoft.PowerShell.Commands.Utility' ,
2017-01-31 08:44:23 +08:00
'Microsoft.PowerShell.Commands.Diagnostics' ,
2016-05-20 10:03:43 +08:00
'Microsoft.PowerShell.ConsoleHost' ,
'Microsoft.PowerShell.Security' ,
2016-06-25 08:25:56 +08:00
'System.Management.Automation' ,
'Microsoft.PowerShell.CoreCLR.AssemblyLoadContext' ,
2016-07-27 07:43:32 +08:00
'Microsoft.PowerShell.CoreCLR.Eventing' ,
2016-08-30 07:01:38 +08:00
'Microsoft.WSMan.Management' ,
'Microsoft.WSMan.Runtime' ,
2016-07-27 07:43:32 +08:00
'Microsoft.PowerShell.SDK'
2017-07-22 12:03:49 +08:00
) | ForEach-Object {
2017-09-07 06:20:25 +08:00
if ( $ReleaseTag ) {
dotnet pack " src/ $_ " - -output $OutputPath " /property:IncludeSymbols=true;ReleaseTag= $ReleaseTagToUse "
2017-03-24 04:04:52 +08:00
} else {
dotnet pack " src/ $_ " - -output $OutputPath
}
2016-05-20 10:03:43 +08:00
}
2017-03-24 04:04:52 +08:00
} finally {
Pop-Location
2016-05-20 10:03:43 +08:00
}
}
2016-07-02 03:09:50 +08:00
function Start-DevPowerShell {
2016-02-04 02:53:43 +08:00
param (
[ string[] ] $ArgumentList = '' ,
[ switch ] $LoadProfile ,
2017-08-17 03:07:45 +08:00
[ string ] $binDir = ( Split-Path ( New-PSOptions ) . Output ) ,
2016-07-02 03:09:50 +08:00
[ switch ] $NoNewWindow ,
[ string ] $Command ,
[ switch ] $KeepPSModulePath
2016-02-04 02:53:43 +08:00
)
2016-04-02 13:01:05 +08:00
try {
2017-07-24 03:29:33 +08:00
if ( ( -not $NoNewWindow ) -and ( $Environment . IsCoreCLR ) ) {
2016-07-28 03:27:41 +08:00
Write-Warning " Start-DevPowerShell -NoNewWindow is currently implied in PowerShellCore edition https://github.com/PowerShell/PowerShell/issues/1543 "
2016-07-28 01:55:42 +08:00
$NoNewWindow = $true
}
2016-07-02 03:09:50 +08:00
if ( -not $LoadProfile ) {
2016-02-04 09:25:51 +08:00
$ArgumentList = @ ( '-noprofile' ) + $ArgumentList
2016-02-04 02:53:43 +08:00
}
2016-08-04 04:23:21 +08:00
if ( -not $KeepPSModulePath ) {
if ( -not $Command ) {
2016-07-02 03:09:50 +08:00
$ArgumentList = @ ( '-NoExit' ) + $ArgumentList
}
2017-03-16 03:04:28 +08:00
$Command = '$env:PSModulePath = Join-Path $env:DEVPATH Modules; ' + $Command
2016-08-04 04:23:21 +08:00
}
2016-07-02 03:09:50 +08:00
2016-08-04 04:23:21 +08:00
if ( $Command ) {
2016-07-02 03:09:50 +08:00
$ArgumentList = $ArgumentList + @ ( " -command $Command " )
}
2016-02-04 02:53:43 +08:00
$env:DEVPATH = $binDir
2016-02-22 07:06:39 +08:00
# splatting for the win
2016-02-04 09:25:51 +08:00
$startProcessArgs = @ {
2016-07-28 01:48:36 +08:00
FilePath = " $binDir \powershell "
2016-02-04 09:25:51 +08:00
ArgumentList = " $ArgumentList "
2016-02-22 07:06:39 +08:00
}
2016-02-05 05:19:24 +08:00
if ( $NoNewWindow ) {
$startProcessArgs . NoNewWindow = $true
$startProcessArgs . Wait = $true
}
2016-02-22 07:06:39 +08:00
2016-02-04 09:25:51 +08:00
Start-Process @startProcessArgs
2016-04-02 13:01:05 +08:00
} finally {
2016-08-31 02:47:27 +08:00
if ( $env:DevPath )
{
Remove-Item env : DEVPATH
}
2017-01-17 05:31:14 +08:00
2016-04-02 13:01:05 +08:00
if ( $ZapDisable ) {
2016-08-31 02:47:27 +08:00
Remove-Item env : COMPLUS_ZapDisable
2016-02-04 02:53:43 +08:00
}
}
2016-02-21 06:35:46 +08:00
}
2016-03-23 07:00:20 +08:00
2016-06-18 02:23:29 +08:00
function Start-TypeGen
{
[ CmdletBinding ( ) ]
param ( )
2016-06-21 02:59:14 +08:00
# Add .NET CLI tools to PATH
Find-Dotnet
2017-03-24 04:04:52 +08:00
$GetDependenciesTargetPath = " $PSScriptRoot /src/Microsoft.PowerShell.SDK/obj/Microsoft.PowerShell.SDK.csproj.TypeCatalog.targets "
$GetDependenciesTargetValue = @ '
< Project >
< Target Name = " _GetDependencies "
Move powershell to .NET Core 2.0 (#3556)
This change moves powershell to .NET Core 2.0. Major changes are:
1. PowerShell assemblies are now targeting `netcoreapp2.0`. We are using `microsoft.netcore.app-2.0.0-preview1-001913-00`, which is from dotnet-core build 4/4/17. We cannot target `netstandard2.0` because the packages `System.Reflection.Emit` and `System.Reflection.Emit.Lightweight`, which are needed for powershell class, cannot be referenced when targeting `netstandard2.0`.
2. Refactor code to remove most CLR stub types and extension types.
3. Update build scripts to enable CI builds. The `-cache` section is specified to depend on `appveyor.yml`, so the cache will be invalidated if `appveyor.yml` is changed.
4. Ship `netcoreapp` reference assemblies with powershell to fix the issues in `Add-Type` (#2764). By default `Add-Type` will reference all those reference assemblies when compiling C# code. If `-ReferenceAssembly` is specified, then we search reference assemblies first, then the framework runtime assemblies, and lastly the loaded assemblies (possibly a third-party one that was already loaded).
5. `dotnet publish` generates executable on Unix platforms, but doesn't set "x" permission and thus it cannot execute. Currently, the "x" permission is set in the build script, `dotnet/cli` issue [#6286](https://github.com/dotnet/cli/issues/6286) is tracking this.
6. Replace the use of some APIs with the ones that take `SecureString`.
7. osx.10.12 is required to update to `netcoreapp2.0` because `dotnet-cli` 2.0.0-preview only works on osx.10.12.
8. Add dependency to `System.ValueTuple` to work around a ambiguous type identity issue in coreclr. The issue is tracked by `dotnet/corefx` [#17797](https://github.com/dotnet/corefx/issues/17797). When moving to newer version of `netcoreapp2.0`, we need to verify if this dependency is still needed.
2017-04-18 02:52:38 +08:00
DependsOnTargets = " ResolveAssemblyReferencesDesignTime " >
2017-03-24 04:04:52 +08:00
< ItemGroup >
Move powershell to .NET Core 2.0 (#3556)
This change moves powershell to .NET Core 2.0. Major changes are:
1. PowerShell assemblies are now targeting `netcoreapp2.0`. We are using `microsoft.netcore.app-2.0.0-preview1-001913-00`, which is from dotnet-core build 4/4/17. We cannot target `netstandard2.0` because the packages `System.Reflection.Emit` and `System.Reflection.Emit.Lightweight`, which are needed for powershell class, cannot be referenced when targeting `netstandard2.0`.
2. Refactor code to remove most CLR stub types and extension types.
3. Update build scripts to enable CI builds. The `-cache` section is specified to depend on `appveyor.yml`, so the cache will be invalidated if `appveyor.yml` is changed.
4. Ship `netcoreapp` reference assemblies with powershell to fix the issues in `Add-Type` (#2764). By default `Add-Type` will reference all those reference assemblies when compiling C# code. If `-ReferenceAssembly` is specified, then we search reference assemblies first, then the framework runtime assemblies, and lastly the loaded assemblies (possibly a third-party one that was already loaded).
5. `dotnet publish` generates executable on Unix platforms, but doesn't set "x" permission and thus it cannot execute. Currently, the "x" permission is set in the build script, `dotnet/cli` issue [#6286](https://github.com/dotnet/cli/issues/6286) is tracking this.
6. Replace the use of some APIs with the ones that take `SecureString`.
7. osx.10.12 is required to update to `netcoreapp2.0` because `dotnet-cli` 2.0.0-preview only works on osx.10.12.
8. Add dependency to `System.ValueTuple` to work around a ambiguous type identity issue in coreclr. The issue is tracked by `dotnet/corefx` [#17797](https://github.com/dotnet/corefx/issues/17797). When moving to newer version of `netcoreapp2.0`, we need to verify if this dependency is still needed.
2017-04-18 02:52:38 +08:00
< _RefAssemblyPath Include = " %(_ReferencesFromRAR.ResolvedPath)%3B " Condition = " '%(_ReferencesFromRAR.Type)' == 'assembly' And '%(_ReferencesFromRAR.PackageName)' != 'Microsoft.Management.Infrastructure' " / >
2017-03-24 04:04:52 +08:00
< / ItemGroup >
Move powershell to .NET Core 2.0 (#3556)
This change moves powershell to .NET Core 2.0. Major changes are:
1. PowerShell assemblies are now targeting `netcoreapp2.0`. We are using `microsoft.netcore.app-2.0.0-preview1-001913-00`, which is from dotnet-core build 4/4/17. We cannot target `netstandard2.0` because the packages `System.Reflection.Emit` and `System.Reflection.Emit.Lightweight`, which are needed for powershell class, cannot be referenced when targeting `netstandard2.0`.
2. Refactor code to remove most CLR stub types and extension types.
3. Update build scripts to enable CI builds. The `-cache` section is specified to depend on `appveyor.yml`, so the cache will be invalidated if `appveyor.yml` is changed.
4. Ship `netcoreapp` reference assemblies with powershell to fix the issues in `Add-Type` (#2764). By default `Add-Type` will reference all those reference assemblies when compiling C# code. If `-ReferenceAssembly` is specified, then we search reference assemblies first, then the framework runtime assemblies, and lastly the loaded assemblies (possibly a third-party one that was already loaded).
5. `dotnet publish` generates executable on Unix platforms, but doesn't set "x" permission and thus it cannot execute. Currently, the "x" permission is set in the build script, `dotnet/cli` issue [#6286](https://github.com/dotnet/cli/issues/6286) is tracking this.
6. Replace the use of some APIs with the ones that take `SecureString`.
7. osx.10.12 is required to update to `netcoreapp2.0` because `dotnet-cli` 2.0.0-preview only works on osx.10.12.
8. Add dependency to `System.ValueTuple` to work around a ambiguous type identity issue in coreclr. The issue is tracked by `dotnet/corefx` [#17797](https://github.com/dotnet/corefx/issues/17797). When moving to newer version of `netcoreapp2.0`, we need to verify if this dependency is still needed.
2017-04-18 02:52:38 +08:00
< WriteLinesToFile File = " $( _DependencyFile ) " Lines = " @(_RefAssemblyPath) " Overwrite = " true " / >
2017-03-24 04:04:52 +08:00
< / Target >
< / Project >
' @
Set-Content -Path $GetDependenciesTargetPath -Value $GetDependenciesTargetValue -Force -Encoding Ascii
Push-Location " $PSScriptRoot /src/Microsoft.PowerShell.SDK "
2016-08-04 04:23:21 +08:00
try {
2017-03-24 04:04:52 +08:00
$ps_inc_file = " $PSScriptRoot /src/TypeCatalogGen/powershell.inc "
dotnet msbuild . \ Microsoft . PowerShell . SDK . csproj / t: _GetDependencies " /property:DesignTimeBuild=true;_DependencyFile= $ps_inc_file " / nologo
2016-08-04 04:23:21 +08:00
} finally {
2016-06-18 02:23:29 +08:00
Pop-Location
}
Push-Location " $PSScriptRoot /src/TypeCatalogGen "
2016-08-04 04:23:21 +08:00
try {
2016-06-18 02:23:29 +08:00
dotnet run . . / Microsoft . PowerShell . CoreCLR . AssemblyLoadContext / CorePsTypeCatalog . cs powershell . inc
2016-08-04 04:23:21 +08:00
} finally {
2016-06-18 02:23:29 +08:00
Pop-Location
}
}
2016-04-05 05:20:34 +08:00
function Start-ResGen
{
2016-06-15 18:42:54 +08:00
[ CmdletBinding ( ) ]
param ( )
2016-08-03 02:47:53 +08:00
# Add .NET CLI tools to PATH
Find-Dotnet
Push-Location " $PSScriptRoot /src/ResGen "
2016-08-04 04:23:21 +08:00
try {
2016-08-03 02:47:53 +08:00
Start-NativeExecution { dotnet run } | Write-Verbose
2016-08-04 04:23:21 +08:00
} finally {
2016-08-03 02:47:53 +08:00
Pop-Location
2016-04-05 05:20:34 +08:00
}
}
2016-04-02 13:01:05 +08:00
2016-06-21 02:59:14 +08:00
function Find-Dotnet ( ) {
$originalPath = $env:PATH
2017-07-24 03:29:33 +08:00
$dotnetPath = if ( $Environment . IsWindows ) {
2016-06-21 02:59:14 +08:00
" $env:LocalAppData \Microsoft\dotnet "
} else {
" $env:HOME /.dotnet "
}
if ( -not ( precheck 'dotnet' " Could not find 'dotnet', appending $dotnetPath to PATH. " ) ) {
$env:PATH + = [ IO.Path ] :: PathSeparator + $dotnetPath
}
if ( -not ( precheck 'dotnet' " Still could not find 'dotnet', restoring PATH. " ) ) {
$env:PATH = $originalPath
}
}
2016-07-01 07:02:07 +08:00
<#
2016-07-02 04:51:14 +08:00
This is one-time conversion . We use it for to turn GetEventResources . txt into GetEventResources . resx
2016-07-01 07:02:07 +08:00
. EXAMPLE Convert-TxtResourceToXml -Path Microsoft . PowerShell . Commands . Diagnostics \ resources
#>
function Convert-TxtResourceToXml
{
param (
[ string[] ] $Path
)
2016-08-04 04:23:21 +08:00
process {
2017-07-22 12:03:49 +08:00
$Path | ForEach-Object {
Get-ChildItem $_ -Filter " *.txt " | ForEach-Object {
2016-07-01 07:02:07 +08:00
$txtFile = $_ . FullName
$resxFile = Join-Path ( Split-Path $txtFile ) " $( $_ . BaseName ) .resx "
$resourceHashtable = ConvertFrom-StringData ( Get-Content -Raw $txtFile )
2017-07-22 12:03:49 +08:00
$resxContent = $resourceHashtable . GetEnumerator ( ) | ForEach-Object {
2016-07-01 07:02:07 +08:00
@ '
< data name = " {0} " xml : space = " preserve " >
< value > { 1 } < / value >
< / data >
' @ -f $_ . Key , $_ . Value
} | Out-String
Set-Content -Path $resxFile -Value ( $script:RESX_TEMPLATE -f $resxContent )
}
}
}
}
2016-06-22 07:54:57 +08:00
function script: Use-MSBuild {
2016-06-25 05:52:04 +08:00
# TODO: we probably should require a particular version of msbuild, if we are taking this dependency
# msbuild v14 and msbuild v4 behaviors are different for XAML generation
$frameworkMsBuildLocation = " ${env:SystemRoot} \Microsoft.Net\Framework\v4.0.30319\msbuild "
2016-06-23 10:46:16 +08:00
2016-06-25 05:52:04 +08:00
$msbuild = get-command msbuild -ErrorAction SilentlyContinue
2016-08-04 04:23:21 +08:00
if ( $msbuild ) {
2016-06-25 05:52:04 +08:00
# all good, nothing to do
return
2016-06-22 07:54:57 +08:00
}
2016-06-23 10:46:16 +08:00
2016-08-04 04:23:21 +08:00
if ( -not ( Test-Path $frameworkMsBuildLocation ) ) {
2016-06-25 05:52:04 +08:00
throw " msbuild not found in ' $frameworkMsBuildLocation '. Install Visual Studio 2015. "
2016-06-23 10:46:16 +08:00
}
2016-06-25 05:52:04 +08:00
Set-Alias msbuild $frameworkMsBuildLocation -Scope Script
2016-06-22 07:54:57 +08:00
}
2016-04-02 13:01:05 +08:00
function script: log([string]$message ) {
Write-Host -Foreground Green $message
2016-08-27 04:46:03 +08:00
#reset colors for older package to at return to default after error message on a compilation error
2016-08-04 04:23:21 +08:00
[ console ] :: ResetColor ( )
2016-04-02 13:01:05 +08:00
}
2016-12-02 03:23:14 +08:00
function script: logerror([string]$message ) {
Write-Host -Foreground Red $message
#reset colors for older package to at return to default after error message on a compilation error
[ console ] :: ResetColor ( )
}
2016-04-02 13:01:05 +08:00
function script: precheck([string]$command , [ string ] $missedMessage ) {
$c = Get-Command $command -ErrorAction SilentlyContinue
if ( -not $c ) {
2017-07-26 07:50:27 +08:00
if ( -not [ string ] :: IsNullOrEmpty ( $missedMessage ) )
2016-07-22 06:53:36 +08:00
{
Write-Warning $missedMessage
}
2016-04-02 13:01:05 +08:00
return $false
} else {
return $true
}
}
2016-04-20 07:59:03 +08:00
# this function wraps native command Execution
# for more information, read https://mnaoumov.wordpress.com/2015/01/11/execution-of-external-commands-in-powershell-done-right/
2016-11-20 15:32:42 +08:00
function script: Start-NativeExecution([scriptblock]$sb , [ switch ] $IgnoreExitcode )
2016-04-20 07:59:03 +08:00
{
$backupEAP = $script:ErrorActionPreference
$script:ErrorActionPreference = " Continue "
2016-08-04 04:23:21 +08:00
try {
2016-04-20 07:59:03 +08:00
& $sb
2016-08-27 04:46:03 +08:00
# note, if $sb doesn't have a native invocation, $LASTEXITCODE will
2016-04-20 07:59:03 +08:00
# point to the obsolete value
2016-11-20 15:32:42 +08:00
if ( $LASTEXITCODE -ne 0 -and -not $IgnoreExitcode ) {
2016-05-19 05:30:24 +08:00
throw " Execution of { $sb } failed with exit code $LASTEXITCODE "
2016-04-20 07:59:03 +08:00
}
2016-08-04 04:23:21 +08:00
} finally {
2016-04-20 07:59:03 +08:00
$script:ErrorActionPreference = $backupEAP
}
}
2016-04-05 05:20:34 +08:00
2016-06-28 07:04:57 +08:00
# Builds coming out of this project can have version number as 'a.b.c' OR 'a.b.c-d-f'
# This function converts the above version into major.minor[.build[.revision]] format
function Get-PackageVersionAsMajorMinorBuildRevision
{
[ CmdletBinding ( ) ]
param (
# Version of the Package
[ Parameter ( Mandatory = $true ) ]
[ ValidateNotNullOrEmpty ( ) ]
[ string ] $Version
)
Write-Verbose " Extract the version in the form of major.minor[.build[.revision]] for $Version "
$packageVersionTokens = $Version . Split ( '-' )
$packageVersion = ( [ regex ] :: matches ( $Version , " \d+(\.\d+)+ " ) ) [ 0 ] . value
2016-08-04 04:23:21 +08:00
if ( 1 -eq $packageVersionTokens . Count ) {
2016-06-28 07:04:57 +08:00
# In case the input is of the form a.b.c, add a '0' at the end for revision field
2016-07-27 12:22:37 +08:00
$packageVersion = $packageVersion + '.0'
2016-08-04 04:23:21 +08:00
} elseif ( 1 -lt $packageVersionTokens . Count ) {
2016-06-28 07:04:57 +08:00
# We have all the four fields
2016-07-27 12:22:37 +08:00
$packageBuildTokens = ( [ regex ] :: Matches ( $packageVersionTokens [ 1 ] , " \d+ " ) ) [ 0 ] . value
2016-09-29 01:47:16 +08:00
$packageVersion = $packageVersion + '.' + $packageBuildTokens
2016-06-28 07:04:57 +08:00
}
2016-12-15 01:28:38 +08:00
$packageVersion
2016-06-28 07:04:57 +08:00
}
2016-06-07 04:20:00 +08:00
function New-MSIPackage
2016-05-25 05:23:38 +08:00
{
[ CmdletBinding ( ) ]
param (
2017-01-17 05:31:14 +08:00
2016-05-25 05:23:38 +08:00
# Name of the Product
[ ValidateNotNullOrEmpty ( ) ]
2016-09-29 01:47:16 +08:00
[ string ] $ProductName = 'PowerShell' ,
# Suffix of the Name
[ string ] $ProductNameSuffix ,
2016-05-25 05:23:38 +08:00
# Version of the Product
[ Parameter ( Mandatory = $true ) ]
[ ValidateNotNullOrEmpty ( ) ]
[ string ] $ProductVersion ,
# Product Guid needs to change for every version to support SxS install
[ ValidateNotNullOrEmpty ( ) ]
[ string ] $ProductGuid = 'a5249933-73a1-4b10-8a4c-13c98bdc16fe' ,
# Source Path to the Product Files - required to package the contents into an MSI
[ Parameter ( Mandatory = $true ) ]
[ ValidateNotNullOrEmpty ( ) ]
[ string ] $ProductSourcePath ,
# File describing the MSI Package creation semantics
[ ValidateNotNullOrEmpty ( ) ]
2016-09-29 01:47:16 +08:00
[ string ] $ProductWxsPath = " $PSScriptRoot \assets\Product.wxs " ,
2016-06-28 02:39:49 +08:00
# Path to Assets folder containing artifacts such as icons, images
[ Parameter ( Mandatory = $true ) ]
[ ValidateNotNullOrEmpty ( ) ]
2017-01-17 05:31:14 +08:00
[ string ] $AssetsPath ,
2016-05-25 05:23:38 +08:00
2016-08-05 04:30:00 +08:00
# Path to license.rtf file - for the EULA
[ Parameter ( Mandatory = $true ) ]
[ ValidateNotNullOrEmpty ( ) ]
2016-11-17 02:32:21 +08:00
[ string ] $LicenseFilePath ,
# Architecture to use when creating the MSI
[ Parameter ( Mandatory = $true ) ]
[ ValidateSet ( " x86 " , " x64 " ) ]
[ ValidateNotNullOrEmpty ( ) ]
2017-08-02 05:35:50 +08:00
[ string ] $ProductTargetArchitecture ,
2016-08-05 04:30:00 +08:00
2017-08-02 05:35:50 +08:00
# Force overwrite of package
[ Switch ] $Force
2016-09-29 01:47:16 +08:00
)
2016-05-25 05:23:38 +08:00
2017-05-23 13:28:31 +08:00
## AppVeyor base image might update the version for Wix. Hence, we should
## not hard code version numbers.
$wixToolsetBinPath = " $ {env:ProgramFiles(x86)}\WiX Toolset *\bin "
2016-05-25 05:23:38 +08:00
Write-Verbose " Ensure Wix Toolset is present on the machine @ $wixToolsetBinPath "
2016-08-05 04:30:00 +08:00
if ( -not ( Test-Path $wixToolsetBinPath ) )
{
2016-09-29 01:47:16 +08:00
throw " Wix Toolset is required to create MSI package. Please install Wix from https://wix.codeplex.com/downloads/get/1540240 "
2016-05-25 05:23:38 +08:00
}
2017-05-23 13:28:31 +08:00
## Get the latest if multiple versions exist.
$wixToolsetBinPath = ( Get-ChildItem $wixToolsetBinPath ) . FullName | Sort-Object -Descending | Select-Object -First 1
2016-05-25 05:23:38 +08:00
Write-Verbose " Initialize Wix executables - Heat.exe, Candle.exe, Light.exe "
$wixHeatExePath = Join-Path $wixToolsetBinPath " Heat.exe "
$wixCandleExePath = Join-Path $wixToolsetBinPath " Candle.exe "
$wixLightExePath = Join-Path $wixToolsetBinPath " Light.exe "
2016-06-28 02:39:49 +08:00
2016-12-15 01:28:38 +08:00
$ProductSemanticVersion = Get-PackageSemanticVersion -Version $ProductVersion
$ProductVersion = Get-PackageVersionAsMajorMinorBuildRevision -Version $ProductVersion
2017-01-17 05:31:14 +08:00
2016-06-28 02:39:49 +08:00
$assetsInSourcePath = Join-Path $ProductSourcePath 'assets'
2016-09-29 01:47:16 +08:00
New-Item $assetsInSourcePath -type directory -Force | Write-Verbose
2016-06-28 02:39:49 +08:00
2017-01-17 05:31:14 +08:00
Write-Verbose " Place dependencies such as icons to $assetsInSourcePath "
2016-06-28 02:39:49 +08:00
Copy-Item " $AssetsPath \*.ico " $assetsInSourcePath -Force
2017-01-17 05:31:14 +08:00
2017-03-30 04:36:44 +08:00
$productVersionWithName = $ProductName + '_' + $ProductVersion
$productSemanticVersionWithName = $ProductName + '-' + $ProductSemanticVersion
2017-01-17 05:31:14 +08:00
2016-12-15 01:28:38 +08:00
Write-Verbose " Create MSI for Product $productSemanticVersionWithName "
2016-05-25 05:23:38 +08:00
[ Environment ] :: SetEnvironmentVariable ( " ProductSourcePath " , $ProductSourcePath , " Process " )
2016-12-15 01:28:38 +08:00
# These variables are used by Product.wxs in assets directory
2016-05-25 05:23:38 +08:00
[ Environment ] :: SetEnvironmentVariable ( " ProductName " , $ProductName , " Process " )
[ Environment ] :: SetEnvironmentVariable ( " ProductGuid " , $ProductGuid , " Process " )
[ Environment ] :: SetEnvironmentVariable ( " ProductVersion " , $ProductVersion , " Process " )
2017-03-30 04:36:44 +08:00
[ Environment ] :: SetEnvironmentVariable ( " ProductSemanticVersion " , $ProductSemanticVersion , " Process " )
2017-04-19 07:51:18 +08:00
[ Environment ] :: SetEnvironmentVariable ( " ProductVersionWithName " , $productVersionWithName , " Process " )
2016-11-17 02:32:21 +08:00
[ Environment ] :: SetEnvironmentVariable ( " ProductTargetArchitecture " , $ProductTargetArchitecture , " Process " )
$ProductProgFilesDir = " ProgramFiles64Folder "
if ( $ProductTargetArchitecture -eq " x86 " )
{
$ProductProgFilesDir = " ProgramFilesFolder "
}
[ Environment ] :: SetEnvironmentVariable ( " ProductProgFilesDir " , $ProductProgFilesDir , " Process " )
2016-05-25 05:23:38 +08:00
$wixFragmentPath = ( Join-path $env:Temp " Fragment.wxs " )
$wixObjProductPath = ( Join-path $env:Temp " Product.wixobj " )
$wixObjFragmentPath = ( Join-path $env:Temp " Fragment.wixobj " )
2016-09-29 01:47:16 +08:00
2016-12-15 01:28:38 +08:00
$packageName = $productSemanticVersionWithName
2016-09-29 01:47:16 +08:00
if ( $ProductNameSuffix ) {
$packageName + = " - $ProductNameSuffix "
}
2017-01-17 05:31:14 +08:00
$msiLocationPath = Join-Path $pwd " $packageName .msi "
2017-08-02 05:35:50 +08:00
if ( ! $Force . IsPresent -and ( Test-Path -Path $msiLocationPath ) )
{
Write-Error -Message " Package already exists, use -Force to overwrite, path: $msiLocationPath " -ErrorAction Stop
}
2016-05-25 05:23:38 +08:00
2016-05-25 06:02:24 +08:00
& $wixHeatExePath dir $ProductSourcePath -dr $productVersionWithName -cg $productVersionWithName -gg -sfrag -srd -scom -sreg -out $wixFragmentPath -var env . ProductSourcePath -v | Write-Verbose
2017-07-15 09:10:35 +08:00
& $wixCandleExePath " $ProductWxsPath " " $wixFragmentPath " -out ( Join-Path " $env:Temp " " \\ " ) -ext WixUIExtension -ext WixUtilExtension -arch x64 -v | Write-Verbose
& $wixLightExePath -out $msiLocationPath $wixObjProductPath $wixObjFragmentPath -ext WixUIExtension -ext WixUtilExtension -dWixUILicenseRtf = " $LicenseFilePath " -v | Write-Verbose
2017-01-17 05:31:14 +08:00
2016-05-25 05:41:23 +08:00
Remove-Item -ErrorAction SilentlyContinue * . wixpdb -Force
2016-05-25 05:23:38 +08:00
2017-09-12 03:36:24 +08:00
if ( Test-Path $msiLocationPath )
{
Write-Verbose " You can find the MSI @ $msiLocationPath " -Verbose
$msiLocationPath
}
else
{
throw " Failed to create $msiLocationPath "
}
2016-05-25 05:23:38 +08:00
}
2016-08-03 04:33:51 +08:00
function Start-CrossGen {
[ CmdletBinding ( ) ]
param (
[ Parameter ( Mandatory = $true ) ]
[ ValidateNotNullOrEmpty ( ) ]
[ String ]
2016-11-21 04:59:50 +08:00
$PublishPath ,
[ Parameter ( Mandatory = $true ) ]
[ ValidateSet ( " ubuntu.14.04-x64 " ,
" ubuntu.16.04-x64 " ,
" debian.8-x64 " ,
" centos.7-x64 " ,
2017-01-07 02:04:18 +08:00
" fedora.24-x64 " ,
2016-11-21 04:59:50 +08:00
" win7-x86 " ,
" win7-x64 " ,
" win81-x64 " ,
" win10-x64 " ,
2017-03-07 09:30:14 +08:00
" osx.10.12-x64 " ,
2017-03-23 05:19:51 +08:00
" opensuse.13.2-x64 " ,
2017-09-12 03:16:58 +08:00
" opensuse.42.1-x64 " ,
" linux-arm " ) ]
2016-11-21 04:59:50 +08:00
[ string ]
$Runtime
2016-08-03 04:33:51 +08:00
)
2016-08-04 03:35:58 +08:00
2016-08-03 04:33:51 +08:00
function Generate-CrossGenAssembly {
param (
[ Parameter ( Mandatory = $true ) ]
[ ValidateNotNullOrEmpty ( ) ]
[ String ]
$AssemblyPath ,
[ Parameter ( Mandatory = $true ) ]
[ ValidateNotNullOrEmpty ( ) ]
[ String ]
$CrossgenPath
)
$outputAssembly = $AssemblyPath . Replace ( " .dll " , " .ni.dll " )
$platformAssembliesPath = Split-Path $AssemblyPath -Parent
$crossgenFolder = Split-Path $CrossgenPath
$niAssemblyName = Split-Path $outputAssembly -Leaf
2016-08-04 03:35:58 +08:00
try {
2016-08-03 04:33:51 +08:00
Push-Location $crossgenFolder
# Generate the ngen assembly
2016-08-04 03:35:58 +08:00
Write-Verbose " Generating assembly $niAssemblyName "
2016-08-03 04:33:51 +08:00
Start-NativeExecution {
2016-08-03 15:19:39 +08:00
& $CrossgenPath / MissingDependenciesOK / in $AssemblyPath / out $outputAssembly / Platform_Assemblies_Paths $platformAssembliesPath
} | Write-Verbose
2016-08-04 03:35:58 +08:00
2016-08-03 04:33:51 +08:00
<#
# TODO: Generate the pdb for the ngen binary - currently, there is a hard dependency on diasymreader.dll, which is available at %windir%\Microsoft.NET\Framework\v4.0.30319.
# However, we still need to figure out the prerequisites on Linux.
Start-NativeExecution {
2016-08-03 15:19:39 +08:00
& $CrossgenPath / Platform_Assemblies_Paths $platformAssembliesPath / CreatePDB $platformAssembliesPath / lines $platformAssembliesPath $niAssemblyName
} | Write-Verbose
2016-08-03 04:33:51 +08:00
#>
2016-08-04 03:35:58 +08:00
} finally {
2016-08-03 04:33:51 +08:00
Pop-Location
}
}
2016-08-04 03:35:58 +08:00
if ( -not ( Test-Path $PublishPath ) ) {
2016-08-03 04:33:51 +08:00
throw " Path ' $PublishPath ' does not exist. "
}
2016-08-04 03:35:58 +08:00
# Get the path to crossgen
2017-07-24 03:29:33 +08:00
$crossGenExe = if ( $Environment . IsWindows ) { " crossgen.exe " } else { " crossgen " }
2016-08-03 04:33:51 +08:00
2016-08-04 03:05:26 +08:00
# The crossgen tool is only published for these particular runtimes
2017-07-24 03:29:33 +08:00
$crossGenRuntime = if ( $Environment . IsWindows ) {
2016-11-21 04:59:50 +08:00
if ( $Runtime -match " -x86 " ) {
2017-05-05 08:09:03 +08:00
" win-x86 "
2016-11-21 04:59:50 +08:00
} else {
2017-05-05 08:09:03 +08:00
" win-x64 "
2016-11-21 04:59:50 +08:00
}
2017-09-12 03:16:58 +08:00
} elseif ( $Runtime -eq " linux-arm " ) {
throw " crossgen is not available for 'linux-arm' "
2017-07-24 03:29:33 +08:00
} elseif ( $Environment . IsLinux ) {
Move powershell to .NET Core 2.0 (#3556)
This change moves powershell to .NET Core 2.0. Major changes are:
1. PowerShell assemblies are now targeting `netcoreapp2.0`. We are using `microsoft.netcore.app-2.0.0-preview1-001913-00`, which is from dotnet-core build 4/4/17. We cannot target `netstandard2.0` because the packages `System.Reflection.Emit` and `System.Reflection.Emit.Lightweight`, which are needed for powershell class, cannot be referenced when targeting `netstandard2.0`.
2. Refactor code to remove most CLR stub types and extension types.
3. Update build scripts to enable CI builds. The `-cache` section is specified to depend on `appveyor.yml`, so the cache will be invalidated if `appveyor.yml` is changed.
4. Ship `netcoreapp` reference assemblies with powershell to fix the issues in `Add-Type` (#2764). By default `Add-Type` will reference all those reference assemblies when compiling C# code. If `-ReferenceAssembly` is specified, then we search reference assemblies first, then the framework runtime assemblies, and lastly the loaded assemblies (possibly a third-party one that was already loaded).
5. `dotnet publish` generates executable on Unix platforms, but doesn't set "x" permission and thus it cannot execute. Currently, the "x" permission is set in the build script, `dotnet/cli` issue [#6286](https://github.com/dotnet/cli/issues/6286) is tracking this.
6. Replace the use of some APIs with the ones that take `SecureString`.
7. osx.10.12 is required to update to `netcoreapp2.0` because `dotnet-cli` 2.0.0-preview only works on osx.10.12.
8. Add dependency to `System.ValueTuple` to work around a ambiguous type identity issue in coreclr. The issue is tracked by `dotnet/corefx` [#17797](https://github.com/dotnet/corefx/issues/17797). When moving to newer version of `netcoreapp2.0`, we need to verify if this dependency is still needed.
2017-04-18 02:52:38 +08:00
" linux-x64 "
2017-09-08 01:34:40 +08:00
} elseif ( $Environment . IsMacOS ) {
2017-05-05 08:09:03 +08:00
" osx-x64 "
2016-08-04 03:05:26 +08:00
}
if ( -not $crossGenRuntime ) {
throw " crossgen is not available for this platform "
}
2016-10-13 01:24:08 +08:00
# Get the CrossGen.exe for the correct runtime with the latest version
2017-07-24 03:29:33 +08:00
$crossGenPath = Get-ChildItem $script:Environment . nugetPackagesRoot $crossGenExe -Recurse | `
2016-10-13 01:24:08 +08:00
Where-Object { $_ . FullName -match $crossGenRuntime } | `
Sort-Object -Property FullName -Descending | `
Select-Object -First 1 | `
ForEach-Object { $_ . FullName }
2016-08-04 03:05:26 +08:00
if ( -not $crossGenPath ) {
2016-08-03 04:33:51 +08:00
throw " Unable to find latest version of crossgen.exe. 'Please run Start-PSBuild -Clean' first, and then try again. "
}
2016-11-21 04:59:50 +08:00
Write-Verbose " Matched CrossGen.exe: $crossGenPath " -Verbose
2016-08-03 04:33:51 +08:00
# Crossgen.exe requires the following assemblies:
# mscorlib.dll
# System.Private.CoreLib.dll
2016-08-04 03:35:58 +08:00
# clrjit.dll on Windows or libclrjit.so/dylib on Linux/OS X
2016-08-03 04:33:51 +08:00
$crossGenRequiredAssemblies = @ ( " mscorlib.dll " , " System.Private.CoreLib.dll " )
2016-08-04 03:35:58 +08:00
2017-07-24 03:29:33 +08:00
$crossGenRequiredAssemblies + = if ( $Environment . IsWindows ) {
2016-08-04 03:35:58 +08:00
" clrjit.dll "
2017-07-24 03:29:33 +08:00
} elseif ( $Environment . IsLinux ) {
2016-08-04 03:35:58 +08:00
" libclrjit.so "
2017-09-08 01:34:40 +08:00
} elseif ( $Environment . IsMacOS ) {
2016-08-04 03:35:58 +08:00
" libclrjit.dylib "
2016-08-03 04:33:51 +08:00
}
2016-08-04 03:35:58 +08:00
# Make sure that all dependencies required by crossgen are at the directory.
2016-08-03 04:33:51 +08:00
$crossGenFolder = Split-Path $crossGenPath
2016-08-04 03:35:58 +08:00
foreach ( $assemblyName in $crossGenRequiredAssemblies ) {
if ( -not ( Test-Path " $crossGenFolder \ $assemblyName " ) ) {
2016-08-03 04:33:51 +08:00
Copy-Item -Path " $PublishPath \ $assemblyName " -Destination $crossGenFolder -Force -ErrorAction Stop
}
}
2017-05-16 14:34:32 +08:00
# Common assemblies used by Add-Type or assemblies with high JIT and no pdbs to crossgen
2017-02-04 07:19:05 +08:00
$commonAssembliesForAddType = @ (
" Microsoft.CodeAnalysis.CSharp.dll "
" Microsoft.CodeAnalysis.dll "
2017-05-16 14:34:32 +08:00
" System.Linq.Expressions.dll "
" Microsoft.CSharp.dll "
" System.Runtime.Extensions.dll "
" System.Linq.dll "
" System.Collections.Concurrent.dll "
" System.Collections.dll "
" Newtonsoft.Json.dll "
" System.IO.FileSystem.dll "
" System.Diagnostics.Process.dll "
" System.Threading.Tasks.Parallel.dll "
" System.Security.AccessControl.dll "
" System.Text.Encoding.CodePages.dll "
" System.Private.Uri.dll "
" System.Threading.dll "
" System.Security.Principal.Windows.dll "
" System.Console.dll "
" Microsoft.Win32.Registry.dll "
" System.IO.Pipes.dll "
" System.Diagnostics.FileVersionInfo.dll "
" System.Collections.Specialized.dll "
2017-02-04 07:19:05 +08:00
)
2016-08-04 03:35:58 +08:00
# Common PowerShell libraries to crossgen
2016-08-03 15:19:39 +08:00
$psCoreAssemblyList = @ (
" Microsoft.PowerShell.Commands.Utility.dll " ,
" Microsoft.PowerShell.Commands.Management.dll " ,
" Microsoft.PowerShell.Security.dll " ,
" Microsoft.PowerShell.CoreCLR.AssemblyLoadContext.dll " ,
" Microsoft.PowerShell.CoreCLR.Eventing.dll " ,
" Microsoft.PowerShell.ConsoleHost.dll " ,
" Microsoft.PowerShell.PSReadLine.dll " ,
" System.Management.Automation.dll "
)
2016-08-03 04:33:51 +08:00
2016-08-04 03:35:58 +08:00
# Add Windows specific libraries
2017-07-24 03:29:33 +08:00
if ( $Environment . IsWindows ) {
2016-08-03 15:19:39 +08:00
$psCoreAssemblyList + = @ (
" Microsoft.WSMan.Management.dll " ,
" Microsoft.WSMan.Runtime.dll " ,
" Microsoft.PowerShell.Commands.Diagnostics.dll " ,
" Microsoft.Management.Infrastructure.CimCmdlets.dll "
)
}
2017-02-04 07:19:05 +08:00
$fullAssemblyList = $commonAssembliesForAddType + $psCoreAssemblyList
foreach ( $assemblyName in $fullAssemblyList ) {
2016-08-03 04:33:51 +08:00
$assemblyPath = Join-Path $PublishPath $assemblyName
2016-08-03 15:19:39 +08:00
Generate-CrossGenAssembly -CrossgenPath $crossGenPath -AssemblyPath $assemblyPath
}
2016-08-03 04:33:51 +08:00
2016-10-19 04:12:51 +08:00
#
# With the latest dotnet.exe, the default load context is only able to load TPAs, and TPA
# only contains IL assembly names. In order to make the default load context able to load
# the NI PS assemblies, we need to replace the IL PS assemblies with the corresponding NI
# PS assemblies, but with the same IL assembly names.
#
Write-Verbose " PowerShell Ngen assemblies have been generated. Deploying ... " -Verbose
2017-02-04 07:19:05 +08:00
foreach ( $assemblyName in $fullAssemblyList ) {
2016-08-03 15:19:39 +08:00
# Remove the IL assembly and its symbols.
2016-08-04 08:35:05 +08:00
$assemblyPath = Join-Path $PublishPath $assemblyName
2016-10-19 04:12:51 +08:00
$symbolsPath = [ System.IO.Path ] :: ChangeExtension ( $assemblyPath , " .pdb " )
2017-02-04 07:19:05 +08:00
2016-10-19 04:12:51 +08:00
Remove-Item $assemblyPath -Force -ErrorAction Stop
2017-02-04 07:19:05 +08:00
# No symbols are available for Microsoft.CodeAnalysis.CSharp.dll, Microsoft.CodeAnalysis.dll,
# Microsoft.CodeAnalysis.VisualBasic.dll, and Microsoft.CSharp.dll.
if ( $commonAssembliesForAddType -notcontains $assemblyName ) {
Remove-Item $symbolsPath -Force -ErrorAction Stop
}
2016-10-19 04:12:51 +08:00
# Rename the corresponding ni.dll assembly to be the same as the IL assembly
$niAssemblyPath = [ System.IO.Path ] :: ChangeExtension ( $assemblyPath , " ni.dll " )
Rename-Item $niAssemblyPath $assemblyPath -Force -ErrorAction Stop
2016-08-03 04:33:51 +08:00
}
}
2016-07-01 07:02:07 +08:00
2017-01-18 05:00:52 +08:00
# Cleans the PowerShell repo - everything but the root folder
2016-09-01 03:13:05 +08:00
function Clear-PSRepo
{
[ CmdletBinding ( ) ]
2017-01-18 05:00:52 +08:00
param ( )
Get-ChildItem $PSScriptRoot \ * -Directory | ForEach-Object {
2017-01-17 05:31:14 +08:00
Write-Verbose " Cleaning $_ ... "
2016-09-01 03:13:05 +08:00
git clean -fdX $_
}
}
2016-11-18 05:54:38 +08:00
# Install PowerShell modules such as PackageManagement, PowerShellGet
function Restore-PSModule
{
[ CmdletBinding ( ) ]
param (
[ Parameter ( Mandatory = $true ) ]
[ ValidateNotNullOrEmpty ( ) ]
2016-11-20 15:11:56 +08:00
[ string[] ] $Name ,
2016-11-18 05:54:38 +08:00
[ Parameter ( Mandatory = $true ) ]
[ ValidateNotNullOrEmpty ( ) ]
[ string ] $Destination ,
2016-11-19 09:51:29 +08:00
[ string ] $SourceLocation = " https://powershell.myget.org/F/powershellmodule/api/v2/ " ,
2016-11-18 05:54:38 +08:00
[ string ] $RequiredVersion
)
$needRegister = $true
$RepositoryName = " mygetpsmodule "
# Check if the PackageManagement works in the base-oS or PowerShellCore
Get-PackageProvider -Name NuGet -ForceBootstrap -Verbose: $VerbosePreference
2016-11-19 09:51:29 +08:00
Get-PackageProvider -Name PowerShellGet -Verbose: $VerbosePreference
2016-11-18 05:54:38 +08:00
# Get the existing registered PowerShellGet repositories
$psrepos = PowerShellGet \ Get-PSRepository
foreach ( $repo in $psrepos )
{
if ( ( $repo . SourceLocation -eq $SourceLocation ) -or ( $repo . SourceLocation . TrimEnd ( " / " ) -eq $SourceLocation . TrimEnd ( " / " ) ) )
{
# found a registered repository that matches the source location
$needRegister = $false
$RepositoryName = $repo . Name
break
}
}
if ( $needRegister )
{
$regVar = PowerShellGet \ Get-PSRepository -Name $RepositoryName -ErrorAction SilentlyContinue
if ( $regVar )
{
PowerShellGet \ UnRegister-PSRepository -Name $RepositoryName
}
log " Registering PSRepository with name: $RepositoryName and sourcelocation: $SourceLocation "
PowerShellGet \ Register-PSRepository -Name $RepositoryName -SourceLocation $SourceLocation -ErrorVariable ev -verbose
if ( $ev )
{
throw ( " Failed to register repository '{0}' " -f $RepositoryName )
}
$regVar = PowerShellGet \ Get-PSRepository -Name $RepositoryName
if ( -not $regVar )
{
throw ( " '{0}' is not registered " -f $RepositoryName )
}
}
2016-11-22 09:36:51 +08:00
log ( " Name='{0}', Destination='{1}', Repository='{2}' " -f ( $Name -join ',' ) , $Destination , $RepositoryName )
2016-11-18 05:54:38 +08:00
2017-01-11 06:42:27 +08:00
# do not output progress
$ProgressPreference = " SilentlyContinue "
2016-11-20 15:11:56 +08:00
$Name | ForEach-Object {
2016-11-18 05:54:38 +08:00
2016-11-20 15:11:56 +08:00
$command = @ {
Name = $_
Path = $Destination
Repository = $RepositoryName
}
2016-11-18 05:54:38 +08:00
2016-11-20 15:11:56 +08:00
if ( $RequiredVersion )
{
$command . Add ( " RequiredVersion " , $RequiredVersion )
}
# pull down the module
2016-11-22 09:36:51 +08:00
log " running save-module $_ "
2016-12-17 14:16:03 +08:00
PowerShellGet \ Save-Module @command -Force
2017-01-17 05:31:14 +08:00
2016-11-22 09:36:51 +08:00
# Remove PSGetModuleInfo.xml file
Find-Module -Name $_ -Repository $RepositoryName -IncludeDependencies | ForEach-Object {
2016-12-17 14:16:03 +08:00
Remove-Item -Path $Destination \ $ ( $_ . Name ) \ * \ PSGetModuleInfo . xml -Force
2016-11-22 09:36:51 +08:00
}
2016-11-20 15:11:56 +08:00
}
2016-11-18 05:54:38 +08:00
# Clean up
if ( $needRegister )
{
2016-11-19 09:51:29 +08:00
$regVar = PowerShellGet \ Get-PSRepository -Name $RepositoryName -ErrorAction SilentlyContinue
if ( $regVar )
{
log " Unregistering PSRepository with name: $RepositoryName "
PowerShellGet \ UnRegister-PSRepository -Name $RepositoryName
}
2016-11-18 05:54:38 +08:00
}
}
2016-09-01 03:13:05 +08:00
2016-07-01 07:02:07 +08:00
$script:RESX_TEMPLATE = @ '
< ? xml version = " 1.0 " encoding = " utf-8 " ? >
< root >
2016-08-04 04:23:21 +08:00
< ! - -
Microsoft ResX Schema
2016-07-01 07:02:07 +08:00
Version 2.0
2016-08-04 04:23:21 +08:00
The primary goals of this format is to allow a simple XML format
that is mostly human readable . The generation and parsing of the
various data types are done through the TypeConverter classes
2016-07-01 07:02:07 +08:00
associated with the data types .
2016-08-04 04:23:21 +08:00
2016-07-01 07:02:07 +08:00
Example :
2016-08-04 04:23:21 +08:00
2016-07-01 07:02:07 +08:00
. . . ado . net / XML headers & schema . . .
< resheader name = " resmimetype " > text / microsoft-resx < / resheader >
< resheader name = " version " > 2.0 < / resheader >
< resheader name = " reader " > System . Resources . ResXResourceReader , System . Windows . Forms , . . . < / resheader >
< resheader name = " writer " > System . Resources . ResXResourceWriter , System . Windows . Forms , . . . < / resheader >
< data name = " Name1 " > < value > this is my long string < / value > < comment > this is a comment < / comment > < / data >
< data name = " Color1 " type = " System.Drawing.Color, System.Drawing " > Blue < / data >
< data name = " Bitmap1 " mimetype = " application/x-microsoft.net.object.binary.base64 " >
< value > [ base64 mime encoded serialized .NET Framework object ] < / value >
< / data >
< data name = " Icon1 " type = " System.Drawing.Icon, System.Drawing " mimetype = " application/x-microsoft.net.object.bytearray.base64 " >
< value > [ base64 mime encoded string representing a byte array form of the .NET Framework object ] < / value >
< comment > This is a comment < / comment >
< / data >
2016-08-04 04:23:21 +08:00
There are any number of " resheader " rows that contain simple
2016-07-01 07:02:07 +08:00
name / value pairs .
2016-08-04 04:23:21 +08:00
Each data row contains a name , and value . The row also contains a
type or mimetype . Type corresponds to a . NET class that support
text / value conversion through the TypeConverter architecture .
Classes that don ' t support this are serialized and stored with the
2016-07-01 07:02:07 +08:00
mimetype set .
2016-08-04 04:23:21 +08:00
The mimetype is used for serialized objects , and tells the
ResXResourceReader how to depersist the object . This is currently not
2016-07-01 07:02:07 +08:00
extensible . For a given mimetype the value must be set accordingly :
2016-08-04 04:23:21 +08:00
Note - application / x-microsoft . net . object . binary . base64 is the format
that the ResXResourceWriter will generate , however the reader can
2016-07-01 07:02:07 +08:00
read any of the formats listed below .
2016-08-04 04:23:21 +08:00
2016-07-01 07:02:07 +08:00
mimetype : application / x-microsoft . net . object . binary . base64
2016-08-04 04:23:21 +08:00
value : The object must be serialized with
2016-07-01 07:02:07 +08:00
: System . Runtime . Serialization . Formatters . Binary . BinaryFormatter
: and then encoded with base64 encoding .
2016-08-04 04:23:21 +08:00
2016-07-01 07:02:07 +08:00
mimetype : application / x-microsoft . net . object . soap . base64
2016-08-04 04:23:21 +08:00
value : The object must be serialized with
2016-07-01 07:02:07 +08:00
: System . Runtime . Serialization . Formatters . Soap . SoapFormatter
: and then encoded with base64 encoding .
mimetype : application / x-microsoft . net . object . bytearray . base64
2016-08-04 04:23:21 +08:00
value : The object must be serialized into a byte array
2016-07-01 07:02:07 +08:00
: using a System . ComponentModel . TypeConverter
: and then encoded with base64 encoding .
- - >
< xsd : schema id = " root " xmlns = " " xmlns : xsd = " http://www.w3.org/2001/XMLSchema " xmlns : msdata = " urn:schemas-microsoft-com:xml-msdata " >
< xsd : import namespace = " http://www.w3.org/XML/1998/namespace " / >
< xsd : element name = " root " msdata : IsDataSet = " true " >
< xsd : complexType >
< xsd : choice maxOccurs = " unbounded " >
< xsd : element name = " metadata " >
< xsd : complexType >
< xsd : sequence >
< xsd : element name = " value " type = " xsd:string " minOccurs = " 0 " / >
< / xsd : sequence >
< xsd : attribute name = " name " use = " required " type = " xsd:string " / >
< xsd : attribute name = " type " type = " xsd:string " / >
< xsd : attribute name = " mimetype " type = " xsd:string " / >
< xsd : attribute ref = " xml:space " / >
< / xsd : complexType >
< / xsd : element >
< xsd : element name = " assembly " >
< xsd : complexType >
< xsd : attribute name = " alias " type = " xsd:string " / >
< xsd : attribute name = " name " type = " xsd:string " / >
< / xsd : complexType >
< / xsd : element >
< xsd : element name = " data " >
< xsd : complexType >
< xsd : sequence >
< xsd : element name = " value " type = " xsd:string " minOccurs = " 0 " msdata : Ordinal = " 1 " / >
< xsd : element name = " comment " type = " xsd:string " minOccurs = " 0 " msdata : Ordinal = " 2 " / >
< / xsd : sequence >
< xsd : attribute name = " name " type = " xsd:string " use = " required " msdata : Ordinal = " 1 " / >
< xsd : attribute name = " type " type = " xsd:string " msdata : Ordinal = " 3 " / >
< xsd : attribute name = " mimetype " type = " xsd:string " msdata : Ordinal = " 4 " / >
< xsd : attribute ref = " xml:space " / >
< / xsd : complexType >
< / xsd : element >
< xsd : element name = " resheader " >
< xsd : complexType >
< xsd : sequence >
< xsd : element name = " value " type = " xsd:string " minOccurs = " 0 " msdata : Ordinal = " 1 " / >
< / xsd : sequence >
< xsd : attribute name = " name " type = " xsd:string " use = " required " / >
< / xsd : complexType >
< / xsd : element >
< / xsd : choice >
< / xsd : complexType >
< / xsd : element >
< / xsd : schema >
< resheader name = " resmimetype " >
< value > text / microsoft-resx < / value >
< / resheader >
< resheader name = " version " >
< value > 2.0 < / value >
< / resheader >
< resheader name = " reader " >
< value > System . Resources . ResXResourceReader , System . Windows . Forms , Version = 2.0 . 0 . 0 , Culture = neutral , PublicKeyToken = b77a5c561934e089 < / value >
< / resheader >
< resheader name = " writer " >
< value > System . Resources . ResXResourceWriter , System . Windows . Forms , Version = 2.0 . 0 . 0 , Culture = neutral , PublicKeyToken = b77a5c561934e089 < / value >
< / resheader >
{ 0 }
< / root >
2016-07-06 01:36:38 +08:00
' @