Como verificar se um MSBuild-Task falhar se usando ContinueOnError = true
Eu estou correndo oMSBuild tarefa comContinueOnError= true:
<MSBuild Projects="@(ComponentToDeploy)"
Targets="$(DeploymentTargets)"
Properties="$(CommonProperties);%(AdditionalProperties)"
ContinueOnError="true"
Condition="%(Condition)"/>
Então, minha construção sempre é bem-sucedida.
Existe uma maneira de descobrir se algum erro ocorre?
Eu não consegui encontrar nenhumSaída doMSBuild tarefa contendo esta informação. A única maneira que eu sei é analisar o arquivo de log para erros, mas parece uma solução para mim.
(Estou usando o MSBuild 4.0)
Esta é uma resposta ao último feedback de @Ilya.
Estou usando feedback / resposta por causa das restrições de tamanho e formatação dos comentários.
O log tem o escopo para destinos individuais ou para tarefas mais específicas ...
Esta foi a primeira pergunta que surgiu quando eu estava lendo o seu comentário com a sugestão de usarLog.HasLoggedErrors
: "Foi o escopo do Log?".
Infelizmente não consegui encontrar uma documentação apropriada. MSND não ajuda muito ...
Por que você sabe que é o escopo da tarefa?
Eu não estou em dúvida sobre a sua declaração em tudo! Eu só estou querendo saber se há uma documentação adequada em algum lugar .. (eu não tenho usadoMSBuild por anos ;-)
De qualquer forma, o que você está construindo como projeto?
Meus projetos de teste são muito simples.
MyTest.project
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="ElenasTarget" ToolsVersion="4.0">
<UsingTask AssemblyFile="$(MSBuildProjectDirectory)\MyCompany.Tools.MSBuild.Tasks.dll" TaskName="MSBuildWithHasLoggedErrors" />
<ItemGroup>
<MyProjects Include="CopyNotExistingFile.proj" />
</ItemGroup>
<Target Name="ElenasTarget">
<MSBuildWithHasLoggedErrors Projects="@(MyProjects)" ContinueOnError="true" >
<Output TaskParameter="HasLoggedErrors" PropertyName="BuildFailed" />
</MSBuildWithHasLoggedErrors>
<Message Text="BuildFailed=$(BuildFailed)" />
</Target>
</Project>
oCopyNotExistingFile.proj apenas tenta copiar um arquivo que não existe:
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Target1" ToolsVersion="4.0">
<Target Name="Target1">
<Copy SourceFiles="C:\lalala.bum" DestinationFiles="C:\tralala.bam" />
</Target>
</Project>
E esta é minha tarefa personalizadaMSBuildWithHasLoggedErrors
namespace MyCompany.Tools.MSBuild.Tasks
{
public class MSBuildWithHasLoggedErrors : Microsoft.Build.Tasks.MSBuild
{
[Output]
public bool HasLoggedErrors { get; private set; }
public override bool Execute()
{
try
{
base.Execute();
HasLoggedErrors = Log.HasLoggedErrors;
}
catch (Exception e)
{
Log.LogErrorFromException(e, true);
return false;
}
return true;
}
}
}
Se eu construir meu MyTest.projHasLoggedErrors
será definido parafalse
embora um erro (MSB3021) foi registrado (?) no logger do console:
Project "C:\Users\elena\mytest.proj" on node 1 (default targets).
Project "C:\Users\elena\mytest.proj" (1) is building "C:\Users\elena\CopyNotExistingFile.proj" (2) on node 1 (default targets).
Target1:
Copying file from "C:\lalala.bum" to "C:\tralala.bam".
C:\Users\elena\CopyNotExistingFile.proj(5,4): error MSB3021: Unable to copy file "C:\lalala.bum" to "C:\tralala.bam". Could not find file 'C:\lalala.bum'.
Done Building Project "C:\Users\elena\CopyNotExistingFile.proj" (default targets) -- FAILED.
ElenasTarget:
BuildFailed=False
Done Building Project "C:\Users\elena\mytest.proj" (default targets).
Build succeeded.
Minha expectativa eraHasLoggedErrors
seria definido paratrue
.
Uma maneira é construir auto, mas com alvo diferente, por exemplo, seu DefaultTargets um lança sua tarefa personalizada MSBuildWrapper apontando para si mesmo (ou seja, $ (MSBuildProjectFile)), mas com um destino diferente que faz outras compilações, cópias
Eu já tentei (que foram as minhas investigações que eu quis dizer no meu post). Infelizmente não funciona :-(
(Eu estou ciente que você disseem teoria). Meu novosolteiro projeto parece com isso:
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="ElenasTarget" ToolsVersion="4.0">
<UsingTask AssemblyFile="$(MSBuildProjectDirectory)\MyCompany.Tools.MSBuild.Tasks.dll" TaskName="MSBuildWithHasLoggedErrors" />
<Target Name="ElenasTarget">
<MSBuildWithHasLoggedErrors Projects="$(MSBuildProjectFile)" Targets="CopyNotExistingFile" ContinueOnError="true" >
<Output TaskParameter="HasLoggedErrors" PropertyName="BuildFailed" />
</MSBuildWithHasLoggedErrors>
<Message Text="BuildFailed=$(BuildFailed)" />
</Target>
<Target Name="CopyNotExistingFile" >
<Copy SourceFiles="C:\lalala.bum" DestinationFiles="C:\tralala.bam" />
</Target>
</Project>
Se eu construir este projetoHasLoggedErrors
ainda será definido parafalse
.
(Além disso, minha build "real" que estou mantendo atualmente é muito mais complexa, contendo vários arquivos de projeto com targets ... então eu não posso empacotá-los em um único arquivo de projeto).
ou escrevendo um registrador personalizado e passando-o pela linha de comando
Essa foi a minha última esperança!
Minha construção "real"tem um logger personalizado passou pela linha de comando (eu não o usei para o meu projeto de teste por uma questão de simplicidade). Isso está realmente produzindo o log (um arquivo XML) que vou analisar para descobrir se algum erro foi registrado.
BTW, eu pensei que o logger do console é uma espécie de logger "global". Estou errado?
De qualquer forma, o logger customizado não ajuda nemLog.HasLoggedErrors
ainda está definido parafalse
.
Existe alguma maneira que eu não estou ciente de fazer referência a um logger particular (por exemplo, meu logger personalizado) para perguntar se ele registrou algum erro?
Realmente pareceLog
tem escopo para alvos individuais.
Hmm ... se o reflexo na instância do buildengine for o último recurso, eu ainda preferiria analisar o log.
(Não me culpe! :-))
Minha decisão
Depois de algumas investigações, decidi continuar com a minha solução inicial: analisar o log para descobrir se a compilação falhou.
Confira meus comentários para ver porque eu prefiro que as sugestões tenham sido fornecidas até agora.
Se alguém tiver outras idéias, não hesite em compartilhar :-)
(Caso contrário, esta questão pode ser encerrada, suponho ...)