web-dev-qa-db-fra.com

Dans MSBuild, puis-je utiliser la fonction String.Replace sur un élément MetaData?

Dans MSBuild v4, on peut utiliser des fonctions (comme string.replace) sur Propriétés . Mais comment puis-je utiliser des fonctions sur les métadonnées ?

J'aimerais utiliser le string.replace fonctionne comme ci-dessous:

<Target Name="Build">
        <Message Text="@(Files->'%(Filename).Replace(&quot;.config&quot;,&quot;&quot;)')" />
</Target>   

Malheureusement, cela sort comme (pas tout à fait ce que j'allais chercher): log4net.Replace (". Config", ""); ajaxPro.Replace (". Config", ""); appSettings.Replace (".config", ""); cachingConfiguration20.Replace (". config", ""); cmsSiteConfiguration.Replace (". config", ""); dataProductsGraphConfiguration.Replace (". config", ""); ajaxPro .Replace (". Config", ""); appSettings.Replace (". Config", ""); cachingConfiguration20.Replace (". Config", ""); cmsSiteConfiguratio

Des pensées?

35
willem

Vous pouvez le faire avec un peu de ruse:

$([System.String]::Copy('%(Filename)').Replace('config',''))

Fondamentalement, nous appelons la méthode statique "Copier" pour créer une nouvelle chaîne (pour une raison quelconque, elle ne l'aime pas si vous essayez simplement $('%(Filename)'.Replace('.config',''))), puis appelez la fonction replace sur la chaîne.

Le texte complet devrait ressembler à ceci:

<Target Name="Build">
        <Message Text="@(Files->'$([System.String]::Copy(&quot;%(Filename)&quot;).Replace(&quot;.config&quot;,&quot;&quot;))')" />
</Target>

Edit: MSBuild 12.0 semble avoir cassé la méthode ci-dessus. Comme alternative, nous pouvons ajouter une nouvelle entrée de métadonnées à tous les éléments Files existants. Nous effectuons le remplacement tout en définissant l'élément de métadonnées, puis nous pouvons accéder à la valeur modifiée comme tout autre élément de métadonnées.

par exemple.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.Microsoft.com/developer/msbuild/2003">

    <ItemGroup>
        <Files Include="Alice.jpg"/>
        <Files Include="Bob.not-config.gif"/>
        <Files Include="Charlie.config.txt"/>
    </ItemGroup>

    <Target Name="Build">
        <ItemGroup>
            <!-- 
            Modify all existing 'Files' items so that they contain an entry where we have done our replace.
            Note: This needs to be done WITHIN the '<Target>' (it's a requirment for modifying existing items like this
            -->
            <Files>
                <FilenameWithoutConfig>$([System.String]::Copy('%(Filename)').Replace('.config', ''))</FilenameWithoutConfig>
            </Files>
        </ItemGroup>

        <Message Text="@(Files->'%(FilenameWithoutConfig)')" Importance="high" />
    </Target>
</Project>

Résultat:

D:\temp>"c:\Program Files (x86)\MSBuild\12.0\Bin\MSBuild.exe" /nologo test.xml
Build started 2015/02/11 11:19:10 AM.
Project "D:\temp\test.xml" on node 1 (default targets).
Build:
  Alice;Bob.not-config;Charlie
Done Building Project "D:\temp\test.xml" (default targets).
61
Grant Peters

Je devais faire quelque chose de similaire, ce qui suit a fonctionné pour moi.

<Target Name="Build">
  <Message Text="@(Files->'%(Filename)'->Replace('.config', ''))" />
</Target>
29
Mike Coumbe

Ces fonctions ne fonctionnent que dans les propriétés (comme je le sais). Créez donc une cible qui effectuera l'opération par lots:

<Target Name="Build"                                 
      DependsOnTargets="ProcessFile" />

<Target Name="ProcessFile"
       Outputs="%(Files.Identity)">
   <PropertyGroup>
       <OriginalFileName>%(Files.Filename)</OriginalFileName>
       <ModifiedFileName>$(OriginalFileName.Replace(".config",""))</ModifiedFileName>
   </PropertyGroup>
   <Message Text="$(ModifiedFileName)" Importance="High"/>
</Target>

Avez-vous vraiment besoin dans votre exemple de ce genre de tâche? Je veux dire qu'il existe Métadonnées d'éléments bien connues de MSBuild

EDIT: Je dois préciser que cette tâche traite tous les éléments dans @ ( Des dossiers).

18
Sergio Rykov

Pour MSBuild 12.0, voici une alternative.

<Target Name="Build">
    <Message Text="$([System.String]::Copy(&quot;%(Files.Filename)&quot;).Replace(&quot;.config&quot;,&quot;&quot;))" />
</Target>
1
RobV8R

J'ai le même problème (sauf avec MakeRelative), j'ai donc passé avec une autre solution: Utiliser un bon vieux CreateItem qui prend une chaîne et se transforme en Item :)

        <ItemGroup>
            <_ToUploadFTP Include="$(PublishDir)**\*.*"></_ToUploadFTP>
        </ItemGroup>
        <CreateItem Include="$([MSBuild]::MakeRelative('c:\$(PublishDir)','c:\%(relativedir)%(filename)%(_ToUploadFTP.extension)'))">
            <Output ItemName="_ToUploadFTPRelative" TaskParameter="Include"/>
        </CreateItem>
        <FtpUpload Username="$(UserName)" 
                   Password="$(UserPassword)" 
                   RemoteUri="$(FtpHost)"
                   LocalFiles="@(_ToUploadFTP)"
                   RemoteFiles="@(_ToUploadFTPRelative->'$(FtpSitePath)/%(relativedir)%(filename)%(extension)')"
                   UsePassive="$(FtpPassiveMode)" ></FtpUpload>
0
Nicolas Dorier

je ne pense pas que vous puissiez utiliser des fonctions directement avec des groupes d'articles et des métadonnées (ce serait facile) Cependant, vous pouvez utiliser le traitement par lots:

Reprenant les idées de ce post: array-iteration

J'essayais de couper un groupe d'éléments à envoyer à un outil de ligne de commande (j'avais besoin de perdre .server hors du nom de fichier)

<Target Name="ProcessFile"  DependsOnTargets="FullPaths">

    <ItemGroup>
        <Environments Include="$(TemplateFolder)\$(Branch)\*.server.xml"/>
    </ItemGroup>

    <MSBuild Projects=".\Configure.msbuild" 
             Properties="CurrentXmlFile=%(Environments.Filename)"
             Targets="Configure"/>

</Target>

<Target Name="Configure" DependsOnTargets="FullPaths">
    <PropertyGroup>
        <Trimmed>$(CurrentXmlFile.Replace('.server',''))</Trimmed>
    </PropertyGroup>

    <Message Text="Trimmed: $(Trimmed)"/>

    <Exec  Command="ConfigCmd $(Trimmed)"/>
</Target>
0
James Woolfenden