MSBuild 101 – Parte 3 –Items

Publicado em 25/01/2011

2


Olá pessoal, tudo certo?

Voltemos a nossa boa série sobre automatização do processo de build. Hoje, pretendo demonstrar os fundamentos para utilização dos ‘Items’ no MSBuild. Na prática, é nosso artifício para trabalhar com arquivos.

Contrariando meu amigo @juanplopes, continuo mantendo o repositório no GitHub com os exemplos de script criados aqui. (ele recomenda, e eu concordo com ele agora, que a melhor solução para esse formato de publicação seja o Gist). Aliás, o cara criou um projeto interessante para quem quer utilizar o MSBuild sem mudar a variável de ambiente path.

Posts anteriores dessa série

Se está chegando agora, talvez queira ler o que já foi escrito nessa série. Considere a leitura dos posts anteriores. São eles:

O que são “Items”

Construir uma aplicação consiste em trabalhar com muitos arquivos. Por causa disso, há um conjunto de recursos especial para trabalhar com eles no MSBuild: Items

Items são referências diretas para arquivos. Entretanto, podem ser utilizados para outros propósitos.

Se você criar um projeto utilizando o Visual Studio, ao examinar o arquivo .csproj, verá que ele mantém os arquivos que você “adiciona” ao projeto em um ItemGroup (que é o nodo parent para items). Observe o exemplo:

1 <?xml version="1.0" encoding="utf-8"?> 2 <Project 3 xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 4 DefaultTarget="build" 5 > 6 <ItemGroup> 7 <Source Include="demo.cs"/> 8 </ItemGroup> 9 <Target Name="build"> 10 <Message Text="@(Source)"/> 11 </Target> 12 </Project>

Como você pode ver nesse exemplo, a utilização de “Items” é bem semelhante a utilização de “Properties”.  Criamos um nodo ItemGroup e dentro acrescentamos os “items”.

O nome do subelemento (em nosso exemplo, Source) é livre e está sob o controle de quem está desenvolvendo. Rodando o script acima, temos o seguinte resultado:

1 C:\git\MSBuild101>msbuild oneitem.proj /nologo 2 Build started 25/01/2011 16:24:08. 3 Project "C:\git\MSBuild101\oneitem.proj" on node 1 (default targets). 4 build: 5 demo.cs 6 Done Building Project "C:\git\MSBuild101\oneitem.proj" (default targets). 7 8 9 Build succeeded. 10 0 Warning(s) 11 0 Error(s) 12 13 Time Elapsed 00:00:00.04 14 Time Elapsed 00:00:00.04

Repare também que na presença do atributo Include. Bacana ele! Permite que continuemos acrescentando elementos a lista. Repare:

1 <?xml version="1.0" encoding="utf-8"?> 2 <Project 3 xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 4 DefaultTarget="build" 5 > 6 <ItemGroup> 7 <Source Include="demo.cs"/> 8 <Source Include="demo2.cs"/> 9 </ItemGroup> 10 <Target Name="build"> 11 <Message Text="@(Source)"/> 12 </Target> 13 </Project>

Repare agora que temos duas linhas definindo Source. Quando isso corre, apenas um item é acrescido na lista (sem substituições, que seria o comportamento de Properties).

1 C:\git\MSBuild101>msbuild twoitems.proj /nologo 2 Build started 25/01/2011 16:30:04. 3 Project "C:\git\MSBuild101\twoitems.proj" on node 1 (default targets). 4 build: 5 demo.cs;demo2.cs 6 Done Building Project "C:\git\MSBuild101\twoitems.proj" (default targets). 7 8 9 Build succeeded. 10 0 Warning(s) 11 0 Error(s) 12 13 Time Elapsed 00:00:00.05

Repare na linha 5 que os dois “arquivos” aparecem juntos, separados por “;”.

Aliás, essa também seria uma forma coerente de configurar a lista. Observe:

1 <?xml version="1.0" encoding="utf-8"?> 2 <Project 3 xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 4 DefaultTarget="build" 5 > 6 <ItemGroup> 7 <Source Include="demo.cs;demo2.cs"/> 8 </ItemGroup> 9 <Target Name="build"> 10 <Message Text="@(Source)"/> 11 </Target> 12 </Project>

