NAnt e construção de plataforma dupla - melhor maneira de construir no Windows E Mono/Linux

StackOverflow https://stackoverflow.com/questions/32027

Pergunta

Sou novo no NAnt, mas tenho alguma experiência com Ant e CruiseControl.

O que eu quero fazer é que meu projeto SVN inclua todas as ferramentas necessárias (como NUnit e Mocks etc.) para que eu possa verificar uma nova máquina e construir.Esta estratégia é delineada por J.P Boodhoo aqui.

Até aí tudo bem se eu quiser rodar apenas no Windows, mas também quero poder fazer check-out no Linux e construir/testar/executar no Mono.Não quero dependências externas ao projeto SVN.Não me importo de ter dois conjuntos de ferramentas no projeto, mas quero apenas um arquivo de construção NAnt

Isto deve ser possível – mas como?quais são os truques / 'armadilhas para jovens jogadores'

Foi útil?

Solução

Este não deve ser um exercício particularmente difícil.Fazemos coisas bastante semelhantes em um dos meus projetos, já que metade dele é executado em Java usando Ant para executar alvos relevantes, e a outra metade é .Net (C#) para a UI.Os projetos são executados em máquinas Windows para desenvolvimento, mas os servidores (Java) rodam Linux, mas no ambiente UAT (Linux) precisamos rodar os nunits (testes de integração).O verdadeiro truque (não é realmente um truque difícil) por trás disso é ter um arquivo de compilação NAnt que pode ser executado em ambos os ambientes, o que parece ser a mesma coisa que você está tentando fazer aqui.

É claro que você percebe que precisará instalar o NAnt no Mono primeiro:

$ export MONO_NO_UNLOAD=1
$ make clean
$ make
$ mono bin/NAnt.exe clean build

E então seu arquivo de construção precisa ser escrito de forma que separe as preocupações.Algumas partes do arquivo de construção escrito para Windows não funcionarão no Linux, por exemplo.Então você realmente só precisa dividi-lo em alvos específicos no arquivo de construção.Depois disso, há várias maneiras de executar alvos específicos na linha de comando.Um exemplo pode ser assim:

<project name="DualBuild">
  <property name="windowsDotNetPath" value="C:\WINDOWS\Microsoft.NET\Framework\v3.5" />
  <property name="windowsSolutionPath" value="D:\WorkingDirectory\branches\1234\source" />
  <property name="windowsNUnitPath" value="C:\Program Files\NUnit-Net-2.0 2.2.8\bin" />
  <property name="monoPath" value="You get the idea..." />

  <target name="BuildAndTestOnWindows" depends="WinUpdateRevision, WinBuild, WinTest" />
  <target name="BuildAndTestOnLinux" depends="MonoUpdateRevision, MonoBuild, MonoTest" />

  <target name="WinUpdateRevision">
    <delete file="${windowsSolutionPath}\Properties\AssemblyInfo.cs" />
    <exec program="subwcrev.exe" basedir="C:\Program Files\TortoiseSVN\bin\"
          workingdir="${windowsSolutionPath}\Properties"
          commandline="${windowsSolutionPath} .\AssemblyInfoTemplate.cs
                       .\AssemblyInfo.cs" />
    <delete file="${windowsSolutionPath}\Properties\AssemblyInfo.cs" />
    <exec program="subwcrev.exe" basedir="C:\Program Files\TortoiseSVN\bin\"
          workingdir="${windowsSolutionPath}\Properties"
          commandline="${windowsSolutionPath} .\AssemblyInfoTemplate.cs 
                       .\AssemblyInfo.cs" />
  </target>

  <target name="WinBuild">
    <exec program="msbuild.exe"
          basedir="${windowsDotNetPath}"
          workingdir="${windowsSolutionPath}"
          commandline="MySolution.sln /logger:ThoughtWorks.CruiseControl.MsBuild.XmlLogger,
                       ThoughtWorks.CruiseControl.MsBuild.dll;msbuild-output.xml 
                       /nologo /verbosity:normal /noconsolelogger 
                       /p:Configuration=Debug /target:Rebuild" />
  </target>

  <target name="WinTest">
    <exec program="NCover.Console.exe"
          basedir="C:\Program Files\NCover"
          workingdir="${windowsSolutionPath}">
      <arg value="//x &quot;ClientCoverage.xml&quot;" />
      <arg value="&quot;C:\Program Files\NUnit-Net-2.0 2.2.8\bin
                       \nunit-console.exe&quot; 
                       MySolution.nunit /xml=nunit-output.xml /nologo" />
    </exec>
  </target>

  <target name="MonoUpdateRevision">
    You get the idea...
  </target>


  <target name="MonoBuild">
    You get the idea...
  </target>

  <target name="MonoTest">
    You get the idea...
  </target>

</project>

Para resumir, deixei ambos os lados de fora.O legal é que você pode usar NUnit e NAnt em ambos os ambientes, o que torna as coisas muito fáceis do ponto de vista da dependência.E para cada executável você pode trocar por outros que funcionem naquele ambiente, por exemplo (xBuild para MSBuild e svn para tortoise etc)

Para obter mais ajuda sobre Nunit etc no Mono, confira esta postagem fantástica.

Espero que ajude,

Saúde,

Rob G.

Outras dicas

@Rob G - Ei!Essa é a minha postagem!;)

