Подтвердить что ты не робот

Обращайтесь ко всем предупреждениям как к ошибкам

Это должно быть очевидно, но я просто не мог заставить его работать...

То, что я пытаюсь сделать, просто: Я хочу, чтобы моя компиляция завершилась с ошибкой, если есть предупреждение. Да, знаменитый TreatWarningsAsErrors...

Я настроил его на свои свойства проекта С#

treat warnings as errors

Это приводит к исключенному разделу TreatWarningsAsErrors в моем csproj:

<TreatWarningsAsErrors>true</TreatWarningsAsErrors>

До сих пор так хорошо, если я добавляю бесполезную переменную private в свой код, это приводит к ошибке компиляции:

private int unused;

Ошибка 3 Предупреждение как ошибка: поле "XXXX.unused" никогда не используется

Но вся проблема в том, что я не могу заставить ее работать для проблем с ссылками на сборку. Если у меня есть ссылка на неизвестную сборку, компилятор (либо devenv, либо msbuild) выдает предупреждение, но вместо этого хочу получить ошибку.

В конечном счете, я пытаюсь настроить конфигурацию сборки TFS с закрытой регистрацией, поэтому TFS отклонит фиксацию в случае, если не будет найден указанный компонент "XXXX". предупреждение. Что-то более простое, чем изменение шаблона процесса сборки, было бы замечательно.

4b9b3361

Ответ 1

Предупреждения MSBuild (все начинаются с MSB *), в отличие от предупреждений CSC, не могут быть подавлены и не допущены к ошибкам. По этой причине задача ResolveAssemblyReference печатает свои сообщения "на лету" и не агрегирует их.

Единственное возможное решение - чтение файлов журнала MSBuild, созданных во время сборки TFS. Я считаю, что наиболее элегантным решением является реализация пользовательской сборки CodeActivity. Ниже приведена простая операция, которая выводит на результат любые файлы, содержащие заданный SearchString:

using System;
using System.Activities;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.TeamFoundation.Build.Client;

namespace MyBuildActivities.FileSystem
{
    [BuildActivity(HostEnvironmentOption.Agent)]
    public sealed class ReadStringFromFile : CodeActivity
    {
        [RequiredArgument]
        public InArgument<IEnumerable<string>> Files { get; set; }

        [RequiredArgument]
        public InArgument<string> SearchString { get; set; }

        public OutArgument<string> Result { get; set; }

        protected override void Execute(CodeActivityContext context)
        {
            var files = context.GetValue(Files);
            var searchString = context.GetValue(SearchString);

            var list =
                (files.Where(file => File.ReadAllText(file).Contains(searchString))
                    .Select(file => string.Format("{0} was found at {1}", searchString, file))).ToList();

            if(list.Count > 0)
                Result.Set(context, string.Join(Environment.NewLine, list));
        }
    }
}

Объявлен в шаблоне процесса сборки так:

xmlns:cfs="clr-namespace:MyBuildActivities.FileSystem;assembly=MyBuildActivities"

Вызывается только в конце последовательности Compile and Test for Configuration:

<Sequence DisplayName="Handle MSBuild Errors">
         <Sequence.Variables>
                 <Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="logFiles" />                                                                                                                 
                 <Variable x:TypeArguments="x:String" Name="readStringFromFileResult" />
         </Sequence.Variables>
         <mtbwa:FindMatchingFiles DisplayName="Find Log Files" MatchPattern="[String.Format(&quot;{0}\**\*.log&quot;, logFileDropLocation)]" Result="[logFiles]" mtbwt:BuildTrackingParticipant.Importance="Low" />
         <cfs:ReadStringFromFile Files="[logFiles]" SearchString="MSB3245" Result="[readStringFromFileResult]" />
         <mtbwa:WriteBuildMessage DisplayName="Write Result" Message="[readStringFromFileResult]" Importance="[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]" />
         <If Condition="[readStringFromFileResult.Count > 0]" DisplayName="If SearchString Was Found" mtbwt:BuildTrackingParticipant.Importance="Low">
                 <If.Then>
                          <Throw DisplayName="Throw Exception" Exception="[New Exception(readStringFromFileResult)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
                 </If.Then>
         </If>                                                                                                              
</Sequence>

Я тестировал это на TFS 2012, хотя он должен работать и для TFS 2010.

Ответ 2

MSBuild 15 теперь поддерживает флаг /warnaserror, который заставляет предупреждения MSBuild рассматриваться как ошибки.

MSBuild 15 инсталлируется Visual Studio 2017, но также может быть загружен с GitHub

Эта проблема GitHub объясняет, почему она не может быть установлена ​​с помощью свойства MSBuild (tl; dr свойство слишком поздно)