daffyduck
daffyduck

Reputation: 13

How do I loop in MSBuild Target file with different files?

I have below MSBuild Target file setup. This works fine with one JSON file.

<Target Name="dev" 
            AfterTargets="PrepareForBuild"
            BeforeTargets="BeforeBuild"
            Condition="$(Configuration) != 'Debug'">  

        <Message Text="Building Application (dev.json)" />

        <ItemGroup>
            <ScriptFile Include="$(MSBuildThisFileDirectory)myscript.ps1" />
    </ItemGroup>
    <ItemGroup>
            <ScriptArgs Include="-Source &quot;$(MSBuildProjectDirectory)&quot;" />
            <ScriptArgs Include="-PathToManifest &quot;$(MSBuildProjectDirectory)\test\dev.json&quot;" />
        </ItemGroup>

        <Exec  Command="powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File &quot;@(ScriptFile)&quot; @(ScriptArgs,' ')" 
               Condition="Exists('@(ScriptFile)')" />
        <Error Condition="!Exists('@(ScriptFile)')"
               Text="Script file: &quot;@(ScriptFile)&quot; not found. Existing dev.json incomplete!" />

    </Target>

I have verified a few questions here but didn't help so posting here. How do I add this in a loop so I can run the same script with different JSON files?

I have test\dev.json configured, and I have test.json, prod.json.

Everything stays the same but the input file needs to looping through.

I have tried a suggestion as below but still didn't work.

 <ItemGroup>
        <MyJsonFile Include="dev.json" />
        <MyJsonFile Include="test.json" />
        <MyJsonFile Include="prod.json" />
 </ItemGroup>
 <ItemGroup>
        <ScriptFile Include="$(MSBuildThisFileDirectory)myscript.ps1" />
 </ItemGroup>
 <ItemGroup>
        <ScriptArgs Include="-Source &quot;$(MSBuildProjectDirectory)&quot;" />
        <ScriptArgs Include="-PathToManifest &quot;$(MSBuildProjectDirectory)\test\%(MyJsonFile.Identity)&quot;" />
    </ItemGroup>
<Target Name="dev" 
            AfterTargets="PrepareForBuild"
            BeforeTargets="BeforeBuild"
            Condition="$(Configuration) != 'Debug'">  
<Exec  Command="powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File &quot;@(ScriptFile)&quot; @(ScriptArgs,' ')" 
               Condition="Exists('@(ScriptFile)')" />
        <Error Condition="!Exists('@(ScriptFile)')"
               Text="Script file: &quot;@(ScriptFile)&quot; not found. Existing dev.json incomplete!" />

    </Target>

I get

Cannot validate argument on parameter 1> 'PathToManifest'.

I tried moving my ScriptArgs' ItemGroup inside Target but that gives another error

Cannot bind parameter because parameter 1> 'PathToManifest' is specified more than once. To provide multiple values to parameters that can accept multiple 1> values, use the array syntax.

Upvotes: 1

Views: 768

Answers (1)

Leo Liu
Leo Liu

Reputation: 76760

How do I loop in MSBuild Target file with different files?

You can add those different JSON files in to the ItemGroup, then use the MSBuild item metadata Identity to loop those input files, like:

  <ItemGroup>
    <MyJsonFile Include="test.json" />
    <MyJsonFile Include="dev.json" />
    <MyJsonFile Include="prod.json" />
  </ItemGroup> 

Then use %(MyJsonFile.Identity) to loop those input files:

<ItemGroup>
        ...
        <ScriptArgs Include="-PathToManifest &quot;$(MSBuildProjectDirectory)\test\%(MyJsonFile.Identity)&quot;" />

</ItemGroup>

Check this thread for some more details.

Hope this helps.

Upvotes: 3

Related Questions