MSBuild предоставляет возможность группировать элементы в таргеты, для описания более сложных сценариев. Пример таргета, который вызывается во время dotnet restore
:
<Target Name="ValidateSolutionConfiguration">
<Error
Condition="('$(CurrentSolutionConfigurationContents)' == '')
and ('$(SkipInvalidConfigurations)' != 'true')"
Text="The specified solution configuration "$(Configuration)|$(Platform)" is invalid." />
<Warning
Condition="('$(CurrentSolutionConfigurationContents)' == '')
and ('$(SkipInvalidConfigurations)' == 'true')"
Text="The specified solution configuration "$(Configuration)|$(Platform)" is invalid." />
<Message
Condition="'$(CurrentSolutionConfigurationContents)' != ''"
Text="Building solution configuration "$(Configuration)|$(Platform)"." />
</Target>
Error - это таска, которая фиксирует сообщение об ошибке сборки. Такая ошибка ведёт к не успешному завершению процесса сборки, следующие шаги не будут выполняться. В контексте ValidateSolutionConfiguration Error используется вместе с условием ('$(CurrentSolutionConfigurationContents)' == '')
, а значит под валидацией подразумевается проверка на то, что $(CurrentSolutionConfigurationContents)
должен быть задан. Вторая часть проверки - это проверка флага SkipInvalidConfigurations. Этот флаг имеет смысл, если рассматривать вместе со следующей таской Warning. Она выполняет такую же валидацию, но вместо ошибки создаётся предупреждение и сборка может выполняться далее. Грубо говоря, эту же логику можно было записать кодом так:
if (CurrentSolutionConfigurationContents == "")
if (!SkipInvalidConfigurations)
throw new Exception("The specified solution configuration is invalid");
else
logger.Warning("The specified solution configuration is invalid");
else
logger.Message("Building solution configuration $"{Configuration}|{Platform}.");
Returns
Таргеты могут иметь возвращаемое значение, для этого в описании таргета используется атрибут Returns
. Пример таргета с возвращаемым значением - _LoadRestoreGraphEntryPoints. Его задача - сформировать список проектов, которые нужно ресторить. Рассматривается два сценария:
- Рестор одного проекта
dotnet restore Project.csproj
. В таком случае в список проектов для рестора добавляется текущий проект:<RestoreGraphProjectInputItems Include="$(MSBuildProjectFullPath)" />
. - Рестор солюшена
dotnet restore Solution.sln
. В таком случае нужно из sln получить список проектов. Для этого выполняется таска GetRestoreSolutionProjectsTask и её output сохраняется в переменную, которая являетсяReturns
таргета.
<!--
============================================================
_LoadRestoreGraphEntryPoints
Find project entry points and load them into items.
============================================================
-->
<Target Name="_LoadRestoreGraphEntryPoints" Returns="@(RestoreGraphProjectInputItems)">
<!-- Project case -->
<ItemGroup
Condition=" $(MSBuildProjectFullPath.EndsWith('.metaproj')) != 'true'
AND @(RestoreGraphProjectInputItems) == '' ">
<RestoreGraphProjectInputItems Include="$(MSBuildProjectFullPath)" />
</ItemGroup>
<!-- Solution case -->
<GetRestoreSolutionProjectsTask
Condition=" $(MSBuildProjectFullPath.EndsWith('.metaproj')) == 'true'
AND @(RestoreGraphProjectInputItems) == '' "
ProjectReferences="@(ProjectReference)"
SolutionFilePath="$(MSBuildProjectFullPath)">
<Output
TaskParameter="OutputProjectReferences"
ItemName="RestoreGraphProjectInputItems" />
</GetRestoreSolutionProjectsTask>
</Target>
Вызвать таргет и получить возвращаемое значение можно используя команду CallTarget:
<CallTarget Targets="_LoadRestoreGraphEntryPoints">
<Output
TaskParameter="RestoreGraphProjectInputItems"
ItemName="VariableForReturnValues" />
</CallTarget>