diff --git a/.gitattributes b/.gitattributes index 6b9302f1..e53d3178 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,74 +1,49 @@ ############################################################################### -# Set default behavior to automatically normalize line endings. +# Set default behavior to: +# automatically normalize line endings on check-in, and +# convert to Windows-style line endings on check-out ############################################################################### * text=auto encoding=UTF-8 - -# csc/vbc are shell scripts and should always have unix line endings -# These shell scripts are included in the toolset packages. Normally, the shell -# scripts in our repo are only run by cloning onto a Linux/Mac machine, and git -# automatically chooses LF as the line ending. -# -# However, right now the toolset packages must be built on Windows, and so the -# files must be hard-coded to be cloned with LF -src/Compilers/CSharp/CscCore/csc text eol=lf -src/Compilers/VisualBasic/VbcCore/vbc text eol=lf +*.sh text eol=lf ############################################################################### -# Set default behavior for command prompt diff. -# -# This is need for earlier builds of msysgit that does not have it on by -# default for csharp files. -# Note: This is only used by command line +# Set file behavior to: +# treat as text, and +# diff as C# source code ############################################################################### -*.cs diff=csharp text -*.vb text +*.cs text diff=csharp ############################################################################### -# Set the merge driver for project and solution files -# -# Merging from the command prompt will add diff markers to the files if there -# are conflicts (Merging from VS is not affected by the settings below, in VS -# the diff markers are never inserted). Diff markers may cause the following -# file extensions to fail to load in VS. An alternative would be to treat -# these files as binary and thus will always conflict and require user -# intervention with every merge. To do so, just uncomment the entries below -############################################################################### -#*.sln merge=binary -#*.csproj merge=binary -#*.vbproj merge=binary -#*.vcxproj merge=binary -#*.vcproj merge=binary -#*.dbproj merge=binary -#*.fsproj merge=binary -#*.lsproj merge=binary -#*.wixproj merge=binary -#*.modelproj merge=binary -#*.sqlproj merge=binary -#*.wwaproj merge=binary - -############################################################################### -# behavior for image files -# -# image files are treated as binary by default. -############################################################################### -#*.jpg binary -#*.png binary -#*.gif binary +# Set file behavior to: +# treat as text +############################################################################### +*.cmd text +*.config text +*.csproj text +*.groovy text +*.json text +*.md text +*.nuspec text +*.pkgdef text +*.proj text +*.projitems text +*.props text +*.ps1 text +*.resx text +*.ruleset text +*.shproj text +*.sln text +*.targets text +*.vb text +*.vbproj text +*.vcxproj text +*.vcxproj.filters text +*.vsct text +*.vsixmanifest text ############################################################################### -# diff behavior for common document formats -# -# Convert binary document formats to text before diffing them. This feature -# is only available from the command line. Turn it on by uncommenting the -# entries below. +# Set file behavior to: +# treat as binary ############################################################################### -#*.doc diff=astextplain -#*.DOC diff=astextplain -#*.docx diff=astextplain -#*.DOCX diff=astextplain -#*.dot diff=astextplain -#*.DOT diff=astextplain -#*.pdf diff=astextplain -#*.PDF diff=astextplain -#*.rtf diff=astextplain -#*.RTF diff=astextplain \ No newline at end of file +*.png binary +*.snk binary diff --git a/.gitignore b/.gitignore index 67f5a6ae..f08771c5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,108 +1,29 @@ -### Repo-specific things ### - -# Test results -*-testResults.xml - -# Multicore JIT Optimization profiles -**/optimizationdata/dotnet - -# Test Asset Manager files -.tam/ - -# NuGet keeps dropping -Library/ - -# local nuget cache -.nuget/ - -# NuGet v3 restore drops these even though we don't use MSBuild :( -*.nuget.targets -*.nuget.props - -# Debian and python stuff -*.dsc -*.tar.gz -*.build -*.changes -*.deb -*.pyc -*.pyo - -# OSX Packaging temp files -*.pkg - -# OS X Device Services Store -.DS_Store - -# CMake generated files -cmake/ - -# stage0 install directory -.dotnet - -# stage0pj install directory -.dotnet_stage0PJ - -# build tools directory -build_tools - -# `dotnet new` template zip files are generated by a pre-build step. -/src/dotnet/commands/dotnet-new/*.zip - -### VisualStudio.gitignore from https://raw.githubusercontent.com/github/gitignore/master/VisualStudio.gitignore ### - ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. # User-specific files *.suo *.user -*.userosscache *.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs +.vs/ +*.VC.db # Build results +[Aa]rtifacts/ [Dd]ebug/ -[Dd]ebugPublic/ [Rr]elease/ -[Rr]eleases/ x64/ -x86/ -bld/ [Bb]in/ [Oo]bj/ +.dotnet*/ +.packages/ +.tools/ -# Visual Studio 2015 cache/options directory -.vs/ - -# Visual Studio Code cache/options directory -.vscode/ - -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# DNX -project.lock.json -artifacts/ +# Per-user project properties +launchSettings.json *_i.c *_p.c -*_i.h *.ilk *.meta *.obj @@ -110,7 +31,6 @@ artifacts/ *.pdb *.pgc *.pgd -*.rsp *.sbr *.tlb *.tli @@ -118,35 +38,27 @@ artifacts/ *.tmp *.tmp_proj *.log +*.wrn *.vspscc *.vssscc .builds *.pidb -*.svclog +*.log *.scc -# Chutzpah Test files -_Chutzpah* - # Visual C++ cache files ipch/ *.aps *.ncb -*.opendb *.opensdf *.sdf *.cachefile -*.VC.db -*.VC.VC.opendb +*.VC.opendb # Visual Studio profiler *.psess *.vsp *.vspx -*.sap - -# TFS 2012 Local Workspace -$tf/ # Guidance Automation Toolkit *.gpState @@ -154,13 +66,6 @@ $tf/ # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper -*.DotSettings.user -.idea/ -*.iml -*.DotSettings - -# JustCode is a .NET coding add-in -.JustCode # TeamCity is a build add-in _TeamCity* @@ -169,138 +74,38 @@ _TeamCity* *.dotCover # NCrunch -_NCrunch_* +*.ncrunch* .*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config - -# Windows Azure Build Output -csx/ -*.build.csdef - -# Windows Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directory -AppPackages/ - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ # Others +sql/ +*.Cache ClientBin/ [Ss]tyle[Cc]op.* ~$* *~ *.dbmdl -*.dbproj.schemaview +*.[Pp]ublish.xml *.pfx *.publishsettings -node_modules/ -orleans.codegen.cs - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm # SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml +App_Data/*.mdf +App_Data/*.ldf -# Node.js Tools for Visual Studio -.ntvs_analysis.dat +# ========================= +# Windows detritus +# ========================= -# Visual Studio 6 build log -*.plg +# Windows image file caches +Thumbs.db +ehthumbs.db -# Visual Studio 6 workspace options file -*.opt +# Folder config file +Desktop.ini -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions +# Recycle Bin used on file shares +$RECYCLE.BIN/ -# Paket dependency manager -.paket/paket.exe - -# FAKE - F# Make -.fake/ - -# Exceptions -# Build Scripts -!scripts/build/ -test/PackagedCommands/Consumers/*/project.json - -# Vim swp files -*.swp -*.*~ - -# VS generated files -launchSettings.json - -# user files used in tests -!TestAssets/TestProjects/TestAppWithLibrary/TestLibrary/TestLibrary.xproj.user -!TestAssets/TestProjects/TestAppWithLibrary/TestApp/TestApp.xproj.user -!TestAssets/TestProjects/PJTestAppSimple/PJTestAppSimple.xproj.user +# Mac desktop service store files +.DS_Store diff --git a/.vsts-ci.yml b/.vsts-ci.yml new file mode 100644 index 00000000..9b1309a0 --- /dev/null +++ b/.vsts-ci.yml @@ -0,0 +1,84 @@ +resources: +- repo: self + clean: true +queue: + name: VSEng-MicroBuildVS2017 + demands: Cmd +variables: + BuildConfiguration: Release + TeamName: Roslyn-Project-System + +steps: +- task: ms-vseng.MicroBuildTasks.30666190-6959-11e5-9f96-f56098202fef.MicroBuildSigningPlugin@1 + displayName: Install Signing Plugin + inputs: + signType: real + esrpSigning: true + condition: and(succeeded(), eq(variables['PB_SignType'], 'real')) + +- script: build\CIBuild.cmd + -configuration $(BuildConfiguration) + /p:PB_PublishBlobFeedKey=$(PB_PublishBlobFeedKey) + displayName: Build + +- task: PublishTestResults@1 + displayName: Publish Test Results + inputs: + testRunner: XUnit + testResultsFiles: 'artifacts/$(BuildConfiguration)/TestResults/*.xml' + mergeTestResults: true + testRunTitle: 'Unit Tests' + condition: and(succeededOrFailed(), ne(variables['PB_SkipTests'], 'true')) + +- task: NuGetPublisher@0 + displayName: Publish NuGet Packages to MyGet + inputs: + searchPattern: 'artifacts\$(BuildConfiguration)\packages\*.nupkg' + connectedServiceName: 'dotnet-core MyGet Feed' + nuGetVersion: 4.0.0.2283 + condition: and(succeeded(), not(contains(variables['PB_PublishType'], 'blob'))) + +- task: PublishSymbols@1 + displayName: Prepare Symbols + inputs: + SymbolsPath: '$(DropRoot)\$(TeamName)\$(Build.DefinitionName)\$(Build.BuildNumber)\Symbols' + SearchPattern: '**/*.dll;**/*.exe;**/*.pdb' + SymbolsFolder: '$(Build.SourcesDirectory)\artifacts\$(BuildConfiguration)\SymStore' + SkipIndexing: true + condition: and(succeeded(), not(contains(variables['PB_PublishType'], 'blob'))) + +- task: ms-vscs-artifact.build-tasks.artifactSymbolTask-1.artifactSymbolTask@0 + displayName: Publish Symbols + inputs: + symbolServiceURI: 'https://microsoft.artifacts.visualstudio.com/DefaultCollection' + requestName: '$(system.teamProject)/$(Build.DefinitionName)/$(Build.BuildNumber)/$(Build.BuildId)' + sourcePath: '$(DropRoot)\$(TeamName)\$(Build.DefinitionName)\$(Build.BuildNumber)\Symbols' + usePat: false + condition: and(succeeded(), not(contains(variables['PB_PublishType'], 'blob'))) + +- task: CopyPublishBuildArtifacts@1 + displayName: Publish Artifacts + inputs: + CopyRoot: '$(Build.SourcesDirectory)' + Contents: | + artifacts\$(BuildConfiguration)\bin + artifacts\$(BuildConfiguration)\log + artifacts\$(BuildConfiguration)\TestResults + artifacts\$(BuildConfiguration)\packages + ArtifactName: '$(Build.BuildNumber)' + ArtifactType: FilePath + TargetPath: '$(DropRoot)\$(TeamName)\$(Build.DefinitionName)' + condition: and(succeededOrFailed(), not(contains(variables['PB_PublishType'], 'blob'))) + +- task: ms-vseng.MicroBuildTasks.521a94ea-9e68-468a-8167-6dcf361ea776.MicroBuildCleanup@1 + displayName: Cleanup + condition: succeededOrFailed() + +- task: PublishBuildArtifacts@1 + displayName: Publish MicroBuild Artifacts + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)\MicroBuild\Output' + ArtifactName: '$(Build.BuildNumber)' + publishLocation: FilePath + TargetPath: '$(DropRoot)\$(TeamName)\$(Build.DefinitionName)' + condition: and(succeededOrFailed(), not(contains(variables['PB_PublishType'], 'blob'))) diff --git a/Directory.Build.props b/Directory.Build.props index 53cd9161..b1d15db3 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,27 +1,8 @@ - - - Debug - - - - - - - $(MSBuildThisFileDirectory) - $(NuGetPackageRoot)roslyntools.repotoolset\$(RoslynToolsRepoToolsetVersion)\tools\ - https://dotnetfeed.blob.core.windows.net/dotnet-core/packages/index.json - - - - $(RepoRoot)artifacts\.dotnet\$(DotNetCliVersion)\ - - https://github.com/dotnet/cli-migrate $(RepositoryUrl) - diff --git a/build/NuGet.props b/build/NuGet.props deleted file mode 100644 index 336d6a4a..00000000 --- a/build/NuGet.props +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - - - - $(NUGET_PACKAGES) - $(UserProfile)\.nuget\packages\ - $(HOME)\.nuget\packages\ - $(NuGetPackageRoot)\ - - - diff --git a/build/RestoreToolset.ps1 b/build/RestoreToolset.ps1 new file mode 100644 index 00000000..45e3bde2 --- /dev/null +++ b/build/RestoreToolset.ps1 @@ -0,0 +1,35 @@ +Set-StrictMode -version 2.0 +$ErrorActionPreference="Stop" + +# Installs dotnet CLI used to restore project.json projects in tests. +function InitializeDotNetCli_ProjectJson { + $dotnetRoot = Join-Path $RepoRoot ".dotnet-test" + $sdkVersion = "1.0.0-preview2-1-003177" + $sdkInstallDir = Join-Path $dotnetRoot "sdk\$sdkVersion" + + if (!(Test-Path $sdkInstallDir)) { + InstallDotNetSdk $dotnetRoot $sdkVersion + } +} + +# Installs additional shared frameworks for testing purposes +function InstallDotNetSharedFramework([string]$dotnetRoot, [string]$version) { + $fxDir = Join-Path $dotnetRoot "shared\Microsoft.NETCore.App\$version" + + if (!(Test-Path $fxDir)) { + $installScript = GetDotNetInstallScript $dotnetRoot + & $installScript -Version $version -InstallDir $dotnetRoot -SharedRuntime + + if($lastExitCode -ne 0) { + throw "Failed to install shared Framework $version to '$dotnetRoot' (exit code '$lastExitCode')." + } + } +} + +# The following frameworks and tools are used only for testing. +# Do not attempt to install them in source build. +if ($env:DotNetBuildFromSource -ne "true") { + InitializeDotNetCli_ProjectJson + InstallDotNetSharedFramework $env:DOTNET_INSTALL_DIR "1.0.5" + InstallDotNetSharedFramework $env:DOTNET_INSTALL_DIR "1.1.1" +} \ No newline at end of file diff --git a/build/RestoreToolset.sh b/build/RestoreToolset.sh new file mode 100644 index 00000000..bf624b81 --- /dev/null +++ b/build/RestoreToolset.sh @@ -0,0 +1,37 @@ +# Installs dotnet CLI used to restore project.json projects in tests. +function InitializeDotNetCli_ProjectJson { + local dotnet_root="$repo_root/.dotnet-test" + local sdk_version="1.0.0-preview2-1-003177" + local sdk_install_dir="$dotnet_root/sdk/$sdk_version" + + if [[ ! -d "$sdk_install_dir" ]]; then + InstallDotNetSdk $dotnet_root $sdk_version + fi +} + +# Installs additional shared frameworks for testing purposes +function InstallDotNetSharedFramework { + local dotnet_root=$1 + local version=$2 + local fx_dir="$dotnet_root/shared/Microsoft.NETCore.App/$version" + + if [[ ! -d "$fx_dir" ]]; then + local install_script=`GetDotNetInstallScript $dotnet_root` + + bash "$install_script" --version $version --install-dir $dotnet_root --shared-runtime + local lastexitcode=$? + + if [[ $lastexitcode != 0 ]]; then + echo "Failed to install Shared Framework $version to '$dotnet_root' (exit code '$lastexitcode')." + ExitWithExitCode $lastexitcode + fi + fi +} + +# The following frameworks and tools are used only for testing. +# Do not attempt to install them in source build. +if [[ "$DotNetBuildFromSource" != "true" ]]; then + InitializeDotNetCli_ProjectJson + InstallDotNetSharedFramework $DOTNET_INSTALL_DIR "1.0.5" + InstallDotNetSharedFramework $DOTNET_INSTALL_DIR "1.1.1" +fi \ No newline at end of file diff --git a/build/Toolset.proj b/build/Toolset.proj deleted file mode 100644 index e8395c32..00000000 --- a/build/Toolset.proj +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - net462 - https://dotnet.myget.org/F/roslyn-tools/api/v3/index.json - - - - - - - diff --git a/build/Versions.props b/build/Versions.props index 89786cd7..ee008a83 100644 --- a/build/Versions.props +++ b/build/Versions.props @@ -1,6 +1,6 @@ - + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) @@ -8,23 +8,10 @@ - 1.3.1 + 1.3.1 alpha - - - false - - - - - 1.1.4 - 1.0.0-preview2-1-003177 - 1.0.0-beta-62522-01 - 2.2.7 - - 2.1.0 @@ -42,7 +29,13 @@ 1.0.3 4.3.0 4.3.0 - 2.3.0 + + + + + $(RestoreSources); + https://dotnetfeed.blob.core.windows.net/dotnet-core/packages/index.json + diff --git a/build/build.ps1 b/build/build.ps1 index ceb58835..60ce0426 100644 --- a/build/build.ps1 +++ b/build/build.ps1 @@ -1,25 +1,26 @@ [CmdletBinding(PositionalBinding=$false)] Param( - [switch] $build, - [switch] $ci, [string] $configuration = "Debug", + [string] $projects = "", + [string] $verbosity = "minimal", + [switch] $restore, + [switch] $deployDeps, + [switch] $build, + [switch] $rebuild, [switch] $deploy, - [switch] $fullMSBuild, - [switch] $help, - [switch] $log, + [switch] $test, + [switch] $integrationTest, + [switch] $sign, [switch] $pack, + [switch] $ci, [switch] $prepareMachine, - [switch] $rebuild, - [switch] $restore, - [switch] $sign, - [string] $solution = "", - [switch] $test, - [string] $verbosity = "minimal", + [switch] $help, [Parameter(ValueFromRemainingArguments=$true)][String[]]$properties ) -Set-StrictMode -Version 2.0 +set-strictmode -version 2.0 $ErrorActionPreference = "Stop" +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 function Print-Usage() { Write-Host "Common settings:" @@ -27,253 +28,226 @@ function Print-Usage() { Write-Host " -verbosity Msbuild verbosity (q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic])" Write-Host " -help Print help and exit" Write-Host "" + Write-Host "Actions:" Write-Host " -restore Restore dependencies" Write-Host " -build Build solution" Write-Host " -rebuild Rebuild solution" Write-Host " -deploy Deploy built VSIXes" + Write-Host " -deployDeps Deploy dependencies (e.g. VSIXes for integration tests)" Write-Host " -test Run all unit tests in the solution" + Write-Host " -integrationTest Run all integration tests in the solution" Write-Host " -sign Sign build outputs" Write-Host " -pack Package build outputs into NuGet packages and Willow components" Write-Host "" + Write-Host "Advanced settings:" - Write-Host " -solution Path to solution to build" + Write-Host " -projects Semi-colon delimited list of sln/proj's to build. Globbing is supported (*.sln)" Write-Host " -ci Set when running on CI server" - Write-Host " -log Enable logging (by default on CI)" Write-Host " -prepareMachine Prepare machine for CI run" - Write-Host " -fullMSBuild Test against the desktop version of MSBuild" Write-Host "" - Write-Host "Command line arguments not listed above are passed through to MSBuild." + Write-Host "Command line arguments not listed above are passed thru to msbuild." Write-Host "The above arguments can be shortened as much as to be unambiguous (e.g. -co for configuration, -t for test, etc.)." } -function Create-Directory([string[]] $Path) { - if (!(Test-Path -Path $Path)) { - New-Item -Path $Path -Force -ItemType "Directory" | Out-Null - } +if ($help -or (($properties -ne $null) -and ($properties.Contains("/help") -or $properties.Contains("/?")))) { + Print-Usage + exit 0 } -function GetVersionsPropsVersion([string[]] $Name) { - [xml]$Xml = Get-Content $VersionsProps - - foreach ($PropertyGroup in $Xml.Project.PropertyGroup) { - if (Get-Member -InputObject $PropertyGroup -name $Name) { - return $PropertyGroup.$Name - } +function Create-Directory([string[]] $path) { + if (!(Test-Path $path)) { + New-Item -path $path -force -itemType "Directory" | Out-Null } - - throw "Failed to locate the $Name property" } -function InstallDotNetCli { - $DotNetCliVersion = GetVersionsPropsVersion -Name "DotNetCliVersion" - $DotNetInstallVerbosity = "" - - if (!$env:DOTNET_INSTALL_DIR) { - $env:DOTNET_INSTALL_DIR = Join-Path $RepoRoot "artifacts\.dotnet\$DotNetCliVersion" - } - - $DotNetRoot = $env:DOTNET_INSTALL_DIR - $DotNetInstallScript = Join-Path $DotNetRoot "dotnet-install.ps1" - - if (!(Test-Path $DotNetInstallScript)) { - Create-Directory $DotNetRoot - Invoke-WebRequest "https://dot.net/v1/dotnet-install.ps1" -UseBasicParsing -OutFile $DotNetInstallScript - } - - if ($verbosity -eq "diagnostic") { - $DotNetInstallVerbosity = "-Verbose" - } - - # Install a stage 0 - $SdkInstallDir = Join-Path $DotNetRoot "sdk\$DotNetCliVersion" - - if (!(Test-Path $SdkInstallDir)) { - # Use Invoke-Expression so that $DotNetInstallVerbosity is not positionally bound when empty - Invoke-Expression -Command "$DotNetInstallScript -Version $DotNetCliVersion $DotNetInstallVerbosity" +function InitializeDotNetCli { + # Don't resolve runtime, shared framework, or SDK from other locations to ensure build determinism + $env:DOTNET_MULTILEVEL_LOOKUP=0 + + # Disable first run since we do not need all ASP.NET packages restored. + $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 - if($LASTEXITCODE -ne 0) { - throw "Failed to install stage0" - } + # Source Build uses DotNetCoreSdkDir variable + if ($env:DotNetCoreSdkDir -ne $null) { + $env:DOTNET_INSTALL_DIR = $env:DotNetCoreSdkDir } - # Install 1.0 shared framework - $NetCoreApp10Version = "1.0.5" - $NetCoreApp10Dir = Join-Path $DotNetRoot "shared\Microsoft.NETCore.App\$NetCoreApp10Version" - - if (!(Test-Path $NetCoreApp10Dir)) { - # Use Invoke-Expression so that $DotNetInstallVerbosity is not positionally bound when empty - Invoke-Expression -Command "$DotNetInstallScript -Channel `"Preview`" -Version $NetCoreApp10Version -SharedRuntime $DotNetInstallVerbosity" - - if($LASTEXITCODE -ne 0) { - throw "Failed to install 1.0 shared framework" + # Use dotnet installation specified in DOTNET_INSTALL_DIR if it contains the required SDK version, + # otherwise install the dotnet CLI and SDK to repo local .dotnet directory to avoid potential permission issues. + if (($env:DOTNET_INSTALL_DIR -ne $null) -and (Test-Path(Join-Path $env:DOTNET_INSTALL_DIR "sdk\$($GlobalJson.sdk.version)"))) { + $dotnetRoot = $env:DOTNET_INSTALL_DIR + } else { + $dotnetRoot = Join-Path $RepoRoot ".dotnet" + $env:DOTNET_INSTALL_DIR = $dotnetRoot + + if ($restore) { + InstallDotNetSdk $dotnetRoot $GlobalJson.sdk.version } } - # Put the stage 0 on the path - $env:PATH = "$DotNetRoot;$env:PATH" - - # Disable first run since we want to control all package sources - $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 - - # Don't resolve runtime, shared framework, or SDK from other locations - $env:DOTNET_MULTILEVEL_LOOKUP=0 + $global:BuildDriver = Join-Path $dotnetRoot "dotnet.exe" + $global:BuildArgs = "msbuild" } -function InstallDotNetCliProjectJson { - $DotNetCliProjectJsonVersion = GetVersionsPropsVersion -Name "DotNetCliProjectJsonVersion" - $DotNetInstallVerbosity = "" - - $DotNetRoot = Join-Path $RepoRoot "artifacts\.dotnet\$DotNetCliProjectJsonVersion" - $DotNetInstallScript = Join-Path $DotNetRoot "dotnet-install.ps1" - - if (!(Test-Path $DotNetInstallScript)) { - Create-Directory $DotNetRoot - Invoke-WebRequest "https://dot.net/v1/dotnet-install.ps1" -UseBasicParsing -OutFile $DotNetInstallScript +function GetDotNetInstallScript([string] $dotnetRoot) { + $installScript = "$dotnetRoot\dotnet-install.ps1" + if (!(Test-Path $installScript)) { + Create-Directory $dotnetRoot + Invoke-WebRequest "https://dot.net/v1/dotnet-install.ps1" -OutFile $installScript } - if ($verbosity -eq "diagnostic") { - $DotNetInstallVerbosity = "-Verbose" - } - - # Install a stage 0 - $SdkInstallDir = Join-Path $DotNetRoot "sdk\$DotNetCliProjectJsonVersion" - - if (!(Test-Path $SdkInstallDir)) { - # Use Invoke-Expression so that $DotNetInstallVerbosity is not positionally bound when empty - Invoke-Expression -Command "$DotNetInstallScript -Version $DotNetCliProjectJsonVersion -InstallDir $DotNetRoot $DotNetInstallVerbosity" - - if($LASTEXITCODE -ne 0) { - throw "Failed to install stage0" - } - } + return $installScript } -function InstallNuGet { - $NugetInstallDir = Join-Path $RepoRoot "artifacts\.nuget" - $NugetExe = Join-Path $NugetInstallDir "nuget.exe" - - if (!(Test-Path -Path $NugetExe)) { - Create-Directory $NugetInstallDir - Invoke-WebRequest "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -UseBasicParsing -OutFile $NugetExe +function InstallDotNetSdk([string] $dotnetRoot, [string] $version) { + $installScript = GetDotNetInstallScript $dotnetRoot + + & $installScript -Version $version -InstallDir $dotnetRoot + if ($lastExitCode -ne 0) { + throw "Failed to install dotnet SDK $version to '$dotnetRoot' (exit code '$lastExitCode')." } } -function InstallRepoToolset { - $RepoToolsetVersion = GetVersionsPropsVersion -Name "RoslynToolsRepoToolsetVersion" - $RepoToolsetDir = Join-Path $NuGetPackageRoot "roslyntools.repotoolset\$RepoToolsetVersion\tools" - $RepoToolsetBuildProj = Join-Path $RepoToolsetDir "Build.proj" - - if ($ci -or $log) { - Create-Directory $LogDir - $logCmd = "/bl:" + (Join-Path $LogDir "Toolset.binlog") - } else { - $logCmd = "" - } - - if (!(Test-Path -Path $RepoToolsetBuildProj)) { - $ToolsetProj = Join-Path $PSScriptRoot "Toolset.proj" - dotnet msbuild $ToolsetProj /t:restore /m /nologo /clp:Summary /warnaserror /v:$verbosity $logCmd | Write-Host - - if($LASTEXITCODE -ne 0) { - throw "Failed to build $ToolsetProj" - } +function InitializeVisualStudioBuild { + $inVSEnvironment = !($env:VS150COMNTOOLS -eq $null) -and (Test-Path $env:VS150COMNTOOLS) + + if ($inVSEnvironment) { + $vsInstallDir = Join-Path $env:VS150COMNTOOLS "..\.." + } else { + $vsInstallDir = LocateVisualStudio + + $env:VS150COMNTOOLS = Join-Path $vsInstallDir "Common7\Tools\" + $env:VSSDK150Install = Join-Path $vsInstallDir "VSSDK\" + $env:VSSDKInstall = Join-Path $vsInstallDir "VSSDK\" } - return $RepoToolsetBuildProj + $global:BuildDriver = Join-Path $vsInstallDir "MSBuild\15.0\Bin\msbuild.exe" + $global:BuildArgs = "/nodeReuse:$(!$ci)" } function LocateVisualStudio { - $VSWhereVersion = GetVersionsPropsVersion -Name "VSWhereVersion" - $VSWhereDir = Join-Path $ArtifactsDir ".tools\vswhere\$VSWhereVersion" - $VSWhereExe = Join-Path $vsWhereDir "vswhere.exe" - - if (!(Test-Path $VSWhereExe)) { - Create-Directory $VSWhereDir - Invoke-WebRequest "http://github.com/Microsoft/vswhere/releases/download/$VSWhereVersion/vswhere.exe" -UseBasicParsing -OutFile $VSWhereExe + $vswhereVersion = $GlobalJson.vswhere.version + $toolsRoot = Join-Path $RepoRoot ".tools" + $vsWhereDir = Join-Path $toolsRoot "vswhere\$vswhereVersion" + $vsWhereExe = Join-Path $vsWhereDir "vswhere.exe" + + if (!(Test-Path $vsWhereExe)) { + Create-Directory $vsWhereDir + Write-Host "Downloading vswhere" + Invoke-WebRequest "https://github.com/Microsoft/vswhere/releases/download/$vswhereVersion/vswhere.exe" -OutFile $vswhereExe } - $VSInstallDir = & $VSWhereExe -latest -property installationPath -requires Microsoft.Component.MSBuild -requires Microsoft.VisualStudio.Component.VSSDK -requires Microsoft.Net.Component.4.6.TargetingPack -requires Microsoft.VisualStudio.Component.Roslyn.Compiler -requires Microsoft.VisualStudio.Component.VSSDK + $vsInstallDir = & $vsWhereExe -latest -prerelease -property installationPath -requires Microsoft.Component.MSBuild -requires Microsoft.VisualStudio.Component.VSSDK -requires Microsoft.Net.Component.4.6.TargetingPack -requires Microsoft.VisualStudio.Component.Roslyn.Compiler -requires Microsoft.VisualStudio.Component.VSSDK - if (!(Test-Path $VSInstallDir)) { - throw "Failed to locate Visual Studio (exit code '$LASTEXITCODE')." + if (!(Test-Path $vsInstallDir)) { + throw "Failed to locate Visual Studio (exit code '$lastExitCode')." } - return $VSInstallDir + return $vsInstallDir } -function Build { - InstallDotNetCliProjectJson - InstallDotNetCli - InstallNuget - $RepoToolsetBuildProj = InstallRepoToolset - - if ($prepareMachine) { - Create-Directory $NuGetPackageRoot - dotnet nuget locals all --clear +function InitializeToolset { + $toolsetVersion = $GlobalJson.'msbuild-sdks'.'RoslynTools.RepoToolset' + $toolsetLocationFile = Join-Path $ToolsetDir "$toolsetVersion.txt" - if($LASTEXITCODE -ne 0) { - throw "Failed to clear NuGet cache" + if (Test-Path $toolsetLocationFile) { + $path = Get-Content $toolsetLocationFile -TotalCount 1 + if (Test-Path $path) { + $global:ToolsetBuildProj = $path + return } } - if ($fullMSBuild) { - if (!($env:VSInstallDir)) { - $env:VSInstallDir = LocateVisualStudio - } + if (!$restore) { + throw "Toolset has not been restored (version $toolsetVersion)." + } - $env:DOTNET_SDK_TEST_MSBUILD_PATH = Join-Path $env:VSInstallDir "MSBuild\15.0\Bin\msbuild.exe" + $proj = Join-Path $ToolsetDir "restore.proj" + + '' | Set-Content $proj + & $BuildDriver $BuildArgs $proj /t:__WriteToolsetLocation /m /nologo /clp:None /warnaserror /bl:$ToolsetRestoreLog /v:$verbosity /p:__ToolsetLocationOutputFile=$toolsetLocationFile + + if ($lastExitCode -ne 0) { + throw "Failed to restore toolset (exit code '$lastExitCode'). See log: $ToolsetRestoreLog" } - if ($ci -or $log) { - Create-Directory $LogDir - $logCmd = "/bl:" + (Join-Path $LogDir "Build.binlog") - } else { - $logCmd = "" + $path = Get-Content $toolsetLocationFile -TotalCount 1 + if (!(Test-Path $path)) { + throw "Invalid toolset path: $path" } - if ($solution -eq "") { - $solution = Join-Path $RepoRoot "cli-migrate.sln" + $global:ToolsetBuildProj = $path +} + +function InitializeCustomToolset { + if (-not $restore) { + return } - dotnet msbuild $RepoToolsetBuildProj /m /nologo /clp:Summary /warnaserror /v:$verbosity $logCmd /p:Configuration=$configuration /p:SolutionPath=$solution /p:Restore=$restore /p:Build=$build /p:Rebuild=$rebuild /p:Deploy=$deploy /p:Test=$test /p:Sign=$sign /p:Pack=$pack /p:CIBuild=$ci $properties + $script = Join-Path $RepoRoot "build\RestoreToolset.ps1" - if($LASTEXITCODE -ne 0) { - throw "Failed to build $RepoToolsetBuildProj" + if (Test-Path $script) { + . $script } } +function Build { + & $BuildDriver $BuildArgs $ToolsetBuildProj /m /nologo /clp:Summary /warnaserror /v:$verbosity /bl:$BuildLog /p:Configuration=$configuration /p:Projects=$projects /p:RepoRoot=$RepoRoot /p:Restore=$restore /p:DeployDeps=$deployDeps /p:Build=$build /p:Rebuild=$rebuild /p:Deploy=$deploy /p:Test=$test /p:IntegrationTest=$integrationTest /p:Sign=$sign /p:Pack=$pack /p:CIBuild=$ci $properties +} + function Stop-Processes() { Write-Host "Killing running build processes..." Get-Process -Name "msbuild" -ErrorAction SilentlyContinue | Stop-Process + Get-Process -Name "dotnet" -ErrorAction SilentlyContinue | Stop-Process Get-Process -Name "vbcscompiler" -ErrorAction SilentlyContinue | Stop-Process } -if ($help -or (($properties -ne $null) -and ($properties.Contains("/help") -or $properties.Contains("/?")))) { - Print-Usage - exit 0 -} +try { + $RepoRoot = Join-Path $PSScriptRoot ".." + $ArtifactsDir = Join-Path $RepoRoot "artifacts" + $ToolsetDir = Join-Path $ArtifactsDir "toolset" + $LogDir = Join-Path (Join-Path $ArtifactsDir $configuration) "log" + $BuildLog = Join-Path $LogDir "Build.binlog" + $ToolsetRestoreLog = Join-Path $LogDir "ToolsetRestore.binlog" + $TempDir = Join-Path (Join-Path $ArtifactsDir $configuration) "tmp" + $GlobalJson = Get-Content(Join-Path $RepoRoot "global.json") | ConvertFrom-Json + + if ($projects -eq "") { + $projects = Join-Path $RepoRoot "*.sln" + } -$RepoRoot = Join-Path $PSScriptRoot "..\" -$ArtifactsDir = Join-Path $RepoRoot "artifacts" -$ArtifactsConfigurationDir = Join-Path $ArtifactsDir $configuration -$LogDir = Join-Path $ArtifactsConfigurationDir "log" -$VersionsProps = Join-Path $PSScriptRoot "Versions.props" + if ($env:NUGET_PACKAGES -eq $null) { + # Use local cache on CI to ensure deterministic build, + # use global cache in dev builds to avoid cost of downloading packages. + $env:NUGET_PACKAGES = if ($ci) { Join-Path $RepoRoot ".packages" } + else { Join-Path $env:UserProfile ".nuget\packages" } + } -try { + Create-Directory $ToolsetDir + Create-Directory $LogDir + if ($ci) { - $TempDir = Join-Path $ArtifactsConfigurationDir "tmp" Create-Directory $TempDir - $env:TEMP = $TempDir $env:TMP = $TempDir } - if (!($env:NUGET_PACKAGES)) { - $env:NUGET_PACKAGES = Join-Path $env:UserProfile ".nuget\packages" + # Presence of vswhere.version indicates the repo needs to build using VS msbuild + if ((Get-Member -InputObject $GlobalJson -Name "vswhere") -ne $null) { + InitializeVisualStudioBuild + } elseif ((Get-Member -InputObject $GlobalJson -Name "sdk") -ne $null) { + InitializeDotNetCli + } else { + throw "/global.json must either specify 'sdk.version' or 'vswhere.version'." } - $NuGetPackageRoot = $env:NUGET_PACKAGES + if ($ci) { + Write-Host "Using $BuildDriver" + } + + InitializeToolset + InitializeCustomToolset Build exit $lastExitCode @@ -290,3 +264,4 @@ finally { Stop-Processes } } + diff --git a/build/build.sh b/build/build.sh index c4065bd5..559b58ed 100755 --- a/build/build.sh +++ b/build/build.sh @@ -1,21 +1,45 @@ -#!/bin/bash +#!/usr/bin/env bash + +source="${BASH_SOURCE[0]}" + +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" build=false ci=false -configuration="Debug" +configuration='Debug' help=false -log=false pack=false -prepareMachine=false +prepare_machine=false rebuild=false restore=false sign=false -solution="" +projects='' test=false -verbosity="minimal" -properties="" - -while [[ $# > 0 ]]; do +verbosity='minimal' +properties='' + +repo_root="$scriptroot/.." +artifacts_dir="$repo_root/artifacts" +artifacts_configuration_dir="$artifacts_dir/$configuration" +toolset_dir="$artifacts_dir/toolset" +log_dir="$artifacts_configuration_dir/log" +build_log="$log_dir/Build.binlog" +toolset_restore_log="$log_dir/ToolsetRestore.binlog" +temp_dir="$artifacts_configuration_dir/tmp" + +global_json_file="$repo_root/global.json" +build_driver="" +toolset_build_proj="" + +while (($# > 0)); do lowerI="$(echo $1 | awk '{print tolower($0)}')" case $lowerI in --build) @@ -33,36 +57,31 @@ while [[ $# > 0 ]]; do --help) echo "Common settings:" echo " --configuration Build configuration Debug, Release" - echo " --verbosity Msbuild verbosity (q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic])" - echo " --help Print help and exit" + echo " --verbosity Msbuild verbosity (q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic])" + echo " --help Print help and exit" echo "" echo "Actions:" - echo " --restore Restore dependencies" - echo " --build Build solution" - echo " --rebuild Rebuild solution" - echo " --test Run all unit tests in the solution" - echo " --sign Sign build outputs" - echo " --pack Package build outputs into NuGet packages and Willow components" + echo " --restore Restore dependencies" + echo " --build Build solution" + echo " --rebuild Rebuild solution" + echo " --test Run all unit tests in the solution" + echo " --sign Sign build outputs" + echo " --pack Package build outputs into NuGet packages and Willow components" echo "" echo "Advanced settings:" - echo " --solution Path to solution to build" - echo " --ci Set when running on CI server" - echo " --log Enable logging (by default on CI)" - echo " --prepareMachine Prepare machine for CI run" + echo " --solution Path to solution to build" + echo " --ci Set when running on CI server" + echo " --prepareMachine Prepare machine for CI run" echo "" echo "Command line arguments not listed above are passed through to MSBuild." exit 0 ;; - --log) - log=true - shift 1 - ;; --pack) pack=true shift 1 ;; - --prepareMachine) - prepareMachine=true + --preparemachine) + prepare_machine=true shift 1 ;; --rebuild) @@ -96,249 +115,198 @@ while [[ $# > 0 ]]; do esac done -function CreateDirectory { - if [ ! -d "$1" ] - then - mkdir -p "$1" - fi +# ReadJson [filename] [json key] +# Result: Sets 'readjsonvalue' to the value of the provided json key +# Note: this method may return unexpected results if there are duplicate +# keys in the json +function ReadJson { + local file=$1 + local key=$2 + + local unamestr="$(uname)" + local sedextended='-r' + if [[ "$unamestr" == 'Darwin' ]]; then + sedextended='-E' + fi; + + readjsonvalue="$(grep -m 1 "\"$key\"" $file | sed $sedextended 's/^ *//;s/.*: *"//;s/",?//')" + if [[ ! "$readjsonvalue" ]]; then + echo "Error: Cannot find \"$key\" in $file" >&2; + ExitWithExitCode 1 + fi; } -function GetVersionsPropsVersion { - echo "$( awk -F'[<>]' "/<$1>/{print \$3}" "$VersionsProps" )" -} +function InitializeDotNetCli { + # Disable first run since we want to control all package sources + export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 -function InstallDotNetCli { - DotNetCliVersion="$( GetVersionsPropsVersion DotNetCliVersion )" - DotNetInstallVerbosity="" + # Don't resolve runtime, shared framework, or SDK from other locations to ensure build determinism + export DOTNET_MULTILEVEL_LOOKUP=0 - if [ -z "$DOTNET_INSTALL_DIR" ] - then - export DOTNET_INSTALL_DIR="$RepoRoot/artifacts/.dotnet/$DotNetCliVersion" + # Source Build uses DotNetCoreSdkDir variable + if [[ -n "$DotNetCoreSdkDir" ]]; then + export DOTNET_INSTALL_DIR="$DotNetCoreSdkDir" fi - DotNetRoot=$DOTNET_INSTALL_DIR - DotNetInstallScript="$DotNetRoot/dotnet-install.sh" + ReadJson "$global_json_file" "version" + local dotnet_sdk_version="$readjsonvalue" + local dotnet_root="" - if [ ! -a "$DotNetInstallScript" ] - then - CreateDirectory "$DotNetRoot" - curl "https://dot.net/v1/dotnet-install.sh" -sSL -o "$DotNetInstallScript" - fi + # Use dotnet installation specified in DOTNET_INSTALL_DIR if it contains the required SDK version, + # otherwise install the dotnet CLI and SDK to repo local .dotnet directory to avoid potential permission issues. + if [[ -d "$DOTNET_INSTALL_DIR/sdk/$dotnet_sdk_version" ]]; then + dotnet_root="$DOTNET_INSTALL_DIR" + else + dotnet_root="$repo_root/.dotnet" + export DOTNET_INSTALL_DIR="$dotnet_root" - if [[ "$(echo $verbosity | awk '{print tolower($0)}')" == "diagnostic" ]] - then - DotNetInstallVerbosity="--verbose" + if [[ "$restore" == true ]]; then + InstallDotNetSdk $dotnet_root $dotnet_sdk_version + fi fi - # Install a stage 0 - SdkInstallDir="$DotNetRoot/sdk/$DotNetCliVersion" + build_driver="$dotnet_root/dotnet" +} + +function InstallDotNetSdk { + local root=$1 + local version=$2 - if [ ! -d "$SdkInstallDir" ] - then - bash "$DotNetInstallScript" --version $DotNetCliVersion $DotNetInstallVerbosity - LASTEXITCODE=$? + local install_script=`GetDotNetInstallScript $root` - if [ $LASTEXITCODE != 0 ] - then - echo "Failed to install stage0" - return $LASTEXITCODE - fi + bash "$install_script" --version $version --install-dir $root + local lastexitcode=$? + + if [[ $lastexitcode != 0 ]]; then + echo "Failed to install dotnet SDK (exit code '$lastexitcode')." + ExitWithExitCode $lastexitcode fi +} - # Install 1.0 shared framework - NetCoreApp10Version="1.0.5" - NetCoreApp10Dir="$DotNetRoot/shared/Microsoft.NETCore.App/$NetCoreApp10Version" +function GetDotNetInstallScript { + local root=$1 + local install_script="$root/dotnet-install.sh" - if [ ! -d "$NetCoreApp10Dir" ] - then - bash "$DotNetInstallScript" --channel "Preview" --version $NetCoreApp10Version --shared-runtime $DotNetInstallVerbosity - LASTEXITCODE=$? + if [[ ! -a "$install_script" ]]; then + mkdir -p "$root" - if [ $LASTEXITCODE != 0 ] - then - echo "Failed to install 1.0 shared framework" - return $LASTEXITCODE + # Use curl if available, otherwise use wget + if command -v curl > /dev/null; then + curl "https://dot.net/v1/dotnet-install.sh" -sSL --retry 10 --create-dirs -o "$install_script" + else + wget -q -O "$install_script" "https://dot.net/v1/dotnet-install.sh" fi fi - # Put the stage 0 on the path - export PATH="$DotNetRoot:$PATH" - - # Disable first run since we want to control all package sources - export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 - - # Don't resolve runtime, shared framework, or SDK from other locations - export DOTNET_MULTILEVEL_LOOKUP=0 + # return value + echo "$install_script" } -function InstallDotNetCliProjectJson { - DotNetCliProjectJsonVersion="$( GetVersionsPropsVersion DotNetCliProjectJsonVersion )" - DotNetInstallVerbosity="" - - DotNetRoot="$RepoRoot/artifacts/.dotnet/$DotNetCliProjectJsonVersion" - DotNetInstallScript="$DotNetRoot/dotnet-install.sh" +function InitializeToolset { + ReadJson $global_json_file "RoslynTools.RepoToolset" + local toolset_version=$readjsonvalue + local toolset_location_file="$toolset_dir/$toolset_version.txt" - if [ ! -a "$DotNetInstallScript" ] - then - CreateDirectory "$DotNetRoot" - curl "https://dot.net/v1/dotnet-install.sh" -sSL -o "$DotNetInstallScript" - fi + if [[ -a "$toolset_location_file" ]]; then + local path=`cat $toolset_location_file` + if [[ -a "$path" ]]; then + toolset_build_proj=$path + return + fi + fi - if [[ "$(echo $verbosity | awk '{print tolower($0)}')" == "diagnostic" ]] - then - DotNetInstallVerbosity="--verbose" + if [[ "$restore" != true ]]; then + echo "Toolset version $toolsetVersion has not been restored." + ExitWithExitCode 2 fi + + local proj="$toolset_dir/restore.proj" - # Install a stage 0 - SdkInstallDir="$DotNetRoot/sdk/$DotNetCliProjectJsonVersion" - - if [ ! -d "$SdkInstallDir" ] - then - bash "$DotNetInstallScript" --version $DotNetCliProjectJsonVersion --install-dir $DotNetRoot $DotNetInstallVerbosity - LASTEXITCODE=$? + echo '' > $proj + "$build_driver" msbuild $proj /t:__WriteToolsetLocation /m /nologo /clp:None /warnaserror /bl:$toolset_restore_log /v:$verbosity /p:__ToolsetLocationOutputFile=$toolset_location_file + local lastexitcode=$? - if [ $LASTEXITCODE != 0 ] - then - echo "Failed to install stage0" - return $LASTEXITCODE - fi + if [[ $lastexitcode != 0 ]]; then + echo "Failed to restore toolset (exit code '$lastexitcode'). See log: $toolset_restore_log" + ExitWithExitCode $lastexitcode fi -} -function InstallRepoToolset { - RepoToolsetVersion="$( GetVersionsPropsVersion RoslynToolsRepoToolsetVersion )" - RepoToolsetDir="$NuGetPackageRoot/roslyntools.repotoolset/$RepoToolsetVersion/tools" - RepoToolsetBuildProj="$RepoToolsetDir/Build.proj" + toolset_build_proj=`cat $toolset_location_file` - if $ci || $log - then - CreateDirectory $LogDir - logCmd="/bl:$LogDir/Build.binlog" - else - logCmd="" + if [[ ! -a "$toolset_build_proj" ]]; then + echo "Invalid toolset path: $toolset_build_proj" + ExitWithExitCode 3 fi +} - if [ ! -d "$RepoToolsetBuildProj" ] - then - ToolsetProj="$ScriptRoot/Toolset.proj" - dotnet msbuild $ToolsetProj /t:restore /m /nologo /clp:Summary /warnaserror /v:$verbosity $logCmd - LASTEXITCODE=$? +function InitializeCustomToolset { + local script="$repo_root/build/RestoreToolset.sh" - if [ $LASTEXITCODE != 0 ] - then - echo "Failed to build $ToolsetProj" - return $LASTEXITCODE - fi + if [[ -a "$script" ]]; then + . "$script" fi } function Build { - InstallDotNetCliProjectJson - - if [ $? != 0 ] - then - return $? + "$build_driver" msbuild $toolset_build_proj /m /nologo /clp:Summary /warnaserror \ + /v:$verbosity /bl:$build_log /p:Configuration=$configuration /p:Projects=$projects /p:RepoRoot="$repo_root" \ + /p:Restore=$restore /p:Build=$build /p:Rebuild=$rebuild /p:Deploy=$deploy /p:Test=$test /p:Sign=$sign /p:Pack=$pack /p:CIBuild=$ci \ + $properties + local lastexitcode=$? + + if [[ $lastexitcode != 0 ]]; then + echo "Failed to build $toolset_build_proj" + ExitWithExitCode $lastexitcode fi +} - InstallDotNetCli - - if [ $? != 0 ] - then - return $? +function ExitWithExitCode { + if [[ "$ci" == true && "$prepare_machine" == true ]]; then + StopProcesses fi + exit $1 +} - InstallRepoToolset +function StopProcesses { + echo "Killing running build processes..." + pkill -9 "dotnet" + pkill -9 "vbcscompiler" +} - if [ $? != 0 ] - then - return $? +function Main { + # HOME may not be defined in some scenarios, but it is required by NuGet + if [[ -z $HOME ]]; then + export HOME="$repo_root/artifacts/.home/" + mkdir -p "$HOME" fi - if $prepareMachine - then - CreateDirectory "$NuGetPackageRoot" - dotnet nuget locals all --clear - LASTEXITCODE=$? - - if [ $LASTEXITCODE != 0 ] - then - echo "Failed to clear NuGet cache" - return $LASTEXITCODE - fi + if [[ -z $projects ]]; then + projects="$repo_root/*.sln" fi - if $ci || $log - then - CreateDirectory $LogDir - logCmd="/bl:$LogDir/Build.binlog" - else - logCmd="" + if [[ -z $NUGET_PACKAGES ]]; then + if [[ $ci ]]; then + export NUGET_PACKAGES="$repo_root/.packages" + else + export NUGET_PACKAGES="$HOME/.nuget/packages" + fi fi - if [ -z $solution ] - then - solution="$RepoRoot/cli-migrate.sln" + mkdir -p "$toolset_dir" + mkdir -p "$log_dir" + + if [[ $ci ]]; then + mkdir -p "$temp_dir" + export TEMP="$temp_dir" + export TMP="$temp_dir" fi - dotnet msbuild $RepoToolsetBuildProj /m /nologo /clp:Summary /warnaserror /v:$verbosity $logCmd /p:Configuration=$configuration /p:SolutionPath=$solution /p:Restore=$restore /p:Build=$build /p:Rebuild=$rebuild /p:Deploy=$deploy /p:Test=$test /p:Sign=$sign /p:Pack=$pack /p:CIBuild=$ci $properties - LASTEXITCODE=$? + InitializeDotNetCli + InitializeToolset + InitializeCustomToolset - if [ $LASTEXITCODE != 0 ] - then - echo "Failed to build $RepoToolsetBuildProj" - return $LASTEXITCODE - fi + Build + ExitWithExitCode $? } -function StopProcesses { - echo "Killing running build processes..." - pkill -9 "msbuild" - pkill -9 "vbcscompiler" -} - -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - ScriptRoot="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - SOURCE="$(readlink "$SOURCE")" - [[ $SOURCE != /* ]] && SOURCE="$ScriptRoot/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -ScriptRoot="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - -RepoRoot="$ScriptRoot/../" -ArtifactsDir="$RepoRoot/artifacts" -ArtifactsConfigurationDir="$ArtifactsDir/$configuration" -LogDir="$ArtifactsConfigurationDir/log" -VersionsProps="$ScriptRoot/Versions.props" - -# HOME may not be defined in some scenarios, but it is required by NuGet -if [ -z $HOME ] -then - export HOME="$RepoRoot/artifacts/.home/" - CreateDirectory "$HOME" -fi - -if $ci -then - TempDir="$ArtifactsConfigurationDir/tmp" - CreateDirectory "$TempDir" - - export TEMP="$TempDir" - export TMP="$TempDir" -fi - -if [ -z $NUGET_PACKAGES ] -then - export NUGET_PACKAGES="$HOME/.nuget/packages" -fi - -NuGetPackageRoot=$NUGET_PACKAGES - -Build -LASTEXITCODE=$? - -if $ci && $prepareMachine -then - StopProcesses -fi - -exit $LASTEXITCODE +Main \ No newline at end of file diff --git a/build/cibuild.cmd b/build/cibuild.cmd index 997546ab..26d1c405 100644 --- a/build/cibuild.cmd +++ b/build/cibuild.cmd @@ -1,3 +1,3 @@ @echo off -powershell -NoLogo -NoProfile -ExecutionPolicy ByPass %~dp0Build.ps1 -restore -build -test -sign -pack -ci %* +powershell -ExecutionPolicy ByPass -command "& {&'%~dp0Build.ps1' -restore -build -test -sign -pack -ci %*} exit /b %ErrorLevel% diff --git a/build/cibuild.sh b/build/cibuild.sh index f3524080..b5112539 100755 --- a/build/cibuild.sh +++ b/build/cibuild.sh @@ -1,11 +1,16 @@ -#!/bin/bash +#!/usr/bin/env bash -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - ScriptRoot="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - SOURCE="$(readlink "$SOURCE")" - [[ $SOURCE != /* ]] && SOURCE="$ScriptRoot/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located +source="${BASH_SOURCE[0]}" + +# resolve $SOURCE until the file is no longer a symlink +while [[ -h $source ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + + # if $source was a relative symlink, we need to resolve it relative to the path where + # the symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" done -ScriptRoot="$( cd -P "$( dirname "$SOURCE" )" && pwd )" +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" -. "$ScriptRoot/build.sh" --restore --build --test --ci $@ +. "$scriptroot/build.sh" --restore --build --test --ci $@ \ No newline at end of file diff --git a/global.json b/global.json new file mode 100644 index 00000000..9e8cb368 --- /dev/null +++ b/global.json @@ -0,0 +1,8 @@ +{ + "sdk": { + "version": "2.1.101" + }, + "msbuild-sdks": { + "RoslynTools.RepoToolset": "1.0.0-beta2-62804-01" + } +} diff --git a/nuget.config b/nuget.config new file mode 100644 index 00000000..071c39f2 --- /dev/null +++ b/nuget.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/Assets/TestProjects/LibraryWithoutNetStandardLibRef/project.json b/src/Assets/TestProjects/LibraryWithoutNetStandardLibRef/project.json index 2e3c0dce..4a40e3e1 100644 --- a/src/Assets/TestProjects/LibraryWithoutNetStandardLibRef/project.json +++ b/src/Assets/TestProjects/LibraryWithoutNetStandardLibRef/project.json @@ -2,7 +2,7 @@ "frameworks": { "netstandard1.3": { "dependencies": { - "System.AppContext": "4.1.0" + "System.AppContext": "4.3.0" } } } diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 0a9a00c0..692ae7c0 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -7,7 +7,6 @@ - MicrosoftAspNet @@ -22,8 +21,4 @@ false - - false - - diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets deleted file mode 100644 index 1692a689..00000000 --- a/src/Directory.Build.targets +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.ProjectJsonMigration.csproj b/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.ProjectJsonMigration.csproj index 6ff4ae0d..4f83b766 100644 --- a/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.ProjectJsonMigration.csproj +++ b/src/Microsoft.DotNet.ProjectJsonMigration/Microsoft.DotNet.ProjectJsonMigration.csproj @@ -1,15 +1,9 @@  - + - Library netstandard1.6 - - - - - true true @@ -33,6 +27,4 @@ - - diff --git a/src/Microsoft.DotNet.Tools.MigrateCommand/Microsoft.DotNet.Tools.MigrateCommand.csproj b/src/Microsoft.DotNet.Tools.MigrateCommand/Microsoft.DotNet.Tools.MigrateCommand.csproj index aa901be4..f3a5d404 100644 --- a/src/Microsoft.DotNet.Tools.MigrateCommand/Microsoft.DotNet.Tools.MigrateCommand.csproj +++ b/src/Microsoft.DotNet.Tools.MigrateCommand/Microsoft.DotNet.Tools.MigrateCommand.csproj @@ -1,15 +1,9 @@  - + - Library netstandard1.6 - - - - - true true @@ -18,6 +12,4 @@ - - diff --git a/src/Tests/Microsoft.DotNet.Cli.Build.Framework/Microsoft.DotNet.Cli.Build.Framework.csproj b/src/Tests/Microsoft.DotNet.Cli.Build.Framework/Microsoft.DotNet.Cli.Build.Framework.csproj index df7ab045..875b56ee 100644 --- a/src/Tests/Microsoft.DotNet.Cli.Build.Framework/Microsoft.DotNet.Cli.Build.Framework.csproj +++ b/src/Tests/Microsoft.DotNet.Cli.Build.Framework/Microsoft.DotNet.Cli.Build.Framework.csproj @@ -1,24 +1,19 @@  - + netstandard1.6 - Tests\$(MSBuildProjectName) false - - - - diff --git a/src/Tests/Microsoft.DotNet.ProjectJsonMigration.Tests/Microsoft.DotNet.ProjectJsonMigration.Tests.csproj b/src/Tests/Microsoft.DotNet.ProjectJsonMigration.Tests/Microsoft.DotNet.ProjectJsonMigration.Tests.csproj index 05a5d802..a50942f2 100644 --- a/src/Tests/Microsoft.DotNet.ProjectJsonMigration.Tests/Microsoft.DotNet.ProjectJsonMigration.Tests.csproj +++ b/src/Tests/Microsoft.DotNet.ProjectJsonMigration.Tests/Microsoft.DotNet.ProjectJsonMigration.Tests.csproj @@ -1,19 +1,12 @@  - + Exe - netcoreapp1.1 + netcoreapp2.0 - - true - Tests\$(MSBuildProjectName) - - - - @@ -48,7 +41,4 @@ - - - diff --git a/src/Tests/Microsoft.DotNet.TestFramework/Microsoft.DotNet.TestFramework.csproj b/src/Tests/Microsoft.DotNet.TestFramework/Microsoft.DotNet.TestFramework.csproj index 9e8a0997..eb3b6c1e 100644 --- a/src/Tests/Microsoft.DotNet.TestFramework/Microsoft.DotNet.TestFramework.csproj +++ b/src/Tests/Microsoft.DotNet.TestFramework/Microsoft.DotNet.TestFramework.csproj @@ -1,22 +1,17 @@  - + netstandard1.6 - Tests\$(MSBuildProjectName) false - - - - diff --git a/src/Tests/Microsoft.DotNet.TestFramework/TestAssets.cs b/src/Tests/Microsoft.DotNet.TestFramework/TestAssets.cs index 0e47e3ba..2ddab886 100644 --- a/src/Tests/Microsoft.DotNet.TestFramework/TestAssets.cs +++ b/src/Tests/Microsoft.DotNet.TestFramework/TestAssets.cs @@ -47,12 +47,12 @@ public TestAssets(DirectoryInfo assetsRoot, FileInfo dotnetCsprojExe, FileInfo d if (!dotnetCsprojExe.Exists) { - throw new FileNotFoundException("Csproj dotnet executable must exist", dotnetCsprojExe.FullName); + throw new FileNotFoundException($"Csproj dotnet executable must exist: '{dotnetCsprojExe.FullName}'", dotnetCsprojExe.FullName); } if (!dotnetProjectJsonExe.Exists) { - throw new FileNotFoundException("project.json dotnet executable must exist", dotnetProjectJsonExe.FullName); + throw new FileNotFoundException($"project.json dotnet executable must exist: '{dotnetProjectJsonExe.FullName}'", dotnetProjectJsonExe.FullName); } _root = assetsRoot; diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/Commands/BuildPJCommand.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/Commands/BuildPJCommand.cs index 6b05edfe..7037ab44 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/Commands/BuildPJCommand.cs +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/Commands/BuildPJCommand.cs @@ -27,7 +27,7 @@ public sealed class BuildPJCommand : TestCommand private DirectoryInfo _workingDirectory; public BuildPJCommand() - : base(new RepoDirectoriesProvider().PjDotnet) + : base(RepoDirectoriesProvider.DotNetProjectJsonPath) { } diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/Commands/RestoreProjectJsonCommand.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/Commands/RestoreProjectJsonCommand.cs index a54d8960..6d5ad5cd 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/Commands/RestoreProjectJsonCommand.cs +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/Commands/RestoreProjectJsonCommand.cs @@ -8,7 +8,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities public sealed class RestoreProjectJsonCommand : TestCommand { public RestoreProjectJsonCommand() - : base(new RepoDirectoriesProvider().PjDotnet) + : base(RepoDirectoriesProvider.DotNetProjectJsonPath) { } diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/Microsoft.DotNet.Tools.Tests.Utilities.csproj b/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/Microsoft.DotNet.Tools.Tests.Utilities.csproj index 75807587..a672d838 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/Microsoft.DotNet.Tools.Tests.Utilities.csproj +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/Microsoft.DotNet.Tools.Tests.Utilities.csproj @@ -1,17 +1,11 @@  - + netstandard1.6 - - - - Tests\$(MSBuildProjectName) false - - @@ -32,6 +26,20 @@ - + + <_RepoDirectoriesFile>$(IntermediateOutputPath)\RepoDirectories.g.cs + + + + <_Attribute Include="Microsoft.DotNet.Tools.Test.Utilities.RepoDirectoriesAttribute"> + <_Parameter1>$(RepoRoot) + + + + + + + + diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/RepoDirectoriesAttribute.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/RepoDirectoriesAttribute.cs new file mode 100644 index 00000000..4d81aa63 --- /dev/null +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/RepoDirectoriesAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace Microsoft.DotNet.Tools.Test.Utilities +{ + [AttributeUsage(AttributeTargets.Assembly)] + internal class RepoDirectoriesAttribute : Attribute + { + public string RepoRoot { get; } + + public RepoDirectoriesAttribute(string repoRoot) + { + RepoRoot = repoRoot; + } + } +} diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/RepoDirectoriesProvider.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/RepoDirectoriesProvider.cs index 11ce13d7..2cdda222 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/RepoDirectoriesProvider.cs +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/RepoDirectoriesProvider.cs @@ -4,59 +4,24 @@ using System; using System.IO; using System.Linq; -using System.Xml.Linq; +using System.Reflection; using Microsoft.DotNet.Cli.Build.Framework; using Microsoft.DotNet.PlatformAbstractions; namespace Microsoft.DotNet.Tools.Test.Utilities { - public class RepoDirectoriesProvider + public static class RepoDirectoriesProvider { - public RepoDirectoriesProvider( - string artifacts = null, - string nugetPackages = null, - string pjDotnet = null) - { - Artifacts = artifacts ?? Path.Combine(RepoRoot, "artifacts", GetConfiguration()); - NugetPackages = nugetPackages ?? Path.Combine(RepoRoot, "artifacts", ".nuget", "packages"); - PjDotnet = pjDotnet ?? GetPjDotnetPath(Artifacts); - } - - private static string s_repoRoot; private static string s_buildRid; - public string Artifacts { get; } - public string NugetPackages { get; } - public string PjDotnet { get; } - - public static string RepoRoot - { - get - { - if (!string.IsNullOrEmpty(s_repoRoot)) - { - return s_repoRoot; - } -#if NET451 - string directory = AppDomain.CurrentDomain.BaseDirectory; -#else - var directory = AppContext.BaseDirectory; -#endif - while (!Directory.Exists(Path.Combine(directory, ".git")) && directory != null) - { - directory = Directory.GetParent(directory).FullName; - } - - s_repoRoot = directory ?? throw new Exception("Cannot find the git repository root"); - return s_repoRoot; - } - } + public static string TestAssetsRoot { get; } + public static string DotNetProjectJsonPath { get; } - private static string GetConfiguration() + static RepoDirectoriesProvider() { - // This is dependent on the current artifacts layout: - // * $(RepoRoot)/artifacts/$(Configuration)/bin/Tests/$(MSBuildProjectName) - return new DirectoryInfo(AppContext.BaseDirectory).Parent.Parent.Parent.Name; + var attribute = typeof(RepoDirectoriesProvider).GetTypeInfo().Assembly.GetCustomAttribute(); + TestAssetsRoot = Path.Combine(attribute.RepoRoot, "src", "Assets"); + DotNetProjectJsonPath = Path.Combine(attribute.RepoRoot, ".dotnet-test", "dotnet" + Constants.ExeSuffix); } public static string BuildRid @@ -72,31 +37,5 @@ public static string BuildRid return s_buildRid; } } - - private static string GetPjDotnetPath(string artifacts) - { - var dotnetCliProjectJsonVersion = GetDotNetCliProjectJsonVersion(RepoRoot); - - return new DirectoryInfo(Path.Combine(RepoRoot, "artifacts", ".dotnet", dotnetCliProjectJsonVersion)) - .GetFiles("dotnet" + Constants.ExeSuffix).First() - .FullName; - } - - private static string GetDotNetCliProjectJsonVersion(string repoRoot) - { - var xml = XDocument.Load(Path.Combine(repoRoot, "build", "Versions.props")); - - foreach (var propertyGroup in xml.Descendants(XName.Get("PropertyGroup", "http://schemas.microsoft.com/developer/msbuild/2003"))) - { - var dotnetCliVersion = propertyGroup.Descendants(XName.Get("DotNetCliProjectJsonVersion", "http://schemas.microsoft.com/developer/msbuild/2003")); - - if (dotnetCliVersion.Any()) - { - return dotnetCliVersion.Single().Value; - } - } - - throw new Exception("Failed to locate the .NET CLI Version"); - } } } \ No newline at end of file diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/TestBase.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/TestBase.cs index 0199623b..660df638 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/TestBase.cs +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.Utilities/TestBase.cs @@ -23,27 +23,18 @@ public abstract class TestBase : IDisposable private TempRoot _temp; private static TestAssets s_testAssets; - - protected static string RepoRoot - { - get - { - return RepoDirectoriesProvider.RepoRoot; - } - } - protected static TestAssets TestAssets { get { if (s_testAssets == null) { - var assetsRoot = Path.Combine(RepoRoot, "src", "Assets"); + var assetsRoot = RepoDirectoriesProvider.TestAssetsRoot; s_testAssets = new TestAssets( new DirectoryInfo(assetsRoot), new FileInfo(new Muxer().MuxerPath), - new FileInfo(new RepoDirectoriesProvider().PjDotnet)); + new FileInfo(RepoDirectoriesProvider.DotNetProjectJsonPath)); } return s_testAssets; diff --git a/src/Tests/dotnet-migrate.Tests/dotnet-migrate.Tests.csproj b/src/Tests/dotnet-migrate.Tests/dotnet-migrate.Tests.csproj index 94dd2703..1c8f06ff 100644 --- a/src/Tests/dotnet-migrate.Tests/dotnet-migrate.Tests.csproj +++ b/src/Tests/dotnet-migrate.Tests/dotnet-migrate.Tests.csproj @@ -1,19 +1,11 @@  - + - Exe - netcoreapp1.1 + netcoreapp2.0 - - true - Tests\$(MSBuildProjectName) - - - - @@ -48,6 +40,4 @@ DestinationFiles="@(_CopyDirectoryBuildTestDependenciesOutput)" /> - -