2

Need some help with this MSBuild code.

I want to generate 4 app.config files with different settings and create 2 setup files for QA and production.

Each setup file will have 2 physical installations (Production lines).

So QA setup should include 2 app.configs with qa settings for production line 1 and 2, the same for production setup.

Here is a extract of the msbuild I have so far.

<ItemGroup>
  <BuildEnvironment Include="QA">
    <Server>qa-server</Server>
  <BuildEnvironment/>
  <BuildEnvironment Include="Prod">
    <Server>prod-server</Server>
  <BuildEnvironment/>

  <Line Include="1">
    <Setting>A</Setting>
  </Line>
  <Line Include="2">
    <Setting>B</Setting>
  </Line>
<ItemGroup>

<Target Name="PublishSetup" Inputs="@(BuildEnvironment)" Outputs="%(BuildEnvironment.Identity)">
  <!-- Doesn't work at all -->
  <ItemGroup>
    <AppConfig Include="@(BuildEnvironment);@(Line)">
      <Path>$(MyOutDir)\App.Config-%(Identity)</Path>
    </AppConfig>
  </ItemGroup>

  <!-- Copy app.config to the four new files -->
  <Copy SourceFiles="$(AppConfigFile)" DestinationFiles="%(AppConfig.Path)" />    

  <!-- Update each new app.config with XmlUpdate (community task), something like the following -->
  <XmlUpdate XmlFileName="%(AppConfig.Path)" XPath=".." Value="%(AppConfig.Server)" />
  <XmlUpdate XmlFileName="%(AppConfig.Path)" XPath=".." Value="%(AppConfig.Setting)" />

  <!-- Build 2 setup.exe, one for qa and one prod using a Exec-task passing in qa and prod as command line argument -->
  <Exec Command="setupcompiler.exe /d%(BuildEnvironment.Identity)" />
</Target>

The 4 resulting app.configs should be like this

app.config-QA-1
<connectionstring datasource="qa-server" ../>
<applicationSetting name="aName" value="A" />

app.config-QA-2
<connectionstring datasource="qa-server" ../>
<applicationSetting name="aName" value="B" />

app.config-Prod-1
<connectionstring datasource="prod-server" ../>
<applicationSetting name="aName" value="A" />

app.config-Prod-2
<connectionstring datasource="prod-server" ../>
<applicationSetting name="aName" value="B" />
Karsten
  • 8,015
  • 8
  • 48
  • 83
  • Your xml has syntax errors, can you first make sure it's valid msbuild, and also state more clearly what exactly the resulting AppConfig should look like (eg if you'd declare it as an ItemGroup manually)? – stijn May 12 '16 at 19:16
  • 1
    Thanks for your comment, I have updated the question. Hopes it makes more sense now. – Karsten May 13 '16 at 08:58

1 Answers1

2

The idea is to first build a 'cross-product', an ItemGroup containing the 4 combinations. Can be done by combining @ and % for the two groups, as shown here. Then in a second step populate the ItemGroup with extra metadata based on existing metadata (adding metadata is just declaring the group again and adding metadata). It's a bit tricky here, because from Line you both want Identity and Setting - I don't know a nice msbuild way of doing this so I resorted to building a string with Identity|Setting, then splitting on the | later on.

<Target Name="PublishSetup">
  <ItemGroup>
    <AppConfig Include="@(BuildEnvironment)">
      <Mod>%(Line.Identity)|%(Line.Setting)</Mod>
    </AppConfig>
    <AppConfig>
      <Line>$([System.String]::Copy('%(Mod)').Split('|')[0])</Line>
      <Setting>$([System.String]::Copy('%(Mod)').Split('|')[1])</Setting>
    </AppConfig>
    <AppConfig>
      <Path>app.config-%(Identity)-%(Line)</Path>
    </AppConfig>
  </ItemGroup>

  <Message Text="Path=%(AppConfig.Path) Server=%(AppConfig.Server) Setting=%(AppConfig.Setting)" />
</Target>

Output:

Path=app.config-QA-1 Server=qa-server Setting=A
Path=app.config-Prod-1 Server=prod-server Setting=A
Path=app.config-QA-2 Server=qa-server Setting=B
Path=app.config-Prod-2 Server=prod-server Setting=B

Community
  • 1
  • 1
stijn
  • 34,664
  • 13
  • 111
  • 163