Domanda

Esiste uno script MSBuild, che include il numero se progetti Delphi e C #, unit test ecc.

Il problema è: come contrassegnare la build non riuscita se sono stati generati avvisi (a scopo di test, non per build di rilascio)? L'uso di LogError invece di LogWarning in attività personalizzate sembra non essere una buona opzione, perché la build dovrebbe testare quanto più è in grado (fino a quando non si verifica un errore reale) di segnalare il maggior numero possibile di avvisi in un momento (il progetto di build sta utilizzando in CruiseControl.NET ).

Forse, la soluzione è quella di creare il mio logger che memorizzi il flag degli avvisi all'interno, ma non riesco a trovare se c'è un modo per leggere questo flag al termine della compilazione?

P.S. Non c'è alcun problema a fallire la compilazione immediatamente dopo aver ricevuto un avviso (l'output del compilatore Delphi viene elaborato dall'attività personalizzata e / warnaserror potrebbe essere usato per C #), ma il comportamento desiderato è "build everything; raccogliere tutti gli avvisi; fallire la compilazione " per riferire su tutti gli avvertimenti, non solo sul primo.

P.P.S. Per quanto non mi serva davvero un numero di avvertimenti, ma solo la bandiera della loro presenza, ho deciso di semplificare il meccanismo di segnalazione e usare un banale Mutex invece della memoria condivisa. Il codice è sotto:

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++;
        }
    }
}
È stato utile?

Soluzione

AFAIK MSBuild non ha supporto integrato per recuperare il conteggio degli avvisi in un determinato punto dello script di compilazione. Puoi comunque seguire questi passaggi per raggiungere questo obiettivo:

  1. Crea un logger personalizzato che ascolta l'evento di avviso e conta il numero di avvisi
  2. Crea un'attività personalizzata che espone una proprietà [Output] WarningCount
  3. L'attività personalizzata ottiene in qualche modo il valore del conteggio degli avvisi dal logger personalizzato

Il passaggio più difficile è il passaggio 3. Per questo ci sono diverse opzioni e puoi cercarle liberamente in IPC - Inter Process Comunication. Segue un esempio funzionante di come è possibile raggiungere questo obiettivo. Ogni elemento è una Libreria di classi diversa

SharedMemory

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

  

Ho creato un wrapper per il nome   memoria condivisa che faceva parte di a   progetto più ampio. Fondamentalmente lo consente   tipi serializzati e grafici di oggetti a   essere archiviato e recuperato da condiviso   memoria (incluso come ti aspetteresti   processo incrociato). Sia il più grande   il progetto che viene mai completato è un altro   importa ;-).

SampleLogger

Implementa il logger personalizzato che tiene traccia del conteggio degli avvisi.

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

Implementa l'attività personalizzata che legge il numero di avvisi generati nel progetto MSbuild. L'attività personalizzata legge dalla memoria condivisa scritta dal logger personalizzato implementato nella libreria di classi 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;
        }
    }
}

Fare un giro.

<?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 si esegue il comando seguente:

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

Questo sarà l'output:

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

Altri suggerimenti

Il compilatore C # (csc.exe) ha un'opzione / warnaserror tratterà gli avvisi come errori e fallirà la compilazione. Questo è disponibile anche come impostazione nel file .csproj. Presumo che Delphi abbia un'abilità simile.

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'. >>

% MrB-BUILDLOG%        ) altro (           echo Creazione riuscita di '% ~ nx1'. & Gt; > % MrB-BUILDLOG%        )     )

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top