开发者

How do I generate an MsBuild itemList from another item list based on the current item's directory name?

开发者 https://www.devze.com 2023-01-16 12:10 出处:网络
i\'m taking a list of files *.config and copying them to a list of directories. The directories are relative to a path C:\\branches\\ have a name and then the name.UnitTest.

i'm taking a list of files *.config and copying them to a list of directories. The directories are relative to a path C:\branches\ have a name and then the name.UnitTest.

so the copy looks like this without being refactored/batched:

<Target Name="CopyClientConfigs">

<ItemGroup>
    <ClientConfigDestinati开发者_运维技巧ons Include="$(LocalSourcePath)\Module1\Module1.UnitTest\;
    $(LocalSourcePath)\Module2\Module2.UnitTest\;
    $(LocalSourcePath)\CommonControls\Module3\Module3.UnitTest\;
    $(LocalSourcePath)\Administration\Module4\Module4.UnitTest\;
    $(LocalSourcePath)\IndividualControls\Configuration\Module5\Module5.UnitTest\" />
    <ClientConfigs
    Include="$(ClientConfigPath)\*.config"
    Exclude="$(ClientConfigPath)\P*.config" >
    </ClientConfigs>
</ItemGroup>
<Copy
        SourceFiles="@(ClientConfigs)"
        DestinationFolder="%(ClientConfigDestinations.FullPath)"
        />

What I want is to be able to use this ItemGroup

<ItemGroup>
<MyModules Include="$(LocalSourcePath)\Module1;
    $(LocalSourcePath)\Module2;
    $(LocalSourcePath)\CommonControls\Module3;
    $(LocalSourcePath)\Administration\Module4;
    $(LocalSourcePath)\IndividualControls\Configuration\Module5"
/>          

So the task would be like

Copy
        SourceFiles="@(ClientConfigs)"
        DestinationFolder="%(ClientConfigDestinations.FullPath)\*.UnitTest\"
        />

Or better

Copy
        SourceFiles="@(ClientConfigs)"
        DestinationFolder="%(ClientConfigDestinations.FullPath)\%(ClientConfigDestinations.NameOnly).UnitTest\"
        />

How do I refactor or properly batch this operation?


If I read your question right, I think you are trying to do a cross-product copy: copy all items in one ItemGroup to all the folders in a different group.

I actually have a neat target that I use to do this, as I hate the way TeamBuild puts all the binaries into a single folder - I want projects to be able to specify that their output is a "bundle" and that the output will also be copied to one or more locations.

To do this, I have two itemgroups: BundleFiles (which is the set of files that I want to copy) and BundleFolders which are the set of folders that I want to copy to.

<ItemGroup>
    <BundleOutDir Include="FirstFolder;SecondFolder" />
    <BundleFiles Include="file1;file2" />
</ItemGroup>

My target then contains two tasks like this:

<ItemGroup>
    <FilesByDirsCrossProduct Include="@(BundleFiles)">
        <BundleOutDir>%(BundleOutDir.FullPath)</BundleOutDir>
    </FilesByDirsCrossProduct>
</ItemGroup>

This creates an uber item group containing a cross product of files by folders.

The copy is then pretty simple:

<Copy SourceFiles="@(FilesByDirsCrossProduct)"
    DestinationFiles="@(FilesByDirsCrossProduct -> '%(BundleOutDir)\%(Filename)%(Extension)' ) "
    SkipUnchangedFiles="true" />

This then copies the files to the folder specified within their meta data.

My target is actually a little more clever in that I can declare that bundles will go to sub folders and/or I can rename a file during the copy through meta data, but that's a different story


<Target Name="CopyClientConfigsBatched" Outputs="%(MyModules.FullPath)">
    <Message Text="@(MyModules -> '%(FullPath)\%(FileName).UnitTest')"/>
  <ItemGroup>
    <ClientConfigs
    Include="$(ClientConfigPath)\*.config"
    Exclude="$(ClientConfigPath)\P*.config" >
    </ClientConfigs>
  </ItemGroup>
  <Copy SourceFiles="@(ClientConfigs)" DestinationFolder="@(MyModules -> '%(FullPath)\%(FileName).UnitTest')"
     SkipUnchangedFiles="true"/>
</Target>

target batching seems to have done it!

0

精彩评论

暂无评论...
验证码 换一张
取 消