Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Users/ersciple/m117fallback #4170

Merged
merged 1 commit into from
May 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Tasks/Common/MSBuildHelpers/MSBuildHelpers.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ Export-ModuleMember -Function @(
'Get-MSBuildPath'
'Get-SolutionFiles'
'Get-VisualStudio_15_0'
'Select-MSBuildPath'
)
132 changes: 110 additions & 22 deletions Tasks/Common/MSBuildHelpers/PathFunctions.ps1
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
########################################
# Public functions.
########################################
$script:visualStudioCache = @{ }

########################################
# Public functions.
########################################
Expand Down Expand Up @@ -170,30 +175,113 @@ function Get-VisualStudio_15_0 {

Trace-VstsEnteringInvocation $MyInvocation
try {
# Query for the latest 15.0.* version.
#
# Note, even though VS 15 Update 1 is sometimes referred to as "15.1", the actual installation
# version number is 15.0.26403.7.
#
# Also note, the capability is registered as VisualStudio_15.0, so the following code should
# query for 15.0.* versions only.
Write-Verbose "Getting latest Visual Studio 15 setup instance."
$output = New-Object System.Text.StringBuilder
Invoke-VstsTool -FileName "$PSScriptRoot\vswhere.exe" -Arguments "-version [15.0,15.1) -latest -format json" -RequireExitCodeZero 2>&1 |
ForEach-Object {
if ($_ -is [System.Management.Automation.ErrorRecord]) {
Write-Verbose "STDERR: $($_.Exception.Message)"
}
else {
Write-Verbose $_
$null = $output.AppendLine($_)
}
if (!$script:visualStudioCache.ContainsKey('15.0')) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i added a cache since VSBuild potentially calls twice. Once to resolve VS, and then again to resolve MSBuild location.

try {
# Query for the latest 15.0.* version.
#
# Note, even though VS 15 Update 1 is sometimes referred to as "15.1", the actual installation
# version number is 15.0.26403.7.
#
# Also note, the capability is registered as VisualStudio_15.0, so the following code should
# query for 15.0.* versions only.
Write-Verbose "Getting latest Visual Studio 15 setup instance."
$output = New-Object System.Text.StringBuilder
Invoke-VstsTool -FileName "$PSScriptRoot\vswhere.exe" -Arguments "-version [15.0,15.1) -latest -format json" -RequireExitCodeZero 2>&1 |
ForEach-Object {
if ($_ -is [System.Management.Automation.ErrorRecord]) {
Write-Verbose "STDERR: $($_.Exception.Message)"
}
else {
Write-Verbose $_
$null = $output.AppendLine($_)
}
}
$script:visualStudioCache['15.0'] = (ConvertFrom-Json -InputObject $output.ToString()) |
Select-Object -First 1
} catch {
Write-Verbose ($_ | Out-String)
$script:visualStudioCache['15.0'] = $null
}
return (ConvertFrom-Json -InputObject $output.ToString()) |
Select-Object -First 1
} catch {
Write-Verbose ($_ | Out-String)
}

return $script:visualStudioCache['15.0']
} finally {
Trace-VstsLeavingInvocation $MyInvocation
}
}

