Сборка NAnt и двойной платформы - лучший способ сборки на Windows И Mono / Linux

Я новичок в NAnt, но имею некоторый опыт работы с Ant и CruiseControl.

Я хочу, чтобы мой проект SVN включал все необходимые инструменты (например, NUnit, Mocks и т. д.), Чтобы я мог проверить на новой машине и собрать. Эта стратегия изложена J.P Boodhoo здесь.

Пока все хорошо, если я хочу работать только в Windows, но я хочу иметь возможность проверять Linux и создавать / тестировать / запускать также против Mono. Мне не нужны внешние зависимости от проекта SVN. Я не против иметь в проекте два набора инструментов, но хочу только один файл сборки NAnt.

Это должно быть возможно - но как? какие уловки / «ловушки для молодых игроков»

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
1 599
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Это не должно быть особенно сложным упражнением. Мы делаем довольно похожие вещи в одном из моих проектов, поскольку половина из них работает на Java с использованием Ant для запуска соответствующих целей, а другая половина - это .Net (C#) для пользовательского интерфейса. Проекты запускаются на машинах с Windows для разработки, но серверы (Java) работают под Linux, но в среде UAT (linux) нам нужно запускать nunits (интеграционные тесты). Настоящий трюк (не совсем сложный) заключается в наличии файла сборки NAnt, который может работать в обеих средах, что похоже на то, что вы пытаетесь сделать здесь.

Конечно, вы понимаете, что сначала вам нужно установить NAnt на Mono:

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

И затем ваш файл сборки должен быть написан таким образом, чтобы он разделял проблемы. Некоторые части файла сборки, написанные для Windows, например, не будут работать в Linux. Так что вам просто нужно разделить его на конкретные цели в файле сборки. После этого есть несколько способов запустить определенные цели из командной строки. Пример может выглядеть так:

<project name = "DualBuild">
  <property name = "windowsDotNetPath" value = "C:\WINDOWS\Microsoft.NET\Framework\v3.5" />
  <property name = "windowsSolutionPath" value = "D:\WorkingDirectory\branches34\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>

Для краткости я не упомянул обе стороны. Самое интересное в том, что вы можете использовать NUnit, а также NAnt в обеих средах, и это действительно упрощает работу с точки зрения зависимости. И для каждого исполняемого файла вы можете заменить его на другие, которые работают в этой среде, например (xBuild для MSBuild, svn для черепахи и т. д.)

Для получения дополнительной помощи по Nunit и т. д. На Mono, ознакомьтесь с этот фантастический пост.

Надеюсь, это поможет,

Ваше здоровье,

Роб Джи

Стоит отметить, что многие инструменты, такие как Nant, работают в моно «из коробки», т.е.

mono nant.exe

работает

@ Роб Джи - Привет! Это мой пост! ;)

Для некоторых других хороших примеров обязательно просмотрите исходный код NUnit. Я работаю в тесном контакте с Чарли, когда могу, чтобы убедиться, что он строится и тестируется на Mono. Он тоже пытается убежать, когда может.

Я использую следующий шаблон. Это позволяет просто строить на любой платформе (build на Win или ./build.sh на linux) и сводит к минимуму дублирование в сценариях сборки.


Исполняемый файл NAnt хранится вместе с проектом в tools\nant.

Файл конфигурации сборки определяет, какой инструмент сборки использовать: MSBuild или xbuild (в этом случае для Windows мне нужна версия VS2015 MSBuild, при необходимости измените путь).

Целевой объект сборки build-csproj можно повторно использовать, когда в одном решении есть несколько проектов.

Целевой показатель test-project необходимо расширить для ваших нужд.

build.bat

@tools\nant\nant.exe %*

build.sh

#!/bin/sh

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

default.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.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>

Другие вопросы по теме