【问题标题】:MSBuild Validating PropertiesMSBuild 验证属性
【发布时间】:2012-12-30 09:25:31
【问题描述】:

我正在开发一个可重用的 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>

这是批处理的尝试。由于额外的“名称”参数,它很难看。是否可以改用 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>

【问题讨论】:

    标签: msbuild properties batch-file


    【解决方案1】:

    好问题!我已经在我的book 和一篇博文Elements of Reusable MSBuild Scripts: Validation 中深入探讨了这一点。我的方法将涵盖属性和项目。

    这里是失败的地方。在共享的 .targets 文件中创建一个验证目标,这应该是文件中声明的第一个目标,以便用户可以轻松找到它。

    属性

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

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

    我将属性的名称放在 include 中,并将其值放在 Value 元数据中。这样做的原因是我可以检测到 Value 何时为空白,然后我使用包含值将丢失的属性的名称报告给用户。

    项目

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

    <_RequiredItems Include="AllConfigurations">
      <RequiredValue>@(AllConfigurations)</RequiredValue>
    </_RequiredItems>
    

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

    <_RequiredItems Include = "AllConfigurations.Configuration">
      <RequiredValue>%(AllConfigurations.Configuration </RequiredValue>
    </_RequiredItems>
    

    如果要确保文件存在,请添加额外的元数据,RequiredFilePath。

    <_RequiredItems Include ="ProjectsToBuild">
      <RequiredValue>%(ProjectsToBuild.Identity)</RequiredValue>
      <RequiredFilePath>%(ProjectsToBuild.Identity)</RequiredFilePath>
    </_RequiredItems>
    

    验证

    这是您执行验证所需的内容

    完整示例

    这是完整的例子

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

    【讨论】:

    • 非常好——这正是我想要的。看来我也需要拿一本你的书 :)
    猜你喜欢
    • 2019-04-17
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2021-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多