2010-04-29 123 views
13

我正在研究一個可複用的MSBuild目標,它將被其他幾個任務使用。該目標需要定義多個屬性。什麼是驗證該屬性的最佳方法是否定義,如果不是,則拋出一個錯誤?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> 

回答

16

偉大的問題!我在我的book和博客文章Elements of Reusable MSBuild Scripts: Validation中深入地寫了這篇文章。我的方法將涵蓋屬性和項目。

這是跑下來。在共享的.targets文件中創建一個驗證目標,並且這應該是該文件中聲明的第一個目標之一,以便用戶可以輕鬆找到它。

屬性

確認目標裏面定義你的屬性是這樣的:

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

我在放在屬性的名稱包括其的Value metadata.The原因,內在價值我這樣做是爲了能夠檢測到Value爲空時,然後使用include值將缺失屬性的名稱報告給用戶。

項目

內部的目標位置就像一個項目內的所需物品:

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

的性質相似,裏面包括你放置物品的名稱,則該值檢查RequiredValue元數據的內部。在這個例子中,它只是檢查以確保AllConfiguraitons項目不是空的。如果你想確保一個給定的元數據值在所有項目中指定,然後像做:如果你想確保文件存在,那麼添加額外的元數據,RequiredFilePath

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

<_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> 
+0

優秀 - 這正是我一直在尋找。 看起來我需要拿起你的書的副本:) – 2010-05-04 17:11:19