function Select-MSBuildPath {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

xamarin android and msbuild tasks both use this same logic, so i moved it into the common module

[CmdletBinding()]
param(
[string]$Method,
[string]$Location,
[string]$PreferredVersion,
[string]$Architecture)

Trace-VstsEnteringInvocation $MyInvocation
try {
# Default the msbuildLocationMethod if not specified. The input msbuildLocationMethod
# was added to the definition after the input msbuildLocation.
if ("$Method".ToUpperInvariant() -ne 'LOCATION' -and "$Method".ToUpperInvariant() -ne 'VERSION') {
# Infer the msbuildLocationMethod based on the whether msbuildLocation is specified.
if ($Location) {
$Method = 'location'
} else {
$Method = 'version'
}

Write-Verbose "Defaulted MSBuild location method to: $Method"
}

if ("$Method".ToUpperInvariant() -eq 'LOCATION') {
# Return the location.
if ($Location) {
return $Location
}

# Fallback to version lookup.
Write-Verbose "Location not specified. Looking up by version instead."
}

$specificVersion = $PreferredVersion -and $PreferredVersion -ne 'latest'
$versions = '15.0', '14.0', '12.0', '4.0' | Where-Object { $_ -ne $PreferredVersion }

# Look for a specific version of MSBuild.
if ($specificVersion) {
if (($path = Get-MSBuildPath -Version $PreferredVersion -Architecture $Architecture)) {
return $path
}

# Do not fallback from 15.0.
if ($PreferredVersion -eq '15.0') {
Write-Error (Get-VstsLocString -Key 'MSB_MSBuild15NotFoundionArchitecture0' -ArgumentList $Architecture)
return
}

# Attempt to fallback.
$versions = $versions | Where-Object { $_ -ne '15.0' } # Fallback is only between 14.0-4.0.
Write-Verbose "Specified version '$PreferredVersion' and architecture '$Architecture' not found. Attempting to fallback."
}

# Look for the latest version of MSBuild.
foreach ($version in $versions) {
if (($path = Get-MSBuildPath -Version $version -Architecture $Architecture)) {
# Warn falling back.
if ($specificVersion) {
Write-Warning (Get-VstsLocString -Key 'MSB_UnableToFindMSBuildVersion0Architecture1FallbackVersion2' -ArgumentList $PreferredVersion, $Architecture, $version)
}

return $path
}
}

# Error. Not found.
if ($specificVersion) {
Write-Error (Get-VstsLocString -Key 'MSB_MSBuildNotFoundVersion0Architecture1' -ArgumentList $PreferredVersion, $Architecture)
} else {
Write-Error (Get-VstsLocString -Key 'MSB_MSBuildNotFound')
}
} finally {
Trace-VstsLeavingInvocation $MyInvocation
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
{
"loc.messages.MSB_Build0": "Build {0}",
"loc.messages.MSB_BuildToolNotFound": "MSBuild or xbuild(Mono) were not found on the Mac/Linux agent.",
"loc.messages.MSB_DetectedNuGetExtensionsLoaderPath0": "Detected NuGet extensions loader path. Environment variable NUGET_EXTENSIONS_PATH is set to '{0}'.",
"loc.messages.MSB_SolutionNotFoundUsingSearchPattern0": "Solution not found using search pattern '{0}'.",
"loc.messages.MSB_MSBuild15NotFoundionArchitecture0": "MSBuild version '15.0' was not found for architecture '{0}'. Verify the architecture input value is correct and verify Visual Studio 2017 is installed. MSBuild version '15.0' is included when Visual Studio 2017 is installed.",
"loc.messages.MSB_MSBuildNotFound": "MSBuild was not found. Try specifying the location to msbuild.exe or install Visual Studio. MSBuild is included when Visual Studio is installed.",
"loc.messages.MSB_MSBuildNotFoundVersion0Architecture1": "MSBuild was not found for version '{0}' and architecture '{1}'. Try a different version/architecture combination, specify a location, or install the appropriate version of Visual Studio. MSBuild is included when Visual Studio is installed.",
"loc.messages.MSB_RestoreNuGetPackagesDeprecated": "The 'Restore NuGet Packages' option is deprecated. To restore NuGet packages in your build, add a NuGet Installer task to your build definition.",
"loc.messages.MSB_BuildToolNotFound": "MSBuild or xbuild(Mono) were not found on the Mac/Linux agent."
"loc.messages.MSB_SolutionNotFoundUsingSearchPattern0": "Solution not found using search pattern '{0}'.",
"loc.messages.MSB_UnableToFindMSBuildVersion0Architecture1FallbackVersion2": "Unable to find MSBuild version '{0}' for architecture '{1}'. Falling back to version '{2}'."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[CmdletBinding()]
param()

# Arrange.
. $PSScriptRoot\..\..\..\..\Tests\lib\Initialize-Test.ps1
Microsoft.PowerShell.Core\Import-Module $PSScriptRoot\..
$script:count = 0
Register-Mock Invoke-VstsTool {
$script:count++
"["
"]"
} -- -FileName (Resolve-Path $PSScriptRoot\..\vswhere.exe).Path -Arguments "-version [15.0,15.1) -latest -format json" -RequireExitCodeZero

# Act.
$null = Get-VisualStudio_15_0
$actual = Get-VisualStudio_15_0

# Assert.
Assert-AreEqual -Expected $null -Actual $actual
Assert-AreEqual -Expected 1 -Actual $script:count
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[CmdletBinding()]
param()

# Arrange.
. $PSScriptRoot\..\..\..\..\Tests\lib\Initialize-Test.ps1
Microsoft.PowerShell.Core\Import-Module $PSScriptRoot\..
$script:count = 0
Register-Mock Invoke-VstsTool {
$script:count++
"["
" {"
" `"installationPath`": `"path$script:count`""
" }"
"]"
} -- -FileName (Resolve-Path $PSScriptRoot\..\vswhere.exe).Path -Arguments "-version [15.0,15.1) -latest -format json" -RequireExitCodeZero

# Act.
$null = Get-VisualStudio_15_0
$actual = Get-VisualStudio_15_0

# Assert.
Assert-AreEqual -Expected "path1" -Actual $actual.installationPath
Assert-AreEqual -Expected 1 -Actual $script:count
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[CmdletBinding()]
param()

# Arrange.
. $PSScriptRoot\..\..\..\..\Tests\lib\Initialize-Test.ps1
Microsoft.PowerShell.Core\Import-Module $PSScriptRoot\..
Register-Mock Invoke-VstsTool {
Write-Error "Some simulated STDERR content" -ErrorAction Continue 2>&1
"["
" {"
" `"installationPath`": `"some path`""
" }"
"]"
} -- -FileName (Resolve-Path $PSScriptRoot\..\vswhere.exe).Path -Arguments "-version [15.0,15.1) -latest -format json" -RequireExitCodeZero

# Act.
$actual = Get-VisualStudio_15_0

# Assert.
Assert-AreEqual -Expected "some path" -Actual $actual.installationPath
45 changes: 42 additions & 3 deletions Tasks/Common/MSBuildHelpers/Tests/L0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ describe('Common-MSBuildHelpers Suite', function () {
it('(Format-MSBuildArguments) adds maximum CPU count', (done) => {
psr.run(path.join(__dirname, 'Format-MSBuildArguments.AddsMaximumCpuCount.ps1'), done);
})
it('(Format-MSBuildArguments) adds MS deploy user agent property', (done) => {
psr.run(path.join(__dirname, 'Format-MSBuildArguments.AddsMSDeployUserAgentProperty.ps1'), done);
})
it('(Format-MSBuildArguments) adds platform property', (done) => {
psr.run(path.join(__dirname, 'Format-MSBuildArguments.AddsPlatformProperty.ps1'), done);
})
it('(Format-MSBuildArguments) adds VS version property', (done) => {
psr.run(path.join(__dirname, 'Format-MSBuildArguments.AddsVSVersionProperty.ps1'), done);
})
it('(Format-MSBuildArguments) adds MS deploy user agent property', (done) => {
psr.run(path.join(__dirname, 'Format-MSBuildArguments.AddsMSDeployUserAgentProperty.ps1'), done);
})
it('(Get-SolutionFiles) resolves wildcards', (done) => {
psr.run(path.join(__dirname, 'Get-SolutionFiles.ResolvesWildcards.ps1'), done);
})
Expand All @@ -54,6 +54,15 @@ describe('Common-MSBuildHelpers Suite', function () {
it('(Get-SolutionFiles) throws if no solution found', (done) => {
psr.run(path.join(__dirname, 'Get-SolutionFiles.ThrowsIfNoSolutionFound.ps1'), done);
})
it('(Get-VisualStudio_15_0) caches not found result', (done) => {
psr.run(path.join(__dirname, 'Get-VisualStudio_15_0.CachesNotFoundResult.ps1'), done);
})
it('(Get-VisualStudio_15_0) caches result', (done) => {
psr.run(path.join(__dirname, 'Get-VisualStudio_15_0.CachesResult.ps1'), done);
})
it('(Get-VisualStudio_15_0) ignores STDERR', (done) => {
psr.run(path.join(__dirname, 'Get-VisualStudio_15_0.IgnoresStderr.ps1'), done);
})
it('(Invoke-BuildTools) invokes all tools for all files', (done) => {
psr.run(path.join(__dirname, 'Invoke-BuildTools.InvokesAllToolsForAllFiles.ps1'), done);
})
Expand All @@ -78,5 +87,35 @@ describe('Common-MSBuildHelpers Suite', function () {
it('(Invoke-MSBuild) writes root timeline detail', (done) => {
psr.run(path.join(__dirname, 'Invoke-MSBuild.WritesRootTimelineDetail.ps1'), done);
})
it('(Select-MSBuildPath) defaults method to location if location specified', (done) => {
psr.run(path.join(__dirname, 'Select-MSBuildPath.DefaultsMethodToLocationIfLocationSpecified.ps1'), done);
})
it('(Select-MSBuildPath) defaults method to version if no location', (done) => {
psr.run(path.join(__dirname, 'Select-MSBuildPath.DefaultsMethodToVersionIfNoLocation.ps1'), done);
})
it('(Select-MSBuildPath) does not fallback from 15', (done) => {
psr.run(path.join(__dirname, 'Select-MSBuildPath.DoesNotFallbackFrom15.ps1'), done);
})
it('(Select-MSBuildPath) errors if version not found', (done) => {
psr.run(path.join(__dirname, 'Select-MSBuildPath.ErrorsIfVersionNotFound.ps1'), done);
})
it('(Select-MSBuildPath) falls back from 14', (done) => {
psr.run(path.join(__dirname, 'Select-MSBuildPath.FallsBackFrom14.ps1'), done);
})
it('(Select-MSBuildPath) falls back to version if no location specified', (done) => {
psr.run(path.join(__dirname, 'Select-MSBuildPath.FallsBackToVersionIfNoLocationSpecified.ps1'), done);
})
it('(Select-MSBuildPath) falls forward from 12', (done) => {
psr.run(path.join(__dirname, 'Select-MSBuildPath.FallsForwardFrom12.ps1'), done);
})
it('(Select-MSBuildPath) returns latest version', (done) => {
psr.run(path.join(__dirname, 'Select-MSBuildPath.ReturnsLatestVersion.ps1'), done);
})
it('(Select-MSBuildPath) returns specified location', (done) => {
psr.run(path.join(__dirname, 'Select-MSBuildPath.ReturnsSpecifiedLocation.ps1'), done);
})
it('(Select-MSBuildPath) returns specified version', (done) => {
psr.run(path.join(__dirname, 'Select-MSBuildPath.ReturnsSpecifiedVersion.ps1'), done);
})
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[cmdletbinding()]
param()

# Arrange.
. $PSScriptRoot\..\..\..\..\Tests\lib\Initialize-Test.ps1
Microsoft.PowerShell.Core\Import-Module $PSScriptRoot\..
$method = ''
$location = 'some location'
$version = 'some version'
$architecture = 'some architecture'

# Act.
$actual = Select-MSBuildPath -Method $method -Location $location -PreferredVersion $version -Architecture $architecture

# Assert.
Assert-AreEqual -Expected $location -Actual $actual
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[cmdletbinding()]
param()

# Arrange.
. $PSScriptRoot\..\..\..\..\Tests\lib\Initialize-Test.ps1
Microsoft.PowerShell.Core\Import-Module $PSScriptRoot\..
Register-Mock Get-MSBuildPath { 'Some resolved location' } -- -Version '15.0' -Architecture 'Some architecture'

# Act.
$actual = Select-MSBuildPath -Method '' -Location '' -PreferredVersion '' -Architecture 'Some architecture'

# Assert.
Assert-AreEqual -Expected 'Some resolved location' -Actual $actual
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[cmdletbinding()]
param()

# Arrange.
. $PSScriptRoot\..\..\..\..\Tests\lib\Initialize-Test.ps1
Microsoft.PowerShell.Core\Import-Module $PSScriptRoot\..
Register-Mock Get-MSBuildPath

# Act/Assert.
Assert-Throws { Select-MSBuildPath -Method 'Version' -Location '' -PreferredVersion '15.0' -Architecture 'Some architecture' }
Assert-WasCalled Get-MSBuildPath -- -Version '15.0' -Architecture 'Some architecture'
Assert-WasCalled Get-MSBuildPath -Times 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[cmdletbinding()]
param()

# Arrange.
. $PSScriptRoot\..\..\..\..\Tests\lib\Initialize-Test.ps1
Microsoft.PowerShell.Core\Import-Module $PSScriptRoot\..
Register-Mock Get-MSBuildPath

# Act/Assert.
Assert-Throws { Select-MSBuildPath -Method 'Version' -Location '' -PreferredVersion '' -Architecture 'Some architecture' }
Assert-WasCalled Get-MSBuildPath -- -Version '15.0' -Architecture 'Some architecture'
Assert-WasCalled Get-MSBuildPath -- -Version '14.0' -Architecture 'Some architecture'
Assert-WasCalled Get-MSBuildPath -- -Version '12.0' -Architecture 'Some architecture'
Assert-WasCalled Get-MSBuildPath -- -Version '4.0' -Architecture 'Some architecture'
Assert-WasCalled Get-MSBuildPath -Times 4
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[cmdletbinding()]
param()

# Arrange.
. $PSScriptRoot\..\..\..\..\Tests\lib\Initialize-Test.ps1
Microsoft.PowerShell.Core\Import-Module $PSScriptRoot\..
Register-Mock Write-Warning
Register-Mock Get-MSBuildPath { 'Some resolved location' } -- -Version '12.0' -Architecture 'Some architecture'

# Act.
$actual = Select-MSBuildPath -Method 'Version' -Location '' -PreferredVersion '14.0' -Architecture 'Some architecture'

# Assert.
Assert-WasCalled Write-Warning
Assert-WasCalled Get-MSBuildPath -Times 2
Assert-AreEqual -Expected 'Some resolved location' -Actual $actual
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[cmdletbinding()]
param()

# Arrange.
. $PSScriptRoot\..\..\..\..\Tests\lib\Initialize-Test.ps1
Microsoft.PowerShell.Core\Import-Module $PSScriptRoot\..
Register-Mock Get-MSBuildPath { 'Some resolved location' } -- -Version '15.0' -Architecture 'Some architecture'

# Act.
$actual = Select-MSBuildPath -Method 'Location' -Location '' -PreferredVersion '' -Architecture 'Some architecture'

# Assert.
Assert-AreEqual -Expected 'Some resolved location' -Actual $actual
Loading