Pergunta

Existe um script MSBuild, que inclui número se Delphi e C # projetos, testes unitários etc.

O problema é: como marcar compilação falhou se advertências foram levantadas (para fins, não para compilações testar)? Usando LogError vez de LogWarning em tarefas personalizadas parece não ser uma boa opção, porque a construção deve testar tanto quanto ele é capaz (até erro real) para relatar tanto advertências quanto possível em um tempo (projeto de construção está usando em CruiseControl.NET ).

Pode ser, a solução é criar minha própria logger que iria armazenar avisos bandeira dentro, mas eu não consigo descobrir se existe uma maneira de ler esta bandeira no final de construção?

P.S. Não há nenhum problema de falhar a construção imediatamente após receber uma advertência (saída do compilador Delphi é processado por tarefa personalizada, e / warnaserror poderia ser usado para C #), mas o comportamento desejado é "construir tudo; recolher todos os avisos; falhar a compilação" o relatório sobre todos os avisos, não apenas sobre o primeiro.

P.P.S. Tanto quanto eu realmente não precisa de número de advertências, mas a bandeira apenas de sua presença, eu decidi simplificar mecanismo de sinalização, e usar trivial Mutex em vez de memória compartilhada. Código está abaixo:

using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System.Threading;

namespace Intrahealth.Build.WarningLogger
{
    public sealed class WarningLoggerCheck : Task
    {
        public override bool Execute()
        {
            Log.LogMessage("WarningLoggerCheck:" + mutexName + "...");
            result = false;
            Mutex m = null;
            try
            {
                m = Mutex.OpenExisting(mutexName);
            }
            catch (WaitHandleCannotBeOpenedException)
            {
                result = true;
            }
            catch (Exception)
            {
            }

            if (result)
                Log.LogMessage("WarningLoggerCheck PASSED");
            else
                Log.LogError("Build log contains warnings. Build is FAILED");

            return result;
        }

        private bool result = true;
        [Output]
        public bool Result
        {
            get { return result; }
        }

        private string mutexName = "WarningLoggerMutex";
        public string MutexName
        {
            get { return mutexName; }
            set { mutexName = value ?? "WarningLoggerMutex"; }
        }
    }

    public class WarningLogger : Logger
    {
        internal static int warningsCount = 0;
        private string mutexName = String.Empty;
        private Mutex mutex = null;

        public override void Initialize(IEventSource eventSource)
        {
            eventSource.WarningRaised += new BuildWarningEventHandler(eventSource_WarningRaised);
        }

        private void SetMutex()
        {
            if (mutexName == String.Empty)
            {
                mutexName = "WarningLoggerMutex";
                if (this.Parameters != null && this.Parameters != String.Empty)
                {
                    mutexName = this.Parameters;
                }
            }

            mutex = new Mutex(false, mutexName);
        }

        void eventSource_WarningRaised(object sender, BuildWarningEventArgs e)
        {
            if (e.Message != null && e.Message.Contains("MSB3146"))
                return;
            if (e.Code != null && e.Code.Equals("MSB3146"))
                return;

            if (warningsCount == 0)
                SetMutex();
            warningsCount++;
        }
    }
}
Foi útil?

Solução

AFAIK MSBuild não tem suporte embutido para recuperar a contagem de aviso em um determinado ponto do script de construção. No entanto, pode seguir estes passos para atingir esse objetivo:

  1. Criar um logger personalizada que ouve o evento aviso e conta o número de avisos
  2. Criar uma tarefa personalizada que expõe uma [saída] propriedade WarningCount
  3. A tarefa personalizada fica de alguma forma o valor da contagem de advertência do logger personalizada

O passo mais difícil é o passo 3. Para isso existem várias opções e você pode livremente procurar-los sob IPC - Comunicação Processo Inter. Segue um exemplo de trabalho de como você pode conseguir isso. Cada item é um diferente Biblioteca Class .

SharedMemory

http://weblogs.asp.net/rosherove/ Arquivo / 2003/05/01 / 6295.aspx

Eu criei um wrapper para chamada memória compartilhada que era parte de um projeto maior. Ele basicamente permite serializado tipos e gráficos de objetos para ser armazenados e recuperados a partir compartilhada memória (incluindo como você esperaria processo cruzado). Se o maior projeto nunca fica concluída é outra importa; -).

SampleLogger

implementa o logger personalizada que mantém o controle da contagem de aviso.

namespace SampleLogger
{
    using System;
    using Microsoft.Build.Utilities;
    using Microsoft.Build.Framework;
    using DM.SharedMemory;

