MSBuild验证属性

Bri*_*pie 14 msbuild properties batch-file

我正在研究一个可重用的MSBuild目标,它将被其他几个任务使用.此目标要求定义多个属性.验证属性是否已定义的最佳方法是什么,如果不是,则抛出错误?

几乎喜欢的两次尝试:

<?xml version="1.0" encoding="utf-8" ?>
  <Project ToolsVersion="3.5" DefaultTarget="Release" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <Target Name="Release">
    <Error
      Text="Property PropA required"
      Condition="'$(PropA)' == ''"/>
    <Error
      Text="Property PropB required"
      Condition="'$(PropB)' == ''"/>

    <!-- The body of the task -->

  </Target>
</Project>
Run Code Online (Sandbox Code Playgroud)

这是一次批量尝试.由于额外的"名称"参数,这很难看.是否可以使用Include属性?

<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="3.5" DefaultTarget="Release" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="Release">
    <!-- MSBuild BuildInParallel="true" Projects="@(ProjectsToBuild)"/ -->
    <ItemGroup>
      <RequiredProperty Include="PropA"><Name>PropA</Name></RequiredProperty>
      <RequiredProperty Include="PropB"><Name>PropB</Name></RequiredProperty>
      <RequiredProperty Include="PropC"><Name>PropC</Name></RequiredProperty>
    </ItemGroup>

    <Error
      Text="Property %(RequiredProperty.Name) required"
      Condition="'$(%(RequiredProperty.Name))' == ''" />

  </Target>

</Project>
Run Code Online (Sandbox Code Playgroud)

Say*_*imi 17

好问题!我已经在我的和博客文章"可重复使用的MSBuild脚本元素:验证"中深入探讨了这一点.我的方法将涵盖属性和项目.

这是倒下的.在共享.targets文件中创建验证目标,这应该是文件中声明的第一个目标之一,以便用户可以轻松找到它.

属性

在验证目标内定义您的属性,如下所示:

<_RequiredProperties Include="Root">
  <Value>$(Root)</Value>
</_RequiredProperties>
Run Code Online (Sandbox Code Playgroud)

我将属性的名称放在include中,并将其值放在Value元数据中.我这样做的原因是我可以检测何时Value为空,然后使用include值将缺少的属性的名称报告回用户.

项目

在目标内部放置项目内的所需项目,如:

<_RequiredItems Include="AllConfigurations">
  <RequiredValue>@(AllConfigurations)</RequiredValue>
</_RequiredItems>
Run Code Online (Sandbox Code Playgroud)

与属性类似,在include中放置项的名称,然后在RequiredValue元数据内部检查值.在此示例中,它只是检查以确保该项AllConfiguraitons不为空.如果要确保在所有项目上指定给定的元数据值,请执行以下操作:

<_RequiredItems Include = "AllConfigurations.Configuration">
  <RequiredValue>%(AllConfigurations.Configuration </RequiredValue>
</_RequiredItems>
Run Code Online (Sandbox Code Playgroud)

如果要确保文件存在,请添加其他元数据RequiredFilePath.

<_RequiredItems Include ="ProjectsToBuild">
  <RequiredValue>%(ProjectsToBuild.Identity)</RequiredValue>
  <RequiredFilePath>%(ProjectsToBuild.Identity)</RequiredFilePath>
</_RequiredItems>
Run Code Online (Sandbox Code Playgroud)

验证

以下是执行验证所需的内容

完整的例子

这是完整的例子

<Target Name="ValidateBuildSettings">
  <ItemGroup>
    <_RequiredProperties Include="Root">
      <Value>$(Root)</Value>
    </_RequiredProperties>

    <_RequiredProperties Include="BuildInstallRoot">
      <Value>$(BuildInstallRoot)</Value>
    </_RequiredProperties>

    <_RequiredProperties Include="SourceRoot">
      <Value>$(SourceRoot)</Value>
    </_RequiredProperties>
    <!-- 
    _RequiredItems is the item where required items should be placed. 
    The following metadata is significant: 
      REQUIRED METADATA: 
      Identity          = This will basically be used to identify the specific required item 
      RequiredValue     = This is the specific value that will be validated to exist 

      OPTIONAL METADATA 
      RequiredFilePath  = Populate this with a path that should exists, if it is not empty 
                            then it will be checked to exist on disk. 
    -->

    <_RequiredItems Include="AllConfigurations">
      <RequiredValue>@(AllConfigurations)</RequiredValue>
    </_RequiredItems>
    <_RequiredItems Include = "AllConfigurations.Configuration">
      <RequiredValue>%(AllConfigurations.Configuration </RequiredValue>
    </_RequiredItems>
    <_RequiredItems Include ="ProjectsToBuild">
      <RequiredValue>%(ProjectsToBuild.Identity)</RequiredValue>
      <RequiredFilePath>%(ProjectsToBuild.Identity)</RequiredFilePath>
    </_RequiredItems>
  </ItemGroup>
  <!-- Raise an error if any value in _RequiredProperties is missing -->

  <Error Condition =" '%(_RequiredProperties.Value)'=='' "
          Text=" Missing required property [%(_RequiredProperties.Identity)]" />

  <!-- Raise an error if any value in _RequiredItems is empty -->
  <Error Condition = " '%(_RequiredItems.RequiredValue)'=='' "
          Text = " Missing required item value [%(_RequiredItems.Identity)] " />

  <!-- Validate any file/directory that should exist -->
  <Error Condition = " '%(_RequiredItems.RequiredFilePath)' != '' and !Exists('%(_RequiredItems.RequiredFilePath)') "
          Text = " Unable to find expeceted path [%(_RequiredItems.RequiredFilePath)] on item [%(_RequiredItems.Identity)] " />
</Target>
Run Code Online (Sandbox Code Playgroud)