<!--
***********************************************************************************************
Microsoft.TestPlatform.CrossTargeting.targets

WARNING:  DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
          created a backup copy.  Incorrect changes to this file will make it
          impossible to load or build your projects from the command-line or the IDE.

Copyright (c) .NET Foundation. All rights reserved.
***********************************************************************************************
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <VSTestTaskAssemblyFile Condition="$(VSTestTaskAssemblyFile) == ''">$(MSBuildExtensionsPath)\Microsoft.TestPlatform.Build.dll</VSTestTaskAssemblyFile>
    <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
  </PropertyGroup>
  <UsingTask TaskName="Microsoft.TestPlatform.Build.Tasks.VSTestLogsTask" AssemblyFile="$(VSTestTaskAssemblyFile)" />
  <!--
  ===================================================================================
               DispatchToInnerBuildsWithVSTestTarget

     Builds this project with /t:$(InnerVSTestTargets) /p:TargetFramework=X for each
     value X in $(TargetFrameworks)

     [IN]
     $(TargetFrameworks) - Semicolon delimited list of target frameworks.
     $(InnerVSTestTargets) - The targets to build for each target framework

     [OUT]
     @(InnerOutput) - The combined output items of inner targets across
                      all target frameworks..

  ===================================================================================
  -->

  <Target Name="DispatchToInnerBuildsWithVSTestTarget" Returns="@(InnerOutput)">
    <PropertyGroup>
      <!-- 
        Emulating technique found in Microsoft.Build.Traversal for deciding whether to run tests in parallel.
        Setting either property will revert to previous behavior of running tests in parallel, but without their
        different TFMs running in parallel.
      -->
      <_TestTfmsInParallel>$([MSBuild]::ValueOrDefault('$(TestTfmsInParallel)', '$(BuildInParallel)'))</_TestTfmsInParallel>
    </PropertyGroup>
    <ItemGroup>
      <_TargetFramework Include="$(TargetFrameworks)" />
      <_ProjectToTestWithTFM Include="$(MSBuildProjectFile)" Properties="TargetFramework=%(_TargetFramework.Identity);VSTestNoBuild=true" />
    </ItemGroup>
    <MSBuild Projects="@(_ProjectToTestWithTFM)"
             Condition="'$(TargetFrameworks)' != '' "
             Targets="$(InnerVSTestTargets)"
             ContinueOnError="ErrorAndContinue"
             BuildInParallel="$(_TestTfmsInParallel)">
      <Output ItemName="InnerOutput" TaskParameter="TargetOutputs" />
    </MSBuild>
  </Target>

  <!--
  ==================================================================================
                                   VSTest

   Cross-targeting version of VSTest.

   [IN]
   $(TargetFrameworks) - Semicolon delimited list of target frameworks.
   $(InnerVSTestTargets) - The targets to build for each target framework. Defaults
                         to 'VSTest' if unset, but allows override to support
                         `msbuild /p:InnerTargets=X;Y;Z` which will build X, Y,
                         and Z targets for each target framework.

   [OUT]
   @(InnerOutput) - The combined output items of the inner targets across
                    all builds.
  =================================================================================
  -->
  <Target Name="VSTest" DependsOnTargets="_ComputeTargetFrameworkItems">
    <CallTarget Condition="'$(VSTestNoBuild)' != 'true'" Targets="BuildProject" />
    <CallTarget Targets="SetVSTestInnerTarget" />
    <CallTarget Targets="DispatchToInnerBuildsWithVSTestTarget" />
  </Target>

  <Target Name="BuildProject">
    <Microsoft.TestPlatform.Build.Tasks.VSTestLogsTask LogType="BuildStarted" />
    <CallTarget Targets="Build" />
    <Microsoft.TestPlatform.Build.Tasks.VSTestLogsTask LogType="BuildCompleted" />
  </Target>

  <Target Name="SetVSTestInnerTarget" Returns="@(InnerOutput)">
    <PropertyGroup Condition="'$(InnerVSTestTargets)' == ''">
      <InnerVSTestTargets>VSTest</InnerVSTestTargets>
    </PropertyGroup>
  </Target>

  <!--
  ===================================================================================
               DispatchToInnerBuildsWithTestProjectTarget

     Builds this project with /t:$(GetTestsProjectTargets) /p:TargetFramework=X for each
     value X in $(TargetFrameworks)

     [IN]
     $(TargetFrameworks) - Semicolon delimited list of target frameworks.
     $(GetTestsProjectTargets) - The targets to build and get module name for each
                               target framework

     [OUT]
     @(InnerOutput) - The combined output items of inner targets across
                      all target frameworks..

  ===================================================================================
  -->

  <Target Name="DispatchToInnerBuildsWithTestProjectTarget" Returns="@(InnerOutput)">
    <PropertyGroup>
      <!-- 
        Emulating technique found in Microsoft.Build.Traversal for deciding whether to run tests in parallel.
        Setting either property will revert to previous behavior of running tests in parallel, but without their
        different TFMs running in parallel.
      -->
      <_TestTfmsInParallel>$([MSBuild]::ValueOrDefault('$(TestTfmsInParallel)', '$(BuildInParallel)'))</_TestTfmsInParallel>
    </PropertyGroup>
    <ItemGroup>
      <_TargetFramework Include="$(TargetFrameworks)" />
      <_ProjectToTestWithTFM Include="$(MSBuildProjectFile)" Properties="TargetFramework=%(_TargetFramework.Identity)" />
    </ItemGroup>
    <MSBuild Projects="@(_ProjectToTestWithTFM)"
             Condition="'$(TargetFrameworks)' != '' "
             Targets="$(GetTestsProjectTargets)"
             ContinueOnError="ErrorAndContinue"
             BuildInParallel="$(_TestTfmsInParallel)">
      <Output ItemName="InnerOutput" TaskParameter="TargetOutputs" />
    </MSBuild>
  </Target>

  <!--
  ==================================================================================
                                   The New Testing Platform

   Cross-targeting version of the new testing platform.

   [IN]
   $(TargetFrameworks) - Semicolon delimited list of target frameworks.
   $(GetTestsProjectTargets) - The targets to build and get module name for each
                             target framework.

   [OUT]
   @(InnerOutput) - The combined output items of the inner targets across
                    all builds.
  =================================================================================
  -->

  <PropertyGroup>
    <GetTestsProjectTargets>_GetTestsProject</GetTestsProjectTargets>
  </PropertyGroup>

  <Target Name="_GetTestsProject" DependsOnTargets="_ComputeTargetFrameworkItems">
    <CallTarget Condition="$(IsTestProject) == 'true' OR '$(IsTestingPlatformApplication)' == 'true'" Targets="Build" />
    <CallTarget Targets="DispatchToInnerBuildsWithTestProjectTarget" />
  </Target>

</Project>
