MSBuild:كيفية الحصول على عدد من التحذيرات التي أثيرت ؟

StackOverflow https://stackoverflow.com/questions/152487

  •  02-07-2019
  •  | 
  •  

سؤال

هناك MSBuild النصي ، ويشمل ذلك عدد إذا Delphi و C# مشاريع وحدة الاختبارات.... الخ

المشكلة هي:كيفية وضع علامة بناء فاشلة إذا كانت التحذيرات رفعت (لأغراض الاختبار ، ليس من أجل الإفراج عن يبني)?باستخدام LogError بدلا من LogWarning في المهام المخصصة يبدو أن لا خيار جيد ، لأن بناء يجب اختبار بقدر ما انها قادرة (حتى الخطأ الحقيقي) أن يقدم الكثير من التحذيرات ممكن في الوقت (بناء المشروع باستخدام في CruiseControl.NET).

قد يكون الحل هو إنشاء بلدي مسجل تخزن تحذيرات العلم في الداخل, ولكن أنا لا يمكن العثور على إذا كان هناك طريقة لقراءة هذا العلم في النهاية من بناء ؟

P. S.لا يوجد مشكلة أن تفشل بناء على الفور بعد تلقي تحذير (دلفي مترجم إخراج معالجة المهام المخصصة ، و /warnaserror يمكن أن تستخدم C#) ، ولكن السلوك المطلوب هو "بناء كل شيء ؛ جمع كل الإنذار ؛ تفشل في بناء" على تقرير عن كل التحذيرات ، ليس فقط عن الأولى.

P. P. S.بقدر ما أنا حقا لا تحتاج إلى عدد من التحذيرات ، ولكن مجرد العلم من وجودها ، قررت تبسيط آلية يشير واستخدام تافهة مزامنة بدلا من الذاكرة المشتركة.رمز أدناه:

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++;
        }
    }
}
هل كانت مفيدة؟

المحلول

AFAIK MSBuild لديه المدمج في دعم لاسترداد تحذير الاعتماد في نقطة معينة من البناء النصي.ومع ذلك يمكنك اتباع الخطوات التالية لتحقيق هذا الهدف:

  1. إنشاء مخصص المسجل أن يستمع للتحذير الحدث بحساب عدد التحذيرات
  2. إنشاء مهمة مخصصة أن يفضح أحد [إخراج] WarningCount الملكية
  3. المهمة المخصصة يحصل بطريقة أو بأخرى قيمة التحذير عد من العرف مسجل

الخطوة الأكثر صعوبة هو الخطوة 3.لهذا هناك عدة خيارات يمكنك بحرية البحث تحت IPC - بين عملية المواصلات.يلي مثالا على كيف يمكن تحقيق هذا.كل عنصر مختلف مكتبة الفئة.

SharedMemory

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

لقد خلق المجمع اسمه الذاكرة المشتركة التي كانت جزءا من مشروع أكبر.فإنه يسمح أساسا تسلسل أنواع وجوه الرسوم البيانية أن يتم تخزينها في استردادها من مشترك الذاكرة (بما في ذلك كما كنت تتوقع عبر عملية).إذا كان أكبر المشروع من أي وقت مضى يحصل على الانتهاء من آخر المسألة؛ -).

SampleLogger

تطبق العرف المسجل أن يحتفظ تعقب من تحذير العد.

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

تنفذ المهمة المخصصة يقرأ عدد من التحذيرات التي أثيرت في MSbuild المشروع.المهمة المخصصة يقرأ من الذاكرة المشتركة كتبها مخصص مسجل تنفيذها في مكتبة الفئة 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;
        }
    }
}

الذهاب في جولة.

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

إذا قمت بتشغيل الأمر التالي:

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

هذا سوف يكون الناتج:

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

نصائح أخرى

المحول البرمجي C# (csc.exe) لديه /warnaserror التبديل سوف علاج والتحذيرات أخطاء تفشل بناء.هذا هو متاح أيضا إعداد في .الملف csproj.أفترض دلفي لديه قدرة مماثلة.

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% ) آخر ( صدى ناجحة بناء '%~nx1'.>> %MrB-BUILDLOG% ) )

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top