문제

Delphi 및 C# 프로젝트, 단위 테스트 등의 숫자가 포함 된 MSBuild 스크립트가 있습니다.

문제는 다음과 같습니다. 경고가 제기 된 경우 (릴리스 빌드를위한 테스트 목적으로) 빌드가 실패하는 방법은 무엇입니까? 사용자 정의 작업에서 로그 워닝 대신 Logerror를 사용하는 것은 좋은 옵션이 아닌 것 같습니다. 빌드는 (실제 오류가 될 때까지) 가능한 한 많은 경고를 한 시간 내에보고 할 수있는만큼 테스트해야하기 때문입니다 (CruiseControl.net에서 빌드 프로젝트가 사용됩니다. ).

솔루션은 경고 깃발을 내부에 저장하는 나만의 로거를 만드는 것이지만 빌드 끝에이 깃발을 읽는 방법이 있는지 찾을 수 없습니까?

추신 PS 경고를받은 직후 빌드에 실패하는 데 문제가 없습니다 (Delphi 컴파일러 출력은 사용자 정의 작업으로 처리되고 /WarnAserror는 C#에 사용될 수 있음), 원하는 동작은 "모든 건축; 모든 경고를 수집하고 빌드에 실패합니다. "첫 번째 경고뿐만 아니라 모든 경고에 대해보고합니다.

PPS는 실제로 많은 경고가 필요하지 않고 그들의 존재의 깃발만으로도 신호 메커니즘을 단순화하고 공유 메모리 대신 사소한 뮤트를 사용하기로 결정했습니다. 코드는 다음과 같습니다.

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. output] 경고 카운트 속성을 노출시키는 사용자 정의 작업 생성
  3. 사용자 정의 작업은 어떻게 든 사용자 정의 로거에서 경고 수의 값을 얻습니다.

가장 어려운 단계는 3 단계입니다.이를 위해 몇 가지 옵션이 있으며 IPC - Inter Process Comunication에서 자유롭게 검색 할 수 있습니다. 이를 달성 할 수있는 방법의 예제를 따릅니다. 각 항목은 다릅니다 수업 도서관.

공유 메모리

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

더 큰 프로젝트의 일부인 이름이 지정된 공유 메모리에 대한 래퍼를 만들었습니다. 기본적으로 직렬화 된 유형 및 객체 그래프를 공유 메모리 (크로스 프로세스를 기대할 수있는)에서 저장하고 검색 할 수 있습니다. 더 큰 프로젝트가 완료되는지 여부는 또 다른 문제입니다 ;-).

샘플 로그거

경고 수를 추적하는 사용자 정의 로거를 구현합니다.

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

샘플레스트

MSBuild 프로젝트에서 제기 된 경고 수를 읽는 사용자 정의 작업을 구현합니다. 사용자 정의 작업은 클래스 라이브러리에서 구현 된 사용자 정의 로거가 작성한 공유 메모리에서 읽습니다. 샘플 로그거.

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# Compiler (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%) else ( '%~ nx1'의 성공적인 빌드. >>%mrb-buildlog%))))

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top