53 votes

Traiter tous les avertissements comme des erreurs

Cela devrait être évident à faire, mais je n'ai pas réussi à le faire fonctionner...

Ce que j'essaie de faire est simple : Je voudrais que ma compilation échoue avec une erreur s'il y a un avertissement. . Oui, le célèbre TreatWarningsAsErrors ...

Je l'ai configuré dans les propriétés de mon projet C#

treat warnings as errors

Il en résulte le résultat attendu TreatWarningsAsErrors dans mon csproj :

<TreatWarningsAsErrors>true</TreatWarningsAsErrors>

Jusqu'ici tout va bien, si j'ajoute un inutile private dans mon code, il en résulte une erreur de compilation :

private int unused;

Erreur 3 Avertissement en tant qu'erreur : Le champ 'XXXX.unused' n'est jamais utilisé.

Mais le problème, c'est que je n'arrive pas à le faire fonctionner pour problèmes de référence d'assemblage . Si j'ai une référence à un assemblage inconnu, le compilateur (soit devenv ou msbuild) lance un avertissement, mais je veux une erreur à la place.

En fin de compte, j'essaie de configurer une configuration de construction TFS avec contrôle de l'entrée, de façon à ce que TFS rejette une livraison s'il y a un " Le composant référencé 'XXXX' n'a pas pu être trouvé. "avertissement. Une solution plus simple que la modification du modèle de processus de construction serait la bienvenue.

2 votes

Une sorte de duplicata : stackoverflow.com/questions/17495278/

0 votes

Essayez une étape post-construction qui inspecte l'avertissement.

22voto

KMoraz Points 7804

Les avertissements MSBuild (qui commencent tous par MSB*), contrairement aux avertissements CSC, ne peuvent pas être supprimés ni promus en erreurs. Pour la raison que le ResolveAssemblyReference imprime ses messages à la volée et n'en agrège aucun.

La seule solution possible est de lire les fichiers journaux MSBuild créés pendant la construction du TFS. Je pense que la solution la plus élégante est d'implémenter une fonction Build CodeActivity . Ce qui suit est une activité simple qui affichera dans les résultats tous les fichiers contenant une valeur donnée de 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));
        }
    }
}

Déclaré dans le modèle de processus de construction comme suit :

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

Invoqué juste à la fin de la Compile and Test for Configuration séquence :

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

J'ai testé cela sur TFS 2012, mais cela devrait également fonctionner pour TFS 2010.

0 votes

C'est ce que je craignais... Je comprends que les avertissements de MSBuild lui-même ne peuvent pas être promus en erreurs. Ce que je ne comprends pas, c'est pourquoi un référence inconnue de l'assemblage n'est pas un avertissement du SCC. Quoi qu'il en soit, une activité personnalisée est effectivement la voie à suivre, même si à première vue, cela semble un peu exagéré pour le cas d'utilisation (apparemment) simple que j'avais. +1, merci pour votre réponse.

0 votes

Pour faire fonctionner la solution postée par KMoraz, j'ai dû faire ce qui suit : 1. Ajouter une chaîne vide au résultat dans la CodeActivity si la chaîne n'a pas été trouvée dans les fichiers. 2. Changer readStringFromFileResult.Count en readStringFromFileResult.Length dans le modèle de construction. Sinon, j'obtiendrais une exception nulle lorsque la chaîne n'est pas trouvée.

20voto

Richard Szalay Points 42486

MSBuild 15 supporte maintenant un /warnaserror qui force MSBuild les avertissements doivent être traités comme des erreurs.

MSBuild 15 est installé avec Visual Studio 2017 mais peut aussi être téléchargé sur GitHub

Ce problème GitHub explique pourquoi il ne peut pas être défini via une propriété MSBuild (tl;dr une propriété est trop tard)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X