    public class MySimpleLogger : Logger
    {
        private Segment s;
        private int warningCount;

        public override void Initialize(IEventSource eventSource)
        {
            eventSource.WarningRaised += new BuildWarningEventHandler(eventSource_WarningRaised);

            this.s = new Segment("MSBuildMetadata", SharedMemoryCreationFlag.Create, 65535);
            this.s.SetData(this.warningCount.ToString());
        }

        void eventSource_WarningRaised(object sender, BuildWarningEventArgs e)
        {
            this.warningCount++;
            this.s.SetData(this.warningCount.ToString());
        }

        public override void Shutdown()
        {
            this.s.Dispose();
            base.Shutdown();
        }
    }
}

SampleTasks

Implementos a tarefa personalizada que lê o número de avisos levantadas no projeto MSbuild. A tarefa personalizada lê a partir da memória compartilhada escrito pelo logger personalizada implementado na biblioteca de classes SampleLogger .

namespace SampleTasks
{
    using System;
    using Microsoft.Build.Utilities;
    using Microsoft.Build.Framework;
    using DM.SharedMemory;

    public class BuildMetadata : Task
    {
        public int warningCount;

        [Output]
        public int WarningCount
        {
            get
            {
                Segment s = new Segment("MSBuildMetadata", SharedMemoryCreationFlag.Attach, 0);
                int warningCount = Int32.Parse(s.GetData() as string);
                return warningCount;
            }
        }

        public override bool Execute()
        {
            return true;
        }
    }
}

Indo para uma rodada.

<?xml version="1.0" encoding="UTF-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Main">
    <UsingTask TaskName="BuildMetadata" AssemblyFile="F:\temp\SampleLogger\bin\debug\SampleTasks.dll" />

    <Target Name="Main">
        <Warning Text="Sample warning #1" />
        <Warning Text="Sample warning #2" />

        <BuildMetadata>
            <Output
                TaskParameter="WarningCount"
                PropertyName="WarningCount" />
        </BuildMetadata>

        <Error Text="A total of $(WarningCount) warning(s) were raised." Condition="$(WarningCount) > 0" />
    </Target>
</Project>

Se você executar o seguinte comando:

c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild test.xml /logger:SampleLogger.dll

Esta será a saída:

Microsoft (R) Build Engine Version 2.0.50727.3053
[Microsoft .NET Framework, Version 2.0.50727.3053]
Copyright (C) Microsoft Corporation 2005. All rights reserved.

Build started 30-09-2008 13:04:39.
__________________________________________________
Project "F:\temp\SampleLogger\bin\debug\test.xml" (default targets):

Target Main:
    F:\temp\SampleLogger\bin\debug\test.xml : warning : Sample warning #1
    F:\temp\SampleLogger\bin\debug\test.xml : warning : Sample warning #2
    F:\temp\SampleLogger\bin\debug\test.xml(15,3): error : A total of 2 warning(s) were raised.
Done building target "Main" in project "test.xml" -- FAILED.

Done building project "test.xml" -- FAILED.

Build FAILED.
F:\temp\SampleLogger\bin\debug\test.xml : warning : Sample warning #1
F:\temp\SampleLogger\bin\debug\test.xml : warning : Sample warning #2
F:\temp\SampleLogger\bin\debug\test.xml(15,3): error : A total of 2 warning(s) were raised.
    2 Warning(s)
    1 Error(s)

Time Elapsed 00:00:00.01

Outras dicas

O compilador C # (csc.exe) tem um / warnaserror interruptor irá tratar avisos como erros e falhar a compilação. Isto também está disponível como uma configuração no arquivo .csproj. Presumo Delphi tem uma habilidade similar.

msbuild.exe %~nx1 /t:Rebuild /p:Configuration=Release >> %MrB-BUILDLOG%
findstr /r /c:"[1-9][0-9]* Error(s)" >> %MrB-BUILDLOG%
if not errorlevel 1 (
   echo ERROR: sending notification email for build errors in '%~nx1'. >> %MrB-BUILDLOG%
) else (
   findstr /r /c:"[1-9][0-9]* Warning(s)" >> %MrB-BUILDLOG%
   if not errorlevel 1 (
       echo ERROR: sending notification email for build warnings in '%~nx1'. >>

% Senhor B.-BUILDLOG% ) outro ( echo construção bem sucedida de '% ~ nx1'. >>% Senhor B.-BUILDLOG% ) )

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top