在PowerShell中获取Grunt退出代码

时间:2015-06-24 17:04:39

标签: node.js powershell gruntjs

基本上与this question相同。我正在为TFS设置一个PowerShell脚本,以便在构建期间运行。当我通过命令提示符执行Grunt命令时,出现错误(如预期的那样)。但是,通过PowerShell运行命令时,不会报告错误。

我的Powershell:

C:\...\grunt --gruntfile $pathOfGruntFile + "\gruntfile.js" prod-build
Write-Output $?

每次都返回true。我也试过

C:\...\grunt --gruntfile $pathOfGruntFile + "\gruntfile.js" prod-build
Write-Output $LASTEXITCODE

但每次都会返回null。

我也尝试过将Diagnostics.Process用作documented here

$process = New-Object Diagnostics.Process
$process.StartInfo.FileName = "C:\...\npm\grunt"
$process.StartInfo.Arguments = @('--gruntfile', "C:\...\gruntfile.js", 'prod-build')

$process.Start()
$process.Close()

Start-Sleep -Seconds 20
if ($process.ExitCode -ne 0) {throw $process.ExitCode}

使用最后一种方法时,无论Grunt进程是成功还是失败,它都会抛出“ScriptHalted”。

如果Grunt任务失败,我需要停止构建。如何在PowerShell中捕获Grunt退出代码,或者至少知道Grunt脚本是否失败?

1 个答案:

答案 0 :(得分:0)

不完全是我想要做的,但它按预期工作。我设法从问题中得到第三种方法,只做了很小的修改:

[string] $pathRemoveReadOnly = $Env:TF_BUILD_BUILDDIRECTORY + "\src\...\"
[string] $pathGruntCliBase = "C:\...\npm\"
$files = Get-ChildItem -File -Path $pathRemoveReadOnly -Recurse

foreach ($file in $files)
{
    Set-ItemProperty $file.FullName -Name IsReadOnly -Value $False
}

# Took and modified this script from https://github.com/gruntjs/grunt/issues/117
$global:finalMessage = $null
$gruntCmdFile = $pathGruntCliBase + "grunt.cmd"
$gruntFile = $pathRemoveReadOnly + "gruntfile.js"

$process = New-Object Diagnostics.Process
$process.StartInfo.FileName = $gruntCmdFile
$process.StartInfo.Arguments = @('--gruntfile', $gruntFile, 'prod-build', '--verbose', '--no-color')
$process.StartInfo.UseShellExecute = $false
$process.StartInfo.RedirectStandardOutput = $true
$process.StartInfo.RedirectStandardError = $true

@{SourceIdentifier = 'GruntOutput'; EventName = 'OutputDataReceived'},
@{SourceIdentifier = 'GruntError'; EventName = 'ErrorDataReceived'} |
  %{
    Unregister-Event -SourceIdentifier $_.SourceIdentifier `
      -ErrorAction SilentlyContinue
    Register-ObjectEvent -InputObject $process @_
  }
-
$process.Start() | Out-Null
$process.BeginOutputReadLine()
$process.BeginErrorReadLine()

function Get-EventMessages([string[]]$names)
{
  $names |
    % { Get-Event -SourceIdentifier $_ -ErrorAction SilentlyContinue } |
    % {
      if ($_.SourceEventArgs.Data)
      {
        #Uncomment this line if you want to see the output
        #Write-Host $_.SourceEventArgs.Data
        $global:finalMessage = $_.SourceEventArgs.Data
      }
      Remove-Event -EventIdentifier $_.EventIdentifier
    }
}

while (!$process.WaitForExit(100))
{
  Get-EventMessages -names 'GruntOutput', 'GruntError'
}

Start-Sleep -Seconds 1
Get-EventMessages -names 'GruntOutput', 'GruntError'
$process.Close()

if ($global:finalMessage -ne 'Done, without errors.') { throw 'Build aborted! Grunt failed.'}

原始作者使用的$process.ExitCode始终返回null。为了解决这个问题,我添加了$global:finalMessage变量,只需从输出中读取最后一条消息。如果它说"完成,没有错误。"然后我知道它成功了。其他任何事都表明Grunt过程失败了。