Question

Il existe un script MSBuild, qui inclut un numéro si des projets Delphi et C #, des tests unitaires, etc.

Le problème est le suivant: comment marquer la construction a échoué si des avertissements ont été émis (à des fins de test, pas pour les versions validées)? Utiliser LogError au lieu de LogWarning dans des tâches personnalisées ne semble pas être une bonne option, car la génération doit tester autant qu'elle est capable (jusqu'à erreur réelle) de signaler autant d'avertissements que possible à un moment donné (le projet de génération utilise actuellement dans CruiseControl.NET ).

Peut-être que la solution consiste à créer mon propre enregistreur qui contiendrait le drapeau d'avertissement à l'intérieur, mais je ne peux pas trouver s'il est possible de lire ce drapeau à la fin de la construction?

P.S. Il n'y a aucun problème à échouer la construction immédiatement après la réception d'un avertissement (la sortie du compilateur Delphi est traitée par une tâche personnalisée et / warnaserror peut être utilisé pour C #), mais le comportement souhaité est le suivant: "Tout construire"; collecter tous les avertissements; échouer la construction " pour signaler tous les avertissements, pas seulement le premier.

P.P.S. En ce qui concerne le nombre d’avertissements nécessaires, mais simplement un indicateur de leur présence, j’ai décidé de simplifier le mécanisme de signalisation et d’utiliser un Mutex trivial au lieu de la mémoire partagée. Le code est ci-dessous:

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++;
        }
    }
}
Était-ce utile?

La solution

AFAIK MSBuild n’a pas de support intégré pour récupérer le nombre d’avertissements à un moment donné du script de construction. Vous pouvez toutefois suivre ces étapes pour atteindre cet objectif:

  1. Créez un enregistreur personnalisé qui écoute l'événement d'avertissement et compte le nombre d'avertissements
  2. Créer une tâche personnalisée qui expose une propriété [Output] WarningCount
  3. La tâche personnalisée obtient en quelque sorte la valeur du nombre d'avertissements de l'enregistreur personnalisé

L'étape la plus difficile est l'étape 3. Pour cela, plusieurs options sont disponibles et vous pouvez les rechercher librement sous IPC - Inter Process Communication. Suit un exemple de travail montrant comment vous pouvez y parvenir. Chaque élément est une bibliothèque de classes différente.

Mémoire partagée

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

  

J'ai créé un wrapper pour named   mémoire partagée qui faisait partie d'un   projet plus grand. Il permet fondamentalement   types sérialisés et graphiques d'objets à   être stocké dans et récupéré de partagé   mémoire (y compris comme vous vous en doutez   processus croisés). Si le plus grand   projet est jamais terminé est un autre   matière ;-).

SampleLogger

Implémente le consignateur personnalisé qui suit le nombre d'avertissements.

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();
        }
    }
}

Exemples de tâches

Implémente la tâche personnalisée qui lit le nombre d'avertissements générés dans le projet MSbuild. La tâche personnalisée lit dans la mémoire partagée écrite par le consignateur personnalisé implémenté dans la bibliothèque 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;
        }
    }
}

Faire un tour.

<?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>

Si vous exécutez la commande suivante:

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

Ce sera la sortie:

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

Autres conseils

Le compilateur C # (csc.exe) possède un commutateur / warnaserror traitera les avertissements comme des erreurs et échouera à la construction. Ceci est également disponible en tant que paramètre dans le fichier .csproj. Je suppose que Delphi a une capacité similaire.

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%        ) autre (           echo Création réussie de '% ~ nx1'. > > % MrB-BUILDLOG%        )     )

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top