Para alguns outros bons exemplos, certifique-se de navegar no código-fonte do NUnit.Eu trabalho em estreita colaboração com Charlie sempre que posso para garantir que ele esteja sendo construído e testado no Mono.Ele tenta correr sempre que pode também.

É importante notar que muitas ferramentas como o Nant rodam em mono 'pronto para uso', ou seja,

mono nant.exe

funciona

Eu uso o seguinte modelo.Permite construção simples em qualquer plataforma (build no Win ou ./build.sh no Linux) e minimiza a duplicação nos scripts de construção.


O executável NAnt é armazenado com o projeto em tools\nant.

O arquivo de configuração de compilação determina qual ferramenta de compilação usar, MSBuild ou xbuild (neste caso, para Windows eu preciso da versão VS2015 MSBuild, altere o caminho conforme necessário).

O build-csproj build target pode ser reutilizado quando você tiver vários projetos em uma solução.

O test-project a meta precisaria ser expandida para suas necessidades.

construir.bat

@tools\nant\nant.exe %*

construir.sh

#!/bin/sh

/usr/bin/cli tools/nant/NAnt.exe "$@"

padrão.build

<?xml version="1.0"?>
<project name="MyProject" default="all">

  <if test="${not property::exists('configuration')}">
    <property name="configuration" value="release" readonly="true" />
  </if>

  <if test="${platform::is-windows()}">
    <property name="BuildTool" value="C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" readonly="true"/>
  </if>
  <if test="${platform::is-unix()}">
    <property name="BuildTool" value="xbuild" readonly="true"/>
  </if>

  <property name="TestTool" value="tools/mytesttool.exe"/>

  <target name="all" depends="myproject myprojectlib" />

  <target name="build-csproj" description="Build a given csproj">
    <!-- Must not be called standalone as it requires some properties set. -->
    <exec program="${BuildTool}">
      <arg path="src/${ProjectName}/${ProjectName}.csproj" />
      <arg line="/property:Configuration=${configuration}" />
      <arg value="/target:Rebuild" />
      <arg value="/verbosity:normal" />
      <arg value="/nologo" />
    </exec>
  </target>

  <target name="test-project">
    <!-- Must not be called standalone as it requires some properties set. -->
    <exec program="${TestTool}">
      <arg path="my/${ProjectName}/tests/path/for/tool" />
      <arg value="/aproperty=value" />
    </exec>
  </target>

  <target name="myproject" description="Build the project">
    <property name="ProjectName" value="MyProject"/>
    <call target="build-csproj" />
    <call target="test-project" />
  </target>

  <target name="myprojectlib" description="Build the project's library dll">
    <property name="ProjectName" value="MyProjectLib"/>
    <call target="build-csproj" />
    <call target="test-project" />
  </target>

</project>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top