如果项目引用不符合预期,如何使构建失败

时间:2015-06-04 01:21:07

标签: visual-studio-2013 msbuild

在我的项目中,有人最近将项目引用更改为hack以完成某项任务。这导致CI构建失败和其他浪费。是否可以创建一个msbuild任务,该任务可以查看项目引用解决方案范围,以检查针对已知正常配置的项目引用,以及在意外更改的情况下构建失败。我意识到这掩盖了一个更深层次的问题,但上次发生的浪费被认为是不可接受的,我被要求确保它不会再发生。

1 个答案:

答案 0 :(得分:0)

您可以使用msbuild inline task。此任务将在csproj类型的文件中搜索禁止引用,并在找到它们时发出日志。您可能会根据任务输出HasForbiddenReferences失败构建。

如果您想要执行一次任务以检查所有csproj,则此方法可用。如果您希望每个项目都进行自我检查,则必须更改任务以接受项目的路径并进行检查。

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">  
  <UsingTask
    TaskName="CheckForbiddenReferences"
    TaskFactory="CodeTaskFactory"
    AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
    <ParameterGroup>
      <SolutionDir ParameterType="System.String" Required="true" />
      <HasForbiddenReferences ParameterType="System.Boolean" Output="true" />
    </ParameterGroup>
    <Task>
      <Reference Include="System.Xml.dll"/>
      <Using Namespace="System"/>
      <Using Namespace="System.IO"/>
      <Using Namespace="System.Linq"/>
      <Using Namespace="System.Xml.Linq"/>
      <Code Type="Fragment" Language="cs">
            <![CDATA[       

            HasForbiddenReferences = false;

            // Load your forbidden references here
            var forbiddenReferences = new[] { "Forbidden1", "Forbidden2", "Forbidden3" };

            var files = Directory.GetFiles(SolutionDir, "*.csproj", SearchOption.AllDirectories);
            XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";

            foreach (var f in files.Where(f =>
            {
                var doc = XDocument.Parse(File.ReadAllText(f));

                return doc
                        .Descendants(msbuild + "Reference")
                        .Union(doc.Descendants(msbuild + "ProjectReference"))
                        .Any(r => forbiddenReferences.Any(fr =>
                        {
                            var forbid = r.Attribute("Include").Value.Contains(fr);

                            if (forbid)
                                Log.LogMessage(string.Format("Forbidden reference {0} on Project {1}", fr, f));

                            return forbid;
                        }));

            }))
            {
                Log.LogMessage(string.Format("File {0} contains forbidden references", f));
                HasForbiddenReferences = true;
            }
            ]]>
      </Code>
    </Task>
  </UsingTask>
</Project>

照常调用任务:

<Target Name="CheckReferences" >
<CheckForbiddenReferences SolutionDir="$(SolutionDir)" >
     <Output PropertyName="HasForbiddenReferences" TaskParameter="HasForbiddenReferences" />
</CheckForbiddenReferences>

<Error Condition="$(HasForbiddenReferences)" Text="Build failed due to forbidden references"/> 

</Target>