Olá pessoal, tudo certo?
Voltando a falar sobre MSBuild. Há quanto tempo! Hoje um post curtinho em função do “avançado da hora”.
Se você está acompanhando a série, já consegue entender direitinho a “lógica” de um projeto para MSBuild. Logo, já tem condições de entender boa parte do Build de seu software. Na medida que avançarmos, criaremos toda a fundamentação necessária para construir processos de Build customizados.
Hoje, mostro como copiar arquivos. Vamos aos fatos…
Se está chegando agora, talvez queira ler o que já foi escrito nessa série. Considere a leitura dos posts anteriores. São eles:
Copiar arquivos é uma operação comum em processos de build. No MSBuild, usamos uma Task chamada Copy para essa operação. Observe:
1 <?xml version="1.0" encoding="utf-8"?> 2 <Project 3 xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 4 DefaultTarget="cf1" 5 > 6 <PropertyGroup> 7 <DstFolder>dst</DstFolder> 8 </PropertyGroup> 9 10 <ItemGroup> 11 <Source Include="src\a.cs;src\b.cs;src\subdir\c.cs"/> 12 </ItemGroup> 13 14 <Target Name="cf1"> 15 <Copy 16 SourceFiles="@(Source)" 17 DestinationFolder="$(DstFolder)" 18 /> 19 </Target> 20 21 </Project>
Perceba que, de forma semelhante a linha de comando, a Copy Task espera basicamente dois argumentos:
Perceba que, no lugar de especificar o diretório destino diretamente, criei uma Property. Essa é uma boa prática na construção de projetos de build.
Relacionar arquivos em um item é muito chato. Por isso, não fazemos isso ![]()
Obviamente, assumo que você esteja habituado a usar coringas. Veja o exemplo anterior reescrito:
1 <?xml version="1.0" encoding="utf-8"?> 2 <Project 3 xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 4 DefaultTarget="cf1" 5 > 6 <PropertyGroup> 7 <DstFolder>dst</DstFolder> 8 </PropertyGroup> 9 10 <ItemGroup> 11 <Source Include="src\**\*.cs"/> 12 </ItemGroup> 13 14 <Target Name="cf1"> 15 <Copy 16 SourceFiles="@(Source)" 17 DestinationFolder="$(DstFolder)" 18 /> 19 </Target> 20 21 </Project>
A grande novidade aqui é o coringa “diretório-recursivo”, indicado pelo **. Esse coringa faz com que a lista de arquivos considerada comece pelo diretório especificado e continue nos seus subdiretórios. Isso significa que, se você tiver dois arquivos em src, e mais dois arquvios em um subdiretório dentro de src, todos os quatro arquivos serão considerados.
Observe, entretanto, que esse script copia todos os arquivos, inclusive os que estão em subdiretórios, para uma única pasta. Ou seja, a estrutura de subdiretórios não é replicada.
Como replicar a estrutura de subdiretórios durante a cópia. Resposa direta: Assim…
1 <?xml version="1.0" encoding="utf-8"?> 2 <Project 3 xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 4 DefaultTarget="cf1" 5 > 6 <PropertyGroup> 7 <DstFolder>dst</DstFolder> 8 </PropertyGroup> 9 10 <ItemGroup> 11 <Source Include="src\**\*.cs"/> 12 </ItemGroup> 13 14 <Target Name="cf1"> 15 <Copy 16 SourceFiles="@(Source)" 17 DestinationFiles= 18 "@(Source->'$(DstFolder)\%(RecursiveDir)%(FileName)%(Extension)')" 19 /> 20 </Target> 21 </Project>
O que eu fiz aqui foi configurar, para cada item, o destino. A chave é o metadado RecursiveDir.
Por hoje, era isso!
![]()
Elemar,
Busquei hoje uma 1a referência pra detalhar o MSBuild e seus 5 posts pro assunto foram bastante úteis.
Uma sugestão é abordar melhores práticas na montagem da estratégia de build: scripts de build, testes unitários, gerenciamento de versão.. qual a recomendação geral? Existe alguma regra de ouro? Como segmentar os testes unitários de outros tipos de testes, mais demorados, através de diferentes estratégias de build? Tem chão..
Abraço e parabéns pelo blog!
José Filipe