diff --git a/src/Assets/TestPackages/PackageLibraryDirectDependency/PackageLibraryDirectDependency/PackageLibraryDirectDependency.csproj b/src/Assets/TestPackages/PackageLibraryDirectDependency/PackageLibraryDirectDependency/PackageLibraryDirectDependency.csproj index 231823edc8c7..c4ed8baeb193 100644 --- a/src/Assets/TestPackages/PackageLibraryDirectDependency/PackageLibraryDirectDependency/PackageLibraryDirectDependency.csproj +++ b/src/Assets/TestPackages/PackageLibraryDirectDependency/PackageLibraryDirectDependency/PackageLibraryDirectDependency.csproj @@ -1,10 +1,6 @@ - true - - - net8.0 © Microsoft Razor Test diff --git a/src/Assets/TestPackages/PackageLibraryDirectDependency/PackageLibraryTransitiveDependency/PackageLibraryTransitiveDependency.csproj b/src/Assets/TestPackages/PackageLibraryDirectDependency/PackageLibraryTransitiveDependency/PackageLibraryTransitiveDependency.csproj index 1da2577afcc2..5da5c0d37f18 100644 --- a/src/Assets/TestPackages/PackageLibraryDirectDependency/PackageLibraryTransitiveDependency/PackageLibraryTransitiveDependency.csproj +++ b/src/Assets/TestPackages/PackageLibraryDirectDependency/PackageLibraryTransitiveDependency/PackageLibraryTransitiveDependency.csproj @@ -2,9 +2,6 @@ true - - - net8.0 © Microsoft Razor Test diff --git a/src/Assets/TestPackages/PackageLibraryNoStaticAssets/PackageLibraryNoStaticAssets.csproj b/src/Assets/TestPackages/PackageLibraryNoStaticAssets/PackageLibraryNoStaticAssets.csproj index c65be45a61e3..3d574e76ce85 100644 --- a/src/Assets/TestPackages/PackageLibraryNoStaticAssets/PackageLibraryNoStaticAssets.csproj +++ b/src/Assets/TestPackages/PackageLibraryNoStaticAssets/PackageLibraryNoStaticAssets.csproj @@ -2,9 +2,6 @@ true - - - net8.0 © Microsoft Razor Test diff --git a/src/Assets/TestPackages/PackageLibraryTransitiveDependency/PackageLibraryTransitiveDependency.csproj b/src/Assets/TestPackages/PackageLibraryTransitiveDependency/PackageLibraryTransitiveDependency.csproj index 1da2577afcc2..5da5c0d37f18 100644 --- a/src/Assets/TestPackages/PackageLibraryTransitiveDependency/PackageLibraryTransitiveDependency.csproj +++ b/src/Assets/TestPackages/PackageLibraryTransitiveDependency/PackageLibraryTransitiveDependency.csproj @@ -2,9 +2,6 @@ true - - - net8.0 © Microsoft Razor Test diff --git a/src/Assets/TestProjects/AllResourcesInSatellite/AllResourcesInSatellite.csproj b/src/Assets/TestProjects/AllResourcesInSatellite/AllResourcesInSatellite.csproj index 89d58fc6df67..04c26e61f36b 100644 --- a/src/Assets/TestProjects/AllResourcesInSatellite/AllResourcesInSatellite.csproj +++ b/src/Assets/TestProjects/AllResourcesInSatellite/AllResourcesInSatellite.csproj @@ -8,15 +8,6 @@ true - - - $(TargetFrameworks);net46 - - false diff --git a/src/Assets/TestProjects/AllResourcesInSatelliteDisableVersionGenerate/AllResourcesInSatellite.csproj b/src/Assets/TestProjects/AllResourcesInSatelliteDisableVersionGenerate/AllResourcesInSatellite.csproj index e88002c8e9fa..bd26300d209a 100644 --- a/src/Assets/TestProjects/AllResourcesInSatelliteDisableVersionGenerate/AllResourcesInSatellite.csproj +++ b/src/Assets/TestProjects/AllResourcesInSatelliteDisableVersionGenerate/AllResourcesInSatellite.csproj @@ -9,15 +9,6 @@ false - - - $(TargetFrameworks);net46 - - false diff --git a/src/Assets/TestProjects/RazorClassLibrary/ClassLibrary.csproj b/src/Assets/TestProjects/RazorClassLibrary/ClassLibrary.csproj index 80a63856ab17..34e81b98ce53 100644 --- a/src/Assets/TestProjects/RazorClassLibrary/ClassLibrary.csproj +++ b/src/Assets/TestProjects/RazorClassLibrary/ClassLibrary.csproj @@ -2,9 +2,6 @@ true - - - $(AspNetTestTfm) © Microsoft Razor Test diff --git a/src/Assets/TestProjects/x64SolutionBuild/x64SolutionBuild.csproj b/src/Assets/TestProjects/x64SolutionBuild/x64SolutionBuild.csproj index 14ef6f89c5e5..e2163fcb1a6e 100644 --- a/src/Assets/TestProjects/x64SolutionBuild/x64SolutionBuild.csproj +++ b/src/Assets/TestProjects/x64SolutionBuild/x64SolutionBuild.csproj @@ -1,13 +1,12 @@ - - - - Exe $(CurrentTargetFramework) + + + diff --git a/src/Cli/dotnet/CommonLocalizableStrings.resx b/src/Cli/dotnet/CommonLocalizableStrings.resx index b5001ce32726..83f629036c43 100644 --- a/src/Cli/dotnet/CommonLocalizableStrings.resx +++ b/src/Cli/dotnet/CommonLocalizableStrings.resx @@ -717,4 +717,10 @@ The default is 'true' if a runtime identifier is specified. OS + + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + + + ARTIFACTS_DIR + diff --git a/src/Cli/dotnet/CommonOptions.cs b/src/Cli/dotnet/CommonOptions.cs index 2f13699c5a36..3659607ce37c 100644 --- a/src/Cli/dotnet/CommonOptions.cs +++ b/src/Cli/dotnet/CommonOptions.cs @@ -51,6 +51,15 @@ public static Option FrameworkOption(string description) => }.ForwardAsSingle(o => $"-property:TargetFramework={o}") .AddCompletions(Complete.TargetFrameworksFromProjectFile); + public static Option ArtifactsPathOption = + new ForwardedOption( + // --artifacts-path is pretty verbose, should we use --artifacts instead (or possibly support both)? + new string[] { "--artifacts-path" }, + description: CommonLocalizableStrings.ArtifactsPathOptionDescription) + { + ArgumentHelpName = CommonLocalizableStrings.ArtifactsPathArgumentName + }.ForwardAsSingle(o => $"-property:ArtifactsPath={CommandDirectoryContext.GetFullPath(o)}"); + private static string RuntimeArgName = CommonLocalizableStrings.RuntimeIdentifierArgumentName; public static IEnumerable RuntimeArgFunc(string rid) { diff --git a/src/Cli/dotnet/commands/dotnet-build/BuildCommandParser.cs b/src/Cli/dotnet/commands/dotnet-build/BuildCommandParser.cs index f31df407073e..814304b3bc31 100644 --- a/src/Cli/dotnet/commands/dotnet-build/BuildCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-build/BuildCommandParser.cs @@ -66,6 +66,7 @@ private static Command ConstructCommand() command.AddOption(CommonOptions.VerbosityOption); command.AddOption(CommonOptions.DebugOption); command.AddOption(OutputOption); + command.AddOption(CommonOptions.ArtifactsPathOption); command.AddOption(NoIncrementalOption); command.AddOption(NoDependenciesOption); command.AddOption(NoLogoOption); diff --git a/src/Cli/dotnet/commands/dotnet-clean/CleanCommandParser.cs b/src/Cli/dotnet/commands/dotnet-clean/CleanCommandParser.cs index 6af6981d0dc3..a5283f3e9484 100644 --- a/src/Cli/dotnet/commands/dotnet-clean/CleanCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-clean/CleanCommandParser.cs @@ -51,6 +51,7 @@ private static Command ConstructCommand() command.AddOption(CommonOptions.InteractiveMsBuildForwardOption); command.AddOption(CommonOptions.VerbosityOption); command.AddOption(OutputOption); + command.AddOption(CommonOptions.ArtifactsPathOption); command.AddOption(NoLogoOption); command.AddOption(CommonOptions.DisableBuildServersOption); diff --git a/src/Cli/dotnet/commands/dotnet-pack/PackCommandParser.cs b/src/Cli/dotnet/commands/dotnet-pack/PackCommandParser.cs index 15bb0ccd2b3e..46b8f6695723 100644 --- a/src/Cli/dotnet/commands/dotnet-pack/PackCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-pack/PackCommandParser.cs @@ -56,6 +56,7 @@ private static Command ConstructCommand() command.AddArgument(SlnOrProjectArgument); command.AddOption(OutputOption); + command.AddOption(CommonOptions.ArtifactsPathOption); command.AddOption(NoBuildOption); command.AddOption(IncludeSymbolsOption); command.AddOption(IncludeSourceOption); diff --git a/src/Cli/dotnet/commands/dotnet-publish/PublishCommandParser.cs b/src/Cli/dotnet/commands/dotnet-publish/PublishCommandParser.cs index 8328f71694db..7f0a4ce103c0 100644 --- a/src/Cli/dotnet/commands/dotnet-publish/PublishCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-publish/PublishCommandParser.cs @@ -65,6 +65,7 @@ private static Command ConstructCommand() command.AddArgument(SlnOrProjectArgument); RestoreCommandParser.AddImplicitRestoreOptions(command, includeRuntimeOption: false, includeNoDependenciesOption: true); command.AddOption(OuputOption); + command.AddOption(CommonOptions.ArtifactsPathOption); command.AddOption(ManifestOption); command.AddOption(NoBuildOption); command.AddOption(SelfContainedOption); diff --git a/src/Cli/dotnet/commands/dotnet-test/TestCommandParser.cs b/src/Cli/dotnet/commands/dotnet-test/TestCommandParser.cs index 0064ad6ab34c..67ec63f07593 100644 --- a/src/Cli/dotnet/commands/dotnet-test/TestCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-test/TestCommandParser.cs @@ -140,6 +140,7 @@ private static Command ConstructCommand() command.AddOption(AdapterOption); command.AddOption(LoggerOption); command.AddOption(OutputOption); + command.AddOption(CommonOptions.ArtifactsPathOption); command.AddOption(DiagOption); command.AddOption(NoBuildOption); command.AddOption(ResultsOption); diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf index 98273c89f7fb..1946508892da 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf @@ -12,6 +12,16 @@ Cílová architektura + + ARTIFACTS_DIR + ARTIFACTS_DIR + + + + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + + Resolving the current runtime identifier failed. Nepovedlo se vyřešit aktuální identifikátor modulu runtime. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf index 8da525643afa..b36dd25f4215 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf @@ -12,6 +12,16 @@ Die Zielarchitektur. + + ARTIFACTS_DIR + ARTIFACTS_DIR + + + + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + + Resolving the current runtime identifier failed. Fehler beim Auflösen des aktuellen Runtimebezeichners. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf index 4180d52534b1..4d42121f4fb9 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf @@ -12,6 +12,16 @@ La arquitectura de destino. + + ARTIFACTS_DIR + ARTIFACTS_DIR + + + + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + + Resolving the current runtime identifier failed. No se ha podido resolver el identificador en el tiempo de ejecución actual. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf index b45e14e79188..dce9d837954d 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf @@ -12,6 +12,16 @@ L’architecture cible + + ARTIFACTS_DIR + ARTIFACTS_DIR + + + + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + + Resolving the current runtime identifier failed. Échec de la résolution de l’identificateur d’exécution actuel diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf index 4bee27daabd7..4f9d6d131706 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf @@ -12,6 +12,16 @@ Architettura di destinazione. + + ARTIFACTS_DIR + ARTIFACTS_DIR + + + + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + + Resolving the current runtime identifier failed. La risoluzione dell'identificatore di runtime corrente non è riuscita. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf index 6e9dab693b05..9f0c5bfeae27 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf @@ -12,6 +12,16 @@ ターゲット アーキテクチャ。 + + ARTIFACTS_DIR + ARTIFACTS_DIR + + + + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + + Resolving the current runtime identifier failed. 現在のランタイム識別子を解決できませんでした。 diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf index 46485cba1768..f5232af3b0e9 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf @@ -12,6 +12,16 @@ 대상 아키텍처입니다. + + ARTIFACTS_DIR + ARTIFACTS_DIR + + + + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + + Resolving the current runtime identifier failed. 현재 런타임 식별자를 확인하지 못했습니다. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf index 94e8e422298d..8a99c9bf627b 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf @@ -12,6 +12,16 @@ Architektura docelowa. + + ARTIFACTS_DIR + ARTIFACTS_DIR + + + + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + + Resolving the current runtime identifier failed. Rozpoznawanie bieżącego identyfikatora środowiska uruchomieniowego nie powiodło się. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf index 6c3869b08b53..37fc84d433fd 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf @@ -12,6 +12,16 @@ A arquitetura de destino. + + ARTIFACTS_DIR + ARTIFACTS_DIR + + + + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + + Resolving the current runtime identifier failed. Falha ao resolver o identificador de tempo de execução atual. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf index eac1a91cff92..3682cf58344f 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf @@ -12,6 +12,16 @@ Целевая архитектура. + + ARTIFACTS_DIR + ARTIFACTS_DIR + + + + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + + Resolving the current runtime identifier failed. Не удалось разрешить текущий идентификатор среды выполнения. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf index 438b3c742e78..a297cf025fef 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf @@ -12,6 +12,16 @@ Hedef mimari. + + ARTIFACTS_DIR + ARTIFACTS_DIR + + + + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + + Resolving the current runtime identifier failed. Geçerli çalışma zamanı tanımlayıcısı çözümlenemedi. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf index 62a9695d4944..66318a8fd908 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf @@ -12,6 +12,16 @@ 目标体系结构。 + + ARTIFACTS_DIR + ARTIFACTS_DIR + + + + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + + Resolving the current runtime identifier failed. 解决当前运行时标识符失败。 diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf index 3f864d8eb366..a893b8a310b0 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf @@ -12,6 +12,16 @@ 目標結構。 + + ARTIFACTS_DIR + ARTIFACTS_DIR + + + + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. + + Resolving the current runtime identifier failed. 解析目前執行階段識別碼失敗。 diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/sdk/Sdk.props b/src/Tasks/Microsoft.NET.Build.Tasks/sdk/Sdk.props index 4a646cb37fda..836484c261f7 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/sdk/Sdk.props +++ b/src/Tasks/Microsoft.NET.Build.Tasks/sdk/Sdk.props @@ -32,6 +32,60 @@ Copyright (c) .NET Foundation. All rights reserved. true + + + + + true + + + <_DirectoryBuildPropsFile Condition="'$(_DirectoryBuildPropsFile)' == ''">Directory.Build.props + <_DirectoryBuildPropsBasePath Condition="'$(_DirectoryBuildPropsBasePath)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), '$(_DirectoryBuildPropsFile)')) + $([System.IO.Path]::Combine('$(_DirectoryBuildPropsBasePath)', '$(_DirectoryBuildPropsFile)')) + + + + + + false + + + + + true + true + + + + + + $(_DirectoryBuildPropsBasePath)\.artifacts + true + + + + + $(MSBuildProjectDirectory)\.artifacts + + + + true + $(MSBuildProjectName) + + + + $(ArtifactsPath)\obj\$(ArtifactsProjectName)\ + $(ArtifactsPath)\obj\ + + $(ProjectExtensionsPathForSpecifiedProject) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.DefaultOutputPaths.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.DefaultOutputPaths.targets index e46b2066d2e1..bbd0e6575c59 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.DefaultOutputPaths.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.DefaultOutputPaths.targets @@ -11,29 +11,109 @@ Copyright (c) .NET Foundation. All rights reserved. --> - - - Debug - AnyCPU - $(Platform) + + + true + + + + + + + true + + + + + + $(_DirectoryBuildPropsBasePath)\.artifacts + true + + + + + $(MSBuildProjectDirectory)\.artifacts + + + + $(MSBuildProjectName) + + bin + publish + package + + + + $(Configuration.ToLowerInvariant()) + + + $(ArtifactsPivots)_$(TargetFramework.ToLowerInvariant()) + + + $(ArtifactsPivots)_$(RuntimeIdentifier.ToLowerInvariant()) + + + + + $(ArtifactsPath)\$(ArtifactsBinOutputName)\$(ArtifactsProjectName)\ + $(ArtifactsPath)\obj\$(ArtifactsProjectName)\ + $(ArtifactsPath)\$(ArtifactsPublishOutputName)\$(ArtifactsProjectName)\$(ArtifactsPivots)\ + + + + + $(ArtifactsPath)\$(ArtifactsBinOutputName)\ + $(ArtifactsPath)\obj\ + $(ArtifactsPath)\$(ArtifactsPublishOutputName)\$(ArtifactsPivots)\ + + + + $(BaseOutputPath)$(ArtifactsPivots)\ + $(BaseIntermediateOutputPath)$(ArtifactsPivots)\ + + + $(ArtifactsPath)\$(ArtifactsPackageOutputName)\$(Configuration.ToLowerInvariant())\ + + + + bin\ $(BaseOutputPath)\ $(BaseOutputPath)$(Configuration)\ $(BaseOutputPath)$(PlatformName)\$(Configuration)\ $(OutputPath)\ + + + obj\ $(BaseIntermediateOutputPath)\ $(BaseIntermediateOutputPath)$(Configuration)\ @@ -42,8 +122,35 @@ Copyright (c) .NET Foundation. All rights reserved. - - $(OutputPath) + + $(OutputPath) + + + $(DefaultItemExcludes);$(OutputPath)/** + $(DefaultItemExcludes);$(IntermediateOutputPath)/** + + + + $(DefaultItemExcludes);$(ArtifactsPath)/** + + $(DefaultItemExcludes);bin/**;obj/** + + + + + $(OutputPath)$(TargetFramework.ToLowerInvariant())\ + + + + $(IntermediateOutputPath)$(TargetFramework.ToLowerInvariant())\ + diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets index 73c6643b6053..07d07e979990 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets @@ -302,8 +302,8 @@ Copyright (c) .NET Foundation. All rights reserved. append a RID the user never mentioned in the path and do so even in the AnyCPU case. --> - $(IntermediateOutputPath)$(RuntimeIdentifier)\ - $(OutputPath)$(RuntimeIdentifier)\ + $(IntermediateOutputPath)$(RuntimeIdentifier)\ + $(OutputPath)$(RuntimeIdentifier)\ - - + + + Debug + AnyCPU + $(Platform) + + + + @@ -55,10 +65,6 @@ Copyright (c) .NET Foundation. All rights reserved. false - - <_TargetFrameworkVersionWithoutV>$(TargetFrameworkVersion.TrimStart('vV')) - - - + + publish - - - - $(DefaultItemExcludes);$(OutputPath)/** - $(DefaultItemExcludes);$(IntermediateOutputPath)/** - - - - - true - - + true true - - - $(IntermediateOutputPath)$(TargetFramework.ToLowerInvariant())\ - $(OutputPath)$(TargetFramework.ToLowerInvariant())\ - + + diff --git a/src/Tests/Microsoft.DotNet.ShellShim.Tests/ShellShimRepositoryTests.cs b/src/Tests/Microsoft.DotNet.ShellShim.Tests/ShellShimRepositoryTests.cs index f208da9d8105..89f924866793 100644 --- a/src/Tests/Microsoft.DotNet.ShellShim.Tests/ShellShimRepositoryTests.cs +++ b/src/Tests/Microsoft.DotNet.ShellShim.Tests/ShellShimRepositoryTests.cs @@ -495,9 +495,7 @@ private FilePath MakeHelloWorldExecutableDll([CallerMemberName] string callingMe var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? "Debug"; - var outputDirectory = new DirectoryInfo(Path.Combine(testInstance.Path, "bin", configuration)) - .EnumerateDirectories() - .Single(); + var outputDirectory = new DirectoryInfo(OutputPathCalculator.FromProject(testInstance.Path, testInstance).GetOutputDirectory(configuration: configuration)); return new FilePath(Path.Combine(outputDirectory.FullName, $"{testAppName}.dll")); } diff --git a/src/Tests/Microsoft.NET.Build.Tests/AppHostTests.cs b/src/Tests/Microsoft.NET.Build.Tests/AppHostTests.cs index 9bf485677e4a..b4b1f81302dc 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/AppHostTests.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/AppHostTests.cs @@ -78,7 +78,7 @@ public void It_builds_a_runnable_apphost_by_default(string targetFramework) .Should() .Pass(); - var outputDirectory = buildCommand.GetOutputDirectory(targetFramework); + var outputDirectory = buildCommand.GetOutputDirectory(); var hostExecutable = $"HelloWorld{Constants.ExeSuffix}"; outputDirectory.Should().OnlyHaveFiles(GetExpectedFilesFromBuild(testAsset, targetFramework)); new RunExeCommand(Log, Path.Combine(outputDirectory.FullName, hostExecutable)) @@ -270,19 +270,19 @@ public void It_uses_an_apphost_based_on_platform_target(string target) var testAsset = _testAssetsManager .CopyTestAsset("HelloWorld", identifier: target) + .WithTargetFramework(targetFramework) .WithSource(); var buildCommand = new BuildCommand(testAsset); buildCommand .Execute(new string[] { - $"/p:TargetFramework={targetFramework}", $"/p:PlatformTarget={target}", $"/p:NETCoreSdkRuntimeIdentifier={EnvironmentInfo.GetCompatibleRid(targetFramework)}" }) .Should() .Pass(); - var apphostPath = Path.Combine(buildCommand.GetOutputDirectory(targetFramework).FullName, "HelloWorld.exe"); + var apphostPath = Path.Combine(buildCommand.GetOutputDirectory().FullName, "HelloWorld.exe"); if (target == "x86") { IsPE32(apphostPath).Should().BeTrue(); @@ -321,7 +321,7 @@ public void AppHost_contains_resources_from_the_managed_dll() .Should() .Pass(); - var outputDirectory = buildCommand.GetOutputDirectory(targetFramework, runtimeIdentifier: runtimeIdentifier); + var outputDirectory = buildCommand.GetOutputDirectory(runtimeIdentifier: runtimeIdentifier); outputDirectory.Should().HaveFiles(new[] { testProject.Name + ".exe" }); string apphostPath = Path.Combine(outputDirectory.FullName, testProject.Name + ".exe"); @@ -406,7 +406,7 @@ public void It_retries_on_failure_to_create_apphost() .Should() .Pass(); - var intermediateDirectory = buildCommand.GetIntermediateDirectory(targetFramework: ToolsetInfo.CurrentTargetFramework).FullName; + var intermediateDirectory = buildCommand.GetIntermediateDirectory().FullName; File.SetLastWriteTimeUtc( Path.Combine( diff --git a/src/Tests/Microsoft.NET.Build.Tests/ArtifactsOutputPathTests.cs b/src/Tests/Microsoft.NET.Build.Tests/ArtifactsOutputPathTests.cs new file mode 100644 index 000000000000..003745419176 --- /dev/null +++ b/src/Tests/Microsoft.NET.Build.Tests/ArtifactsOutputPathTests.cs @@ -0,0 +1,516 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using FluentAssertions; +using Microsoft.NET.TestFramework; +using Microsoft.NET.TestFramework.Assertions; +using Microsoft.NET.TestFramework.Commands; +using Microsoft.NET.TestFramework.ProjectConstruction; +using Xunit; +using Xunit.Abstractions; +using Xunit.Sdk; + +namespace Microsoft.NET.Build.Tests +{ + using ArtifactsTestExtensions; + + public class ArtifactsOutputPathTests : SdkTest + { + public ArtifactsOutputPathTests(ITestOutputHelper log) : base(log) + { + } + + (List testProjects, TestAsset testAsset) GetTestProjects(bool useDirectoryBuildProps, [CallerMemberName] string callingMethod = "") + { + var testProject1 = new TestProject() + { + Name = "App1", + IsExe = true + }; + + var testProject2 = new TestProject() + { + Name = "App2", + IsExe = true + }; + + var testLibraryProject = new TestProject() + { + Name = "Library", + }; + + testProject1.ReferencedProjects.Add(testLibraryProject); + testProject2.ReferencedProjects.Add(testLibraryProject); + + List testProjects = new() { testProject1, testProject2, testLibraryProject }; + + foreach (var testProject in testProjects) + { + testProject.UseArtifactsOutput = true; + testProject.UseDirectoryBuildPropsForArtifactsOutput = useDirectoryBuildProps; + } + + var testAsset = _testAssetsManager.CreateTestProjects(testProjects, callingMethod: callingMethod, identifier: useDirectoryBuildProps.ToString()); + + if (useDirectoryBuildProps) + { + File.WriteAllText(Path.Combine(testAsset.Path, "Directory.Build.props"), + """ + + + true + + + """); + } + + return (testProjects, testAsset); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ItUsesArtifactsOutputPathForBuild(bool useDirectoryBuildProps) + { + var (testProjects, testAsset) = GetTestProjects(useDirectoryBuildProps); + + new DotnetCommand(Log, "build") + .WithWorkingDirectory(testAsset.Path) + .SetEnvironmentVariables(useDirectoryBuildProps) + .Execute() + .Should() + .Pass(); + + ValidateIntermediatePaths(testAsset, testProjects, useDirectoryBuildProps); + + foreach (var testProject in testProjects) + { + OutputPathCalculator outputPathCalculator = OutputPathCalculator.FromProject(Path.Combine(testAsset.Path, testProject.Name), testProject); + new FileInfo(Path.Combine(outputPathCalculator.GetOutputDirectory(), testProject.Name + ".dll")) + .Should() + .Exist(); + } + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ItUsesArtifactsOutputPathForPublish(bool useDirectoryBuildProps) + { + var (testProjects, testAsset) = GetTestProjects(useDirectoryBuildProps); + + new DotnetCommand(Log, "publish") + .WithWorkingDirectory(testAsset.Path) + .SetEnvironmentVariables(useDirectoryBuildProps) + .Execute() + .Should() + .Pass(); + + ValidateIntermediatePaths(testAsset, testProjects, useDirectoryBuildProps, "release"); + + foreach (var testProject in testProjects) + { + OutputPathCalculator outputPathCalculator = OutputPathCalculator.FromProject(Path.Combine(testAsset.Path, testProject.Name), testProject); + new FileInfo(Path.Combine(outputPathCalculator.GetOutputDirectory(configuration: "release"), testProject.Name + ".dll")) + .Should() + .Exist(); + new FileInfo(Path.Combine(outputPathCalculator.GetPublishDirectory(configuration: "release"), testProject.Name + ".dll")) + .Should() + .Exist(); + } + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ItUseArtifactstOutputPathForPack(bool useDirectoryBuildProps) + { + var (testProjects, testAsset) = GetTestProjects(useDirectoryBuildProps); + + new DotnetCommand(Log, "pack") + .WithWorkingDirectory(testAsset.Path) + .SetEnvironmentVariables(useDirectoryBuildProps) + .Execute() + .Should() + .Pass(); + + ValidateIntermediatePaths(testAsset, testProjects, useDirectoryBuildProps, "release"); + + foreach (var testProject in testProjects) + { + OutputPathCalculator outputPathCalculator = OutputPathCalculator.FromProject(Path.Combine(testAsset.Path, testProject.Name), testProject); + new FileInfo(Path.Combine(outputPathCalculator.GetOutputDirectory(configuration: "release"), testProject.Name + ".dll")) + .Should() + .Exist(); + new FileInfo(Path.Combine(outputPathCalculator.GetPackageDirectory(configuration: "release"), testProject.Name + ".1.0.0.nupkg")) + .Should() + .Exist(); + } + } + + void ValidateIntermediatePaths(TestAsset testAsset, IEnumerable testProjects, bool useDirectoryBuildProps, string configuration = "debug") + { + foreach (var testProject in testProjects) + { + if (!useDirectoryBuildProps) + { + new DirectoryInfo(Path.Combine(testAsset.TestRoot, testProject.Name)) + .Should() + .HaveDirectory("obj"); + + new DirectoryInfo(Path.Combine(testAsset.TestRoot, testProject.Name, "bin")) + .Should() + .NotExist(); + + new DirectoryInfo(Path.Combine(testAsset.TestRoot, "artifacts", "obj")) + .Should() + .NotExist(); + } + else + { + new DirectoryInfo(Path.Combine(testAsset.TestRoot, testProject.Name)) + .Should() + .NotHaveSubDirectories(); + + new DirectoryInfo(Path.Combine(testAsset.TestRoot, ".artifacts", "obj", testProject.Name, configuration)) + .Should() + .Exist(); + }; + } + } + + [Fact] + public void ProjectsCanSwitchOutputFormats() + { + var testProject = new TestProject() + { + IsExe = true, + }; + + var testAsset = _testAssetsManager.CreateTestProject(testProject); + + // Build without artifacts format + new BuildCommand(testAsset) + .Execute() + .Should() + .Pass(); + + new DirectoryInfo(OutputPathCalculator.FromProject(testAsset.Path, testProject).GetOutputDirectory()) + .Should() + .Exist(); + + // Now build as if UseArtifactsOutput was set in project file + new BuildCommand(testAsset) + .Execute("/p:UseArtifactsOutput=true", "/p:ImportDirectoryBuildProps=false") + .Should() + .Pass(); + + new DirectoryInfo(Path.Combine(testAsset.Path, testProject.Name, ".artifacts", "bin", "debug")) + .Should() + .Exist(); + + // Now add a Directory.Build.props file setting UseArtifactsOutput to true + File.WriteAllText(Path.Combine(testAsset.Path, "Directory.Build.props"), """ + + + true + + + """); + + new BuildCommand(testAsset) + .Execute() + .Should() + .Pass(); + + new DirectoryInfo(OutputPathCalculator.FromProject(testAsset.Path, testProject).GetOutputDirectory()) + .Should() + .Exist(); + + // Now go back to not using artifacts output format + File.Delete(Path.Combine(testAsset.Path, "Directory.Build.props")); + + new BuildCommand(testAsset) + .Execute() + .Should() + .Pass(); + } + + [Fact] + public void ProjectsCanCustomizeOutputPathBasedOnTargetFramework() + { + var testProject = new TestProject("CustomizeArtifactsPath") + { + IsExe = true, + TargetFrameworks = "net7.0;net8.0;netstandard2.0" + }; + + var testAsset = _testAssetsManager.CreateTestProject(testProject); + + File.WriteAllText(Path.Combine(testAsset.Path, "Directory.Build.props"), """ + + + true + $(MSBuildThisFileDirectory)\Directory.AfterTargetFrameworkInference.targets + + + """); + + File.WriteAllText(Path.Combine(testAsset.Path, "Directory.AfterTargetFrameworkInference.targets"), """ + + + NET8_$(Configuration) + NET7_$(Configuration) + + + """); + + new BuildCommand(testAsset) + .Execute() + .Should() + .Pass(); + + new DirectoryInfo(Path.Combine(testAsset.Path, ".artifacts", "bin", testProject.Name, "NET8_Debug")).Should().Exist(); + new DirectoryInfo(Path.Combine(testAsset.Path, ".artifacts", "bin", testProject.Name, "NET7_Debug")).Should().Exist(); + new DirectoryInfo(Path.Combine(testAsset.Path, ".artifacts", "bin", testProject.Name, "debug_netstandard2.0")).Should().Exist(); + + new DirectoryInfo(Path.Combine(testAsset.Path, ".artifacts", "bin", testProject.Name, "debug_net8.0")).Should().NotExist(); + new DirectoryInfo(Path.Combine(testAsset.Path, ".artifacts", "bin", testProject.Name, "debug_net7.0")).Should().NotExist(); + + new DirectoryInfo(Path.Combine(testAsset.Path, ".artifacts", "obj", testProject.Name, "NET8_Debug")).Should().Exist(); + new DirectoryInfo(Path.Combine(testAsset.Path, ".artifacts", "obj", testProject.Name, "NET7_Debug")).Should().Exist(); + new DirectoryInfo(Path.Combine(testAsset.Path, ".artifacts", "obj", testProject.Name, "debug_netstandard2.0")).Should().Exist(); + + new DirectoryInfo(Path.Combine(testAsset.Path, ".artifacts", "obj", testProject.Name, "debug_net8.0")).Should().NotExist(); + new DirectoryInfo(Path.Combine(testAsset.Path, ".artifacts", "obj", testProject.Name, "debug_net7.0")).Should().NotExist(); + + foreach (var targetFramework in testProject.TargetFrameworks.Split(';')) + { + new DotnetPublishCommand(Log, "-f", targetFramework) + .WithWorkingDirectory(Path.Combine(testAsset.Path, testProject.Name)) + .Execute() + .Should() + .Pass(); + } + + // Note that publish defaults to release configuration for .NET 8 but not prior TargetFrameworks + new DirectoryInfo(Path.Combine(testAsset.Path, ".artifacts", "publish", testProject.Name, "NET8_Release")).Should().Exist(); + new DirectoryInfo(Path.Combine(testAsset.Path, ".artifacts", "publish", testProject.Name, "NET7_Debug")).Should().Exist(); + new DirectoryInfo(Path.Combine(testAsset.Path, ".artifacts", "publish", testProject.Name, "debug_netstandard2.0")).Should().Exist(); + + new DotnetPackCommand(Log) + .WithWorkingDirectory(Path.Combine(testAsset.Path, testProject.Name)) + .Execute() + .Should() + .Pass(); + + new DirectoryInfo(Path.Combine(testAsset.Path, ".artifacts", "package", "release")).Should().Exist(); + new FileInfo(Path.Combine(testAsset.Path, ".artifacts", "package", "release", testProject.Name + ".1.0.0.nupkg")).Should().Exist(); + } + + TestAsset CreateCustomizedTestProject(bool useDirectoryBuildProps, string propertyName, string propertyValue, [CallerMemberName] string callingMethod = "") + { + var testProject = new TestProject("App") + { + IsExe = true + }; + + testProject.UseArtifactsOutput = true; + testProject.UseDirectoryBuildPropsForArtifactsOutput = useDirectoryBuildProps; + + if (!useDirectoryBuildProps) + { + testProject.AdditionalProperties[propertyName] = propertyValue; + } + + var testAsset = _testAssetsManager.CreateTestProjects(new[] { testProject }, callingMethod: callingMethod, identifier: useDirectoryBuildProps.ToString()); + + if (useDirectoryBuildProps) + { + File.WriteAllText(Path.Combine(testAsset.Path, "Directory.Build.props"), + $""" + + + true + <{propertyName}>{propertyValue} + + + """); + } + + return testAsset; + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ArtifactsPathCanBeSet(bool useDirectoryBuildProps) + { + var artifactsFolder = _testAssetsManager.CreateTestDirectory(identifier: "ArtifactsPath").Path; + + var testAsset = CreateCustomizedTestProject(useDirectoryBuildProps, "ArtifactsPath", artifactsFolder); + + new DotnetBuildCommand(testAsset) + .SetEnvironmentVariables(useDirectoryBuildProps) + .Execute() + .Should() + .Pass(); + + if (useDirectoryBuildProps) + { + new FileInfo(Path.Combine(artifactsFolder, "bin", "App", "debug", "App.dll")) + .Should() + .Exist(); + } + else + { + new FileInfo(Path.Combine(artifactsFolder, "bin", "debug", "App.dll")) + .Should() + .Exist(); + } + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void BinOutputNameCanBeSet(bool useDirectoryBuildProps) + { + var testAsset = CreateCustomizedTestProject(useDirectoryBuildProps, "ArtifactsBinOutputName", "binaries"); + + new DotnetBuildCommand(testAsset) + .SetEnvironmentVariables(useDirectoryBuildProps) + .Execute() + .Should() + .Pass(); + + if (useDirectoryBuildProps) + { + new FileInfo(Path.Combine(testAsset.Path, ".artifacts", "binaries", "App", "debug", "App.dll")) + .Should() + .Exist(); + } + else + { + new FileInfo(Path.Combine(testAsset.Path, "App", ".artifacts", "binaries", "debug", "App.dll")) + .Should() + .Exist(); + } + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void PublishOutputNameCanBeSet(bool useDirectoryBuildProps) + { + var testAsset = CreateCustomizedTestProject(useDirectoryBuildProps, "ArtifactsPublishOutputName", "published_app"); + + new DotnetPublishCommand(Log) + .WithWorkingDirectory(testAsset.Path) + .SetEnvironmentVariables(useDirectoryBuildProps) + .Execute() + .Should() + .Pass(); + + if (useDirectoryBuildProps) + { + new FileInfo(Path.Combine(testAsset.Path, ".artifacts", "published_app", "App", "release", "App.dll")) + .Should() + .Exist(); + } + else + { + new FileInfo(Path.Combine(testAsset.Path, "App", ".artifacts", "published_app", "release", "App.dll")) + .Should() + .Exist(); + } + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void PackageOutputNameCanBeSet(bool useDirectoryBuildProps) + { + var testAsset = CreateCustomizedTestProject(useDirectoryBuildProps, "ArtifactsPackageOutputName", "package_output"); + + new DotnetPackCommand(Log) + .WithWorkingDirectory(testAsset.Path) + .SetEnvironmentVariables(useDirectoryBuildProps) + .Execute() + .Should() + .Pass(); + + if (useDirectoryBuildProps) + { + new FileInfo(Path.Combine(testAsset.Path, ".artifacts", "package_output", "release", "App.1.0.0.nupkg")) + .Should() + .Exist(); + } + else + { + new FileInfo(Path.Combine(testAsset.Path, "App", ".artifacts", "package_output", "release", "App.1.0.0.nupkg")) + .Should() + .Exist(); + } + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ProjectNameCanBeSet(bool useDirectoryBuildProps) + { + var testAsset = CreateCustomizedTestProject(useDirectoryBuildProps, "ArtifactsProjectName", "Apps\\MyApp"); + + new DotnetBuildCommand(Log) + .WithWorkingDirectory(testAsset.Path) + .SetEnvironmentVariables(useDirectoryBuildProps) + .Execute() + .Should() + .Pass(); + + if (useDirectoryBuildProps) + { + new FileInfo(Path.Combine(testAsset.Path, ".artifacts", "bin", "Apps", "MyApp", "debug", "App.dll")) + .Should() + .Exist(); + } + else + { + // Note that customized ArtifactsProjectName doesn't have an impact here when the artifacts folder is already inside the project folder + new FileInfo(Path.Combine(testAsset.Path, "App", ".artifacts", "bin", "debug", "App.dll")) + .Should() + .Exist(); + } + } + } + + namespace ArtifactsTestExtensions + { + static class Extensions + { + public static TestCommand SetEnvironmentVariables(this TestCommand command, bool useDirectoryBuildProps) + { + // There is an empty Directory.Build.props file in the test execution root, to stop other files further up in the repo from + // impacting the tests. So if a project set UseArtifactsOutput to true, the logic would find that file and put the output + // in that folder. To simulate the situation where there is no Directory.Build.props, we turn it off via an environment + // variable. + if (!useDirectoryBuildProps) + { + return command.WithEnvironmentVariable("ImportDirectoryBuildProps", "false"); + } + else + { + return command; + } + } + } + } +} diff --git a/src/Tests/Microsoft.NET.Build.Tests/COMReferenceTests.cs b/src/Tests/Microsoft.NET.Build.Tests/COMReferenceTests.cs index b4d9dd473235..e967989ba781 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/COMReferenceTests.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/COMReferenceTests.cs @@ -119,7 +119,7 @@ static void Main(string[] args) .CreateTestProject(testProject) .WithProjectChanges(doc => doc.Root.Add(new[] { reference1, reference2 })); - var buildCommand = new BuildCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var buildCommand = new BuildCommand(testAsset); buildCommand.Execute().Should().Pass(); var outputDirectory = buildCommand.GetOutputDirectory(targetFramework); diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenFrameworkReferences.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenFrameworkReferences.cs index 3ce1ce8c5403..422252fc69c2 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenFrameworkReferences.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenFrameworkReferences.cs @@ -107,9 +107,9 @@ public void Multiple_frameworks_are_written_to_runtimeconfig_for_self_contained_ .Should() .Pass(); - DirectoryInfo outputDirectory = buildCommand.GetOutputDirectory(testProject.TargetFrameworks); + DirectoryInfo outputDirectory = buildCommand.GetOutputDirectory(runtimeIdentifier: testProject.RuntimeIdentifier); - string runtimeConfigFile = Path.Combine(outputDirectory.FullName, testProject.RuntimeIdentifier, testProject.Name + ".runtimeconfig.json"); + string runtimeConfigFile = Path.Combine(outputDirectory.FullName, testProject.Name + ".runtimeconfig.json"); List includedFrameworkNames = GetIncludedFrameworks(runtimeConfigFile); if (shouldHaveIncludedFrameworks) { @@ -724,13 +724,13 @@ public void TransitiveFrameworkReferenceFromPackageReference() var packageAsset = _testAssetsManager.CreateTestProject(referencedPackage); - var packCommand = new PackCommand(Log, packageAsset.TestRoot, referencedPackage.Name); + var packCommand = new PackCommand(packageAsset); packCommand.Execute() .Should() .Pass(); - var nupkgFolder = packCommand.GetOutputDirectory(null); + var nupkgFolder = packCommand.GetPackageDirectory(); var testProject = new TestProject() { @@ -1110,7 +1110,7 @@ private ResolvedVersionInfo GetResolvedVersions(TestProject testProject, testAsset = testAsset.WithProjectChanges(projectChanges); } - var command = new MSBuildCommand(Log, "WriteResolvedVersions", Path.Combine(testAsset.TestRoot, testProject.Name)); + var command = new MSBuildCommand(testAsset, "WriteResolvedVersions"); command.ExecuteWithoutRestore() .Should() diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeHaveAPackageReferenceWithAliases.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeHaveAPackageReferenceWithAliases.cs index 80e9bcb7fd6c..f1db2a2ad0d8 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeHaveAPackageReferenceWithAliases.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeHaveAPackageReferenceWithAliases.cs @@ -13,6 +13,7 @@ using System.Runtime.CompilerServices; using Xunit; using Xunit.Abstractions; +using static System.Net.WebRequestMethods; namespace Microsoft.NET.Build.Tests { @@ -153,7 +154,7 @@ private IEnumerable GetPackageReferencesWithConflictingTyp private TestPackageReference GetPackageReference(string targetFramework, string packageName, string projectFileContent, [CallerMemberName] string callingMethod = "", string identifier = null) { var project = GetProject(targetFramework, packageName, projectFileContent); - var packCommand = new PackCommand(Log, _testAssetsManager.CreateTestProject(project, callingMethod: callingMethod, identifier: identifier).TestRoot, packageName); + var packCommand = new PackCommand(_testAssetsManager.CreateTestProject(project, callingMethod: callingMethod, identifier: identifier)); packCommand .Execute() diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantAllResourcesInSatellite.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantAllResourcesInSatellite.cs index 19c0aa0285a2..0865bbc874fc 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantAllResourcesInSatellite.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantAllResourcesInSatellite.cs @@ -44,6 +44,14 @@ internal static void TestSatelliteResources( testAsset = testAsset.WithProjectChanges(projectChanges); } + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Also target desktop on Windows to get more test coverage: + // * Desktop requires satellites to have same public key as parent whereas coreclr does not. + // * Reference path handling of satellite assembly generation used to be incorrect for desktop. + testAsset = testAsset.WithTargetFrameworks($"{ToolsetInfo.CurrentTargetFramework};net46"); + } + var buildCommand = new BuildCommand(testAsset); if (setup != null) diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantRuntimeConfigInBuiltProjectOutputGroup.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantRuntimeConfigInBuiltProjectOutputGroup.cs index 583785def0e2..1ca70610bf83 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantRuntimeConfigInBuiltProjectOutputGroup.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantRuntimeConfigInBuiltProjectOutputGroup.cs @@ -32,9 +32,7 @@ public void It_has_target_path_and_final_outputput_path_metadata(string targetFr .WithTargetFramework(targetFramework); var command = new GetValuesCommand( - Log, - testAsset.TestRoot, - targetFramework, + testAsset, "BuiltProjectOutputGroupOutput", GetValuesCommand.ValueType.Item) { @@ -65,12 +63,14 @@ public void It_has_runtime_config_properties_after_partial_build() }; var testAsset = _testAssetsManager.CreateTestProject(testProject, testProject.Name); - new BuildCommand(testAsset) + var buildCommand = new BuildCommand(testAsset); + + buildCommand .Execute("/property:Configuration=Release") .Should() .Pass(); - var configFile = Path.Combine(testAsset.TestRoot, testProject.Name, "bin", "Release", testProject.TargetFrameworks, testProject.RuntimeIdentifier, testProject.Name + ".runtimeconfig.json"); + var configFile = Path.Combine(buildCommand.GetOutputDirectory(configuration: "Release", runtimeIdentifier: testProject.RuntimeIdentifier).FullName, testProject.Name + ".runtimeconfig.json"); File.Exists(configFile).Should().BeTrue(); File.ReadAllText(configFile).Should().NotContain("\"System.Runtime.TieredCompilation\""); @@ -120,12 +120,14 @@ public void It_updates_runtime_config_properties_after_partial_build() propertyGroup.Add(new XElement(ns + "ThreadPoolMinThreads", "3")); }); - new BuildCommand(testAsset) + var buildCommand = new BuildCommand(testAsset); + + buildCommand .Execute("/property:Configuration=Release") .Should() .Pass(); - var configFile = Path.Combine(testAsset.TestRoot, testProject.Name, "bin", "Release", testProject.TargetFrameworks, testProject.RuntimeIdentifier, testProject.Name + ".runtimeconfig.json"); + var configFile = Path.Combine(buildCommand.GetOutputDirectory(configuration: "Release", runtimeIdentifier: testProject.RuntimeIdentifier).FullName, testProject.Name + ".runtimeconfig.json"); File.Exists(configFile).Should().BeTrue(); File.ReadAllText(configFile).Should().Contain("\"System.Runtime.TieredCompilation\": true"); diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantSatelliteAssembliesHaveassemblyVersion.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantSatelliteAssembliesHaveassemblyVersion.cs index fa348e70e07f..292aed62fdd7 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantSatelliteAssembliesHaveassemblyVersion.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantSatelliteAssembliesHaveassemblyVersion.cs @@ -11,6 +11,7 @@ using FluentAssertions; using System.Reflection; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace Microsoft.NET.Build.Tests { @@ -28,6 +29,14 @@ private void RestoreAndBuildTestAssets([CallerMemberName] string callingMethod = .CopyTestAsset("AllResourcesInSatelliteDisableVersionGenerate", callingMethod) .WithSource(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Also target desktop on Windows to get more test coverage: + // * Desktop requires satellites to have same public key as parent whereas coreclr does not. + // * Reference path handling of satellite assembly generation used to be incorrect for desktop. + testAsset = testAsset.WithTargetFrameworks($"{ToolsetInfo.CurrentTargetFramework};net46"); + } + var buildCommand = new BuildCommand(testAsset); buildCommand .Execute() diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildACppCliProject.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildACppCliProject.cs index e1c4156ae6bd..672d983df948 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildACppCliProject.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildACppCliProject.cs @@ -40,12 +40,14 @@ public void It_builds_and_runs() .Should() .Pass(); - new BuildCommand(testAsset, "CSConsoleApp") + var buildCommand = new BuildCommand(testAsset, "CSConsoleApp"); + buildCommand .Execute(new string[] { "-p:Platform=x64", "-p:BuildProjectReferences=false" }) .Should() .Pass(); - var exe = Path.Combine( //find the platform directory + var exe = Path.Combine( + //find the platform directory new DirectoryInfo(Path.Combine(testAsset.TestRoot, "CSConsoleApp", "bin")).GetDirectories().Single().FullName, "Debug", ToolsetInfo.CurrentTargetFramework, diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildACrossTargetedLibrary.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildACrossTargetedLibrary.cs index d1c81c30e854..9c822b903fe5 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildACrossTargetedLibrary.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildACrossTargetedLibrary.cs @@ -24,16 +24,16 @@ public GivenThatWeWantToBuildACrossTargetedLibrary(ITestOutputHelper log) : base public void It_builds_nondesktop_library_successfully_on_all_platforms() { var testAsset = _testAssetsManager - .CopyTestAsset("CrossTargeting") + .CopyTestAsset(Path.Combine("CrossTargeting", "NetStandardAndNetCoreApp")) .WithSource(); - var buildCommand = new BuildCommand(testAsset, "NetStandardAndNetCoreApp"); + var buildCommand = new BuildCommand(testAsset); buildCommand .Execute() .Should() .Pass(); - var outputDirectory = buildCommand.GetOutputDirectory(targetFramework: ""); + var outputDirectory = new DirectoryInfo(Path.Combine(buildCommand.ProjectRootPath, "bin", "Debug")); outputDirectory.Should().OnlyHaveFiles(new[] { $"{ToolsetInfo.CurrentTargetFramework}/NetStandardAndNetCoreApp.dll", $"{ToolsetInfo.CurrentTargetFramework}/NetStandardAndNetCoreApp.pdb", @@ -61,7 +61,7 @@ public void It_builds_desktop_library_successfully_on_windows() .Should() .Pass(); - var outputDirectory = buildCommand.GetOutputDirectory(targetFramework: ""); + var outputDirectory = new DirectoryInfo(Path.Combine(buildCommand.ProjectRootPath, "bin", "Debug")); outputDirectory.Should().OnlyHaveFiles(new[] { "net40/DesktopAndNetStandard.dll", "net40/DesktopAndNetStandard.pdb", diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildANetCoreApp.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildANetCoreApp.cs index 8c239e4ada92..25442a599c5d 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildANetCoreApp.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildANetCoreApp.cs @@ -612,40 +612,53 @@ public void It_publishes_package_satellites_correctly(bool crossTarget) outputDirectory.Should().HaveFile(Path.Combine("fr", "Humanizer.resources.dll")); } - [Fact] - public void It_uses_lowercase_form_of_the_target_framework_for_the_output_path() + [Theory] + [InlineData(true)] + [InlineData(false)] + public void It_uses_lowercase_form_of_the_target_framework_for_the_output_path(bool useStandardOutputPaths) { var testProject = new TestProject() { Name = "OutputPathCasing", - TargetFrameworks = "ignored", + // Force the actual TargetFramework to be included in the artifact pivots + TargetFrameworks = "ignored;ignored2", IsExe = true }; string[] extraArgs = new[] { $"/p:TargetFramework={ToolsetInfo.CurrentTargetFramework.ToUpper()}" }; - var testAsset = _testAssetsManager.CreateTestProject(testProject, testProject.Name); + var testAsset = _testAssetsManager.CreateTestProject(testProject, testProject.Name, identifier: useStandardOutputPaths.ToString()); var buildCommand = new BuildCommand(testAsset); buildCommand + .WithEnvironmentVariable("UseStandardOutputPaths", useStandardOutputPaths.ToString()) .Execute(extraArgs) .Should() .Pass(); - string outputFolderWithConfiguration = Path.Combine(buildCommand.ProjectRootPath, "bin", "Debug"); + if (useStandardOutputPaths) + { + buildCommand.GetOutputDirectory().Should().Exist(); - Directory.GetDirectories(outputFolderWithConfiguration) - .Select(Path.GetFileName) - .Should() - .BeEquivalentTo(ToolsetInfo.CurrentTargetFramework); + buildCommand.GetIntermediateDirectory().Should().Exist(); + } + else + { + string outputFolderWithConfiguration = Path.Combine(buildCommand.ProjectRootPath, "bin", "Debug"); - string intermediateFolderWithConfiguration = Path.Combine(buildCommand.GetBaseIntermediateDirectory().FullName, "Debug"); + Directory.GetDirectories(outputFolderWithConfiguration) + .Select(Path.GetFileName) + .Should() + .BeEquivalentTo(ToolsetInfo.CurrentTargetFramework); - Directory.GetDirectories(intermediateFolderWithConfiguration) - .Select(Path.GetFileName) - .Should() - .BeEquivalentTo(ToolsetInfo.CurrentTargetFramework); + string intermediateFolderWithConfiguration = Path.Combine(buildCommand.GetBaseIntermediateDirectory().FullName, "Debug"); + + Directory.GetDirectories(intermediateFolderWithConfiguration) + .Select(Path.GetFileName) + .Should() + .BeEquivalentTo(ToolsetInfo.CurrentTargetFramework); + } } [Fact] diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildASolutionWithNonAnyCPUPlatform.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildASolutionWithNonAnyCPUPlatform.cs index 2d94ba83179c..5405f5f45d6b 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildASolutionWithNonAnyCPUPlatform.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildASolutionWithNonAnyCPUPlatform.cs @@ -26,11 +26,11 @@ public void It_builds_solution_successfully() var buildCommand = new BuildCommand(testAsset, "x64SolutionBuild.sln"); buildCommand - .Execute("/p:ProduceReferenceAssembly=false") + .Execute("/p:ProduceReferenceAssembly=false", "/p:UseStandardOutputPaths=false") .Should() .Pass(); - buildCommand.GetOutputDirectory(ToolsetInfo.CurrentTargetFramework, Path.Combine("x64", "Debug")) + new DirectoryInfo(Path.Combine(testAsset.TestRoot, "bin", "x64", "Debug", ToolsetInfo.CurrentTargetFramework)) .Should() .OnlyHaveFiles(new[] { "x64SolutionBuild.runtimeconfig.json", diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToControlGeneratedAssemblyInfo.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToControlGeneratedAssemblyInfo.cs index 3ba7af9fa07a..1754d1f528b8 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToControlGeneratedAssemblyInfo.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToControlGeneratedAssemblyInfo.cs @@ -740,7 +740,7 @@ public void It_does_not_write_to_undefined_assembly_metadata_attribute(string ta var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: targetFramework); - var buildCommand = new BuildCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var buildCommand = new BuildCommand(testAsset); buildCommand.Execute() .Should() .Pass(); diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToCopyPPFileToOutput.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToCopyPPFileToOutput.cs index 166346adf201..f48e0ac00ebd 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToCopyPPFileToOutput.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToCopyPPFileToOutput.cs @@ -41,7 +41,7 @@ public void It_copies_to_output_successfully() .Should() .Pass(); - var outputPath = Path.Combine(testAsset.TestRoot, testProject.Name, "bin", "Debug", testProject.TargetFrameworks); + var outputPath = buildCommand.GetOutputDirectory().FullName; File.Exists(Path.Combine(outputPath, packageReference.ID + ".dll")).Should().BeTrue(); File.Exists(Path.Combine(outputPath, "Nontransformed.ps1")).Should().BeTrue(); File.Exists(Path.Combine(outputPath, "Test.ps1")).Should().BeTrue(); @@ -61,7 +61,7 @@ private TestPackageReference GetPackageReference() packageAsset = packageAsset .WithProjectChanges(project => AddContent(project)); - var packCommand = new PackCommand(Log, packageAsset.TestRoot, referencedPackage.Name); + var packCommand = new PackCommand(packageAsset); packCommand.Execute() .Should() .Pass(); diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToReferenceAProject.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToReferenceAProject.cs index f8baf8f293de..c38f1764006e 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToReferenceAProject.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToReferenceAProject.cs @@ -285,9 +285,9 @@ public void It_copies_content_transitively() .Should() .Pass(); - var contentPath = Path.Combine(testAsset.Path, testProjectC.Name, "bin", "Debug", targetFramework, "a.txt"); + var contentPath = Path.Combine(testProjectC.GetOutputDirectory(testAsset.Path), "a.txt"); File.Exists(contentPath).Should().BeTrue(); - var binDir = new DirectoryInfo(Path.Combine(testAsset.Path, testProjectC.Name, "bin")); + var binDir = new DirectoryInfo(Path.GetDirectoryName(contentPath)); binDir.Delete(true); buildCommand diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToVerifyNuGetReferenceCompat.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToVerifyNuGetReferenceCompat.cs index d2f78b0c1559..1ea90238295d 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToVerifyNuGetReferenceCompat.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToVerifyNuGetReferenceCompat.cs @@ -207,7 +207,7 @@ public void It_chooses_lowest_netfx_in_default_atf() var buildCommand = new BuildCommand(testProjectTestAsset); buildCommand.Execute().Should().Pass(); - var referencedDll = buildCommand.GetOutputDirectory(ToolsetInfo.CurrentTargetFramework).File("net462_net472_pkg.dll").FullName; + var referencedDll = buildCommand.GetOutputDirectory().File("net462_net472_pkg.dll").FullName; var referencedTargetFramework = AssemblyInfo.Get(referencedDll)["TargetFrameworkAttribute"]; referencedTargetFramework.Should().Be(".NETFramework,Version=v4.6.2"); } diff --git a/src/Tests/Microsoft.NET.Build.Tests/GlobalPropertyFlowTests.cs b/src/Tests/Microsoft.NET.Build.Tests/GlobalPropertyFlowTests.cs index 86de89a9c09a..7a1acc3802b2 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GlobalPropertyFlowTests.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GlobalPropertyFlowTests.cs @@ -160,7 +160,7 @@ public void TestGlobalPropertyFlowToLibraryWithRuntimeIdentifier(bool passSelfCo bool buildingSelfContained = passSelfContained || passRuntimeIdentifier; ValidateProperties(testAsset, _testProject, expectSelfContained: buildingSelfContained, expectRuntimeIdentifier: buildingSelfContained); - ValidateProperties(testAsset, _referencedProject, expectSelfContained: passSelfContained, expectRuntimeIdentifier: buildingSelfContained, + ValidateProperties(testAsset, _referencedProject, expectSelfContained: passSelfContained, expectRuntimeIdentifier: true, // Right now passing "--self-contained" also causes the RuntimeIdentifier to be passed as a global property. // That should change with https://github.com/dotnet/sdk/pull/26143, which will likely require updating this and other tests in this class expectedRuntimeIdentifier: buildingSelfContained ? "" : _referencedProject.RuntimeIdentifier); @@ -252,14 +252,6 @@ private static void ValidateProperties(TestAsset testAsset, TestProject testProj { targetFramework = targetFramework ?? testProject.TargetFrameworks; - - if (string.IsNullOrEmpty(expectedRuntimeIdentifier) && (expectSelfContained || expectRuntimeIdentifier)) - { - // RuntimeIdentifier might be inferred, so look at the output path to figure out what the actual value used was - string dir = (Path.Combine(testAsset.TestRoot, testProject.Name, "bin", "Debug", targetFramework)); - expectedRuntimeIdentifier = Path.GetFileName(Directory.GetDirectories(dir).Single()); - } - var properties = testProject.GetPropertyValues(testAsset.TestRoot, targetFramework: targetFramework); if (expectSelfContained) { @@ -270,7 +262,23 @@ private static void ValidateProperties(TestAsset testAsset, TestProject testProj properties["SelfContained"].ToLowerInvariant().Should().BeOneOf("false", ""); } - properties["RuntimeIdentifier"].Should().Be(expectedRuntimeIdentifier); + + if (expectRuntimeIdentifier) + { + if (!string.IsNullOrEmpty(expectedRuntimeIdentifier)) + { + properties["RuntimeIdentifier"].Should().Be(expectedRuntimeIdentifier); + } + else + { + properties["RuntimeIdentifier"].Should().NotBeEmpty(); + } + } + else + { + properties["RuntimeIdentifier"].Should().BeEmpty(); + } + } } diff --git a/src/Tests/Microsoft.NET.Pack.Tests/GivenThatWeWantToPackASimpleLibrary.cs b/src/Tests/Microsoft.NET.Pack.Tests/GivenThatWeWantToPackASimpleLibrary.cs index cf3e1061a2a9..fc57621f4b00 100644 --- a/src/Tests/Microsoft.NET.Pack.Tests/GivenThatWeWantToPackASimpleLibrary.cs +++ b/src/Tests/Microsoft.NET.Pack.Tests/GivenThatWeWantToPackASimpleLibrary.cs @@ -23,21 +23,26 @@ public void It_packs_successfully() .CopyTestAsset("HelloWorld") .WithSource(); - new PackCommand(Log, testAsset.TestRoot) + var packCommand = new PackCommand(testAsset); + + packCommand .Execute() .Should() .Pass(); - + var packageDirectory = packCommand.GetPackageDirectory(); + packageDirectory.Should().OnlyHaveFiles(new[] + { + "HelloWorld.1.0.0.nupkg", + }, SearchOption.TopDirectoryOnly); - var outputDirectory = new DirectoryInfo(Path.Combine(testAsset.TestRoot, "bin", "Debug")); + var outputDirectory = packCommand.GetOutputDirectory(); outputDirectory.Should().OnlyHaveFiles(new[] { - "HelloWorld.1.0.0.nupkg", - $"{ToolsetInfo.CurrentTargetFramework}/HelloWorld.dll", - $"{ToolsetInfo.CurrentTargetFramework}/HelloWorld.pdb", - $"{ToolsetInfo.CurrentTargetFramework}/HelloWorld.deps.json", - $"{ToolsetInfo.CurrentTargetFramework}/HelloWorld.runtimeconfig.json", - $"{ToolsetInfo.CurrentTargetFramework}/HelloWorld{EnvironmentInfo.ExecutableExtension}", + $"HelloWorld.dll", + $"HelloWorld.pdb", + $"HelloWorld.deps.json", + $"HelloWorld.runtimeconfig.json", + $"HelloWorld{EnvironmentInfo.ExecutableExtension}", }); } } diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAComServerLibrary.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAComServerLibrary.cs index 9587a35c352c..41734f9704d7 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAComServerLibrary.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAComServerLibrary.cs @@ -31,7 +31,7 @@ public void It_publishes_comhost_to_the_publish_folder() .Pass(); var publishDirectory = publishCommand.GetOutputDirectory(ToolsetInfo.CurrentTargetFramework); - var outputDirectory = publishDirectory.Parent; + var outputDirectory = new BuildCommand(testAsset).GetOutputDirectory(); var filesPublished = new[] { "ComServer.dll", diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAFrameworkDependentApp.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAFrameworkDependentApp.cs index 6bf37290983a..f60ac09a0b28 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAFrameworkDependentApp.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAFrameworkDependentApp.cs @@ -41,14 +41,14 @@ public void It_publishes_with_or_without_apphost(string useAppHost, string targe var testAsset = _testAssetsManager .CopyTestAsset(TestProjectName, $"It_publishes_with_or_without_apphost_{(useAppHost ?? "null")}_{targetFramework}") - .WithSource(); + .WithSource() + .WithTargetFramework(targetFramework); var msbuildArgs = new List() { $"/p:RuntimeIdentifier={runtimeIdentifier}", $"/p:TestRuntimeIdentifier={runtimeIdentifier}", "/p:SelfContained=false", - $"/p:TargetFramework={targetFramework}" }; if (useAppHost != null) diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAHelloWorldProject.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAHelloWorldProject.cs index 4a8deecd2b7b..65c5bf0d2d96 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAHelloWorldProject.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAHelloWorldProject.cs @@ -58,7 +58,7 @@ public void It_publishes_portable_apps_to_the_publish_folder_and_the_app_should_ publishResult.Should().Pass(); var publishDirectory = publishCommand.GetOutputDirectory(targetFramework); - var outputDirectory = publishDirectory.Parent; + var outputDirectory = new BuildCommand(helloWorldAsset).GetOutputDirectory(targetFramework); var filesPublished = new[] { "HelloWorld.dll", @@ -104,7 +104,7 @@ public void It_publishes_self_contained_apps_to_the_publish_folder_and_the_app_s var publishDirectory = publishCommand.GetOutputDirectory( targetFramework: targetFramework, runtimeIdentifier: rid); - var outputDirectory = publishDirectory.Parent; + var outputDirectory = new BuildCommand(helloWorldAsset).GetOutputDirectory(targetFramework, runtimeIdentifier: rid); var selfContainedExecutable = $"HelloWorld{Constants.ExeSuffix}"; var filesPublished = new[] { diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAProjectWithDependencies.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAProjectWithDependencies.cs index 99828d4fc9e5..fdf0566fe8e4 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAProjectWithDependencies.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAProjectWithDependencies.cs @@ -213,7 +213,7 @@ public void It_publishes_documentation_files(string properties, bool expectAppDo .CopyTestAsset("KitchenSink", identifier: $"{expectAppDocPublished}_{expectLibProjectDocPublished}") .WithSource(); - var publishCommand = new PublishCommand(Log, Path.Combine(kitchenSinkAsset.TestRoot, "TestApp")); + var publishCommand = new PublishCommand(kitchenSinkAsset, "TestApp"); var publishArgs = properties.Split(';').Select(p => $"/p:{p}").ToArray(); var publishResult = publishCommand.Execute(publishArgs); @@ -269,10 +269,9 @@ public void It_publishes_referenced_assembly_documentation(string property, bool }; var appAsset = _testAssetsManager.CreateTestProject(appProject, identifier: identifier); - var appSourcePath = Path.Combine(appAsset.TestRoot, "TestApp"); new RestoreCommand(appAsset, "TestApp").Execute().Should().Pass(); - var appPublishCommand = new PublishCommand(Log, appSourcePath); + var appPublishCommand = new PublishCommand(appAsset); var appPublishResult = appPublishCommand.Execute("/p:" + property); appPublishResult.Should().Pass(); diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs index 44ba08a54016..cb9154770b0d 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs @@ -53,7 +53,7 @@ public void NativeAot_hw_runs_with_no_warnings_when_PublishAot_is_enabled(string } var testAsset = _testAssetsManager.CreateTestProject(testProject); - var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var publishCommand = new PublishCommand(testAsset); publishCommand .Execute($"/p:UseCurrentRuntimeIdentifier=true") .Should().Pass() @@ -96,7 +96,7 @@ public void NativeAot_hw_runs_with_no_warnings_when_PublishAot_is_false(string t testProject.AdditionalProperties["PublishAot"] = "false"; var testAsset = _testAssetsManager.CreateTestProject(testProject); - var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var publishCommand = new PublishCommand(testAsset); publishCommand .Execute($"/p:RuntimeIdentifier={rid}") .Should().Pass() @@ -144,7 +144,7 @@ public void NativeAot_app_runs_in_debug_with_no_config_when_PublishAot_is_enable // .WithProjectChanges(project => AddRuntimeConfigOption(project)); - var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var publishCommand = new PublishCommand(testAsset); publishCommand .Execute($"/p:UseCurrentRuntimeIdentifier=true") .Should().Pass(); @@ -202,7 +202,7 @@ public void NativeAot_app_runs_in_release_with_no_config_when_PublishAot_is_enab // .WithProjectChanges(project => AddRuntimeConfigOption(project)); - var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var publishCommand = new PublishCommand(testAsset); publishCommand .Execute($"/p:UseCurrentRuntimeIdentifier=true") .Should().Pass(); @@ -294,7 +294,7 @@ public void NativeAot_hw_runs_with_PackageReference_PublishAot_is_enabled(string } var testAsset = _testAssetsManager.CreateTestProject(testProject); - var publishCommand= new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var publishCommand = new PublishCommand(testAsset); publishCommand .Execute($"/p:UseCurrentRuntimeIdentifier=true") .Should().Pass() @@ -348,7 +348,7 @@ public void NativeAot_hw_runs_with_PackageReference_PublishAot_is_empty(string t } var testAsset = _testAssetsManager.CreateTestProject(testProject); - var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var publishCommand = new PublishCommand(testAsset); publishCommand .Execute($"/p:RuntimeIdentifier={rid}") .Should().Pass(); @@ -380,7 +380,7 @@ public void NativeAot_hw_runs_with_cross_target_PublishAot_is_enabled(string tar var testAsset = _testAssetsManager.CreateTestProject(testProject); - var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var publishCommand = new PublishCommand(testAsset); publishCommand .Execute($"/p:RuntimeIdentifier={rid}") .Should().Pass(); @@ -411,7 +411,7 @@ public void NativeAot_hw_runs_with_cross_PackageReference_PublishAot_is_enabled( var testAsset = _testAssetsManager.CreateTestProject(testProject); - var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var publishCommand = new PublishCommand(testAsset); publishCommand .Execute($"/p:RuntimeIdentifier={rid}") .Should().Pass() @@ -446,7 +446,7 @@ public void NativeAot_hw_runs_with_cross_PackageReference_PublishAot_is_empty(st var testAsset = _testAssetsManager.CreateTestProject(testProject); - var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var publishCommand = new PublishCommand(testAsset); publishCommand .Execute($"/p:RuntimeIdentifier={rid}") .Should().Pass(); @@ -569,7 +569,7 @@ public void NativeAot_compiler_runs_when_PublishAot_is_enabled(string targetFram testProject.AdditionalProperties["UseCurrentRuntimeIdentifier"] = "true"; var testAsset = _testAssetsManager.CreateTestProject(testProject); - var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var publishCommand = new PublishCommand(testAsset); publishCommand .Execute() .Should().Pass() @@ -614,7 +614,7 @@ public void Warnings_are_generated_even_with_analyzers_disabled(string targetFra testProject.AdditionalProperties["UseCurrentRuntimeIdentifier"] = "true"; var testAsset = _testAssetsManager.CreateTestProject(testProject); - var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var publishCommand = new PublishCommand(testAsset); publishCommand .Execute() .Should().Pass() @@ -653,7 +653,7 @@ public void NativeAotStaticLib_only_runs_when_switch_is_enabled(string targetFra testProject.AdditionalProperties["SelfContained"] = "true"; var testAsset = _testAssetsManager.CreateTestProject(testProject); - var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var publishCommand = new PublishCommand(testAsset); publishCommand .Execute() .Should().Pass(); @@ -686,7 +686,7 @@ public void NativeAotSharedLib_only_runs_when_switch_is_enabled(string targetFra testProject.AdditionalProperties["SelfContained"] = "true"; var testAsset = _testAssetsManager.CreateTestProject(testProject); - var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var publishCommand = new PublishCommand(testAsset); publishCommand .Execute() .Should().Pass(); diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAppWithLibrariesAndRid.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAppWithLibrariesAndRid.cs index 1488993bcaaa..26e1954d226a 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAppWithLibrariesAndRid.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAppWithLibrariesAndRid.cs @@ -94,8 +94,6 @@ private void PublishAppWithLibraryAndRid(bool selfContained, out DirectoryInfo p .CopyTestAsset("AppWithLibraryAndRid", $"PublishAppWithLibraryAndRid{selfContained}") .WithSource(); - var projectPath = Path.Combine(testAsset.TestRoot, "App"); - var msbuildArgs = new List() { $"/p:RuntimeIdentifier={runtimeIdentifier}", @@ -116,7 +114,7 @@ private void PublishAppWithLibraryAndRid(bool selfContained, out DirectoryInfo p .Should() .Pass(); - var publishCommand = new PublishCommand(Log, projectPath); + var publishCommand = new PublishCommand(testAsset, "App"); publishCommand .Execute(msbuildArgs.ToArray()) diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishIncrementally.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishIncrementally.cs index 19fcfd76ea37..d97b7195c8c5 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishIncrementally.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishIncrementally.cs @@ -11,6 +11,7 @@ using Xunit; using Xunit.Abstractions; using System.Collections.Generic; +using System.Runtime.InteropServices; namespace Microsoft.NET.Publish.Tests { @@ -32,22 +33,27 @@ public void It_cleans_before_single_file_publish() }; var testAsset = _testAssetsManager.CreateTestProject(testProject, testProject.Name); - var publishDir = Path.Combine(testAsset.TestRoot, testProject.Name, "bin", "Debug", testProject.TargetFrameworks, testProject.RuntimeIdentifier, "publish"); - var expectedNonSingleExeFiles = new string[] { ".dll", ".deps.json", ".runtimeconfig.json" } - .Select(ending => testProject.Name + ending); - var expectedSingleExeFiles = new string[] { ".exe", ".pdb" }.Select(ending => testProject.Name + ending); + // Publish normally - new PublishCommand(testAsset) + var publishCommand = new PublishCommand(testAsset); + + publishCommand .Execute() .Should() .Pass(); + + var publishDir = publishCommand.GetOutputDirectory(runtimeIdentifier: "win-x86").FullName; + var expectedNonSingleExeFiles = new string[] { ".dll", ".deps.json", ".runtimeconfig.json" } + .Select(ending => testProject.Name + ending); + var expectedSingleExeFiles = new string[] { ".exe", ".pdb" }.Select(ending => testProject.Name + ending); + CheckPublishOutput(publishDir, expectedSingleExeFiles.Concat(expectedNonSingleExeFiles), null); File.WriteAllText(Path.Combine(publishDir, "UserData.txt"), string.Empty); // Publish as a single file - new PublishCommand(testAsset) + publishCommand .Execute(@"/p:PublishSingleFile=true") .Should() .Pass(); @@ -66,14 +72,17 @@ public void It_cleans_between_renames() }; var testAsset = _testAssetsManager.CreateTestProject(testProject, testProject.Name); - var publishDir = Path.Combine(testAsset.TestRoot, testProject.Name, "bin", "Debug", testProject.TargetFrameworks, testProject.RuntimeIdentifier, "publish"); - var expectedSingleExeFileExtensions = new string[] { ".exe", ".pdb" }; // Publish as a single file - new PublishCommand(testAsset) + var publishCommand = new PublishCommand(testAsset); + publishCommand .Execute(@"/p:PublishSingleFile=true") .Should() .Pass(); + + var publishDir = publishCommand.GetOutputDirectory(runtimeIdentifier: "win-x86").FullName; + var expectedSingleExeFileExtensions = new string[] { ".exe", ".pdb" }; + CheckPublishOutput(publishDir, expectedSingleExeFileExtensions.Select(ending => testProject.Name + ending), null); File.WriteAllText(Path.Combine(publishDir, "UserData.txt"), string.Empty); @@ -105,21 +114,23 @@ public void It_cleans_between_single_file_publishes() }; var testAsset = _testAssetsManager.CreateTestProject(testProject, testProject.Name); - var publishDir = Path.Combine(testAsset.TestRoot, testProject.Name, "bin", "Debug", testProject.TargetFrameworks, testProject.RuntimeIdentifier, "publish"); - var expectedSingleExeFiles = new string[] { ".exe", ".pdb" }.Select(ending => testProject.Name + ending); - // Publish as a single file - new PublishCommand(testAsset) + var publishCommand = new PublishCommand(testAsset); + publishCommand .Execute(@"/p:PublishSingleFile=true") .Should() .Pass(); + + var publishDir = publishCommand.GetOutputDirectory(runtimeIdentifier: "win-x86").FullName; + var expectedSingleExeFiles = new string[] { ".exe", ".pdb" }.Select(ending => testProject.Name + ending); + CheckPublishOutput(publishDir, expectedSingleExeFiles, null); // Write a file that would have been in a full publish, should still be there after another single file publish File.WriteAllText(Path.Combine(publishDir, testProject.Name + ".dll"), string.Empty); // Publish as a single file - new PublishCommand(testAsset) + publishCommand .Execute(@"/p:PublishSingleFile=true") .Should() .Pass(); @@ -139,22 +150,25 @@ public void It_cleans_before_trimmed_single_file_publish() testProject.AdditionalProperties["PublishTrimmed"] = "true"; var testAsset = _testAssetsManager.CreateTestProject(testProject, testProject.Name); - var publishDir = Path.Combine(testAsset.TestRoot, testProject.Name, "bin", "Debug", testProject.TargetFrameworks, testProject.RuntimeIdentifier, "publish"); - var expectedNonSingleExeFiles = new string[] { ".dll", ".deps.json", ".runtimeconfig.json" } - .Select(ending => testProject.Name + ending); - var expectedSingleExeFiles = new string[] { ".exe", ".pdb" }.Select(ending => testProject.Name + ending); - // Publish trimmed - new PublishCommand(testAsset) + var publishCommand = new PublishCommand(testAsset); + + publishCommand .Execute() .Should() .Pass(); + + var publishDir = publishCommand.GetOutputDirectory(runtimeIdentifier: "win-x86").FullName; + var expectedNonSingleExeFiles = new string[] { ".dll", ".deps.json", ".runtimeconfig.json" } + .Select(ending => testProject.Name + ending); + var expectedSingleExeFiles = new string[] { ".exe", ".pdb" }.Select(ending => testProject.Name + ending); + CheckPublishOutput(publishDir, expectedSingleExeFiles.Concat(expectedNonSingleExeFiles), null); File.WriteAllText(Path.Combine(publishDir, "UserData.txt"), string.Empty); // Publish as a single file - new PublishCommand(testAsset) + publishCommand .Execute(@"/p:PublishSingleFile=true") .Should() .Pass(); @@ -290,14 +304,14 @@ private void CheckPublishOutput(string publishDir, IEnumerable expectedF { foreach (var expectedFile in expectedFiles) { - File.Exists(Path.Combine(publishDir, expectedFile)).Should().BeTrue(); + new FileInfo(Path.Combine(publishDir, expectedFile)).Should().Exist(); } } if (unexpectedFiles != null) { foreach (var unexpectedFile in unexpectedFiles) { - File.Exists(Path.Combine(publishDir, unexpectedFile)).Should().BeFalse(); + new FileInfo(Path.Combine(publishDir, unexpectedFile)).Should().NotExist(); } } } diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs index 395c522f98b9..49d064327996 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs @@ -843,7 +843,7 @@ public void TrimmingOptions_are_defaulted_correctly_on_trimmed_apps(string targe var testProject = CreateTestProjectForILLinkTesting(targetFramework, projectName); var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: projectName + targetFramework); - var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + var publishCommand = new PublishCommand(testAsset); publishCommand.Execute($"/p:RuntimeIdentifier={rid}", "/p:PublishTrimmed=true") .Should().Pass(); diff --git a/src/Tests/Microsoft.NET.Publish.Tests/PublishWpfApp.cs b/src/Tests/Microsoft.NET.Publish.Tests/PublishWpfApp.cs index 75a69367d90a..7a8ae9f476b2 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/PublishWpfApp.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/PublishWpfApp.cs @@ -57,13 +57,13 @@ public void It_publishes_and_runs_self_contained_wpf_app() .Should() .Pass(); - var publishDirectory = publishCommand.GetOutputDirectory( + var publishDirectory = OutputPathCalculator.FromProject(Path.Combine(testDir.Path, Path.GetFileName(testDir.Path) + ".csproj")).GetPublishDirectory( targetFramework: targetFramework, runtimeIdentifier: rid); var runAppCommand = new SdkCommandSpec() { - FileName = Path.Combine(publishDirectory.FullName, Path.GetFileName(testDir.Path) + ".exe") + FileName = Path.Combine(publishDirectory, Path.GetFileName(testDir.Path) + ".exe") }; runAppCommand.Environment["DOTNET_ROOT"] = Path.GetDirectoryName(TestContext.Current.ToolsetUnderTest.DotNetHostPath); diff --git a/src/Tests/Microsoft.NET.Publish.Tests/RuntimeIdentifiersTests.cs b/src/Tests/Microsoft.NET.Publish.Tests/RuntimeIdentifiersTests.cs index 1bc6143b14a8..ff15f6958207 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/RuntimeIdentifiersTests.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/RuntimeIdentifiersTests.cs @@ -102,6 +102,8 @@ public void BuildWithUseCurrentRuntimeIdentifier() // Use a test-specific packages folder testProject.AdditionalProperties["RestorePackagesPath"] = @"$(MSBuildProjectDirectory)\..\pkg"; + testProject.RecordProperties("RuntimeIdentifier"); + var testAsset = _testAssetsManager.CreateTestProject(testProject); var buildCommand = new BuildCommand(testAsset); @@ -110,12 +112,11 @@ public void BuildWithUseCurrentRuntimeIdentifier() .Should() .Pass(); - string targetFrameworkOutputDirectory = Path.Combine(buildCommand.GetNonSDKOutputDirectory().FullName, testProject.TargetFrameworks); - string outputDirectoryWithRuntimeIdentifier = Directory.EnumerateDirectories(targetFrameworkOutputDirectory, "*", SearchOption.AllDirectories).FirstOrDefault(); - outputDirectoryWithRuntimeIdentifier.Should().NotBeNullOrWhiteSpace(); + var runtimeIdentifier = testProject.GetPropertyValues(testAsset.TestRoot)["RuntimeIdentifier"]; + runtimeIdentifier.Should().NotBeNullOrWhiteSpace(); var selfContainedExecutable = $"{testProject.Name}{Constants.ExeSuffix}"; - string selfContainedExecutableFullPath = Path.Combine(outputDirectoryWithRuntimeIdentifier, selfContainedExecutable); + string selfContainedExecutableFullPath = Path.Combine(buildCommand.GetOutputDirectory(runtimeIdentifier: runtimeIdentifier).FullName, selfContainedExecutable); new RunExeCommand(Log, selfContainedExecutableFullPath) .Execute() diff --git a/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.AoT.Tests/WasmAoTPublishIntegrationTest.cs b/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.AoT.Tests/WasmAoTPublishIntegrationTest.cs index 54fb6f6c4d0d..74491eb0c6bb 100644 --- a/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.AoT.Tests/WasmAoTPublishIntegrationTest.cs +++ b/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.AoT.Tests/WasmAoTPublishIntegrationTest.cs @@ -30,7 +30,7 @@ public void AoT_Publish_InRelease_Works() var testInstance = CreateAspNetSdkTestAssetWithAot(testAppName, new [] { "blazorwasm" }); File.WriteAllText(Path.Combine(testInstance.TestRoot, "blazorwasm", "App.razor.css"), "h1 { font-size: 16px; }"); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.Execute("/p:Configuration=Release").Should().Pass(); var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm, "Release"); @@ -68,14 +68,16 @@ public void AoT_Publish_WithExistingWebConfig_Works() var webConfigContents = "test webconfig contents"; File.WriteAllText(Path.Combine(testInstance.TestRoot, "blazorwasm", "web.config"), webConfigContents); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.Execute("/p:Configuration=Release").Should().Pass(); var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm, "Release"); + var webConfig = new BuildCommand(testInstance, "blazorwasm").GetOutputDirectory(configuration: "Release").File("web.config"); + // Verify web.config - new FileInfo(Path.Combine(publishDirectory.ToString(), "..", "web.config")).Should().Exist(); - new FileInfo(Path.Combine(publishDirectory.ToString(), "..", "web.config")).Should().Contain(webConfigContents); + webConfig.Should().Exist(); + webConfig.Should().Contain(webConfigContents); } [RequiresMSBuildVersionFact("17.0.0")] @@ -91,7 +93,7 @@ public void AoT_Publish_HostedAppWithScopedCss_VisualStudio() buildCommand.Execute("/p:BuildInsideVisualStudio=true /p:Configuration=Release").Should().Pass(); // Publish - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorhosted")); + var publishCommand = new PublishCommand(testInstance, "blazorhosted"); publishCommand.Execute("/p:BuildProjectReferences=false /p:BuildInsideVisualStudio=true /p:Configuration=Release").Should().Pass(); var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm); diff --git a/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmBuildIntegrationTest.cs b/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmBuildIntegrationTest.cs index 2c3f12643c4a..8cb65b48b8d2 100644 --- a/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmBuildIntegrationTest.cs +++ b/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmBuildIntegrationTest.cs @@ -7,6 +7,7 @@ using System.Text.Json; using System.Xml.Linq; using FluentAssertions; +using Microsoft.NET.TestFramework; using Microsoft.AspNetCore.StaticWebAssets.Tasks; using Microsoft.NET.TestFramework.Assertions; using Microsoft.NET.TestFramework.Commands; @@ -93,7 +94,7 @@ public void Build_Works_WithLibraryUsingHintPath() reference.Name = "Reference"; reference.Add(new XElement( "HintPath", - Path.Combine("..", "razorclasslibrary", "bin", "Debug", DefaultTfm, "RazorClassLibrary.dll"))); + Path.Combine("..", "razorclasslibrary", "bin", "Debug", ToolsetInfo.CurrentTargetFramework, "RazorClassLibrary.dll"))); } }); diff --git a/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmBuildLazyLoadTest.cs b/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmBuildLazyLoadTest.cs index 66ec3cf61726..e30f506c8a0d 100644 --- a/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmBuildLazyLoadTest.cs +++ b/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmBuildLazyLoadTest.cs @@ -135,7 +135,7 @@ public void Publish_LazyLoadExplicitAssembly_Debug_Works() }); // Act - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.WithWorkingDirectory(testInstance.TestRoot); publishCommand.Execute("/bl") .Should().Pass(); @@ -184,7 +184,7 @@ public void Publish_LazyLoadExplicitAssembly_Release_Works() }); // Act - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.Execute("/p:Configuration=Release") .Should().Pass(); diff --git a/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmCompressionTests.cs b/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmCompressionTests.cs index 320f71157fa3..b7f5994072ee 100644 --- a/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmCompressionTests.cs +++ b/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmCompressionTests.cs @@ -23,13 +23,14 @@ public void Publish_UpdatesFilesWhenSourcesChange() var testAppName = "BlazorHosted"; var testInstance = CreateAspNetSdkTestAsset(testAppName); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorhosted")); + var publishCommand = new PublishCommand(testInstance, "blazorhosted"); publishCommand.Execute().Should().Pass(); // Act - var mainAppDll = Path.Combine(testInstance.TestRoot, "blazorhosted", "bin", "Debug", DefaultTfm, "publish", "wwwroot", "_framework", "blazorwasm.dll"); + var blazorHostedPublishDirectory = publishCommand.GetOutputDirectory().FullName; + var mainAppDll = Path.Combine(blazorHostedPublishDirectory, "wwwroot", "_framework", "blazorwasm.dll"); var mainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); - var mainAppCompressedDll = Path.Combine(testInstance.TestRoot, "blazorhosted", "bin", "Debug", DefaultTfm, "publish", "wwwroot", "_framework", "blazorwasm.dll.br"); + var mainAppCompressedDll = Path.Combine(blazorHostedPublishDirectory, "wwwroot", "_framework", "blazorwasm.dll.br"); var mainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); var blazorBootJson = Path.Combine(testInstance.TestRoot, publishCommand.GetOutputDirectory(DefaultTfm).ToString(), "wwwroot", "_framework", "blazor.boot.json"); @@ -64,15 +65,15 @@ public void Publish_WithoutLinkerAndCompression_UpdatesFilesWhenSourcesChange() var testAppName = "BlazorHosted"; var testInstance = CreateAspNetSdkTestAsset(testAppName); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorhosted")); + var publishCommand = new PublishCommand(testInstance, "blazorhosted"); publishCommand.Execute("/p:BlazorWebAssemblyEnableLinking=false").Should().Pass(); // Act - var buildOutputDirectory = publishCommand.GetOutputDirectory(DefaultTfm).ToString(); - var mainAppDll = Path.Combine(testInstance.TestRoot, "blazorhosted", "bin", "Debug", DefaultTfm, "publish", "wwwroot", "_framework", "blazorwasm.dll"); + var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm).FullName; + var mainAppDll = Path.Combine(publishDirectory, "wwwroot", "_framework", "blazorwasm.dll"); var mainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); - var mainAppCompressedDll = Path.Combine(testInstance.TestRoot, "blazorhosted", "bin", "Debug", DefaultTfm, "publish", "wwwroot", "_framework", "blazorwasm.dll.br"); + var mainAppCompressedDll = Path.Combine(publishDirectory, "wwwroot", "_framework", "blazorwasm.dll.br"); var mainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); var programFile = Path.Combine(testInstance.TestRoot, "blazorwasm", "Program.cs"); @@ -161,7 +162,7 @@ public void Publish_CompressesAllFrameworkFiles() var testAppName = "BlazorWasmWithLibrary"; var testInstance = CreateAspNetSdkTestAsset(testAppName); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.WithWorkingDirectory(testInstance.TestRoot); publishCommand.Execute("/bl").Should().Pass(); @@ -169,7 +170,7 @@ public void Publish_CompressesAllFrameworkFiles() // Act var publishOutputDirectory = publishCommand.GetOutputDirectory(DefaultTfm).ToString(); - var frameworkFilesPath = Path.Combine(Path.Combine(testInstance.TestRoot, "blazorwasm"), publishOutputDirectory, "wwwroot", "_framework"); + var frameworkFilesPath = Path.Combine(publishOutputDirectory, "wwwroot", "_framework"); // Assert foreach (var file in Directory.EnumerateFiles(frameworkFilesPath, "*", new EnumerationOptions { RecurseSubdirectories = true, })) diff --git a/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmPublishIntegrationTest.cs b/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmPublishIntegrationTest.cs index a0aed309781a..61034b067f11 100644 --- a/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmPublishIntegrationTest.cs +++ b/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmPublishIntegrationTest.cs @@ -29,7 +29,7 @@ public void Publish_MinimalApp_Works() var testAppName = "BlazorWasmMinimal"; var testInstance = CreateAspNetSdkTestAsset(testAppName); - var publishCommand = new PublishCommand(Log, testInstance.TestRoot); + var publishCommand = new PublishCommand(testInstance); publishCommand.Execute().Should().Pass() .And.NotHaveStdOutContaining("warning IL"); @@ -61,7 +61,7 @@ public void Publish_WithDefaultSettings_Works() var testAppName = "BlazorWasmWithLibrary"; var testInstance = CreateAspNetSdkTestAsset(testAppName); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.Execute().Should().Pass(); var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm); @@ -119,7 +119,7 @@ public void Publish_Works_WithLibraryUsingHintPath() reference.Name = "Reference"; reference.Add(new XElement( "HintPath", - Path.Combine("..", "razorclasslibrary", "bin", "Debug", DefaultTfm, "RazorClassLibrary.dll"))); + Path.Combine("..", "razorclasslibrary", "bin", "Debug", ToolsetInfo.CurrentTargetFramework, "RazorClassLibrary.dll"))); } }); @@ -128,7 +128,7 @@ public void Publish_Works_WithLibraryUsingHintPath() buildLibraryCommand.Execute("/bl") .Should().Pass(); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.WithWorkingDirectory(testInstance.TestRoot); publishCommand.Execute("/bl").Should().Pass(); @@ -155,7 +155,7 @@ public void Publish_WithScopedCss_Works() var testInstance = CreateAspNetSdkTestAsset(testAppName); File.WriteAllText(Path.Combine(testInstance.TestRoot, "blazorwasm", "App.razor.css"), "h1 { font-size: 16px; }"); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.Execute().Should().Pass(); var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm); @@ -197,7 +197,7 @@ public void Publish_InRelease_Works() var testInstance = CreateAspNetSdkTestAsset(testAppName); File.WriteAllText(Path.Combine(testInstance.TestRoot, "blazorwasm", "App.razor.css"), "h1 { font-size: 16px; }"); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.Execute("/p:Configuration=Release").Should().Pass(); var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm, "Release"); @@ -235,14 +235,14 @@ public void Publish_WithExistingWebConfig_Works() var webConfigContents = "test webconfig contents"; File.WriteAllText(Path.Combine(testInstance.TestRoot, "blazorwasm", "web.config"), webConfigContents); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.Execute("/p:Configuration=Release").Should().Pass(); - var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm, "Release"); - // Verify web.config - new FileInfo(Path.Combine(publishDirectory.ToString(), "..", "web.config")).Should().Exist(); - new FileInfo(Path.Combine(publishDirectory.ToString(), "..", "web.config")).Should().Contain(webConfigContents); + var outputDirectory = new BuildCommand(testInstance, "blazorwasm").GetOutputDirectory(configuration: "Release"); + var webConfig = outputDirectory.File("web.config"); + webConfig.Should().Exist(); + webConfig.Should().Contain(webConfigContents); } [Fact] @@ -256,7 +256,7 @@ public void Publish_WithNoBuild_Works() buildCommand.Execute() .Should().Pass(); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.WithWorkingDirectory(testInstance.TestRoot); publishCommand.Execute("/p:NoBuild=true", "/bl").Should().Pass(); @@ -310,7 +310,7 @@ public void Publish_WithStaticWebBasePathWorks(string basePath) }); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.Execute().Should().Pass(); var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm); @@ -371,7 +371,7 @@ public void Publish_Hosted_WithStaticWebBasePathWorks(string basePath) }); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorhosted")); + var publishCommand = new PublishCommand(testInstance, "blazorhosted"); publishCommand.Execute().Should().Pass(); var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm); @@ -437,7 +437,7 @@ public void Publish_WithTrimmingdDisabled_Works() }); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.Execute().Should().Pass(); var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm); @@ -510,7 +510,7 @@ public void Publish_SatelliteAssemblies_AreCopiedToBuildOutput() } }); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.Execute().Should().Pass(); var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm); @@ -536,7 +536,7 @@ public void Publish_HostedApp_DefaultSettings_Works() var testAppName = "BlazorHosted"; var testInstance = CreateAspNetSdkTestAsset(testAppName); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorhosted")); + var publishCommand = new PublishCommand(testInstance, "blazorhosted"); publishCommand.WithWorkingDirectory(testInstance.TestRoot); publishCommand.Execute("/bl").Should().Pass(); @@ -624,7 +624,7 @@ public void Publish_HostedApp_ProducesBootJsonDataWithExpectedContent() File.WriteAllText(Path.Combine(wwwroot, "appsettings.json"), "Default settings"); File.WriteAllText(Path.Combine(wwwroot, "appsettings.development.json"), "Development settings"); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorhosted")); + var publishCommand = new PublishCommand(testInstance, "blazorhosted"); publishCommand.Execute().Should().Pass(); var buildOutputDirectory = publishCommand.GetOutputDirectory(DefaultTfm).ToString(); @@ -674,7 +674,7 @@ public void Publish_HostedApp_WithSatelliteAssemblies() var resxfileInProject = Path.Combine(testInstance.TestRoot, "blazorwasm", "Resources.ja.resx.txt"); File.Move(resxfileInProject, Path.Combine(testInstance.TestRoot, "blazorwasm", "Resource.ja.resx")); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorhosted")); + var publishCommand = new PublishCommand(testInstance, "blazorhosted"); publishCommand.WithWorkingDirectory(testInstance.TestRoot); publishCommand.Execute("/bl").Should().Pass(); @@ -719,7 +719,7 @@ public void Publish_HostedApp_WithoutTrimming_Works() buildCommand.Execute().Should().Pass(); // Publish - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorhosted")); + var publishCommand = new PublishCommand(testInstance, "blazorhosted"); publishCommand.Execute("/p:BuildDependencies=false /bl").Should().Pass(); var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm); @@ -805,7 +805,7 @@ public void Publish_HostedApp_WithNoBuild_Works() var buildCommand = new BuildCommand(testInstance, "blazorhosted"); buildCommand.Execute().Should().Pass(); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorhosted")); + var publishCommand = new PublishCommand(testInstance, "blazorhosted"); publishCommand.WithWorkingDirectory(testInstance.TestRoot); publishCommand.Execute("/p:NoBuild=true", "/bl").Should().Pass(); @@ -861,7 +861,7 @@ public void Publish_HostedApp_VisualStudio() buildCommand.Execute("/p:BuildInsideVisualStudio=true").Should().Pass(); // Publish - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorhosted")); + var publishCommand = new PublishCommand(testInstance, "blazorhosted"); publishCommand.Execute("/p:BuildProjectReferences=false /p:BuildInsideVisualStudio=true").Should().Pass(); var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm); @@ -945,7 +945,7 @@ public void Publish_HostedAppWithScopedCss_VisualStudio() buildCommand.Execute("/p:BuildInsideVisualStudio=true /p:Configuration=Release").Should().Pass(); // Publish - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorhosted")); + var publishCommand = new PublishCommand(testInstance, "blazorhosted"); publishCommand.Execute("/p:BuildProjectReferences=false /p:BuildInsideVisualStudio=true").Should().Pass(); var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm); @@ -1051,7 +1051,7 @@ public void Publish_HostedApp_VisualStudio_WithSatelliteAssemblies() buildCommand.WithWorkingDirectory(testInstance.TestRoot); buildCommand.Execute("/bl:build-msbuild.binlog").Should().Pass(); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.WithWorkingDirectory(testInstance.TestRoot); publishCommand.Execute("/p:BuildProjectReferences=false", "/bl:publish-msbuild.binlog").Should().Pass(); @@ -1080,7 +1080,7 @@ public void Publish_HostedApp_WithRidSpecifiedInCLI_Works() var testAppName = "BlazorHostedRID"; var testInstance = CreateAspNetSdkTestAsset(testAppName); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorhosted")); + var publishCommand = new PublishCommand(testInstance, "blazorhosted"); publishCommand.WithWorkingDirectory(testInstance.TestRoot); publishCommand.Execute("/p:RuntimeIdentifier=linux-x64", "/bl").Should().Pass(); @@ -1094,7 +1094,7 @@ public void Publish_HostedApp_WithRid_Works() var testAppName = "BlazorHostedRID"; var testInstance = CreateAspNetSdkTestAsset(testAppName); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorhosted")); + var publishCommand = new PublishCommand(testInstance, "blazorhosted"); publishCommand.WithWorkingDirectory(testInstance.TestRoot); publishCommand.Execute("/bl").Should().Pass(); @@ -1196,7 +1196,7 @@ public void Publish_WithInvariantGlobalizationEnabled_DoesNotCopyGlobalizationDa project.Root.Add(itemGroup); }); - var publishCommand = new PublishCommand(Log, testInstance.TestRoot); + var publishCommand = new PublishCommand(testInstance); publishCommand.Execute().Should().Pass(); var publishOutputDirectory = publishCommand.GetOutputDirectory(DefaultTfm).ToString(); @@ -1227,7 +1227,7 @@ public void Publish_HostingMultipleBlazorWebApps_Works() var testAppName = "BlazorMultiApp"; var testInstance = CreateAspNetSdkTestAsset(testAppName); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "BlazorMultipleApps.Server")); + var publishCommand = new PublishCommand(testInstance, "BlazorMultipleApps.Server"); publishCommand.Execute().Should().Pass(); var publishOutputDirectory = publishCommand.GetOutputDirectory(DefaultTfm).ToString(); diff --git a/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmPwaManifestTests.cs b/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmPwaManifestTests.cs index 287707faac85..19e17a772edd 100644 --- a/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmPwaManifestTests.cs +++ b/src/Tests/Microsoft.NET.Sdk.BlazorWebAssembly.Tests/WasmPwaManifestTests.cs @@ -71,7 +71,7 @@ public void Build_HostedAppWithServiceWorker_Works() buildCommand.Execute() .Should().Pass(); - var buildOutputDirectory = Path.Combine(testInstance.TestRoot, "blazorwasm", "bin", "Debug", DefaultTfm); + var buildOutputDirectory = OutputPathCalculator.FromProject(Path.Combine(testInstance.TestRoot, "blazorwasm")).GetOutputDirectory(); var serviceWorkerAssetsManifest = Path.Combine(buildOutputDirectory, "wwwroot", "custom-service-worker-assets.js"); // Trim prefix 'self.assetsManifest = ' and suffix ';' @@ -93,7 +93,7 @@ public void PublishWithPWA_ProducesAssets() var testAppName = "BlazorWasmWithLibrary"; var testInstance = CreateAspNetSdkTestAsset(testAppName); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.Execute().Should().Pass(); var publishOutputDirectory = publishCommand.GetOutputDirectory(DefaultTfm).ToString(); @@ -121,7 +121,7 @@ public void PublishHostedWithPWA_ProducesAssets() var testAppName = "BlazorHosted"; var testInstance = CreateAspNetSdkTestAsset(testAppName); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorhosted")); + var publishCommand = new PublishCommand(testInstance, "blazorhosted"); publishCommand.Execute().Should().Pass(); var publishOutputDirectory = publishCommand.GetOutputDirectory(DefaultTfm).ToString(); @@ -148,7 +148,7 @@ public void Publish_UpdatesServiceWorkerVersionHash_WhenSourcesChange() var testAppName = "BlazorWasmWithLibrary"; var testInstance = CreateAspNetSdkTestAsset(testAppName); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.Execute("/p:ServiceWorkerAssetsManifest=service-worker-assets.js").Should().Pass(); var publishOutputDirectory = publishCommand.GetOutputDirectory(DefaultTfm).ToString(); @@ -167,7 +167,7 @@ public void Publish_UpdatesServiceWorkerVersionHash_WhenSourcesChange() File.WriteAllText(cssFile, ".updated { }"); // Assert - publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.Execute("/p:ServiceWorkerAssetsManifest=service-worker-assets.js").Should().Pass(); var updatedVersion = File.ReadAllLines(serviceWorkerFile).Last(); @@ -188,7 +188,7 @@ public void Publish_DeterministicAcrossBuilds_WhenNoSourcesChange() var testAppName = "BlazorWasmWithLibrary"; var testInstance = CreateAspNetSdkTestAsset(testAppName); - var publishCommand = new PublishCommand(Log, Path.Combine(testInstance.TestRoot, "blazorwasm")); + var publishCommand = new PublishCommand(testInstance, "blazorwasm"); publishCommand.Execute("/p:ServiceWorkerAssetsManifest=service-worker-assets.js").Should().Pass(); var publishOutputDirectory = publishCommand.GetOutputDirectory(DefaultTfm).ToString(); diff --git a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/JsModulesIntegrationTest.cs b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/JsModulesIntegrationTest.cs index 43aced964ca4..415617b497da 100644 --- a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/JsModulesIntegrationTest.cs +++ b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/JsModulesIntegrationTest.cs @@ -243,7 +243,7 @@ public void PublishProjectWithReferences_IncorporatesInitializersFromClassLibrar // Notice that it does not follow the pattern $(PackageId).lib.module.js CreateFile("console.log('Hello world ClassLibrary')", "ClassLibrary", "wwwroot", "AnotherClassLib.lib.module.js"); - var publish = new PublishCommand(Log, Path.Combine(ProjectDirectory.TestRoot, "AppWithPackageAndP2PReference")); + var publish = new PublishCommand(ProjectDirectory, "AppWithPackageAndP2PReference"); publish.WithWorkingDirectory(ProjectDirectory.Path); publish.Execute("/bl").Should().Pass(); @@ -295,7 +295,7 @@ public void PublishProjectWithReferences_DifferentBuildAndPublish_LibraryInitial new XAttribute("TargetPath", "wwwroot\\AnotherClassLib.lib.module.js")))); } }); - var publish = new PublishCommand(Log, Path.Combine(ProjectDirectory.TestRoot, "AppWithPackageAndP2PReference")); + var publish = new PublishCommand(ProjectDirectory, "AppWithPackageAndP2PReference"); publish.WithWorkingDirectory(ProjectDirectory.Path); publish.Execute("/bl").Should().Pass(); diff --git a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/PackIntegrationTest.cs b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/PackIntegrationTest.cs index 9b5878c7cfbc..afd380706fce 100644 --- a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/PackIntegrationTest.cs +++ b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/PackIntegrationTest.cs @@ -33,7 +33,7 @@ public void Pack_NoBuild_Works_IncludesAssembly() var build = new BuildCommand(projectDirectory); build.Execute().Should().Pass(); - var pack = new MSBuildCommand(Log, "Pack", projectDirectory.Path); + var pack = new MSBuildCommand(projectDirectory, "Pack"); var result = pack.Execute("/p:NoBuild=true"); result.Should().Pass(); @@ -45,17 +45,17 @@ public void Pack_NoBuild_Works_IncludesAssembly() result.Should().NuSpecContain( Path.Combine(projectDirectory.Path, "obj", "Debug", "ClassLibrary.1.0.0.nuspec"), - $""); result.Should().NuSpecDoesNotContain( Path.Combine(projectDirectory.Path, "obj", "Debug", "ClassLibrary.1.0.0.nuspec"), - $""); result.Should().NuSpecDoesNotContain( Path.Combine(projectDirectory.Path, "obj", "Debug", "ClassLibrary.1.0.0.nuspec"), - $""); result.Should().NuSpecDoesNotContain( @@ -63,7 +63,7 @@ public void Pack_NoBuild_Works_IncludesAssembly() $@""); result.Should().NuPkgContain( - Path.Combine(projectDirectory.Path, "bin", "Debug", "ClassLibrary.1.0.0.nupkg"), + Path.Combine(build.GetPackageDirectory().FullName, "ClassLibrary.1.0.0.nupkg"), Path.Combine("lib", DefaultTfm, "ClassLibrary.dll")); } } diff --git a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/PublishIntegrationTest.cs b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/PublishIntegrationTest.cs index c445697754a5..bc716be12871 100644 --- a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/PublishIntegrationTest.cs +++ b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/PublishIntegrationTest.cs @@ -26,11 +26,11 @@ public void Publish_RazorCompileOnPublish_IsDefault() var testAsset = "RazorSimpleMvc"; var projectDirectory = CreateAspNetSdkTestAsset(testAsset); - var publish = new PublishCommand(Log, projectDirectory.TestRoot); + var publish = new PublishCommand(projectDirectory); publish.Execute().Should().Pass(); - var outputPath = Path.Combine(projectDirectory.Path, "bin", "Debug", DefaultTfm); - var publishOutputPath = publish.GetOutputDirectory(DefaultTfm, "Debug").ToString(); + var outputPath = new BuildCommand(projectDirectory).GetOutputDirectory().FullName; + var publishOutputPath = publish.GetOutputDirectory(DefaultTfm, "Debug").FullName; new FileInfo(Path.Combine(publishOutputPath, "SimpleMvc.dll")).Should().Exist(); new FileInfo(Path.Combine(publishOutputPath, "SimpleMvc.pdb")).Should().Exist(); @@ -81,7 +81,7 @@ public void Publish_NoopsWith_RazorCompileOnPublishFalse() Directory.Delete(Path.Combine(projectDirectory.Path, "Views"), recursive: true); - var publish = new PublishCommand(Log, projectDirectory.TestRoot); + var publish = new PublishCommand(projectDirectory); publish.Execute("/p:RazorCompileOnPublish=false").Should().Pass(); var publishOutputPath = publish.GetOutputDirectory(DefaultTfm, "Debug").ToString(); @@ -97,7 +97,7 @@ public void Publish_IncludeCshtmlAndRefAssemblies_CopiesFiles() var testAsset = "RazorSimpleMvc"; var projectDirectory = CreateAspNetSdkTestAsset(testAsset); - var publish = new PublishCommand(Log, projectDirectory.TestRoot); + var publish = new PublishCommand(projectDirectory); publish.Execute("/p:CopyRazorGenerateFilesToPublishDirectory=true", "/p:CopyRefAssembliesToPublishDirectory=true").Should().Pass(); var publishOutputPath = publish.GetOutputDirectory(DefaultTfm, "Debug").ToString(); @@ -125,7 +125,7 @@ public void Publish_WithPreserveCompilationReferencesSetInProjectFile_CopiesRefs }); - var publish = new PublishCommand(Log, projectDirectory.TestRoot); + var publish = new PublishCommand(projectDirectory); publish.Execute().Should().Pass(); var publishOutputPath = publish.GetOutputDirectory(DefaultTfm, "Debug").ToString(); @@ -143,7 +143,7 @@ public void Publish_WithP2P_AndRazorCompileOnBuild_CopiesRazorAssembly() var testAsset = "RazorAppWithP2PReference"; var projectDirectory = CreateAspNetSdkTestAsset(testAsset); - var publish = new PublishCommand(Log, Path.Combine(projectDirectory.TestRoot, "AppWithP2PReference")); + var publish = new PublishCommand(projectDirectory, "AppWithP2PReference"); publish.Execute().Should().Pass(); var publishOutputPath = publish.GetOutputDirectory(DefaultTfm, "Debug").ToString(); @@ -190,7 +190,7 @@ public void Publish_WithP2P_WorksWhenBuildProjectReferencesIsDisabled() new FileInfo(Path.Combine(outputPath, "AnotherClassLib.dll")).Should().Exist(); // dotnet msbuild /t:Publish /p:BuildProjectReferences=false - var publish = new PublishCommand(Log, Path.Combine(projectDirectory.TestRoot, "AppWithP2PReference")); + var publish = new PublishCommand(projectDirectory, "AppWithP2PReference"); publish.Execute("/p:BuildProjectReferences=false", "/p:ErrorOnDuplicatePublishOutputFiles=false").Should().Pass(); var publishOutputPath = publish.GetOutputDirectory(DefaultTfm, "Debug").ToString(); @@ -222,7 +222,7 @@ public void Publish_WithNoBuild_CopiesAlreadyCompiledViews() var assemblyVersion = AssemblyName.GetAssemblyName(assemblyPath).Version; // Publish should copy dlls from OutputPath - var publish = new PublishCommand(Log, projectDirectory.TestRoot); + var publish = new PublishCommand(projectDirectory); publish.Execute("/p:NoBuild=true").Should().Pass(); var publishOutputPath = publish.GetOutputDirectory(DefaultTfm, "Debug").ToString(); diff --git a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/ScopedCssIntegrationTests.cs b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/ScopedCssIntegrationTests.cs index fdef1f8adb5c..38d74663fc35 100644 --- a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/ScopedCssIntegrationTests.cs +++ b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/ScopedCssIntegrationTests.cs @@ -247,7 +247,7 @@ public void Publish_PublishesBundleToTheRightLocation() var testAsset = "RazorComponentApp"; var projectDirectory = CreateAspNetSdkTestAsset(testAsset); - var publish = new PublishCommand(Log, projectDirectory.TestRoot); + var publish = new PublishCommand(projectDirectory); publish.WithWorkingDirectory(projectDirectory.TestRoot); publish.Execute("/bl").Should().Pass(); @@ -269,7 +269,7 @@ public void Publish_NoBuild_PublishesBundleToTheRightLocation() var buildResult = build.Execute("/bl"); buildResult.Should().Pass(); - var publish = new PublishCommand(Log, projectDirectory.TestRoot); + var publish = new PublishCommand(projectDirectory); publish.Execute("/p:NoBuild=true").Should().Pass(); var publishOutputPath = publish.GetOutputDirectory(DefaultTfm, "Debug").ToString(); @@ -302,7 +302,7 @@ public void Publish_Publishes_IndividualScopedCssFiles_WhenNoBundlingIsEnabled() var testAsset = "RazorComponentApp"; var projectDirectory = CreateAspNetSdkTestAsset(testAsset); - var publish = new PublishCommand(Log, projectDirectory.TestRoot); + var publish = new PublishCommand(projectDirectory); publish.WithWorkingDirectory(projectDirectory.TestRoot); publish.Execute("/p:DisableScopedCssBundling=true", "/bl").Should().Pass(); diff --git a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/StaticWebAssetsIntegrationTest.cs b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/StaticWebAssetsIntegrationTest.cs index ae2347c67f6b..7668cbf6e62e 100644 --- a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/StaticWebAssetsIntegrationTest.cs +++ b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/StaticWebAssetsIntegrationTest.cs @@ -283,7 +283,7 @@ public void PublishProjectWithReferences_WorksWithStaticWebAssetsV1ClassLibrarie var restore = new RestoreCommand(Log, Path.Combine(ProjectDirectory.TestRoot, "AppWithPackageAndP2PReference")); restore.Execute().Should().Pass(); - var publish = new PublishCommand(Log, Path.Combine(ProjectDirectory.TestRoot, "AppWithPackageAndP2PReference")); + var publish = new PublishCommand(ProjectDirectory, "AppWithPackageAndP2PReference"); publish.WithWorkingDirectory(ProjectDirectory.Path); publish.Execute("/bl").Should().Pass(); @@ -616,7 +616,7 @@ public void PublishProjectWithReferences_GeneratesPublishJsonManifestAndCopiesPu var restore = new RestoreCommand(Log, Path.Combine(ProjectDirectory.TestRoot, "AppWithPackageAndP2PReference")); restore.Execute().Should().Pass(); - var publish = new PublishCommand(Log, Path.Combine(ProjectDirectory.TestRoot, "AppWithPackageAndP2PReference")); + var publish = new PublishCommand(ProjectDirectory, "AppWithPackageAndP2PReference"); publish.WithWorkingDirectory(ProjectDirectory.Path); publish.Execute("/bl").Should().Pass(); @@ -654,7 +654,7 @@ public void PublishProjectWithReferences_PublishSingleFile_GeneratesPublishJsonM var testAsset = "RazorAppWithPackageAndP2PReference"; ProjectDirectory = CreateAspNetSdkTestAsset(testAsset); - var publish = new PublishCommand(Log, Path.Combine(ProjectDirectory.TestRoot, "AppWithPackageAndP2PReference")); + var publish = new PublishCommand(ProjectDirectory, "AppWithPackageAndP2PReference"); publish.Execute($"/p:PublishSingleFile=true /p:RuntimeIdentifier={RuntimeInformation.RuntimeIdentifier}").Should().Pass(); var intermediateOutputPath = publish.GetIntermediateDirectory(DefaultTfm, "Debug").ToString(); @@ -758,12 +758,13 @@ public void PublishProjectWithReferences_AppendTargetFrameworkToOutputPathFalse_ var restore = new RestoreCommand(Log, Path.Combine(ProjectDirectory.TestRoot, "AppWithPackageAndP2PReference")); restore.Execute().Should().Pass(); - var publish = new PublishCommand(Log, Path.Combine(ProjectDirectory.TestRoot, "AppWithPackageAndP2PReference")); + var publish = new PublishCommand(ProjectDirectory, "AppWithPackageAndP2PReference"); publish.WithWorkingDirectory(ProjectDirectory.Path); publish.Execute("/p:AppendTargetFrameworkToOutputPath=false", "/bl").Should().Pass(); - var intermediateOutputPath = publish.GetIntermediateDirectory("", "Debug").ToString(); - var publishPath = publish.GetOutputDirectory("", "Debug").ToString(); + // Hard code output paths here to account for AppendTargetFrameworkToOutputPath=false + var intermediateOutputPath = Path.Combine(ProjectDirectory.Path, "AppWithPackageAndP2PReference", "obj", "Debug"); + var publishPath = Path.Combine(ProjectDirectory.Path, "AppWithPackageAndP2PReference", "bin", "Debug", "publish"); // GenerateStaticWebAssetsManifest should generate the manifest file. var path = Path.Combine(intermediateOutputPath, "staticwebassets.build.json"); @@ -910,7 +911,7 @@ public void Pack_IncludesStaticWebAssets() var testAsset = "PackageLibraryDirectDependency"; var projectDirectory = CreateAspNetSdkTestAsset(testAsset, subdirectory: "TestPackages"); - var pack = new MSBuildCommand(Log, "Pack", projectDirectory.Path, "PackageLibraryDirectDependency"); + var pack = new MSBuildCommand(projectDirectory, "Pack", "PackageLibraryDirectDependency"); pack.WithWorkingDirectory(projectDirectory.Path); var result = pack.Execute("/bl"); @@ -921,7 +922,7 @@ public void Pack_IncludesStaticWebAssets() new FileInfo(Path.Combine(outputPath, "PackageLibraryDirectDependency.dll")).Should().Exist(); result.Should().NuPkgContain( - Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "bin", "Debug", "PackageLibraryDirectDependency.1.0.0.nupkg"), + Path.Combine(pack.GetPackageDirectory().FullName, "PackageLibraryDirectDependency.1.0.0.nupkg"), filePaths: new[] { Path.Combine("staticwebassets", "js", "pkg-direct-dep.js"), @@ -940,7 +941,7 @@ public void Pack_NoAssets_DoesNothing() var testAsset = "PackageLibraryNoStaticAssets"; var projectDirectory = CreateAspNetSdkTestAsset(testAsset, subdirectory: "TestPackages"); - var pack = new MSBuildCommand(Log, "Pack", projectDirectory.Path); + var pack = new MSBuildCommand(projectDirectory, "Pack"); pack.WithWorkingDirectory(projectDirectory.Path); var result = pack.Execute("/bl"); @@ -951,7 +952,7 @@ public void Pack_NoAssets_DoesNothing() new FileInfo(Path.Combine(outputPath, "PackageLibraryNoStaticAssets.dll")).Should().Exist(); result.Should().NuPkgDoesNotContain( - Path.Combine(projectDirectory.Path, "bin", "Debug", "PackageLibraryNoStaticAssets.1.0.0.nupkg"), + Path.Combine(pack.GetPackageDirectory().FullName, "PackageLibraryNoStaticAssets.1.0.0.nupkg"), filePaths: new[] { Path.Combine("staticwebassets"), @@ -1003,13 +1004,13 @@ public void Pack_Incremental_IncludesStaticWebAssets() var testAsset = "PackageLibraryDirectDependency"; var projectDirectory = CreateAspNetSdkTestAsset(testAsset, subdirectory: "TestPackages"); - var pack = new MSBuildCommand(Log, "Pack", projectDirectory.Path, "PackageLibraryDirectDependency"); + var pack = new MSBuildCommand(projectDirectory, "Pack", "PackageLibraryDirectDependency"); pack.WithWorkingDirectory(projectDirectory.Path); var result = pack.Execute("/bl"); result.Should().Pass(); - var pack2 = new MSBuildCommand(Log, "Pack", projectDirectory.Path, "PackageLibraryDirectDependency"); + var pack2 = new MSBuildCommand(projectDirectory, "Pack", "PackageLibraryDirectDependency"); pack2.WithWorkingDirectory(projectDirectory.Path); var result2 = pack2.Execute("/bl"); @@ -1020,7 +1021,7 @@ public void Pack_Incremental_IncludesStaticWebAssets() new FileInfo(Path.Combine(outputPath, "PackageLibraryDirectDependency.dll")).Should().Exist(); result2.Should().NuPkgContain( - Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "bin", "Debug", "PackageLibraryDirectDependency.1.0.0.nupkg"), + Path.Combine(pack2.GetPackageDirectory().FullName, "PackageLibraryDirectDependency.1.0.0.nupkg"), filePaths: new[] { Path.Combine("staticwebassets", "js", "pkg-direct-dep.js"), @@ -1041,7 +1042,7 @@ public void Pack_StaticWebAssets_WithoutFileExtension_AreCorrectlyPacked() File.WriteAllText(Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "wwwroot", "LICENSE"), "license file contents"); - var pack = new MSBuildCommand(Log, "Pack", projectDirectory.Path, "PackageLibraryDirectDependency"); + var pack = new MSBuildCommand(projectDirectory, "Pack", "PackageLibraryDirectDependency"); pack.WithWorkingDirectory(projectDirectory.Path); var result = pack.Execute("/bl"); @@ -1052,7 +1053,7 @@ public void Pack_StaticWebAssets_WithoutFileExtension_AreCorrectlyPacked() new FileInfo(Path.Combine(outputPath, "PackageLibraryDirectDependency.dll")).Should().Exist(); result.Should().NuPkgContain( - Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "bin", "Debug", "PackageLibraryDirectDependency.1.0.0.nupkg"), + Path.Combine(pack.GetPackageDirectory().FullName, "PackageLibraryDirectDependency.1.0.0.nupkg"), filePaths: new[] { Path.Combine("staticwebassets", "js", "pkg-direct-dep.js"), @@ -1074,7 +1075,7 @@ public void Build_StaticWebAssets_GeneratePackageOnBuild_PacksStaticWebAssets() File.WriteAllText(Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "wwwroot", "LICENSE"), "license file contents"); - var buildCommand = new BuildCommand(Log, projectDirectory.Path, "PackageLibraryDirectDependency"); + var buildCommand = new BuildCommand(projectDirectory, "PackageLibraryDirectDependency"); buildCommand.WithWorkingDirectory(projectDirectory.Path); var result = buildCommand.Execute("/p:GeneratePackageOnBuild=true", "/bl"); @@ -1085,7 +1086,7 @@ public void Build_StaticWebAssets_GeneratePackageOnBuild_PacksStaticWebAssets() new FileInfo(Path.Combine(outputPath, "PackageLibraryDirectDependency.dll")).Should().Exist(); result.Should().NuPkgContain( - Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "bin", "Debug", "PackageLibraryDirectDependency.1.0.0.nupkg"), + Path.Combine(buildCommand.GetPackageDirectory().FullName, "PackageLibraryDirectDependency.1.0.0.nupkg"), filePaths: new[] { Path.Combine("staticwebassets", "js", "pkg-direct-dep.js"), @@ -1106,7 +1107,7 @@ public void Build_StaticWebAssets_GeneratePackageOnBuild_DoesNotIncludeAssetsAsC File.WriteAllText(Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "wwwroot", "LICENSE"), "license file contents"); - var buildCommand = new BuildCommand(Log, projectDirectory.Path, "PackageLibraryDirectDependency"); + var buildCommand = new BuildCommand(projectDirectory, "PackageLibraryDirectDependency"); buildCommand.WithWorkingDirectory(projectDirectory.Path); var result = buildCommand.Execute("/p:GeneratePackageOnBuild=true", "/bl"); @@ -1117,7 +1118,7 @@ public void Build_StaticWebAssets_GeneratePackageOnBuild_DoesNotIncludeAssetsAsC new FileInfo(Path.Combine(outputPath, "PackageLibraryDirectDependency.dll")).Should().Exist(); result.Should().NuPkgDoesNotContain( - Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "bin", "Debug", "PackageLibraryDirectDependency.1.0.0.nupkg"), + Path.Combine(buildCommand.GetPackageDirectory().FullName, "PackageLibraryDirectDependency.1.0.0.nupkg"), filePaths: new[] { Path.Combine("content", "js", "pkg-direct-dep.js"), @@ -1141,13 +1142,13 @@ public void Pack_MultipleTargetFrameworks_Works() tfm.Name = "TargetFrameworks"; tfm.FirstNode.ReplaceWith(tfm.FirstNode.ToString() + ";netstandard2.1"); - document.Descendants("AddRazorSupportForMvc").SingleOrDefault()?.Parent.Remove(); - document.Descendants("FrameworkReference").SingleOrDefault()?.Parent.Remove(); + document.Descendants("AddRazorSupportForMvc").SingleOrDefault()?.Remove(); + document.Descendants("FrameworkReference").SingleOrDefault()?.Remove(); }); Directory.Delete(Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "Components"), recursive: true); - var pack = new MSBuildCommand(Log, "Pack", projectDirectory.Path, "PackageLibraryDirectDependency"); + var pack = new MSBuildCommand(projectDirectory, "Pack", "PackageLibraryDirectDependency"); pack.WithWorkingDirectory(projectDirectory.Path); var result = pack.Execute("/bl"); @@ -1182,17 +1183,17 @@ public void Pack_MultipleTargetFrameworks_NoBuild_IncludesStaticWebAssets() tfm.Name = "TargetFrameworks"; tfm.FirstNode.ReplaceWith(tfm.FirstNode.ToString() + ";netstandard2.1"); - document.Descendants("AddRazorSupportForMvc").SingleOrDefault()?.Parent.Remove(); - document.Descendants("FrameworkReference").SingleOrDefault()?.Parent.Remove(); + document.Descendants("AddRazorSupportForMvc").SingleOrDefault()?.Remove(); + document.Descendants("FrameworkReference").SingleOrDefault()?.Remove(); }); Directory.Delete(Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "Components"), recursive: true); - var build = new BuildCommand(Log, projectDirectory.Path, "PackageLibraryDirectDependency"); + var build = new BuildCommand(projectDirectory, "PackageLibraryDirectDependency"); build.WithWorkingDirectory(projectDirectory.Path); var buildResult = build.Execute("/bl"); - var pack = new MSBuildCommand(Log, "Pack", projectDirectory.Path, "PackageLibraryDirectDependency"); + var pack = new MSBuildCommand(projectDirectory, "Pack", "PackageLibraryDirectDependency"); pack.WithWorkingDirectory(projectDirectory.Path); var result = pack.Execute("/p:NoBuild=true", "/bl"); @@ -1227,8 +1228,8 @@ public void Pack_MultipleTargetFrameworks_NoBuild_DoesNotIncludeAssetsAsContent( tfm.Name = "TargetFrameworks"; tfm.FirstNode.ReplaceWith(tfm.FirstNode.ToString() + ";netstandard2.1"); - document.Descendants("AddRazorSupportForMvc").SingleOrDefault()?.Parent.Remove(); - document.Descendants("FrameworkReference").SingleOrDefault()?.Parent.Remove(); + document.Descendants("AddRazorSupportForMvc").SingleOrDefault()?.Remove(); + document.Descendants("FrameworkReference").SingleOrDefault()?.Remove(); }); Directory.Delete(Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "Components"), recursive: true); @@ -1237,7 +1238,7 @@ public void Pack_MultipleTargetFrameworks_NoBuild_DoesNotIncludeAssetsAsContent( build.WithWorkingDirectory(projectDirectory.Path); var buildResult = build.Execute("/bl"); - var pack = new MSBuildCommand(Log, "Pack", projectDirectory.Path, "PackageLibraryDirectDependency"); + var pack = new MSBuildCommand(projectDirectory, "Pack", "PackageLibraryDirectDependency"); pack.WithWorkingDirectory(projectDirectory.Path); var result = pack.Execute("/p:NoBuild=true", "/bl"); @@ -1270,13 +1271,13 @@ public void Pack_MultipleTargetFrameworks_GeneratePackageOnBuild_IncludesStaticW tfm.Name = "TargetFrameworks"; tfm.FirstNode.ReplaceWith(tfm.FirstNode.ToString() + ";netstandard2.1"); - document.Descendants("AddRazorSupportForMvc").SingleOrDefault()?.Parent.Remove(); - document.Descendants("FrameworkReference").SingleOrDefault()?.Parent.Remove(); + document.Descendants("AddRazorSupportForMvc").SingleOrDefault()?.Remove(); + document.Descendants("FrameworkReference").SingleOrDefault()?.Remove(); }); Directory.Delete(Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "Components"), recursive: true); - var build = new BuildCommand(Log, projectDirectory.Path, "PackageLibraryDirectDependency"); + var build = new BuildCommand(projectDirectory, "PackageLibraryDirectDependency"); build.WithWorkingDirectory(projectDirectory.Path); var result = build.Execute("/p:GeneratePackageOnBuild=true", "/bl"); @@ -1311,13 +1312,13 @@ public void Pack_MultipleTargetFrameworks_GeneratePackageOnBuild_DoesNotIncludeA tfm.Name = "TargetFrameworks"; tfm.FirstNode.ReplaceWith(tfm.FirstNode.ToString() + ";netstandard2.1"); - document.Descendants("AddRazorSupportForMvc").SingleOrDefault()?.Parent.Remove(); - document.Descendants("FrameworkReference").SingleOrDefault()?.Parent.Remove(); + document.Descendants("AddRazorSupportForMvc").SingleOrDefault()?.Remove(); + document.Descendants("FrameworkReference").SingleOrDefault()?.Remove(); }); Directory.Delete(Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "Components"), recursive: true); - var build = new BuildCommand(Log, projectDirectory.Path, "PackageLibraryDirectDependency"); + var build = new BuildCommand(projectDirectory, "PackageLibraryDirectDependency"); build.WithWorkingDirectory(projectDirectory.Path); var result = build.Execute("/p:GeneratePackageOnBuild=true", "/bl"); @@ -2420,13 +2421,13 @@ public void Pack_MultipleTargetFrameworks_DoesNotIncludeAssetsAsContent() tfm.Name = "TargetFrameworks"; tfm.FirstNode.ReplaceWith(tfm.FirstNode.ToString() + ";netstandard2.1"); - document.Descendants("AddRazorSupportForMvc").SingleOrDefault()?.Parent.Remove(); - document.Descendants("FrameworkReference").SingleOrDefault()?.Parent.Remove(); + document.Descendants("AddRazorSupportForMvc").SingleOrDefault()?.Remove(); + document.Descendants("FrameworkReference").SingleOrDefault()?.Remove(); }); Directory.Delete(Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "Components"), recursive: true); - var pack = new MSBuildCommand(Log, "Pack", projectDirectory.Path, "PackageLibraryDirectDependency"); + var pack = new MSBuildCommand(projectDirectory, "Pack", "PackageLibraryDirectDependency"); pack.WithWorkingDirectory(projectDirectory.Path); var result = pack.Execute("/bl"); @@ -2453,7 +2454,7 @@ public void Pack_DoesNotInclude_TransitiveBundleOrScopedCssAsStaticWebAsset() var testAsset = "PackageLibraryDirectDependency"; var projectDirectory = CreateAspNetSdkTestAsset(testAsset, subdirectory: "TestPackages"); - var pack = new MSBuildCommand(Log, "Pack", projectDirectory.Path, "PackageLibraryDirectDependency"); + var pack = new MSBuildCommand(projectDirectory, "Pack", "PackageLibraryDirectDependency"); pack.WithWorkingDirectory(projectDirectory.TestRoot); var result = pack.Execute("/bl"); @@ -2464,7 +2465,7 @@ public void Pack_DoesNotInclude_TransitiveBundleOrScopedCssAsStaticWebAsset() new FileInfo(Path.Combine(outputPath, "PackageLibraryDirectDependency.dll")).Should().Exist(); result.Should().NuPkgDoesNotContain( - Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "bin", "Debug", "PackageLibraryDirectDependency.1.0.0.nupkg"), + Path.Combine(pack.GetPackageDirectory().FullName, "PackageLibraryDirectDependency.1.0.0.nupkg"), filePaths: new[] { // This is to make sure we don't include the scoped css files on the package when bundling is enabled. @@ -2479,7 +2480,7 @@ public void Pack_DoesNotIncludeStaticWebAssetsAsContent() var testAsset = "PackageLibraryDirectDependency"; var projectDirectory = CreateAspNetSdkTestAsset(testAsset, subdirectory: "TestPackages"); - var pack = new MSBuildCommand(Log, "Pack", projectDirectory.Path, "PackageLibraryDirectDependency"); + var pack = new MSBuildCommand(projectDirectory, "Pack", "PackageLibraryDirectDependency"); var result = pack.Execute(); result.Should().Pass(); @@ -2489,7 +2490,7 @@ public void Pack_DoesNotIncludeStaticWebAssetsAsContent() new FileInfo(Path.Combine(outputPath, "PackageLibraryDirectDependency.dll")).Should().Exist(); result.Should().NuPkgDoesNotContain( - Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "bin", "Debug", "PackageLibraryDirectDependency.1.0.0.nupkg"), + Path.Combine(pack.GetPackageDirectory().FullName, "PackageLibraryDirectDependency.1.0.0.nupkg"), filePaths: new[] { Path.Combine("content", "wwwroot", "js", "pkg-direct-dep.js"), @@ -2514,7 +2515,7 @@ public void Pack_NoBuild_IncludesStaticWebAssets() var build = new BuildCommand(projectDirectory, "PackageLibraryDirectDependency"); build.Execute().Should().Pass(); - var pack = new MSBuildCommand(Log, "Pack", projectDirectory.Path, "PackageLibraryDirectDependency"); + var pack = new MSBuildCommand(projectDirectory, "Pack", "PackageLibraryDirectDependency"); pack.WithWorkingDirectory(projectDirectory.TestRoot); var result = pack.Execute("/p:NoBuild=true", "/bl"); @@ -2523,7 +2524,7 @@ public void Pack_NoBuild_IncludesStaticWebAssets() new FileInfo(Path.Combine(outputPath, "PackageLibraryDirectDependency.dll")).Should().Exist(); result.Should().NuPkgContain( - Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "bin", "Debug", "PackageLibraryDirectDependency.1.0.0.nupkg"), + Path.Combine(build.GetPackageDirectory().FullName, "PackageLibraryDirectDependency.1.0.0.nupkg"), filePaths: new[] { Path.Combine("staticwebassets", "js", "pkg-direct-dep.js"), @@ -2545,7 +2546,7 @@ public void Pack_NoBuild_DoesNotIncludeFilesAsContent() var build = new BuildCommand(projectDirectory, "PackageLibraryDirectDependency"); build.Execute().Should().Pass(); - var pack = new MSBuildCommand(Log, "Pack", projectDirectory.Path, "PackageLibraryDirectDependency"); + var pack = new MSBuildCommand(projectDirectory, "Pack", "PackageLibraryDirectDependency"); pack.WithWorkingDirectory(projectDirectory.TestRoot); var result = pack.Execute("/p:NoBuild=true", "/bl"); @@ -2554,7 +2555,7 @@ public void Pack_NoBuild_DoesNotIncludeFilesAsContent() new FileInfo(Path.Combine(outputPath, "PackageLibraryDirectDependency.dll")).Should().Exist(); result.Should().NuPkgDoesNotContain( - Path.Combine(projectDirectory.Path, "PackageLibraryDirectDependency", "bin", "Debug", "PackageLibraryDirectDependency.1.0.0.nupkg"), + Path.Combine(pack.GetPackageDirectory().FullName, "PackageLibraryDirectDependency.1.0.0.nupkg"), filePaths: new[] { Path.Combine("content", "wwwroot", "js", "pkg-direct-dep.js"), @@ -2598,7 +2599,7 @@ public void Pack_Incremental_DoesNotRegenerateCacheAndPropsFiles() .CopyTestAsset(testAsset, testAssetSubdirectory: "TestPackages") .WithSource(); - var pack = new MSBuildCommand(Log, "Pack", projectDirectory.Path); + var pack = new MSBuildCommand(projectDirectory, "Pack"); pack.WithWorkingDirectory(projectDirectory.TestRoot); var result = pack.Execute("/bl"); diff --git a/src/Tests/Microsoft.NET.Sdk.Web.Tests/PublishTests.cs b/src/Tests/Microsoft.NET.Sdk.Web.Tests/PublishTests.cs index 430f9f855d4b..2e4142f2889b 100644 --- a/src/Tests/Microsoft.NET.Sdk.Web.Tests/PublishTests.cs +++ b/src/Tests/Microsoft.NET.Sdk.Web.Tests/PublishTests.cs @@ -34,8 +34,8 @@ public void TrimmingOptions_Are_Defaulted_Correctly_On_Trimmed_Apps(string targe var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: projectName + targetFramework); - var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); - publishCommand.Execute().Should().Pass(); + var publishCommand = new PublishCommand(testAsset); + publishCommand.Execute($"/p:RuntimeIdentifier={rid}").Should().Pass(); var buildProperties = testProject.GetPropertyValues(testAsset.TestRoot, targetFramework); buildProperties["TrimMode"].Should().Be("partial"); diff --git a/src/Tests/Microsoft.NET.TestFramework/Commands/DotnetBuildCommand.cs b/src/Tests/Microsoft.NET.TestFramework/Commands/DotnetBuildCommand.cs index d34e6d5301d5..1783c972cc38 100644 --- a/src/Tests/Microsoft.NET.TestFramework/Commands/DotnetBuildCommand.cs +++ b/src/Tests/Microsoft.NET.TestFramework/Commands/DotnetBuildCommand.cs @@ -16,7 +16,14 @@ public DotnetBuildCommand(ITestOutputHelper log, params string[] args) : base(lo public DotnetBuildCommand(TestAsset testAsset, params string[] args) : this(testAsset.Log, args) { - WorkingDirectory = Path.Combine(testAsset.TestRoot, testAsset.TestProject.Name); + if (testAsset.TestProject != null) + { + WorkingDirectory = Path.Combine(testAsset.TestRoot, testAsset.TestProject.Name); + } + else + { + WorkingDirectory = testAsset.TestRoot; + } } } } diff --git a/src/Tests/Microsoft.NET.TestFramework/Commands/DotnetPublishCommand.cs b/src/Tests/Microsoft.NET.TestFramework/Commands/DotnetPublishCommand.cs index cbb67fc4ab82..77c29ef4fe6c 100644 --- a/src/Tests/Microsoft.NET.TestFramework/Commands/DotnetPublishCommand.cs +++ b/src/Tests/Microsoft.NET.TestFramework/Commands/DotnetPublishCommand.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Text; using Microsoft.DotNet.Cli.Utils; using Xunit.Abstractions; diff --git a/src/Tests/Microsoft.NET.TestFramework/Commands/GetValuesCommand.cs b/src/Tests/Microsoft.NET.TestFramework/Commands/GetValuesCommand.cs index 5b98effe54ac..bb9c3aa42838 100644 --- a/src/Tests/Microsoft.NET.TestFramework/Commands/GetValuesCommand.cs +++ b/src/Tests/Microsoft.NET.TestFramework/Commands/GetValuesCommand.cs @@ -53,9 +53,7 @@ public GetValuesCommand(TestAsset testAsset, string targetFramework = null) : base(testAsset, "WriteValuesToFile", relativePathToProject: null) { - - _targetFramework = targetFramework ?? testAsset.TestProject?.TargetFrameworks; - _targetFramework = _targetFramework.Contains(";") ? "" : _targetFramework; + _targetFramework = targetFramework ?? OutputPathCalculator.FromProject(ProjectFile, testAsset).TargetFramework; _valueName = valueName; _valueType = valueType; @@ -119,7 +117,7 @@ protected override SdkCommandSpec CreateCommand(IEnumerable args) File.WriteAllText(injectTargetPath, injectTargetContents); - var outputDirectory = GetOutputDirectory(_targetFramework); + var outputDirectory = GetValuesOutputDirectory(_targetFramework); outputDirectory.Create(); return TestContext.Current.ToolsetUnderTest.CreateCommandForTarget(TargetName, newArgs); @@ -133,7 +131,7 @@ public List GetValues() public List<(string value, Dictionary metadata)> GetValuesWithMetadata() { string outputFilename = $"{_valueName}Values.txt"; - var outputDirectory = GetOutputDirectory(_targetFramework, Configuration ?? "Debug"); + var outputDirectory = GetValuesOutputDirectory(_targetFramework, Configuration ?? "Debug"); string fullFileName = Path.Combine(outputDirectory.FullName, outputFilename); if (File.Exists(fullFileName)) @@ -166,5 +164,17 @@ public List GetValues() return new List<(string value, Dictionary metadata)>(); } } + + DirectoryInfo GetValuesOutputDirectory(string targetFramework = "", string configuration = "Debug") + { + // Use a consistent directory format to put the values text file in, so we don't have to worry about + // whether the project uses the standard output path format or not + + targetFramework = targetFramework ?? string.Empty; + configuration = configuration ?? string.Empty; + + string output = Path.Combine(ProjectRootPath, "bin", configuration, targetFramework); + return new DirectoryInfo(output); + } } } diff --git a/src/Tests/Microsoft.NET.TestFramework/Commands/MSBuildCommand.cs b/src/Tests/Microsoft.NET.TestFramework/Commands/MSBuildCommand.cs index f7bd715e74a3..107b6ad4da0d 100644 --- a/src/Tests/Microsoft.NET.TestFramework/Commands/MSBuildCommand.cs +++ b/src/Tests/Microsoft.NET.TestFramework/Commands/MSBuildCommand.cs @@ -22,6 +22,8 @@ public class MSBuildCommand : TestCommand public string ProjectFile { get; } + public TestAsset TestAsset { get; } + public string FullPathProjectFile => Path.Combine(ProjectRootPath, ProjectFile); public MSBuildCommand(ITestOutputHelper log, string target, string projectRootPath, string relativePathToProject = null) @@ -37,6 +39,7 @@ public MSBuildCommand(ITestOutputHelper log, string target, string projectRootPa public MSBuildCommand(TestAsset testAsset, string target, string relativePathToProject = null) : this(testAsset.Log, target, testAsset.TestRoot, relativePathToProject ?? testAsset.TestProject?.Name) { + TestAsset = testAsset; } internal static string FindProjectFile(ref string projectRootPath, string relativePathToProject) @@ -72,8 +75,13 @@ internal static string FindProjectFile(ref string projectRootPath, string relati return buildProjectFiles[0]; } - public virtual DirectoryInfo GetOutputDirectory(string targetFramework, string configuration = "Debug", string runtimeIdentifier = "") + public virtual DirectoryInfo GetOutputDirectory(string targetFramework = null, string configuration = "Debug", string runtimeIdentifier = null) { + if (TestAsset != null) + { + return new DirectoryInfo(OutputPathCalculator.FromProject(ProjectFile, TestAsset).GetOutputDirectory(targetFramework, configuration, runtimeIdentifier)); + } + targetFramework = targetFramework ?? string.Empty; configuration = configuration ?? string.Empty; runtimeIdentifier = runtimeIdentifier ?? string.Empty; @@ -82,8 +90,13 @@ public virtual DirectoryInfo GetOutputDirectory(string targetFramework, string c return new DirectoryInfo(output); } - public virtual DirectoryInfo GetIntermediateDirectory(string targetFramework, string configuration = "Debug", string runtimeIdentifier = "") + public virtual DirectoryInfo GetIntermediateDirectory(string targetFramework = null, string configuration = "Debug", string runtimeIdentifier = null) { + if (TestAsset != null) + { + return new DirectoryInfo(OutputPathCalculator.FromProject(ProjectFile, TestAsset).GetIntermediateDirectory(targetFramework, configuration, runtimeIdentifier)); + } + targetFramework = targetFramework ?? string.Empty; configuration = configuration ?? string.Empty; runtimeIdentifier = runtimeIdentifier ?? string.Empty; @@ -92,6 +105,17 @@ public virtual DirectoryInfo GetIntermediateDirectory(string targetFramework, st return new DirectoryInfo(output); } + public DirectoryInfo GetPackageDirectory(string configuration = "Debug") + { + if (TestAsset != null) + { + return new DirectoryInfo(OutputPathCalculator.FromProject(ProjectFile, TestAsset).GetPackageDirectory(configuration)); + } + + string output = Path.Combine(ProjectRootPath, "bin", configuration); + return new DirectoryInfo(output); + } + public virtual DirectoryInfo GetNonSDKOutputDirectory(string configuration = "Debug") { configuration = configuration ?? string.Empty; diff --git a/src/Tests/Microsoft.NET.TestFramework/Commands/PackCommand.cs b/src/Tests/Microsoft.NET.TestFramework/Commands/PackCommand.cs index 07f9b30a337f..46ef48ad8b51 100644 --- a/src/Tests/Microsoft.NET.TestFramework/Commands/PackCommand.cs +++ b/src/Tests/Microsoft.NET.TestFramework/Commands/PackCommand.cs @@ -11,6 +11,13 @@ public sealed class PackCommand : MSBuildCommand public PackCommand(ITestOutputHelper log, string projectPath, string relativePathToProject = null) : base(log, "Pack", projectPath, relativePathToProject) { + + } + + public PackCommand(TestAsset testAsset, string relativePathToProject = null) + : base(testAsset, "Pack", relativePathToProject) + { + } public string GetIntermediateNuspecPath(string packageId = null, string configuration = "Debug", string packageVersion = "1.0.0") @@ -30,7 +37,7 @@ public string GetNuGetPackage(string packageId = null, string configuration = "D packageId = Path.GetFileNameWithoutExtension(ProjectFile); } - return Path.Combine(GetOutputDirectory(null, configuration).FullName, $"{packageId}.{packageVersion}.nupkg"); + return Path.Combine(GetPackageDirectory(configuration).FullName, $"{packageId}.{packageVersion}.nupkg"); } } } diff --git a/src/Tests/Microsoft.NET.TestFramework/Commands/PublishCommand.cs b/src/Tests/Microsoft.NET.TestFramework/Commands/PublishCommand.cs index 57298deb5cce..2dcad7d0d5f0 100644 --- a/src/Tests/Microsoft.NET.TestFramework/Commands/PublishCommand.cs +++ b/src/Tests/Microsoft.NET.TestFramework/Commands/PublishCommand.cs @@ -24,13 +24,23 @@ public PublishCommand(TestAsset testAsset, string relativePathToProject = null) } - public override DirectoryInfo GetOutputDirectory(string targetFramework = "netcoreapp1.1", string configuration = "Debug", string runtimeIdentifier = "") + public override DirectoryInfo GetOutputDirectory(string targetFramework = null, string configuration = "Debug", string runtimeIdentifier = "") { + if (TestAsset != null) + { + return new DirectoryInfo(OutputPathCalculator.FromProject(ProjectFile, TestAsset).GetPublishDirectory(targetFramework, configuration, runtimeIdentifier)); + } + + if (string.IsNullOrEmpty(targetFramework)) + { + targetFramework = "netcoreapp1.1"; + } + DirectoryInfo baseDirectory = base.GetOutputDirectory(targetFramework, configuration, runtimeIdentifier); return new DirectoryInfo(Path.Combine(baseDirectory.FullName, PublishSubfolderName)); } - public string GetPublishedAppPath(string appName, string targetFramework = "netcoreapp1.1") + public string GetPublishedAppPath(string appName, string targetFramework = "") { return Path.Combine(GetOutputDirectory(targetFramework).FullName, $"{appName}.dll"); } diff --git a/src/Tests/Microsoft.NET.TestFramework/OutputPathCalculator.cs b/src/Tests/Microsoft.NET.TestFramework/OutputPathCalculator.cs new file mode 100644 index 000000000000..f9407be3dc87 --- /dev/null +++ b/src/Tests/Microsoft.NET.TestFramework/OutputPathCalculator.cs @@ -0,0 +1,300 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.NET.TestFramework.ProjectConstruction; +using System.Xml.Linq; +using NuGet.Frameworks; +using Xunit.Sdk; +using System.ComponentModel.DataAnnotations; + +namespace Microsoft.NET.TestFramework +{ + public class OutputPathCalculator + { + public string ProjectPath { get; set; } + public bool UseArtifactsOutput { get; set; } + public bool IncludeProjectNameInArtifactsPaths { get; set; } + public string ArtifactsPath { get; set; } + public string TargetFramework { get; set; } + public string TargetFrameworks { get; set; } + + public string RuntimeIdentifier { get; set; } + + public bool IsSdkProject { get; set; } = true; + + public static OutputPathCalculator FromProject(string projectPath, TestAsset testAsset) + { + return FromProject(projectPath, testAsset?.TestProject); + } + + public static OutputPathCalculator FromProject(string projectPath, TestProject testProject = null) + { + string originalProjectPath = projectPath; + + if (!File.Exists(projectPath) && Directory.Exists(projectPath)) + { + projectPath = Directory.GetFiles(projectPath, "*.*proj").FirstOrDefault(); + } + + // Support passing in the root test path and looking in subfolder specified by testProject + if (projectPath == null && testProject != null) + { + projectPath = Path.Combine(originalProjectPath, testProject.Name); + + if (!File.Exists(projectPath) && Directory.Exists(projectPath)) + { + projectPath = Directory.GetFiles(projectPath, "*.*proj").FirstOrDefault(); + } + } + + if (projectPath == null) + { + throw new ArgumentException($"Test project not found under {projectPath}"); + } + + var calculator = new OutputPathCalculator() + { + ProjectPath = projectPath, + }; + + if (testProject != null) + { + calculator.UseArtifactsOutput = testProject.UseArtifactsOutput; + calculator.IsSdkProject = testProject.IsSdkProject; + calculator.IncludeProjectNameInArtifactsPaths = testProject.UseDirectoryBuildPropsForArtifactsOutput; + + if (testProject.TargetFrameworks.Contains(';')) + { + calculator.TargetFrameworks = testProject.TargetFrameworks; + } + else + { + calculator.TargetFramework = testProject.TargetFrameworks; + } + + calculator.RuntimeIdentifier = testProject.RuntimeIdentifier; + + if (calculator.IncludeProjectNameInArtifactsPaths) + { + string directoryBuildPropsFile = GetDirectoryBuildPropsPath(projectPath); + if (directoryBuildPropsFile == null) + { + throw new InvalidOperationException("Couldn't find Directory.Build.props for test project " + projectPath); + } + calculator.ArtifactsPath = Path.Combine(Path.GetDirectoryName(directoryBuildPropsFile), ".artifacts"); + } + else + { + calculator.ArtifactsPath = Path.Combine(Path.GetDirectoryName(projectPath), ".artifacts"); + } + } + else + { + var project = XDocument.Load(projectPath); + var ns = project.Root.Name.Namespace; + + var useArtifactsOutputElement = project.Root.Elements(ns + "PropertyGroup").Elements(ns + "UseArtifactsOutput").FirstOrDefault(); + if (useArtifactsOutputElement != null) + { + calculator.UseArtifactsOutput = bool.Parse(useArtifactsOutputElement.Value); + if (calculator.UseArtifactsOutput) + { + calculator.IncludeProjectNameInArtifactsPaths = false; + calculator.ArtifactsPath = Path.Combine(Path.GetDirectoryName(projectPath), ".artifacts"); + } + } + + var targetFrameworkElement = project.Root.Elements(ns + "PropertyGroup").Elements(ns + "TargetFramework").FirstOrDefault(); + if (targetFrameworkElement != null) + { + calculator.TargetFramework = targetFrameworkElement.Value; + } + + var targetFrameworksElement = project.Root.Elements(ns + "PropertyGroup").Elements(ns + "TargetFrameworks").FirstOrDefault(); + if (targetFrameworksElement != null) + { + calculator.TargetFrameworks = targetFrameworksElement.Value; + } + + var runtimeIdentifierElement = project.Root.Elements(ns + "PropertyGroup").Elements(ns + "RuntimeIdentifier").FirstOrDefault(); + if (runtimeIdentifierElement != null) + { + calculator.RuntimeIdentifier = runtimeIdentifierElement.Value; + } + + var directoryBuildPropsFile = GetDirectoryBuildPropsPath(projectPath); + if (directoryBuildPropsFile != null) + { + var dbp = XDocument.Load(directoryBuildPropsFile); + var dbpns = dbp.Root.Name.Namespace; + + var dbpUsesArtifacts = dbp.Root.Elements(dbpns + "PropertyGroup").Elements(dbpns + "UseArtifactsOutput").FirstOrDefault(); + if (dbpUsesArtifacts != null) + { + + calculator.UseArtifactsOutput = bool.Parse(dbpUsesArtifacts.Value); + if (calculator.UseArtifactsOutput) + { + calculator.IncludeProjectNameInArtifactsPaths = true; + calculator.ArtifactsPath = Path.Combine(Path.GetDirectoryName(directoryBuildPropsFile), ".artifacts"); + } + } + } + } + + return calculator; + } + + private static string GetDirectoryBuildPropsPath(string projectPath) + { + string folder = Path.GetDirectoryName(projectPath); + while (folder != null) + { + string directoryBuildPropsFile = Path.Combine(folder, "Directory.Build.props"); + if (File.Exists(directoryBuildPropsFile)) + { + return directoryBuildPropsFile; + } + folder = Path.GetDirectoryName(folder); + } + return null; + } + + public bool IsMultiTargeted() + { + return !string.IsNullOrEmpty(TargetFrameworks); + } + + public string GetOutputDirectory(string targetFramework = null, string configuration = "Debug", string runtimeIdentifier = "") + { + if (UseArtifactsOutput) + { + string pivot = configuration.ToLowerInvariant(); + if (IsMultiTargeted()) + { + pivot += "_" + targetFramework ?? TargetFramework; + } + if (string.IsNullOrEmpty(runtimeIdentifier)) + { + runtimeIdentifier = RuntimeIdentifier; + } + if (!string.IsNullOrEmpty(runtimeIdentifier)) + { + pivot += "_" + runtimeIdentifier; + } + + if (IncludeProjectNameInArtifactsPaths) + { + return Path.Combine(ArtifactsPath, "bin", Path.GetFileNameWithoutExtension(ProjectPath), pivot); + } + else + { + return Path.Combine(ArtifactsPath, "bin", pivot); + } + } + else + { + targetFramework = targetFramework ?? TargetFramework ?? string.Empty; + configuration = configuration ?? string.Empty; + runtimeIdentifier = runtimeIdentifier ?? RuntimeIdentifier ?? string.Empty; + + if (IsSdkProject) + { + string output = System.IO.Path.Combine(Path.GetDirectoryName(ProjectPath), "bin", configuration, targetFramework, runtimeIdentifier); + return output; + } + else + { + string output = System.IO.Path.Combine(Path.GetDirectoryName(ProjectPath), "bin", configuration); + return output; + } + } + } + + public string GetPublishDirectory(string targetFramework = null, string configuration = "Debug", string runtimeIdentifier = "") + { + if (UseArtifactsOutput) + { + string pivot = configuration.ToLowerInvariant(); + if (IsMultiTargeted()) + { + pivot += "_" + targetFramework ?? TargetFramework; + } + if (string.IsNullOrEmpty(runtimeIdentifier)) + { + runtimeIdentifier = RuntimeIdentifier; + } + if (!string.IsNullOrEmpty(runtimeIdentifier)) + { + pivot += "_" + runtimeIdentifier; + } + + if (IncludeProjectNameInArtifactsPaths) + { + return Path.Combine(ArtifactsPath, "publish", Path.GetFileNameWithoutExtension(ProjectPath), pivot); + } + else + { + return Path.Combine(ArtifactsPath, "publish", pivot); + } + } + else + { + targetFramework = targetFramework ?? TargetFramework ?? string.Empty; + configuration = configuration ?? string.Empty; + runtimeIdentifier = runtimeIdentifier ?? RuntimeIdentifier ?? string.Empty; + + string output = System.IO.Path.Combine(Path.GetDirectoryName(ProjectPath), "bin", configuration, targetFramework, runtimeIdentifier, "publish"); + return output; + } + } + + public string GetIntermediateDirectory(string targetFramework = null, string configuration = "Debug", string runtimeIdentifier = "") + { + // IncludeProjectNameInArtifactsPath is likely to be true if UseArtifactsOutput was set in Directory.Build.props, and hence the intermediate folder should be in the artifacts path + if (UseArtifactsOutput && IncludeProjectNameInArtifactsPaths) + { + string pivot = configuration.ToLowerInvariant(); + if (IsMultiTargeted()) + { + pivot += "_" + targetFramework ?? TargetFramework; + } + if (string.IsNullOrEmpty(runtimeIdentifier)) + { + runtimeIdentifier = RuntimeIdentifier; + } + if (!string.IsNullOrEmpty(runtimeIdentifier)) + { + pivot += "_" + runtimeIdentifier; + } + return Path.Combine(ArtifactsPath, "obj", Path.GetFileNameWithoutExtension(ProjectPath), pivot); + } + + targetFramework = targetFramework ?? TargetFramework ?? string.Empty; + configuration = configuration ?? string.Empty; + runtimeIdentifier = runtimeIdentifier ?? RuntimeIdentifier ?? string.Empty; + + string output = System.IO.Path.Combine(Path.GetDirectoryName(ProjectPath), "obj", configuration, targetFramework, runtimeIdentifier); + return output; + } + + public string GetPackageDirectory(string configuration = "Debug") + { + if (UseArtifactsOutput) + { + return System.IO.Path.Combine(ArtifactsPath, "package", configuration.ToLowerInvariant()); + } + else + { + return System.IO.Path.Combine(Path.GetDirectoryName(ProjectPath), "bin", configuration); + } + } + } +} diff --git a/src/Tests/Microsoft.NET.TestFramework/ProjectConstruction/TestProject.cs b/src/Tests/Microsoft.NET.TestFramework/ProjectConstruction/TestProject.cs index 11d978947895..8ae1bb1994cb 100644 --- a/src/Tests/Microsoft.NET.TestFramework/ProjectConstruction/TestProject.cs +++ b/src/Tests/Microsoft.NET.TestFramework/ProjectConstruction/TestProject.cs @@ -37,8 +37,11 @@ public TestProject([CallerMemberName] string name = null) public string ProjectSdk { get; set; } - // Applies to SDK Projects - public string TargetFrameworks { get; set; } + /// + /// Applies to SDK-style projects. If the value has only one target framework (ie no semicolons), the value will be used + /// for the MSBuild TargetFramework (singular) property. Otherwise, the value will be used for the TargetFrameworks property. + /// + public string TargetFrameworks { get; set; } = ToolsetInfo.CurrentTargetFramework; public string RuntimeFrameworkVersion { get; set; } @@ -49,6 +52,10 @@ public TestProject([CallerMemberName] string name = null) public string TargetFrameworkProfile { get; set; } + public bool UseArtifactsOutput { get; set; } + + public bool UseDirectoryBuildPropsForArtifactsOutput { get; set; } + public List ReferencedProjects { get; } = new List(); public List References { get; } = new List(); @@ -244,6 +251,11 @@ internal void Create(TestAsset targetTestAsset, string testProjectsSourceFolder, propertyGroup.Add(new XElement(ns + additionalProperty.Key, additionalProperty.Value)); } + if (UseArtifactsOutput && !UseDirectoryBuildPropsForArtifactsOutput) + { + propertyGroup.Add(new XElement(ns + "UseArtifactsOutput", "true")); + } + if (AdditionalItems.Any()) { foreach (var additionalItem in AdditionalItems) @@ -499,5 +511,16 @@ public static bool ReferenceAssembliesAreInstalled(TargetDotNetFrameworkVersion var referenceAssemblies = ToolLocationHelper.GetPathToDotNetFrameworkReferenceAssemblies(targetFrameworkVersion); return referenceAssemblies != null; } + + private OutputPathCalculator GetOutputPathCalculator(string testRoot) + { + return OutputPathCalculator.FromProject(Path.Combine(testRoot, Name, Name + ".csproj"), this); + } + + public string GetOutputDirectory(string testRoot, string targetFramework = null, string configuration = "Debug", string runtimeIdentifier = "") + { + return GetOutputPathCalculator(testRoot) + .GetOutputDirectory(targetFramework, configuration, runtimeIdentifier); + } } } diff --git a/src/Tests/Microsoft.NET.TestFramework/TestAsset.cs b/src/Tests/Microsoft.NET.TestFramework/TestAsset.cs index 42ae7f9780f0..48a8af4e3813 100644 --- a/src/Tests/Microsoft.NET.TestFramework/TestAsset.cs +++ b/src/Tests/Microsoft.NET.TestFramework/TestAsset.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using Xunit.Abstractions; using Microsoft.NET.TestFramework.ProjectConstruction; +using NuGet.Frameworks; namespace Microsoft.NET.TestFramework { @@ -111,39 +112,46 @@ public TestAsset WithSource() public TestAsset UpdateProjProperty(string propertyName, string variableName, string targetValue) { - return WithTargetFramework( + return WithProjectChanges( p => { var ns = p.Root.Name.Namespace; var getNode = p.Root.Elements(ns + "PropertyGroup").Elements(ns + propertyName).FirstOrDefault(); getNode ??= p.Root.Elements(ns + "PropertyGroup").Elements(ns + $"{propertyName}s").FirstOrDefault(); getNode?.SetValue(getNode?.Value.Replace(variableName, targetValue)); - }, targetValue); + }); } public TestAsset WithTargetFramework(string targetFramework, string projectName = null) { - return WithTargetFramework( + if (targetFramework == null) + { + return this; + } + return WithProjectChanges( p => { var ns = p.Root.Name.Namespace; p.Root.Elements(ns + "PropertyGroup").Elements(ns + "TargetFramework").Single().SetValue(targetFramework); }, - targetFramework, projectName); } public TestAsset WithTargetFrameworks(string targetFrameworks, string projectName = null) { - return WithTargetFramework( + if (targetFrameworks == null) + { + return this; + } + return WithProjectChanges( p => { var ns = p.Root.Name.Namespace; var propertyGroup = p.Root.Elements(ns + "PropertyGroup").First(); propertyGroup.Elements(ns + "TargetFramework").SingleOrDefault()?.Remove(); + propertyGroup.Elements(ns + "TargetFrameworks").SingleOrDefault()?.Remove(); propertyGroup.Add(new XElement(ns + "TargetFrameworks", targetFrameworks)); }, - targetFrameworks, projectName); } @@ -159,13 +167,8 @@ public TestAsset WithTargetFrameworkOrFrameworks(string targetFrameworkOrFramewo } } - private TestAsset WithTargetFramework(Action actionOnProject, string targetFramework, string projectName = null) + private TestAsset WithProjectChanges(Action actionOnProject, string projectName = null) { - if (string.IsNullOrEmpty(targetFramework)) - { - return this; - } - return WithProjectChanges((path, project) => { if (!string.IsNullOrEmpty(projectName)) diff --git a/src/Tests/Microsoft.NET.TestFramework/TestAssetsManager.cs b/src/Tests/Microsoft.NET.TestFramework/TestAssetsManager.cs index 67496b2010a2..993b3c5d518e 100644 --- a/src/Tests/Microsoft.NET.TestFramework/TestAssetsManager.cs +++ b/src/Tests/Microsoft.NET.TestFramework/TestAssetsManager.cs @@ -1,17 +1,18 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using FluentAssertions; using Microsoft.NET.TestFramework.Assertions; using Microsoft.NET.TestFramework.Commands; using Microsoft.NET.TestFramework.ProjectConstruction; using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using Xunit.Abstractions; -using FluentAssertions; namespace Microsoft.NET.TestFramework { diff --git a/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProject.cs b/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProject.cs index 2a61a4260565..fa7ba8476a32 100644 --- a/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProject.cs +++ b/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProject.cs @@ -42,7 +42,7 @@ private string SetupNuGetPackage(bool multiTarget, [CallerMemberName] string cal _testRoot = helloWorldAsset.TestRoot; - var packCommand = new PackCommand(Log, helloWorldAsset.TestRoot); + var packCommand = new PackCommand(helloWorldAsset); var result = packCommand.Execute(); result.Should().Pass(); diff --git a/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithExplicitConfig.cs b/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithExplicitConfig.cs index d2e186501949..83da3d3f5ef3 100644 --- a/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithExplicitConfig.cs +++ b/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithExplicitConfig.cs @@ -39,7 +39,7 @@ public void It_finds_the_entry_point_dll_and_put_in_setting_file() propertyGroup.Add(new XElement("ToolEntryPoint", explicitEntryPoint)); }); - var packCommand = new PackCommand(Log, helloWorldAsset.TestRoot); + var packCommand = new PackCommand(helloWorldAsset); packCommand.Execute(); @@ -74,7 +74,7 @@ public void It_finds_commandName_and_put_in_setting_file() XElement propertyGroup = project.Root.Elements(ns + "PropertyGroup").First(); propertyGroup.Add(new XElement("ToolCommandName", explicitCommandName)); }); - var packCommand = new PackCommand(Log, helloWorldAsset.TestRoot); + var packCommand = new PackCommand(helloWorldAsset); packCommand.Execute(); diff --git a/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithGeneratePackageOnBuild.cs b/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithGeneratePackageOnBuild.cs index 6d655e2c420c..dc34077477c8 100644 --- a/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithGeneratePackageOnBuild.cs +++ b/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithGeneratePackageOnBuild.cs @@ -62,11 +62,10 @@ public void It_builds_successfully() public void It_builds_and_result_contains_dependencies_dll() { TestAsset testAsset = SetupAndRestoreTestAsset(); - var appProjectDirectory = Path.Combine(testAsset.TestRoot, "App"); var buildCommand = new BuildCommand(testAsset, "App"); buildCommand.Execute(); - var packCommand = new PackCommand(Log, appProjectDirectory); + var packCommand = new PackCommand(testAsset, "App"); // Do not run pack, just use it to get nupkg since it should be run by build. var nugetPackage = packCommand.GetNuGetPackage(); diff --git a/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithP2PReference.cs b/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithP2PReference.cs index 5cb1c2823ed2..79284ee1d5b2 100644 --- a/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithP2PReference.cs +++ b/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithP2PReference.cs @@ -26,8 +26,7 @@ private string SetupNuGetPackage([CallerMemberName] string callingMethod = "") .CopyTestAsset("PortableToolWithP2P", callingMethod) .WithSource(); - var appProjectDirectory = Path.Combine(testAsset.TestRoot, "App"); - var packCommand = new PackCommand(Log, appProjectDirectory); + var packCommand = new PackCommand(testAsset, "App"); packCommand.Execute(); diff --git a/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithPackagedShim.cs b/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithPackagedShim.cs index 4403b0ddfa38..23dbb036fa09 100644 --- a/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithPackagedShim.cs +++ b/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithPackagedShim.cs @@ -47,7 +47,7 @@ private string SetupNuGetPackage( _testRoot = helloWorldAsset.TestRoot; - var packCommand = new PackCommand(Log, helloWorldAsset.TestRoot); + var packCommand = new PackCommand(helloWorldAsset); packCommand.Execute().Should().Pass(); _packageId = Path.GetFileNameWithoutExtension(packCommand.ProjectFile); @@ -191,7 +191,7 @@ public void It_uses_outputs_to_bin_by_default(bool multiTarget, string targetFra _testRoot = helloWorldAsset.TestRoot; - var packCommand = new PackCommand(Log, helloWorldAsset.TestRoot); + var packCommand = new PackCommand(helloWorldAsset); var outputDirectory = packCommand.GetOutputDirectory(targetFramework); packCommand.Execute().Should().Pass(); @@ -273,7 +273,7 @@ public void It_contains_shim_with_no_build(bool multiTarget, string targetFramew var buildCommand = new BuildCommand(testAsset); buildCommand.Execute().Should().Pass(); - var packCommand = new PackCommand(Log, testAsset.TestRoot); + var packCommand = new PackCommand(testAsset); packCommand.Execute("/p:NoBuild=true").Should().Pass(); var nugetPackage = packCommand.GetNuGetPackage(); @@ -336,7 +336,7 @@ public void It_produces_valid_shims_when_the_first_build_is_wrong(bool multiTarg var buildCommand = new BuildCommand(helloWorldAsset); buildCommand.Execute("/p:PackageId=wrongpackagefirstbuild"); - var packCommand = new PackCommand(Log, helloWorldAsset.TestRoot); + var packCommand = new PackCommand(helloWorldAsset); packCommand.Execute().Should().Pass(); var nugetPackage = packCommand.GetNuGetPackage(); diff --git a/src/Tests/Microsoft.NET.ToolPack.Tests/PackWithShimsAndResultNugetPackageNuGetPackagexFixture.cs b/src/Tests/Microsoft.NET.ToolPack.Tests/PackWithShimsAndResultNugetPackageNuGetPackagexFixture.cs index 6e796f10a9ba..c77be288716a 100644 --- a/src/Tests/Microsoft.NET.ToolPack.Tests/PackWithShimsAndResultNugetPackageNuGetPackagexFixture.cs +++ b/src/Tests/Microsoft.NET.ToolPack.Tests/PackWithShimsAndResultNugetPackageNuGetPackagexFixture.cs @@ -60,7 +60,7 @@ private string SetupNuGetPackage( nameof(NupkgOfPackWithShimsFixture) + multiTarget + targetFramework, targetFramework); - var packCommand = new PackCommand(Log, helloWorldAsset.TestRoot); + var packCommand = new PackCommand(helloWorldAsset); packCommand.Execute().Should().Pass(); return packCommand.GetNuGetPackage(packageVersion: _packageVersion); diff --git a/src/Tests/dotnet-add-package.Tests/GivenDotnetPackageAdd.cs b/src/Tests/dotnet-add-package.Tests/GivenDotnetPackageAdd.cs index 6cda61560c12..cf22c330c4e3 100644 --- a/src/Tests/dotnet-add-package.Tests/GivenDotnetPackageAdd.cs +++ b/src/Tests/dotnet-add-package.Tests/GivenDotnetPackageAdd.cs @@ -253,7 +253,7 @@ private static TestProject GetProject(string targetFramework, string referencePr private string GetPackagePath(string targetFramework, string packageName, string version, [CallerMemberName] string callingMethod = "", string identifier = null) { var project = GetProject(targetFramework, packageName, version); - var packCommand = new PackCommand(Log, _testAssetsManager.CreateTestProject(project, callingMethod: callingMethod, identifier: identifier).TestRoot, packageName); + var packCommand = new PackCommand(_testAssetsManager.CreateTestProject(project, callingMethod: callingMethod, identifier: identifier)); packCommand .Execute() diff --git a/src/Tests/dotnet-build.Tests/GivenDotnetBuildBuildsCsproj.cs b/src/Tests/dotnet-build.Tests/GivenDotnetBuildBuildsCsproj.cs index 4595ae11ffb7..7c4c7dbfb13a 100644 --- a/src/Tests/dotnet-build.Tests/GivenDotnetBuildBuildsCsproj.cs +++ b/src/Tests/dotnet-build.Tests/GivenDotnetBuildBuildsCsproj.cs @@ -40,7 +40,9 @@ public void ItBuildsARunnableOutput() var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? "Debug"; - var outputDll = Path.Combine(testInstance.Path, "bin", configuration, ToolsetInfo.CurrentTargetFramework, $"{testAppName}.dll"); + var outputPathCalculator = OutputPathCalculator.FromProject(testInstance.Path); + + var outputDll = Path.Combine(outputPathCalculator.GetOutputDirectory(configuration: configuration), $"{testAppName}.dll"); var outputRunCommand = new DotnetCommand(Log); @@ -129,7 +131,7 @@ public void ItRunsWhenRestoringToSpecificPackageDir() var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? "Debug"; var outputDll = Directory.EnumerateFiles( - Path.Combine(rootPath, "bin", configuration, ToolsetInfo.CurrentTargetFramework), "*.dll", + OutputPathCalculator.FromProject(rootPath).GetOutputDirectory(configuration: configuration), "*.dll", SearchOption.TopDirectoryOnly) .Single(); diff --git a/src/Tests/dotnet-clean.Tests/GivenDotnetCleanCleansBuildArtifacts.cs b/src/Tests/dotnet-clean.Tests/GivenDotnetCleanCleansBuildArtifacts.cs index b28789b8ca89..f4ee95482aaa 100644 --- a/src/Tests/dotnet-clean.Tests/GivenDotnetCleanCleansBuildArtifacts.cs +++ b/src/Tests/dotnet-clean.Tests/GivenDotnetCleanCleansBuildArtifacts.cs @@ -33,7 +33,7 @@ public void ItCleansAProjectBuiltWithRuntimeIdentifier() .Should().Pass(); var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? "Debug"; - var outputFolder = new DirectoryInfo(Path.Combine(testInstance.Path, "bin", configuration, ToolsetInfo.CurrentTargetFramework, $"{ToolsetInfo.LatestWinRuntimeIdentifier}-x64")); + var outputFolder = new DirectoryInfo(OutputPathCalculator.FromProject(testInstance.Path).GetOutputDirectory(configuration: configuration, runtimeIdentifier: $"{ToolsetInfo.LatestWinRuntimeIdentifier}-x64")); outputFolder.Should().NotBeEmpty(); diff --git a/src/Tests/dotnet-publish.Tests/GivenDotnetPublishPublishesProjects.cs b/src/Tests/dotnet-publish.Tests/GivenDotnetPublishPublishesProjects.cs index 1777a1d3acf2..c90594fd583d 100644 --- a/src/Tests/dotnet-publish.Tests/GivenDotnetPublishPublishesProjects.cs +++ b/src/Tests/dotnet-publish.Tests/GivenDotnetPublishPublishesProjects.cs @@ -48,7 +48,7 @@ public void ItPublishesARunnablePortableApp() .Should().Pass(); var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? _defaultConfiguration; - var outputDll = Path.Combine(testProjectDirectory, "bin", configuration, ToolsetInfo.CurrentTargetFramework, "publish", $"{testAppName}.dll"); + var outputDll = Path.Combine(OutputPathCalculator.FromProject(testProjectDirectory).GetPublishDirectory(configuration: configuration), $"{testAppName}.dll"); new DotnetCommand(Log) .Execute(outputDll) @@ -309,7 +309,7 @@ private DirectoryInfo PublishApp(string testAppName, string rid, string args = n .Should().Pass(); var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? _defaultConfiguration; - return new DirectoryInfo(Path.Combine(testProjectDirectory, "bin", configuration, ToolsetInfo.CurrentTargetFramework, rid ?? "", "publish")); + return new DirectoryInfo(OutputPathCalculator.FromProject(testProjectDirectory).GetPublishDirectory(configuration: configuration, runtimeIdentifier: rid)); } [Fact] @@ -331,7 +331,7 @@ public void ItPublishesAppWhenRestoringToSpecificPackageDirectory() var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? _defaultConfiguration; - var outputProgram = Path.Combine(rootDir, "bin", configuration, ToolsetInfo.CurrentTargetFramework, "publish", $"TestAppSimple.dll"); + var outputProgram = Path.Combine(OutputPathCalculator.FromProject(rootDir).GetPublishDirectory(configuration: configuration), $"TestAppSimple.dll"); new DotnetCommand(Log, outputProgram) .Execute() @@ -383,7 +383,7 @@ public void ItPublishesSuccessfullyWithNoBuildIfPreviouslyBuilt(bool selfContain var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? _defaultConfiguration; - var outputProgram = Path.Combine(rootPath, "bin", configuration, ToolsetInfo.CurrentTargetFramework, rid, "publish", $"TestAppSimple.dll"); + var outputProgram = Path.Combine(OutputPathCalculator.FromProject(rootPath).GetPublishDirectory(configuration: configuration, runtimeIdentifier: rid), $"TestAppSimple.dll"); new DotnetCommand(Log, outputProgram) .Execute() diff --git a/src/Tests/dotnet-sln.Tests/GivenDotnetSlnAdd.cs b/src/Tests/dotnet-sln.Tests/GivenDotnetSlnAdd.cs index c6818801dd6b..62a57fd21d2e 100644 --- a/src/Tests/dotnet-sln.Tests/GivenDotnetSlnAdd.cs +++ b/src/Tests/dotnet-sln.Tests/GivenDotnetSlnAdd.cs @@ -832,21 +832,15 @@ public void WhenValidProjectIsPassedTheSlnBuilds(string testAsset) var reasonString = "should be built in release mode, otherwise it means build configurations are missing from the sln file"; - var appReleaseDirectory = Directory.EnumerateDirectories( - Path.Combine(projectDirectory, "App", "bin"), - "Release", - SearchOption.AllDirectories); - appReleaseDirectory.Count().Should().Be(1, $"App {reasonString}"); - Directory.EnumerateFiles(appReleaseDirectory.Single(), "App.dll", SearchOption.AllDirectories) - .Count().Should().Be(1, $"App {reasonString}"); - - var libReleaseDirectory = Directory.EnumerateDirectories( - Path.Combine(projectDirectory, "Lib", "bin"), - "Release", - SearchOption.AllDirectories); - libReleaseDirectory.Count().Should().Be(1, $"Lib {reasonString}"); - Directory.EnumerateFiles(libReleaseDirectory.Single(), "Lib.dll", SearchOption.AllDirectories) - .Count().Should().Be(1, $"Lib {reasonString}"); + var appPathCalculator = OutputPathCalculator.FromProject(Path.Combine(projectDirectory, "App", "App.csproj")); + new DirectoryInfo(appPathCalculator.GetOutputDirectory(configuration: "Debug")).Should().NotExist(reasonString); + new DirectoryInfo(appPathCalculator.GetOutputDirectory(configuration: "Release")).Should().Exist() + .And.HaveFile("App.dll"); + + var libPathCalculator = OutputPathCalculator.FromProject(Path.Combine(projectDirectory, "Lib", "Lib.csproj")); + new DirectoryInfo(libPathCalculator.GetOutputDirectory(configuration: "Debug")).Should().NotExist(reasonString); + new DirectoryInfo(libPathCalculator.GetOutputDirectory(configuration: "Release")).Should().Exist() + .And.HaveFile("Lib.dll"); } [Theory] diff --git a/src/Tests/dotnet-sln.Tests/GivenDotnetSlnRemove.cs b/src/Tests/dotnet-sln.Tests/GivenDotnetSlnRemove.cs index 820f8a1a0c31..7882826505a8 100644 --- a/src/Tests/dotnet-sln.Tests/GivenDotnetSlnRemove.cs +++ b/src/Tests/dotnet-sln.Tests/GivenDotnetSlnRemove.cs @@ -619,13 +619,13 @@ public void WhenReferenceIsRemovedSlnBuilds() var reasonString = "should be built in release mode, otherwise it means build configurations are missing from the sln file"; - var releaseDirectory = Directory.EnumerateDirectories( - Path.Combine(projectDirectory, "App", "bin"), - "Release", - SearchOption.AllDirectories); - releaseDirectory.Count().Should().Be(1, $"App {reasonString}"); - Directory.EnumerateFiles(releaseDirectory.Single(), "App.dll", SearchOption.AllDirectories) - .Count().Should().Be(1, $"App {reasonString}"); + var outputCalculator = OutputPathCalculator.FromProject(Path.Combine(projectDirectory, "App")); + + new DirectoryInfo(outputCalculator.GetOutputDirectory(configuration: "Debug")).Should().NotExist(reasonString); + + var outputDirectory = new DirectoryInfo(outputCalculator.GetOutputDirectory(configuration: "Release")); + outputDirectory.Should().Exist(); + outputDirectory.Should().HaveFile("App.dll"); } [Fact] diff --git a/src/Tests/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestFromDll.cs b/src/Tests/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestFromDll.cs index d17ab2294344..758b076a2515 100644 --- a/src/Tests/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestFromDll.cs +++ b/src/Tests/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestFromDll.cs @@ -33,11 +33,13 @@ public void TestsFromAGivenContainerShouldRunWithExpectedOutput() var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? "Debug"; - new BuildCommand(testAsset) + var buildCommand = new BuildCommand(testAsset); + + buildCommand .Execute() .Should().Pass(); - var outputDll = Path.Combine(testRoot, "bin", configuration, ToolsetInfo.CurrentTargetFramework, $"{testAppName}.dll"); + var outputDll = Path.Combine(buildCommand.GetOutputDirectory(configuration: configuration).FullName, $"{testAppName}.dll"); // Call vstest var result = new DotnetTestCommand(Log) diff --git a/src/Tests/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestfromCsprojWithCorrectTestRunParameters.cs b/src/Tests/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestfromCsprojWithCorrectTestRunParameters.cs index aec125674ea2..b61e1c430700 100644 --- a/src/Tests/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestfromCsprojWithCorrectTestRunParameters.cs +++ b/src/Tests/dotnet-test.Tests/GivenDotnetTestBuildsAndRunsTestfromCsprojWithCorrectTestRunParameters.cs @@ -61,7 +61,7 @@ public void GivenADllAndMultipleTestRunParametersItPassesThemToVStestConsoleInTh .Execute() .Should().Pass(); - var outputDll = Path.Combine(testProjectDirectory, "bin", configuration, ToolsetInfo.CurrentTargetFramework, "VSTestTestRunParameters.dll"); + var outputDll = Path.Combine(OutputPathCalculator.FromProject(testProjectDirectory).GetOutputDirectory(configuration: configuration), "VSTestTestRunParameters.dll"); // Call test CommandResult result = new DotnetTestCommand(Log) diff --git a/src/Tests/dotnet-test.Tests/GivenDotnetTestContainsEnvironmentVariables.cs b/src/Tests/dotnet-test.Tests/GivenDotnetTestContainsEnvironmentVariables.cs index 3f00a0bf7322..6ed9e878e239 100644 --- a/src/Tests/dotnet-test.Tests/GivenDotnetTestContainsEnvironmentVariables.cs +++ b/src/Tests/dotnet-test.Tests/GivenDotnetTestContainsEnvironmentVariables.cs @@ -75,11 +75,13 @@ public void ItPassesEnvironmentVariablesFromCommandLineParametersWhenRunningViaD var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? "Debug"; - new BuildCommand(testAsset) + var buildCommand = new BuildCommand(testAsset); + + buildCommand .Execute() .Should().Pass(); - var outputDll = Path.Combine(testRoot, "bin", configuration, ToolsetInfo.CurrentTargetFramework, $"{TestAppName}.dll"); + var outputDll = Path.Combine(buildCommand.GetOutputDirectory(configuration: configuration).FullName, $"{TestAppName}.dll"); var result = new DotnetTestCommand(Log, EnvironmentVariables) .Execute(outputDll, $"{ConsoleLoggerOutputDetailed[0]}:{ConsoleLoggerOutputDetailed[1]}"); diff --git a/src/Tests/dotnet-vstest.Tests/VSTestTests.cs b/src/Tests/dotnet-vstest.Tests/VSTestTests.cs index a187186c6aa7..699b6874e50c 100644 --- a/src/Tests/dotnet-vstest.Tests/VSTestTests.cs +++ b/src/Tests/dotnet-vstest.Tests/VSTestTests.cs @@ -33,11 +33,13 @@ public void TestsFromAGivenContainerShouldRunWithExpectedOutput() var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? "Debug"; - new BuildCommand(testAsset) + var buildCommand = new BuildCommand(testAsset); + + buildCommand .Execute() .Should().Pass(); - var outputDll = Path.Combine(testRoot, "bin", configuration, ToolsetInfo.CurrentTargetFramework, $"{testAppName}.dll"); + var outputDll = Path.Combine(buildCommand.GetOutputDirectory(configuration: configuration).FullName, $"{testAppName}.dll"); // Call vstest var result = new DotnetVSTestCommand(Log) @@ -66,7 +68,7 @@ public void GivenADllAndMultipleTestRunParametersItPassesThemToVStestConsoleInTh .Execute() .Should().Pass(); - var outputDll = Path.Combine(testProjectDirectory, "bin", configuration, ToolsetInfo.CurrentTargetFramework, "VSTestTestRunParameters.dll"); + var outputDll = Path.Combine(OutputPathCalculator.FromProject(testProjectDirectory).GetOutputDirectory(configuration: configuration), "VSTestTestRunParameters.dll"); // Call test CommandResult result = new DotnetVSTestCommand(Log) diff --git a/src/Tests/dotnet.Tests/GivenThatICareAboutVBApps.cs b/src/Tests/dotnet.Tests/GivenThatICareAboutVBApps.cs index aaa90534e26f..c55a8ac8ba0c 100644 --- a/src/Tests/dotnet.Tests/GivenThatICareAboutVBApps.cs +++ b/src/Tests/dotnet.Tests/GivenThatICareAboutVBApps.cs @@ -49,17 +49,15 @@ public void ICanPublicAndRunVBApps() var testInstance = _testAssetsManager.CopyTestAsset("VBTestApp") .WithSource(); - new PublishCommand(Log, testInstance.Path) + var publishCommand = new PublishCommand(testInstance); + + publishCommand .Execute() .Should().Pass(); var configuration = Environment.GetEnvironmentVariable("CONFIGURATION") ?? "Debug"; var outputDll = Path.Combine( - testInstance.Path, - "bin", - configuration, - ToolsetInfo.CurrentTargetFramework, - "publish", + publishCommand.GetOutputDirectory(configuration: configuration).FullName, "VBTestApp.dll"); new DotnetCommand(Log) diff --git a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetBuildInvocation.cs b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetBuildInvocation.cs index af21b8b7fd31..9ca7422181d3 100644 --- a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetBuildInvocation.cs +++ b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetBuildInvocation.cs @@ -21,6 +21,7 @@ public class GivenDotnetBuildInvocation : IClassFixturefoo -property:_CommandLineDefinedOutputPath=true")] [InlineData(new string[] { "-property:Verbosity=diag" }, "--property:Verbosity=diag")] [InlineData(new string[] { "--output", "foo" }, "-property:OutputPath=foo -property:_CommandLineDefinedOutputPath=true")] + [InlineData(new string[] { "--artifacts-path", "foo" }, "-property:ArtifactsPath=foo")] [InlineData(new string[] { "-o", "foo1 foo2" }, "\"-property:OutputPath=foo1 foo2\" -property:_CommandLineDefinedOutputPath=true")] [InlineData(new string[] { "--no-incremental" }, "-target:Rebuild")] [InlineData(new string[] { "-r", "rid" }, "-property:RuntimeIdentifier=rid -property:_CommandLineDefinedRuntimeIdentifier=true")] diff --git a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetCleanInvocation.cs b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetCleanInvocation.cs index e86feb9dcd67..6029410bd888 100644 --- a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetCleanInvocation.cs +++ b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetCleanInvocation.cs @@ -28,6 +28,7 @@ public void ItAddsProjectToMsbuildInvocation() [InlineData(new string[] { }, "")] [InlineData(new string[] { "-o", "" }, "-property:OutputPath= -property:_CommandLineDefinedOutputPath=true")] [InlineData(new string[] { "--output", "" }, "-property:OutputPath= -property:_CommandLineDefinedOutputPath=true")] + [InlineData(new string[] { "--artifacts-path", "foo" }, "-property:ArtifactsPath=foo")] [InlineData(new string[] { "-f", "" }, "-property:TargetFramework=")] [InlineData(new string[] { "--framework", "" }, "-property:TargetFramework=")] [InlineData(new string[] { "-c", "" }, "-property:Configuration=")] diff --git a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPackInvocation.cs b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPackInvocation.cs index e9114dfed35e..973b6bc88d6d 100644 --- a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPackInvocation.cs +++ b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPackInvocation.cs @@ -26,6 +26,7 @@ public class GivenDotnetPackInvocation : IClassFixture" }, "-property:PackageOutputPath=")] [InlineData(new string[] { "--output", "" }, "-property:PackageOutputPath=")] + [InlineData(new string[] { "--artifacts-path", "foo" }, "-property:ArtifactsPath=foo")] [InlineData(new string[] { "--no-build" }, "-property:NoBuild=true")] [InlineData(new string[] { "--include-symbols" }, "-property:IncludeSymbols=true")] [InlineData(new string[] { "--include-source" }, "-property:IncludeSource=true")] diff --git a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPublishInvocation.cs b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPublishInvocation.cs index e1acd1938d46..f50495502f23 100644 --- a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPublishInvocation.cs +++ b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPublishInvocation.cs @@ -34,6 +34,7 @@ public GivenDotnetPublishInvocation(ITestOutputHelper output) [InlineData(new string[] { "--ucr" }, "-property:UseCurrentRuntimeIdentifier=True")] [InlineData(new string[] { "-o", "" }, "-property:PublishDir= -property:_CommandLineDefinedOutputPath=true")] [InlineData(new string[] { "--output", "" }, "-property:PublishDir= -property:_CommandLineDefinedOutputPath=true")] + [InlineData(new string[] { "--artifacts-path", "foo" }, "-property:ArtifactsPath=foo")] [InlineData(new string[] { "-c", "" }, "-property:Configuration= -property:DOTNET_CLI_DISABLE_PUBLISH_AND_PACK_RELEASE=true")] [InlineData(new string[] { "--configuration", "" }, "-property:Configuration= -property:DOTNET_CLI_DISABLE_PUBLISH_AND_PACK_RELEASE=true")] [InlineData(new string[] { "--version-suffix", "" }, "-property:VersionSuffix=")]