Mesmo resultado! Outra possibilidade é criar mais do que um “ItemGroup”. Observe:

1 <?xml version="1.0" encoding="utf-8"?> 2 <Project 3 xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 4 DefaultTarget="build" 5 > 6 <ItemGroup> 7 <Source Include="demo.cs"/> 8 </ItemGroup> 9 <ItemGroup> 10 <Source Include="demo2.cs"/> 11 </ItemGroup> 12 13 <Target Name="build"> 14 <Message Text="@(Source)"/> 15 </Target> 16 </Project>

Fácil assim.

Metadados

Outra diferença interessante entre propriedades e “items” é que os “items” podem ter medados associados a eles. Quando criamos um “item”, Observe:

1 <?xml version="1.0" encoding="utf-8"?> 2 <Project 3 xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 4 DefaultTarget="build" 5 > 6 <ItemGroup> 7 <Source Include="demo.cs"/> 8 </ItemGroup> 9 <Target Name="build"> 10 <Message Text="@(Source)->%(Identity)"/> 11 <Message Text="@(source)->%(FullPath)"/> 12 <Message Text="@(source)->%(RootDir)"/> 13 <Message Text="@(source)->%(FileName)"/> 14 <Message Text="@(source)->%(Extension)"/> 15 <Message Text="@(source)->%(Directory)"/> 16 <Message Text="@(source)->%(ModifiedTime)"/> 17 <Message Text="@(source)->%(CreatedTime)"/> 18 <Message Text="@(source)->%(AccessedTime)"/> 19 </Target> 20 </Project>

Esse script gera essa saída:

1 C:\git\MSBuild101>msbuild ItemMetadata.proj 2 Microsoft (R) Build Engine Version 4.0.30319.1 3 [Microsoft .NET Framework, Version 4.0.30319.1] 4 Copyright (C) Microsoft Corporation 2007. All rights reserved. 5 6 Build started 25/01/2011 17:01:07. 7 Project "C:\git\MSBuild101\ItemMetadata.proj" on node 1 (default targets). 8 build: 9 demo.cs->demo.cs 10 demo.cs->C:\git\MSBuild101\demo.cs 11 demo.cs->C:\ 12 demo.cs->demo 13 demo.cs->.cs 14 demo.cs->git\MSBuild101\ 15 demo.cs->2011-01-25 16:38:29.6638361 16 demo.cs->2011-01-25 16:38:29.6638361 17 demo.cs->2011-01-25 16:38:29.6638361 18 Done Building Project "C:\git\MSBuild101\ItemMetadata.proj" (default targets). 19 20 21 Build succeeded. 22 0 Warning(s) 23 0 Error(s) 24 25 Time Elapsed 00:00:00.05

 

Esses metadados são providos pelo MSBuild e resolvidos para cada Item.  Também podemos criar nossos próprios metadados. Observe:

1 <?xml version="1.0" encoding="utf-8"?> 2 <Project 3 xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 4 DefaultTarget="build" 5 > 6 <ItemGroup> 7 <Source Include="demo.cs"> 8 <JustForFun>Bu!</JustForFun> 9 </Source> 10 </ItemGroup> 11 <Target Name="build"> 12 <Message Text="@(Source)->%(JustForFun)"/> 13 </Target> 14 </Project>

Eis aqui a saída desse script:

1 C:\git\MSBuild101>msbuild ItemMetadata2.proj /nologo 2 Build started 25/01/2011 17:11:29. 3 Project "C:\git\MSBuild101\ItemMetadata2.proj" on node 1 (default targets). 4 build: 5 demo.cs->Bu! 6 Done Building Project "C:\git\MSBuild101\ItemMetadata2.proj" (default targets). 7 8 9 Build succeeded. 10 0 Warning(s) 11 0 Error(s) 12 13 Time Elapsed 00:00:00.04

Recomendo que você dê uma boa olhada em um arquivo .csproj seu para ver como esse mecanismo funciona.

Por hoje, era isso.

Smiley piscando

Etiquetado:
Publicado em: Sem categoria