2012-04-30 11 views
8

Sto cercando di trasformare tutti i file web.config in un progetto che ho, ecco una struttura di mio albero:Come posso ottenere un'attività di msbuild per trasformare le trasformazioni in una raccolta di file?

  • Transform.bat
  • trasforma
    • ConfigTransform.proj
    • Web .Transform.config
  • Sito
    • web.config
    • Visualizzazioni
      • web.config

C'è più file web.config, ma l'idea è che questo troverà tutti loro e applicare la stessa configurazione di trasformare su di essi.

Ho preso alcuni suggerimenti da a blog post I found ma mi blocco nell'ultimo passaggio, la trasformazione effettiva. C'è anche un po 'di grezzo nel mezzo che non mi piace molto (non capisco bene cosa sto facendo e ovviamente sto sbagliando). Ecco dove sono finora:

<Project ToolsVersion="4.0" DefaultTargets="Transform" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <UsingTask TaskName="TransformXml" AssemblyFile="Tools\Microsoft.Web.Publishing.Tasks.dll"/> 

    <PropertyGroup> 
     <SitePath>..\..\Website</SitePath> 
     <WebConfigTransformInputFile>$(SitePath)\Web.config</WebConfigTransformInputFile> 
     <WebConfigTransformFile>Web.Transform.config</WebConfigTransformFile> 
     <OutDir>..\N\N\</OutDir> 

    </PropertyGroup> 

    <ItemGroup> 
     <_FilesToTransform Include="$(SitePath)\**\web.config"/> 
    </ItemGroup> 

    <Target Name="Transform"> 

    <MakeDir Directories="@(_FilesToTransform->'$(OutDir)%(RelativeDir)')" /> 

    <TransformXml Source="@(_FilesToTransform->'$(OutDir)%(RelativeDir)%(Filename)%(Extension)')" 
        Transform="$(WebConfigTransformFile)" 
        Destination="@(_FilesToTransform->'$(OutDir)%(RelativeDir)%(Filename)%(Extension)')" /> 
    </Target> 
</Project> 

mio Transform.bat si presenta così:

%systemroot%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe %CD%\Transforms\ConfigTransform.proj 

Così, quando io chiamo il lotto, le directory appropriate vengono creati. Tuttavia, come puoi vedere, ho dovuto essere un po 'creativo con l'OutDir, rendendolo ... \ N \ N. Per qualche motivo, se non lo faccio, il percorso di OutDir sarà esattamente lo stesso della directory di input. Quindi ovviamente ho bisogno di cambiare qualcosa in MakeDir ma non sono sicuro di cosa.

Il vero problema arriva quando inizia a fare le trasformazioni. Ho cercato di mantenere il parametro Transformxml Fonte come questo o questo modo:

@(_FilesToTransformNotAppConfig->'%(FullPath)') 

Quest'ultimo mi dà un errore "Could not File sorgente aperto: Il formato data del percorso non è supportato." e l'ex mi dà questo output:

Build started 30-4-2012 14:02:48. 
Project "D:\Dev\transform\DoTransforms\Transforms\ConfigTransform.proj" on node 1 (default targets). 
Transform: 
    Creating directory "..\N\N\..\..\Website\Views\". 
    Transforming Source File: ..\N\N\..\..\Website\Views\Web.config;..\N\N\..\..\Website\Web.config 
D:\Dev\transform\DoTransforms\Transforms\ConfigTransform.proj(32,2): error : Could not open Source file: Could not find a part of the path 'D:\Dev\transform\DoTransforms\Website\Views\Web.config;\Website\Web.config'. 
    Transformation failed 
Done Building Project "D:\Dev\transform\DoTransforms\Transforms\ConfigTransform.proj" (default targets) -- FAILED. 

Build FAILED. 

In sintesi le mie domande:

  1. Come posso evitare il problema percorso per l'OutDir? Ho manipolato più percorsi ma non riesco a farlo bene.
  2. Come si ottiene l'attività TransformXml per accettare più file nell'attributo Source?
+0

Prima di andare dove sei, puoi spiegare che cosa stai cercando di fare? –

+0

Trasformazione di tutti i file di configurazione nella mia soluzione. – sebastiaan

+0

Chiarito nel post (sotto la struttura ad albero). – sebastiaan

risposta

10

Penso che tu fossi abbastanza vicino. Ho incollato un esempio qui sotto che mostra come farlo.

Nel mio esempio scopro la trasformazione che si trova accanto al file web.config stesso. Per il tuo scenario puoi semplicemente usare una proprietà MSBuild che punta a un file specifico.

<?xml version="1.0" encoding="utf-8"?> 
<Project DefaultTargets="TransformAll" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 

    <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/> 

    <PropertyGroup> 
    <Configuration Condition=" '$(Configuration)'=='' ">Release</Configuration> 
    <OutputFolder Condition=" '$(OutputFolder)'=='' ">C:\temp\transformed-files\</OutputFolder> 
    </PropertyGroup> 

    <!-- 
    This target shows how to transform web.config with a specific transform file associated to that specific web.config file. 
    --> 
    <Target Name="TransformAll"> 

    <!-- discover the files to transform --> 
    <ItemGroup> 
     <FilesToTransofm Include="$(MSBuildProjectDirectory)\**\web.config"/> 
    </ItemGroup> 

    <!-- Ensure all target directories exist --> 
    <MakeDir Directories="@(FilesToTransofm->'$(OutputFolder)%(RecursiveDir)')"/> 

    <!-- TransformXml only supports single values for source/transform/destination so use %(FilesToTransofm.Identity) 
     to sned only 1 value to it --> 
    <TransformXml Source="%(FilesToTransofm.Identity)" 
        Transform="@(FilesToTransofm->'%(RecursiveDir)web.$(Configuration).config')" 
        Destination="@(FilesToTransofm->'$(OutputFolder)%(RecursiveDir)web.config')" />  
    </Target> 

</Project> 

FYI è possibile scaricare un campione completo a https://github.com/sayedihashimi/sayed-samples/tree/master/TransformMultipleWebConfigs.

+0

Meraviglioso, con un piccolo ritocco per farlo funzionare nel modo in cui ne ho bisogno e correggendo un errore con il MakeDir (hai dimenticato il backslash) sta facendo esattamente quello che voglio! https://gist.github.com/2601426 – sebastiaan

+0

Un'altra domanda: Posso fare $ (MSBuildProjectDirectory) \ ** \ web.config ma escludere il primo web.config trovato (quello nella radice del sito)? – sebastiaan

+1

FYI Non ho dimenticato la barra, è stata definita sulla proprietà stessa. In MSBuild in genere la barra viene definita alla fine della proprietà in modo da non dimenticare quando si utilizza la proprietà. Ti consiglierei di seguirlo, a meno che tu non possa, per qualche motivo. Sulla tua altra domanda dovresti aggiungere Exclude = "$ (MSBuildProjectDirectory) \ web.config" per saltare il web.config di root. –