Skip to content
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
16 changes: 0 additions & 16 deletions PSCMake/Common/CMake.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,6 @@ $CMakeCandidates = @(
}
)

<#
.Synopsis
Invokes CMake.

.Description
A function wrapping calls to CMake, allowing the calls to be mocked for testing.
#>
function InvokeCMake {
param(
[string] $CMakePath,
[string[]] $Arguments
)
Write-Verbose "CMake Arguments: $Arguments"
& $CMakePath @Arguments
}

<#
.Synopsis
Finds the root of the CMake build - the current or ancestral folder containing a 'CMakePresets.json' file.
Expand Down
24 changes: 20 additions & 4 deletions PSCMake/PSCMake.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@ $ErrorActionPreference = 'Stop'
. $PSScriptRoot/Common/Common.ps1
. $PSScriptRoot/Common/Ninja.ps1

<#
.Synopsis
Invokes an executable.

.Description
A function wrapping calls to '&', allowing the calls to be mocked for testing.
#>
function InvokeExecutable {
param(
[string] $Path,
[string[]] $Arguments
)
Write-Verbose "Invoking: $Path $Arguments"
& $Path @Arguments
}

<#
.Synopsis
An argument-completer for `Build-CMakeBuild`'s `-Preset` parameter.
Expand Down Expand Up @@ -129,7 +145,7 @@ function BuildTargetsCompleter {

<#
.Synopsis
An argument-completer for `Build-CMakeBuild`'s `-Targets` parameter.
An argument-completer for `Invoke-CMakeOutput`'s `-Target` parameter.
#>
function ExecutableTargetsCompleter {
param(
Expand Down Expand Up @@ -210,7 +226,7 @@ function ConfigureCMake {
}
)

InvokeCMake $CMake $CMakeArguments
InvokeExecutable $CMake $CMakeArguments
if ($LASTEXITCODE -ne 0) {
Write-Error "Configuration failed. Command line: '$($CMake.Source)' $($CMakeArguments -join ' ')"
}
Expand Down Expand Up @@ -410,7 +426,7 @@ function Build-CMakeBuild {
)

$StartTime = [datetime]::Now
InvokeCMake $CMake $CMakeArguments
InvokeExecutable $CMake $CMakeArguments
if ($LASTEXITCODE -ne 0) {
Write-Error "Build failed. Command line: '$($CMake.Source)' $($CMakeArguments -join ' ')"
}
Expand Down Expand Up @@ -563,7 +579,7 @@ function Invoke-CMakeOutput {

Write-Output "Running: $TargetPath $Arguments"
Write-Output '----'
& $TargetPath @Arguments
InvokeExecutable $TargetPath $Arguments
}

Register-ArgumentCompleter -CommandName Invoke-CMakeOutput -ParameterName Preset -ScriptBlock $function:BuildPresetsCompleter
Expand Down
2 changes: 1 addition & 1 deletion Tests/Build-CMakeBuild.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ BeforeAll {

# Mock subsequent calls to invoke CMake so that we don't actually try to build anything.
$script:CMakeCalls = @()
Mock -ModuleName PSCMake InvokeCMake {
Mock -ModuleName PSCMake InvokeExecutable {
param(
[string] $CMakePath,
[string[]] $Arguments
Expand Down
3 changes: 2 additions & 1 deletion Tests/Configure-CMakeBuild.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ BeforeAll {
Import-Module -Force $PSScriptRoot/../PSCMake/PSCMake.psd1 -DisableNameChecking

# Mock subsequent calls to invoke CMake so that we don't actually try to build anything.
Mock -ModuleName PSCMake InvokeCMake {
Mock -ModuleName PSCMake InvokeExecutable {
param(
[string] $CMakePath,
[string[]] $Arguments
)
$null = $CMakePath
$script:CMakeCalls += , $Arguments
}
}
Expand Down
25 changes: 25 additions & 0 deletions Tests/ExecutableTargetsCompleter.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#Requires -PSEdition Core

BeforeAll {
. $PSScriptRoot/TestUtilities.ps1
. $PSScriptRoot/ReferenceBuild.ps1

$Properties = PrepareReferenceBuild

$CMake = "$env:ProgramFiles/CMake/bin/cmake.exe"
& $CMake @Properties

Import-Module -Force $PSScriptRoot/../PSCMake/PSCMake.psd1 -DisableNameChecking
}

Describe 'ExecutableTargetsCompleter' {
It 'Returns the executable targets' {
Using-Location "$PSScriptRoot/ReferenceBuild" {
$Completions = Get-CommandCompletion "Invoke-CMakeOutput -Target "
$Completions.CompletionMatches.CompletionText | Should -Be @(
'SubDirectoryOther_Executable',
'SubDirectory_Executable'
)
}
}
}
81 changes: 81 additions & 0 deletions Tests/Invoke-CMakeOutput.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#Requires -PSEdition Core

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

BeforeAll {
. $PSScriptRoot/TestUtilities.ps1
. $PSScriptRoot/ReferenceBuild.ps1

$Properties = PrepareReferenceBuild

$CMake = "$env:ProgramFiles/CMake/bin/cmake.exe"
& $CMake @Properties

Import-Module -Force $PSScriptRoot/../PSCMake/PSCMake.psd1 -DisableNameChecking

# Mock subsequent calls to invoke CMake so that we don't actually try to build anything.
Mock -ModuleName PSCMake InvokeExecutable {
param(
[string] $Path,
[string[]] $Arguments
)
$script:ExecutableCalls += [PSCustomObject]@{Path = $Path; Arguments = $Arguments}
}
}

Describe 'Invoke-CMakeOutput' {
BeforeEach {
$script:ExecutableCalls = @()
}

It 'Builds then invokes a specified target' {
Using-Location "$PSScriptRoot/ReferenceBuild" {
Invoke-CMakeOutput -Target SubDirectory_Executable

$script:ExecutableCalls | Should -HaveCount 2
$script:ExecutableCalls[0].Arguments | Should -Be @('--build', '--preset', 'windows-x64', '--target', 'SubDirectory_Executable')
$script:ExecutableCalls[1].Arguments | Should -BeNullOrEmpty
$script:ExecutableCalls[1].Path | Should -Be @("$PSScriptRoot\ReferenceBuild\__output\windows-x64\SubDirectory\Debug\SubDirectory_Executable.exe")
}
}

It 'Builds then invokes a specified target - configuration specified' {
Using-Location "$PSScriptRoot/ReferenceBuild" {
Invoke-CMakeOutput -Target SubDirectory_Executable -Configuration Release

$script:ExecutableCalls | Should -HaveCount 2
$script:ExecutableCalls[0].Arguments | Should -Be @('--build', '--preset', 'windows-x64', '--config', 'Release', '--target', 'SubDirectory_Executable')
$script:ExecutableCalls[1].Arguments | Should -BeNullOrEmpty
$script:ExecutableCalls[1].Path | Should -Be @("$PSScriptRoot\ReferenceBuild\__output\windows-x64\SubDirectory\Release\SubDirectory_Executable.exe")
}
}

It 'Passes extra parameters to the invocation' {
Using-Location "$PSScriptRoot/ReferenceBuild" {
Invoke-CMakeOutput -Target SubDirectory_Executable chunky bacon

$script:ExecutableCalls | Should -HaveCount 2
$script:ExecutableCalls[0].Arguments | Should -Be @('--build', '--preset', 'windows-x64', '--target', 'SubDirectory_Executable')
$script:ExecutableCalls[1].Arguments | Should -Be @('chunky', 'bacon')
$script:ExecutableCalls[1].Path | Should -Be @("$PSScriptRoot\ReferenceBuild\__output\windows-x64\SubDirectory\Debug\SubDirectory_Executable.exe")
}
}

It 'Runs a single in-scope executable' {
Using-Location "$PSScriptRoot/ReferenceBuild/SubDirectory" {
Invoke-CMakeOutput

$script:ExecutableCalls | Should -HaveCount 2
$script:ExecutableCalls[0].Arguments | Should -Be @('--build', '--preset', 'windows-x64', '--target', 'SubDirectory_Executable')
$script:ExecutableCalls[1].Arguments | Should -BeNullOrEmpty
$script:ExecutableCalls[1].Path | Should -Be @("$PSScriptRoot\ReferenceBuild\__output\windows-x64\SubDirectory\Debug\SubDirectory_Executable.exe")
}
}

It 'Fails with multiple executable targets in scope' {
Using-Location "$PSScriptRoot/ReferenceBuild" {
{ Invoke-CMakeOutput } | Should -Throw "Multiple executable scoped targets match. Specify a target explicitly: SubDirectoryOther_Executable SubDirectory_Executable"
}
}
}