From 0fd81e0a2dc70b18a93211f5d98b6edb664e0b7b Mon Sep 17 00:00:00 2001 From: Bryan Date: Fri, 11 Mar 2016 16:41:00 -0800 Subject: [PATCH] Extract dotnet-compile-fsc into a standalone command Add basic Tests for dotnet-compile-fsc Package Targets execute before TestTargets. Use Generated Nuget Packages in TestTargets. Generate Nuget packages on all platforms, and in C# Fix bug in dotnet-restore, change fsharp new template, add support for native assets in DependencyContextCsvReader copy fsc.exe to temp directory instead of package cache fix rebase error fix issue fixes fixes fix temporarily disable debian package e2e testing fixes bump fsc version update fsc version fix rebase errors WIP update fsc tool WIP, rebased and working again, need to solve issues with System.CommandLine Working state for packaged, command, fsc.exe bugging out with dlopen(, 1): no suitable image found. execute fsc like a unpublished standalone app fixup after rebase working? internet is out working cleanup More cleanup, and run the debian package tests during the Test phase of the build. update FSharp Test Projects NetStandard Library Version Update Version Suffix when packing TestPackages. This will enable packing with the right dependency versions on Windows. update dotnet-test version Undo the reordering of the build fix test package project pathsj ignore net451 build failures for test packages which we need to build on non-windows update dependency of desktop test app add dotnetcli feed to nuget config for fsharp dotnet new update deps after rebase update dependency of dotnet-compile-fsc pass args before commandPath when using muxer for tools adjust testpackage cleaning not to clean packages which are also generated as part of the product from the nuget cache. undo Pass projectJson to pack instead of using WorkingDirectory fix path separators using depsjsoncommandresolver on windows, fix building only specific frameworks for testpackages on non-windows. PR Feedback rebase overwrite fsc runtimeconfig --- .../project.json | 2 +- .../CompileFail/project.json | 19 -- .../FSharpTestProjects/TestApp/project.json | 20 -- .../TestAppWithArgs/project.json | 19 -- .../TestLibrary/project.json | 17 -- TestAssets/FSharpTestProjects/global.json | 3 - .../CompileFailApp/.noautobuild | 0 .../CompileFailApp}/Program.fs | 0 .../CompileFailApp/project.json | 31 ++ .../FSharpTestProjects/TestApp/.noautobuild | 0 .../TestApp/FSharpTestApp.xproj | 0 .../FSharpTestProjects/TestApp/Program.fs | 0 .../FSharpTestProjects/TestApp/project.json | 39 +++ .../TestAppWithArgs/.noautobuild | 0 .../TestAppWithArgs/Program.fs | 0 .../TestAppWithArgs/project.json | 31 ++ .../TestLibrary/.noautobuild | 0 .../TestLibrary/FSharpTestLibrary.xproj | 0 .../FSharpTestProjects/TestLibrary/Helper.fs | 0 .../FSharpTestProjects/TestLibrary/Helper2.fs | 0 .../TestLibrary/project.json | 31 ++ .../FSharpTestProjects/global.json | 3 + packaging/nuget/package.ps1 | 36 --- scripts/dotnet-cli-build/CompileTargets.cs | 23 +- scripts/dotnet-cli-build/DebTargets.cs | 4 +- scripts/dotnet-cli-build/InstallerTargets.cs | 2 +- scripts/dotnet-cli-build/PackageTargets.cs | 55 +++- scripts/dotnet-cli-build/PrepareTargets.cs | 11 - .../dotnet-cli-build/TestPackageProjects.cs | 165 +++++++++++ scripts/dotnet-cli-build/TestTargets.cs | 121 ++++++-- scripts/dotnet-cli-build/Utils/Dirs.cs | 5 + scripts/package/projectsToPack.ps1 | 15 - .../CommandResolutionStrategy.cs | 3 + .../CommandResolverArguments.cs | 2 + .../DepsJsonCommandResolver.cs | 264 ++++++++++++++++++ .../DepsJsonCommandFactory.cs | 50 ++++ src/corehost/cli/fxr/fx_muxer.cpp | 2 +- src/corehost/cli/libhost.cpp | 7 +- .../dotnet-compile-fsc/Program.cs | 137 +++++++-- .../dotnet-compile-fsc.xproj | 19 ++ src/dotnet-compile-fsc/project.json | 29 ++ src/dotnet/Program.cs | 1 - .../dotnet-new/FSharp_Console/NuGet.Config | 3 + .../FSharp_Console/project.json.template | 5 + .../Assertions/CommandResultAssertions.cs | 7 - .../GivenThatIWantToCompileFSharpPrograms.cs | 66 +++++ .../dotnet-compile-fsc.Tests.xproj | 21 ++ test/dotnet-compile-fsc.Tests/project.json | 34 +++ test/dotnet.Tests/PackagedCommandTests.cs | 2 +- 49 files changed, 1066 insertions(+), 238 deletions(-) delete mode 100644 TestAssets/FSharpTestProjects/CompileFail/project.json delete mode 100644 TestAssets/FSharpTestProjects/TestApp/project.json delete mode 100644 TestAssets/FSharpTestProjects/TestAppWithArgs/project.json delete mode 100644 TestAssets/FSharpTestProjects/TestLibrary/project.json delete mode 100644 TestAssets/FSharpTestProjects/global.json create mode 100644 TestAssets/TestProjects/FSharpTestProjects/CompileFailApp/.noautobuild rename TestAssets/{FSharpTestProjects/CompileFail => TestProjects/FSharpTestProjects/CompileFailApp}/Program.fs (100%) create mode 100644 TestAssets/TestProjects/FSharpTestProjects/CompileFailApp/project.json create mode 100644 TestAssets/TestProjects/FSharpTestProjects/TestApp/.noautobuild rename TestAssets/{ => TestProjects}/FSharpTestProjects/TestApp/FSharpTestApp.xproj (100%) rename TestAssets/{ => TestProjects}/FSharpTestProjects/TestApp/Program.fs (100%) create mode 100644 TestAssets/TestProjects/FSharpTestProjects/TestApp/project.json create mode 100644 TestAssets/TestProjects/FSharpTestProjects/TestAppWithArgs/.noautobuild rename TestAssets/{ => TestProjects}/FSharpTestProjects/TestAppWithArgs/Program.fs (100%) create mode 100644 TestAssets/TestProjects/FSharpTestProjects/TestAppWithArgs/project.json create mode 100644 TestAssets/TestProjects/FSharpTestProjects/TestLibrary/.noautobuild rename TestAssets/{ => TestProjects}/FSharpTestProjects/TestLibrary/FSharpTestLibrary.xproj (100%) rename TestAssets/{ => TestProjects}/FSharpTestProjects/TestLibrary/Helper.fs (100%) rename TestAssets/{ => TestProjects}/FSharpTestProjects/TestLibrary/Helper2.fs (100%) create mode 100644 TestAssets/TestProjects/FSharpTestProjects/TestLibrary/project.json create mode 100644 TestAssets/TestProjects/FSharpTestProjects/global.json delete mode 100644 packaging/nuget/package.ps1 create mode 100644 scripts/dotnet-cli-build/TestPackageProjects.cs create mode 100644 src/Microsoft.DotNet.Cli.Utils/CommandResolution/DepsJsonCommandResolver.cs create mode 100644 src/Microsoft.DotNet.Cli.Utils/DepsJsonCommandFactory.cs rename src/{dotnet/commands => }/dotnet-compile-fsc/Program.cs (70%) create mode 100644 src/dotnet-compile-fsc/dotnet-compile-fsc.xproj create mode 100644 src/dotnet-compile-fsc/project.json create mode 100644 test/dotnet-compile-fsc.Tests/GivenThatIWantToCompileFSharpPrograms.cs create mode 100644 test/dotnet-compile-fsc.Tests/dotnet-compile-fsc.Tests.xproj create mode 100644 test/dotnet-compile-fsc.Tests/project.json diff --git a/TestAssets/DesktopTestProjects/AppWithDirectDependencyDesktopAndPortable/project.json b/TestAssets/DesktopTestProjects/AppWithDirectDependencyDesktopAndPortable/project.json index f4799dbc9..1dbf645ce 100644 --- a/TestAssets/DesktopTestProjects/AppWithDirectDependencyDesktopAndPortable/project.json +++ b/TestAssets/DesktopTestProjects/AppWithDirectDependencyDesktopAndPortable/project.json @@ -4,7 +4,7 @@ "emitEntryPoint": true }, "dependencies": { - "dotnet-desktop-and-portable": "1.0.0" + "dotnet-desktop-and-portable": "1.0.0-*" }, "frameworks": { "netstandardapp1.5": { diff --git a/TestAssets/FSharpTestProjects/CompileFail/project.json b/TestAssets/FSharpTestProjects/CompileFail/project.json deleted file mode 100644 index 1409f11f4..000000000 --- a/TestAssets/FSharpTestProjects/CompileFail/project.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "version": "1.0.0-*", - "compilationOptions": { - "emitEntryPoint": true - }, - "compilerName": "fsc", - "compileFiles": [ - "Program.fs" - ], - "dependencies": { - "Microsoft.FSharp.Core.netcore": "1.0.0-alpha-151221", - "NETStandard.Library": "1.5.0-rc2-23931" - }, - "frameworks": { - "netstandardapp1.5": { - "imports": "dnxcore50" - } - } -} diff --git a/TestAssets/FSharpTestProjects/TestApp/project.json b/TestAssets/FSharpTestProjects/TestApp/project.json deleted file mode 100644 index ae811983a..000000000 --- a/TestAssets/FSharpTestProjects/TestApp/project.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": "1.0.0-*", - "compilationOptions": { - "emitEntryPoint": true - }, - "compilerName": "fsc", - "compileFiles": [ - "Program.fs" - ], - "dependencies": { - "TestLibrary": "1.0.0-*", - "NETStandard.Library": "1.5.0-rc2-23931", - "Microsoft.FSharp.Core.netcore": "1.0.0-alpha-151221" - }, - "frameworks": { - "netstandardapp1.5": { - "imports": "dnxcore50" - } - } -} diff --git a/TestAssets/FSharpTestProjects/TestAppWithArgs/project.json b/TestAssets/FSharpTestProjects/TestAppWithArgs/project.json deleted file mode 100644 index 1409f11f4..000000000 --- a/TestAssets/FSharpTestProjects/TestAppWithArgs/project.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "version": "1.0.0-*", - "compilationOptions": { - "emitEntryPoint": true - }, - "compilerName": "fsc", - "compileFiles": [ - "Program.fs" - ], - "dependencies": { - "Microsoft.FSharp.Core.netcore": "1.0.0-alpha-151221", - "NETStandard.Library": "1.5.0-rc2-23931" - }, - "frameworks": { - "netstandardapp1.5": { - "imports": "dnxcore50" - } - } -} diff --git a/TestAssets/FSharpTestProjects/TestLibrary/project.json b/TestAssets/FSharpTestProjects/TestLibrary/project.json deleted file mode 100644 index c2c6d67fb..000000000 --- a/TestAssets/FSharpTestProjects/TestLibrary/project.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": "1.0.0-*", - "dependencies": { - "Microsoft.FSharp.Core.netcore": "1.0.0-alpha-151221", - "NETStandard.Library": "1.5.0-rc2-23931" - }, - "compilerName": "fsc", - "compileFiles": [ - "Helper2.fs", - "Helper.fs" - ], - "frameworks": { - "netstandardapp1.5": { - "imports": "dnxcore50" - } - } -} diff --git a/TestAssets/FSharpTestProjects/global.json b/TestAssets/FSharpTestProjects/global.json deleted file mode 100644 index 98b00dc4e..000000000 --- a/TestAssets/FSharpTestProjects/global.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "projects": [ ".", "../../src" ] -} diff --git a/TestAssets/TestProjects/FSharpTestProjects/CompileFailApp/.noautobuild b/TestAssets/TestProjects/FSharpTestProjects/CompileFailApp/.noautobuild new file mode 100644 index 000000000..e69de29bb diff --git a/TestAssets/FSharpTestProjects/CompileFail/Program.fs b/TestAssets/TestProjects/FSharpTestProjects/CompileFailApp/Program.fs similarity index 100% rename from TestAssets/FSharpTestProjects/CompileFail/Program.fs rename to TestAssets/TestProjects/FSharpTestProjects/CompileFailApp/Program.fs diff --git a/TestAssets/TestProjects/FSharpTestProjects/CompileFailApp/project.json b/TestAssets/TestProjects/FSharpTestProjects/CompileFailApp/project.json new file mode 100644 index 000000000..e9c499f79 --- /dev/null +++ b/TestAssets/TestProjects/FSharpTestProjects/CompileFailApp/project.json @@ -0,0 +1,31 @@ +{ + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": true + }, + "compilerName": "fsc", + "compileFiles": [ + "Program.fs" + ], + "dependencies": { + "Microsoft.FSharp.Core.netcore": "1.0.0-alpha-151221", + "NETStandard.Library": "1.5.0-rc2-23931" + }, + + "tools": { + "dotnet-compile-fsc": { + "version": "1.0.0-*", + "imports": [ + "dnxcore50", + "portable-net45+win81", + "netstandard1.3" + ] + } + }, + + "frameworks": { + "netstandardapp1.5": { + "imports": ["dnxcore50", "netstandard1.3"] + } + } +} diff --git a/TestAssets/TestProjects/FSharpTestProjects/TestApp/.noautobuild b/TestAssets/TestProjects/FSharpTestProjects/TestApp/.noautobuild new file mode 100644 index 000000000..e69de29bb diff --git a/TestAssets/FSharpTestProjects/TestApp/FSharpTestApp.xproj b/TestAssets/TestProjects/FSharpTestProjects/TestApp/FSharpTestApp.xproj similarity index 100% rename from TestAssets/FSharpTestProjects/TestApp/FSharpTestApp.xproj rename to TestAssets/TestProjects/FSharpTestProjects/TestApp/FSharpTestApp.xproj diff --git a/TestAssets/FSharpTestProjects/TestApp/Program.fs b/TestAssets/TestProjects/FSharpTestProjects/TestApp/Program.fs similarity index 100% rename from TestAssets/FSharpTestProjects/TestApp/Program.fs rename to TestAssets/TestProjects/FSharpTestProjects/TestApp/Program.fs diff --git a/TestAssets/TestProjects/FSharpTestProjects/TestApp/project.json b/TestAssets/TestProjects/FSharpTestProjects/TestApp/project.json new file mode 100644 index 000000000..60b0f771a --- /dev/null +++ b/TestAssets/TestProjects/FSharpTestProjects/TestApp/project.json @@ -0,0 +1,39 @@ +{ + "version": "1.0.0-*", + + "compilationOptions": { + "emitEntryPoint": true + }, + + "compilerName": "fsc", + + "compileFiles": [ + "Program.fs" + ], + "dependencies": { + "TestLibrary": { + "version": "1.0.0-*", + "target": "project" + }, + "NETStandard.Library": "1.5.0-rc2-23931", + "Microsoft.FSharp.Core.netcore": "1.0.0-alpha-151221" + }, + + "tools": { + "dotnet-compile-fsc": { + "version": "1.0.0-*", + "imports": [ + "dnxcore50", + "portable-net45+win81", + "netstandard1.3" + ] + } + }, + + "frameworks": { + "netstandardapp1.5": { + "imports": "dnxcore50" + } + } + +} diff --git a/TestAssets/TestProjects/FSharpTestProjects/TestAppWithArgs/.noautobuild b/TestAssets/TestProjects/FSharpTestProjects/TestAppWithArgs/.noautobuild new file mode 100644 index 000000000..e69de29bb diff --git a/TestAssets/FSharpTestProjects/TestAppWithArgs/Program.fs b/TestAssets/TestProjects/FSharpTestProjects/TestAppWithArgs/Program.fs similarity index 100% rename from TestAssets/FSharpTestProjects/TestAppWithArgs/Program.fs rename to TestAssets/TestProjects/FSharpTestProjects/TestAppWithArgs/Program.fs diff --git a/TestAssets/TestProjects/FSharpTestProjects/TestAppWithArgs/project.json b/TestAssets/TestProjects/FSharpTestProjects/TestAppWithArgs/project.json new file mode 100644 index 000000000..ff70fb64f --- /dev/null +++ b/TestAssets/TestProjects/FSharpTestProjects/TestAppWithArgs/project.json @@ -0,0 +1,31 @@ +{ + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": true + }, + "compilerName": "fsc", + "compileFiles": [ + "Program.fs" + ], + "dependencies": { + "Microsoft.FSharp.Core.netcore": "1.0.0-alpha-151221", + "NETStandard.Library": "1.5.0-rc2-23931" + }, + + "tools": { + "dotnet-compile-fsc": { + "version": "1.0.0-*", + "imports": [ + "dnxcore50", + "portable-net45+win81", + "netstandard1.3" + ] + } + }, + + "frameworks": { + "netstandardapp1.5": { + "imports": "dnxcore50" + } + } +} diff --git a/TestAssets/TestProjects/FSharpTestProjects/TestLibrary/.noautobuild b/TestAssets/TestProjects/FSharpTestProjects/TestLibrary/.noautobuild new file mode 100644 index 000000000..e69de29bb diff --git a/TestAssets/FSharpTestProjects/TestLibrary/FSharpTestLibrary.xproj b/TestAssets/TestProjects/FSharpTestProjects/TestLibrary/FSharpTestLibrary.xproj similarity index 100% rename from TestAssets/FSharpTestProjects/TestLibrary/FSharpTestLibrary.xproj rename to TestAssets/TestProjects/FSharpTestProjects/TestLibrary/FSharpTestLibrary.xproj diff --git a/TestAssets/FSharpTestProjects/TestLibrary/Helper.fs b/TestAssets/TestProjects/FSharpTestProjects/TestLibrary/Helper.fs similarity index 100% rename from TestAssets/FSharpTestProjects/TestLibrary/Helper.fs rename to TestAssets/TestProjects/FSharpTestProjects/TestLibrary/Helper.fs diff --git a/TestAssets/FSharpTestProjects/TestLibrary/Helper2.fs b/TestAssets/TestProjects/FSharpTestProjects/TestLibrary/Helper2.fs similarity index 100% rename from TestAssets/FSharpTestProjects/TestLibrary/Helper2.fs rename to TestAssets/TestProjects/FSharpTestProjects/TestLibrary/Helper2.fs diff --git a/TestAssets/TestProjects/FSharpTestProjects/TestLibrary/project.json b/TestAssets/TestProjects/FSharpTestProjects/TestLibrary/project.json new file mode 100644 index 000000000..265e2d41e --- /dev/null +++ b/TestAssets/TestProjects/FSharpTestProjects/TestLibrary/project.json @@ -0,0 +1,31 @@ +{ + "version": "1.0.0-*", + "dependencies": { + "Microsoft.FSharp.Core.netcore": "1.0.0-alpha-151221", + "NETStandard.Library": "1.5.0-rc2-23931" + }, + + "compilerName": "fsc", + + "compileFiles": [ + "Helper2.fs", + "Helper.fs" + ], + + "tools": { + "dotnet-compile-fsc": { + "version": "1.0.0-*", + "imports": [ + "dnxcore50", + "portable-net45+win81", + "netstandard1.3" + ] + } + }, + + "frameworks": { + "netstandardapp1.5": { + "imports": "dnxcore50" + } + } +} diff --git a/TestAssets/TestProjects/FSharpTestProjects/global.json b/TestAssets/TestProjects/FSharpTestProjects/global.json new file mode 100644 index 000000000..9e455db71 --- /dev/null +++ b/TestAssets/TestProjects/FSharpTestProjects/global.json @@ -0,0 +1,3 @@ +{ + "projects": [ ".", "../../../src" ] +} diff --git a/packaging/nuget/package.ps1 b/packaging/nuget/package.ps1 deleted file mode 100644 index b08fd21f3..000000000 --- a/packaging/nuget/package.ps1 +++ /dev/null @@ -1,36 +0,0 @@ -# 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. - -param( - [Parameter(Mandatory=$true)][string]$toolsDir, - [string]$versionSuffix = "" -) - -# unify trailing backslash -$toolsDir = $toolsDir.TrimEnd('\') -$versionArg = "" -if ($versionSuffix -ne "") { - $versionArg = "--version-suffix" -} - -$RepoRoot = Convert-Path "$PSScriptRoot\..\.." - -. "$RepoRoot\scripts\common\_common.ps1" -. "$RepoRoot\scripts\package\projectsToPack.ps1" - -$IntermediatePackagesDir = "$RepoRoot\artifacts\packages\intermediate" -$PackagesDir = "$RepoRoot\artifacts\packages" - -New-Item -ItemType Directory -Force -Path $IntermediatePackagesDir - -foreach ($ProjectName in $ProjectsToPack) { - $ProjectFile = "$RepoRoot\src\$ProjectName\project.json" - - & $toolsDir\dotnet pack "$ProjectFile" --no-build --build-base-path "$Stage2CompilationDir\forPackaging" --output "$IntermediatePackagesDir" --configuration "$env:CONFIGURATION" $versionArg $versionSuffix - if (!$?) { - Write-Host "$toolsDir\dotnet pack failed for: $ProjectFile" - Exit 1 - } -} - -Get-ChildItem $IntermediatePackagesDir -Filter *.nupkg | ? {$_.Name -NotLike "*.symbols.nupkg"} | Copy-Item -Destination $PackagesDir diff --git a/scripts/dotnet-cli-build/CompileTargets.cs b/scripts/dotnet-cli-build/CompileTargets.cs index ff4d85168..79fccf0b3 100644 --- a/scripts/dotnet-cli-build/CompileTargets.cs +++ b/scripts/dotnet-cli-build/CompileTargets.cs @@ -33,16 +33,6 @@ namespace Microsoft.DotNet.Cli.Build "vbc.exe" }; - public static readonly string[] ProjectsToPack = new[] - { - "Microsoft.DotNet.Cli.Utils", - "Microsoft.DotNet.ProjectModel", - "Microsoft.DotNet.ProjectModel.Loader", - "Microsoft.DotNet.ProjectModel.Workspaces", - "Microsoft.Extensions.DependencyModel", - "Microsoft.Extensions.Testing.Abstractions" - }; - public const string SharedFrameworkName = "Microsoft.NETCore.App"; private static string CoreHostBaseName => $"corehost{Constants.ExeSuffix}"; @@ -282,22 +272,23 @@ namespace Microsoft.DotNet.Cli.Build return result; } - // Build projects that are packed in NuGet packages, but only on Windows - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (CurrentPlatform.IsWindows) { + // build projects for nuget packages var packagingOutputDir = Path.Combine(Dirs.Stage2Compilation, "forPackaging"); Mkdirp(packagingOutputDir); - foreach (var project in ProjectsToPack) + foreach (var project in PackageTargets.ProjectsToPack) { // Just build them, we'll pack later - DotNetCli.Stage1.Build( + var packBuildResult = DotNetCli.Stage1.Build( "--build-base-path", packagingOutputDir, "--configuration", configuration, Path.Combine(c.BuildContext.BuildDirectory, "src", project)) - .Execute() - .EnsureSuccessful(); + .Execute(); + + packBuildResult.EnsureSuccessful(); } } diff --git a/scripts/dotnet-cli-build/DebTargets.cs b/scripts/dotnet-cli-build/DebTargets.cs index 532c53429..685e0d4f0 100644 --- a/scripts/dotnet-cli-build/DebTargets.cs +++ b/scripts/dotnet-cli-build/DebTargets.cs @@ -128,7 +128,7 @@ namespace Microsoft.DotNet.Cli.Build return c.Success(); } - [Target] + [Target(nameof(InstallSharedHost))] public static BuildTargetResult InstallSharedFramework(BuildTargetContext c) { InstallPackage(c.BuildContext.Get("SharedFrameworkInstallerFile")); @@ -136,7 +136,7 @@ namespace Microsoft.DotNet.Cli.Build return c.Success(); } - [Target] + [Target(nameof(InstallSharedFramework))] public static BuildTargetResult InstallSDK(BuildTargetContext c) { InstallPackage(c.BuildContext.Get("SdkInstallerFile")); diff --git a/scripts/dotnet-cli-build/InstallerTargets.cs b/scripts/dotnet-cli-build/InstallerTargets.cs index d90bd4fb6..fcea28e86 100644 --- a/scripts/dotnet-cli-build/InstallerTargets.cs +++ b/scripts/dotnet-cli-build/InstallerTargets.cs @@ -20,7 +20,7 @@ namespace Microsoft.DotNet.Cli.Build { return c.Success(); } - + [Target(nameof(DebTargets.TestDebInstaller))] public static BuildTargetResult TestInstaller(BuildTargetContext c) diff --git a/scripts/dotnet-cli-build/PackageTargets.cs b/scripts/dotnet-cli-build/PackageTargets.cs index d4e532da4..40bc5e3bc 100644 --- a/scripts/dotnet-cli-build/PackageTargets.cs +++ b/scripts/dotnet-cli-build/PackageTargets.cs @@ -12,6 +12,20 @@ namespace Microsoft.DotNet.Cli.Build { public static class PackageTargets { + public static readonly string[] ProjectsToPack = new string[] + { + "Microsoft.DotNet.Cli.Utils", + "Microsoft.DotNet.ProjectModel", + "Microsoft.DotNet.ProjectModel.Loader", + "Microsoft.DotNet.ProjectModel.Workspaces", + "Microsoft.DotNet.InternalAbstractions", + "Microsoft.Extensions.DependencyModel", + "Microsoft.Extensions.Testing.Abstractions", + "Microsoft.DotNet.Compiler.Common", + "Microsoft.DotNet.Files", + "dotnet-compile-fsc" + }; + [Target(nameof(PackageTargets.CopyCLISDKLayout), nameof(PackageTargets.CopySharedHostLayout), nameof(PackageTargets.CopySharedFxLayout), @@ -28,8 +42,8 @@ namespace Microsoft.DotNet.Cli.Build nameof(PackageTargets.GenerateVersionBadge), nameof(PackageTargets.GenerateCompressedFile), nameof(InstallerTargets.GenerateInstaller), - nameof(InstallerTargets.TestInstaller), - nameof(PackageTargets.GenerateNugetPackages))] + nameof(PackageTargets.GenerateNugetPackages), + nameof(InstallerTargets.TestInstaller))] [Environment("DOTNET_BUILD_SKIP_PACKAGING", null, "0", "false")] public static BuildTargetResult Package(BuildTargetContext c) { @@ -175,16 +189,45 @@ namespace Microsoft.DotNet.Cli.Build } [Target] - [BuildPlatforms(BuildPlatform.Windows)] public static BuildTargetResult GenerateNugetPackages(BuildTargetContext c) { var versionSuffix = c.BuildContext.Get("BuildVersion").VersionSuffix; + var configuration = c.BuildContext.Get("Configuration"); + var env = GetCommonEnvVars(c); - Cmd("powershell", "-NoProfile", "-NoLogo", - Path.Combine(Dirs.RepoRoot, "packaging", "nuget", "package.ps1"), Dirs.Stage2, versionSuffix) - .Environment(env) + var dotnet = DotNetCli.Stage2; + + var packagingBuildBasePath = Path.Combine(Dirs.Stage2Compilation, "forPackaging"); + + FS.Mkdirp(Dirs.PackagesIntermediate); + FS.Mkdirp(Dirs.Packages); + + foreach (var projectName in ProjectsToPack) + { + var projectFile = Path.Combine(Dirs.RepoRoot, "src", projectName, "project.json"); + + dotnet.Pack( + projectFile, + "--no-build", + "--build-base-path", packagingBuildBasePath, + "--output", Dirs.PackagesIntermediate, + "--configuration", configuration, + "--version-suffix", versionSuffix) .Execute() .EnsureSuccessful(); + } + + var packageFiles = Directory.EnumerateFiles(Dirs.PackagesIntermediate, "*.nupkg"); + + foreach (var packageFile in packageFiles) + { + if (!packageFile.EndsWith(".symbols.nupkg")) + { + var destinationPath = Path.Combine(Dirs.Packages, Path.GetFileName(packageFile)); + File.Copy(packageFile, destinationPath, overwrite: true); + } + } + return c.Success(); } diff --git a/scripts/dotnet-cli-build/PrepareTargets.cs b/scripts/dotnet-cli-build/PrepareTargets.cs index 2faad973b..d65df0094 100644 --- a/scripts/dotnet-cli-build/PrepareTargets.cs +++ b/scripts/dotnet-cli-build/PrepareTargets.cs @@ -345,17 +345,6 @@ cmake is required to build the native host 'corehost'"; throw new InvalidOperationException("Unable to match the version name from " + pathToProjectJson); } - private static bool AptPackageIsInstalled(string packageName) - { - var result = Command.Create("dpkg", "-s", packageName) - .CaptureStdOut() - .CaptureStdErr() - .QuietBuildReporter() - .Execute(); - - return result.ExitCode == 0; - } - private static IDictionary ReadBranchInfo(BuildTargetContext c, string path) { var lines = File.ReadAllLines(path); diff --git a/scripts/dotnet-cli-build/TestPackageProjects.cs b/scripts/dotnet-cli-build/TestPackageProjects.cs new file mode 100644 index 000000000..b15db4705 --- /dev/null +++ b/scripts/dotnet-cli-build/TestPackageProjects.cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using Microsoft.DotNet.Cli.Build.Framework; + +using static Microsoft.DotNet.Cli.Build.FS; +using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers; +using static Microsoft.DotNet.Cli.Build.Utils; + +namespace Microsoft.DotNet.Cli.Build +{ + public static class TestPackageProjects + { + private static string s_testPackageBuildVersionSuffix = ""; + + public static string TestPackageBuildVersionSuffix + { + get + { + return s_testPackageBuildVersionSuffix; + } + } + + public static readonly dynamic[] Projects = new[] + { + new + { + Name = "dotnet-dependency-tool-invoker", + IsTool = true, + Path = "TestAssets/TestPackages/dotnet-dependency-tool-invoker", + IsApplicable = new Func(() => CurrentPlatform.IsWindows), + VersionSuffix = s_testPackageBuildVersionSuffix, + Clean = true + }, + new + { + Name = "dotnet-desktop-and-portable", + IsTool = true, + Path = "TestAssets/TestPackages/dotnet-desktop-and-portable", + IsApplicable = new Func(() => CurrentPlatform.IsWindows), + VersionSuffix = s_testPackageBuildVersionSuffix, + Clean = true + }, + new + { + Name = "dotnet-hello", + IsTool = true, + Path = "TestAssets/TestPackages/dotnet-hello/v1/dotnet-hello", + IsApplicable = new Func(() => true), + VersionSuffix = string.Empty, + Clean = true + }, + new + { + Name = "dotnet-hello", + IsTool = true, + Path = "TestAssets/TestPackages/dotnet-hello/v2/dotnet-hello", + IsApplicable = new Func(() => true), + VersionSuffix = string.Empty, + Clean = true + }, + new + { + Name = "dotnet-portable", + IsTool = true, + Path = "TestAssets/TestPackages/dotnet-portable", + IsApplicable = new Func(() => true), + VersionSuffix = string.Empty, + Clean = true + }, + new + { + Name = "Microsoft.DotNet.Cli.Utils", + IsTool = true, + Path = "src/Microsoft.DotNet.Cli.Utils", + IsApplicable = new Func(() => true), + VersionSuffix = s_testPackageBuildVersionSuffix, + Clean = false + }, + new + { + Name = "Microsoft.DotNet.ProjectModel", + IsTool = true, + Path = "src/Microsoft.DotNet.ProjectModel", + IsApplicable = new Func(() => true), + VersionSuffix = s_testPackageBuildVersionSuffix, + Clean = false + }, + new + { + Name = "Microsoft.DotNet.ProjectModel.Loader", + IsTool = true, + Path = "src/Microsoft.DotNet.ProjectModel.Loader", + IsApplicable = new Func(() => true), + VersionSuffix = s_testPackageBuildVersionSuffix, + Clean = false + }, + new + { + Name = "Microsoft.DotNet.ProjectModel.Workspaces", + IsTool = true, + Path = "src/Microsoft.DotNet.ProjectModel.Workspaces", + IsApplicable = new Func(() => true), + VersionSuffix = s_testPackageBuildVersionSuffix, + Clean = false + }, + new + { + Name = "Microsoft.DotNet.InternalAbstractions", + IsTool = true, + Path = "src/Microsoft.DotNet.InternalAbstractions", + IsApplicable = new Func(() => true), + VersionSuffix = s_testPackageBuildVersionSuffix, + Clean = false + }, + new + { + Name = "Microsoft.Extensions.DependencyModel", + IsTool = true, + Path = "src/Microsoft.Extensions.DependencyModel", + IsApplicable = new Func(() => true), + VersionSuffix = s_testPackageBuildVersionSuffix, + Clean = false + }, + new + { + Name = "Microsoft.Extensions.Testing.Abstractions", + IsTool = true, + Path = "src/Microsoft.Extensions.Testing.Abstractions", + IsApplicable = new Func(() => true), + VersionSuffix = s_testPackageBuildVersionSuffix, + Clean = false + }, + new + { + Name = "Microsoft.DotNet.Compiler.Common", + IsTool = true, + Path = "src/Microsoft.DotNet.Compiler.Common", + IsApplicable = new Func(() => true), + VersionSuffix = s_testPackageBuildVersionSuffix, + Clean = false + }, + new + { + Name = "Microsoft.DotNet.Files", + IsTool = true, + Path = "src/Microsoft.DotNet.Files", + IsApplicable = new Func(() => true), + VersionSuffix = s_testPackageBuildVersionSuffix, + Clean = false + }, + new + { + Name = "dotnet-compile-fsc", + IsTool = true, + Path = "src/dotnet-compile-fsc", + IsApplicable = new Func(() => true), + VersionSuffix = s_testPackageBuildVersionSuffix, + Clean = true + } + }; + } +} \ No newline at end of file diff --git a/scripts/dotnet-cli-build/TestTargets.cs b/scripts/dotnet-cli-build/TestTargets.cs index 32c31aea2..13c197f0b 100644 --- a/scripts/dotnet-cli-build/TestTargets.cs +++ b/scripts/dotnet-cli-build/TestTargets.cs @@ -13,20 +13,7 @@ namespace Microsoft.DotNet.Cli.Build { public class TestTargets { - public static readonly dynamic[] TestPackageProjects = new[] - { - new { Name = "Microsoft.DotNet.Cli.Utils", IsTool = false, Path = "src/Microsoft.DotNet.Cli.Utils", IsApplicable = new Func(() => CurrentPlatform.IsWindows) }, - new { Name = "Microsoft.DotNet.ProjectModel", IsTool = false, Path = "src/Microsoft.DotNet.ProjectModel", IsApplicable = new Func(() => CurrentPlatform.IsWindows) }, - new { Name = "Microsoft.DotNet.Compiler.Common", IsTool = false, Path = "src/Microsoft.DotNet.Compiler.Common", IsApplicable = new Func(() => CurrentPlatform.IsWindows) }, - new { Name = "Microsoft.Extensions.DependencyModel", IsTool = false, Path = "src/Microsoft.Extensions.DependencyModel", IsApplicable = new Func(() => CurrentPlatform.IsWindows) }, - new { Name = "Microsoft.DotNet.Files", IsTool = false, Path = "src/Microsoft.DotNet.Files", IsApplicable = new Func(() => CurrentPlatform.IsWindows) }, - new { Name = "Microsoft.DotNet.InternalAbstractions", IsTool = false, Path = "src/Microsoft.DotNet.InternalAbstractions", IsApplicable = new Func(() => CurrentPlatform.IsWindows) }, - new { Name = "dotnet-dependency-tool-invoker", IsTool = true, Path = "TestAssets/TestPackages/dotnet-dependency-tool-invoker", IsApplicable = new Func(() => CurrentPlatform.IsWindows) }, - new { Name = "dotnet-desktop-and-portable", IsTool = true, Path = "TestAssets/TestPackages/dotnet-desktop-and-portable", IsApplicable = new Func(() => CurrentPlatform.IsWindows) }, - new { Name = "dotnet-hello", IsTool = true, Path = "TestAssets/TestPackages/dotnet-hello/v1/dotnet-hello", IsApplicable = new Func(() => true) }, - new { Name = "dotnet-hello", IsTool = true, Path = "TestAssets/TestPackages/dotnet-hello/v2/dotnet-hello", IsApplicable = new Func(() => true) }, - new { Name = "dotnet-portable", IsTool = true, Path = "TestAssets/TestPackages/dotnet-portable", IsApplicable = new Func(() => true) } - }; + private static string s_testPackageBuildVersionSuffix = ""; public static readonly string[] TestProjects = new[] { @@ -35,6 +22,7 @@ namespace Microsoft.DotNet.Cli.Build "dotnet-publish.Tests", "dotnet-compile.Tests", "dotnet-compile.UnitTests", + "dotnet-compile-fsc.Tests", "dotnet-build.Tests", "dotnet-pack.Tests", "dotnet-projectmodel-server.Tests", @@ -54,7 +42,13 @@ namespace Microsoft.DotNet.Cli.Build new { Path = "AppWithDirectDependencyDesktopAndPortable", Skip = new Func(() => !CurrentPlatform.IsWindows) } }; - [Target(nameof(PrepareTargets.Init), nameof(SetupTests), nameof(RestoreTests), nameof(BuildTests), nameof(RunTests), nameof(ValidateDependencies))] + [Target( + nameof(PrepareTargets.Init), + nameof(SetupTests), + nameof(RestoreTests), + nameof(BuildTests), + nameof(RunTests), + nameof(ValidateDependencies))] public static BuildTargetResult Test(BuildTargetContext c) => c.Success(); [Target(nameof(SetupTestPackages), nameof(SetupTestProjects))] @@ -75,7 +69,10 @@ namespace Microsoft.DotNet.Cli.Build CleanNuGetTempCache(); var dotnet = DotNetCli.Stage2; - dotnet.Restore("--verbosity", "verbose", "--infer-runtimes", "--disable-parallel").WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "TestPackages")).Execute().EnsureSuccessful(); + dotnet.Restore("--verbosity", "verbose", "--infer-runtimes", "--disable-parallel") + .WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "TestPackages")) + .Execute() + .EnsureSuccessful(); return c.Success(); } @@ -89,17 +86,26 @@ namespace Microsoft.DotNet.Cli.Build CleanNuGetTempCache(); var dotnet = DotNetCli.Stage2; - - dotnet.Restore("--verbosity", "verbose", "--disable-parallel", "--infer-runtimes", "--fallbacksource", Dirs.TestPackages) + dotnet.Restore( + "--verbosity", "verbose", + "--disable-parallel", + "--infer-runtimes", + "--fallbacksource", Dirs.TestPackages) .WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "TestProjects")) .Execute().EnsureSuccessful(); // The 'ProjectModelServer' directory contains intentionally-unresolved dependencies, so don't check for success. Also, suppress the output - dotnet.Restore("--verbosity", "verbose", "--disable-parallel", "--infer-runtimes") + dotnet.Restore( + "--verbosity", "verbose", + "--disable-parallel", + "--infer-runtimes") .WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "ProjectModelServer", "DthTestProjects")) .Execute(); - dotnet.Restore("--verbosity", "verbose", "--disable-parallel", "--infer-runtimes") + dotnet.Restore( + "--verbosity", "verbose", + "--disable-parallel", + "--infer-runtimes") .WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "ProjectModelServer", "DthUpdateSearchPathSample")) .Execute(); @@ -112,14 +118,16 @@ namespace Microsoft.DotNet.Cli.Build { var dotnet = DotNetCli.Stage2; - dotnet.Restore("--verbosity", "verbose", "--disable-parallel", "--infer-runtimes", "--fallbacksource", Dirs.TestPackages) + dotnet.Restore("--verbosity", "verbose", + "--disable-parallel", "--infer-runtimes", + "--fallbacksource", Dirs.TestPackages) .WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "DesktopTestProjects")) .Execute().EnsureSuccessful(); return c.Success(); } - [Target(nameof(CleanTestPackages))] + [Target(nameof(CleanTestPackages), nameof(CleanProductPackages))] public static BuildTargetResult BuildTestAssetPackages(BuildTargetContext c) { CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "TestPackages")); @@ -129,12 +137,62 @@ namespace Microsoft.DotNet.Cli.Build Rmdir(Dirs.TestPackages); Mkdirp(Dirs.TestPackages); - foreach (var relativePath in TestPackageProjects.Where(p => p.IsApplicable()).Select(p => p.Path)) + foreach (var testPackageProject in TestPackageProjects.Projects.Where(p => p.IsApplicable())) { + var relativePath = testPackageProject.Path; + + var versionSuffix = testPackageProject.VersionSuffix; + if (versionSuffix.Equals(s_testPackageBuildVersionSuffix)) + { + versionSuffix = c.BuildContext.Get("BuildVersion").VersionSuffix; + } + var fullPath = Path.Combine(c.BuildContext.BuildDirectory, relativePath.Replace('/', Path.DirectorySeparatorChar)); c.Info($"Packing: {fullPath}"); - dotnet.Pack("--output", Dirs.TestPackages) - .WorkingDirectory(fullPath) + + // build and ignore failure, so net451 fail on non-windows doesn't crash the build + var packageBuildFrameworks = new List() + { + "netstandard1.5", + "netstandard1.3", + "netstandardapp1.5" + }; + + if (CurrentPlatform.IsWindows) + { + packageBuildFrameworks.Add("net451"); + } + + foreach (var packageBuildFramework in packageBuildFrameworks) + { + var buildArgs = new List(); + buildArgs.Add("-f"); + buildArgs.Add(packageBuildFramework); + buildArgs.Add("--build-base-path"); + buildArgs.Add(Dirs.TestPackagesBuild); + buildArgs.Add(fullPath); + + Mkdirp(Dirs.TestPackagesBuild); + var packBuildResult = DotNetCli.Stage1.Build(buildArgs.ToArray()) + .Execute(); + } + + + var projectJson = Path.Combine(fullPath, "project.json"); + var dotnetPackArgs = new List { + projectJson, + "--no-build", + "--build-base-path", Dirs.TestPackagesBuild, + "--output", Dirs.TestPackages + }; + + if (!string.IsNullOrEmpty(versionSuffix)) + { + dotnetPackArgs.Add("--version-suffix"); + dotnetPackArgs.Add(versionSuffix); + } + + dotnet.Pack(dotnetPackArgs.ToArray()) .Execute() .EnsureSuccessful(); } @@ -142,10 +200,21 @@ namespace Microsoft.DotNet.Cli.Build return c.Success(); } + [Target] + public static BuildTargetResult CleanProductPackages(BuildTargetContext c) + { + foreach (var packageName in PackageTargets.ProjectsToPack) + { + Rmdir(Path.Combine(Dirs.NuGetPackages, packageName)); + } + + return c.Success(); + } + [Target] public static BuildTargetResult CleanTestPackages(BuildTargetContext c) { - foreach (var packageProject in TestPackageProjects.Where(p => p.IsApplicable())) + foreach (var packageProject in TestPackageProjects.Projects.Where(p => p.IsApplicable() && p.Clean)) { Rmdir(Path.Combine(Dirs.NuGetPackages, packageProject.Name)); if(packageProject.IsTool) diff --git a/scripts/dotnet-cli-build/Utils/Dirs.cs b/scripts/dotnet-cli-build/Utils/Dirs.cs index eea866d9b..62ebe8f73 100644 --- a/scripts/dotnet-cli-build/Utils/Dirs.cs +++ b/scripts/dotnet-cli-build/Utils/Dirs.cs @@ -12,6 +12,8 @@ namespace Microsoft.DotNet.Cli.Build RepoRoot, "artifacts", PlatformServices.Default.Runtime.GetRuntimeIdentifier()); + + public static readonly string PackagesIntermediate = Path.Combine(Output, "packages/intermediate"); public static readonly string Packages = Path.Combine(Output, "packages"); public static readonly string Stage1 = Path.Combine(Output, "stage1"); public static readonly string Stage1Compilation = Path.Combine(Output, "stage1compilation"); @@ -21,11 +23,14 @@ namespace Microsoft.DotNet.Cli.Build public static readonly string TestOutput = Path.Combine(Output, "tests"); public static readonly string TestArtifacts = Path.Combine(TestOutput, "artifacts"); public static readonly string TestPackages = Path.Combine(TestOutput, "packages"); + public static readonly string TestPackagesBuild = Path.Combine(TestOutput, "packagesBuild"); + public static readonly string OSXReferenceAssembliesPath = "/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/xbuild-frameworks"; public static readonly string UsrLocalReferenceAssembliesPath = "/usr/local/lib/mono/xbuild-frameworks"; public static readonly string UsrReferenceAssembliesPath = "/usr/lib/mono/xbuild-frameworks"; + public static string NuGetPackages = Environment.GetEnvironmentVariable("NUGET_PACKAGES") ?? GetNuGetPackagesDir(); private static string GetNuGetPackagesDir() diff --git a/scripts/package/projectsToPack.ps1 b/scripts/package/projectsToPack.ps1 index 5c08c9573..e69de29bb 100644 --- a/scripts/package/projectsToPack.ps1 +++ b/scripts/package/projectsToPack.ps1 @@ -1,15 +0,0 @@ -# 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. - -$ProjectsToPack = @( - "Microsoft.DotNet.Cli.Utils", - "Microsoft.DotNet.Compiler.Common", - "Microsoft.DotNet.Files", - "Microsoft.DotNet.InternalAbstractions", - "Microsoft.DotNet.ProjectModel", - "Microsoft.DotNet.ProjectModel.Loader", - "Microsoft.DotNet.ProjectModel.Workspaces", - "Microsoft.DotNet.TestFramework", - "Microsoft.Extensions.DependencyModel", - "Microsoft.Extensions.Testing.Abstractions" -) \ No newline at end of file diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/CommandResolutionStrategy.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/CommandResolutionStrategy.cs index c3059c8a0..a819e9143 100644 --- a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/CommandResolutionStrategy.cs +++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/CommandResolutionStrategy.cs @@ -2,6 +2,9 @@ { public enum CommandResolutionStrategy { + // command loaded from a deps file + DepsFile, + // command loaded from project dependencies nuget package ProjectDependenciesPackage, diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/CommandResolverArguments.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/CommandResolverArguments.cs index f5ce255ba..e43b377b5 100644 --- a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/CommandResolverArguments.cs +++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/CommandResolverArguments.cs @@ -24,5 +24,7 @@ namespace Microsoft.DotNet.Cli.Utils public IEnumerable InferredExtensions { get; set; } public string BuildBasePath { get; set; } + + public string DepsJsonFile { get; set; } } } diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/DepsJsonCommandResolver.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/DepsJsonCommandResolver.cs new file mode 100644 index 000000000..f4b54347c --- /dev/null +++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/DepsJsonCommandResolver.cs @@ -0,0 +1,264 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using Microsoft.DotNet.ProjectModel; +using Microsoft.DotNet.ProjectModel.Graph; +using Microsoft.DotNet.ProjectModel.Compilation; +using Microsoft.Extensions.DependencyModel; +using Microsoft.Extensions.PlatformAbstractions; +using Microsoft.DotNet.ProjectModel.Resolution; +using NuGet.Frameworks; +using NuGet.Packaging; +using NuGet.ProjectModel; + +using LockFile = Microsoft.DotNet.ProjectModel.Graph.LockFile; +using FileFormatException = Microsoft.DotNet.ProjectModel.FileFormatException; + +namespace Microsoft.DotNet.Cli.Utils +{ + public class DepsJsonCommandResolver : ICommandResolver + { + private static readonly string[] s_extensionPreferenceOrder = new [] + { + "", + ".exe", + ".dll" + }; + + private string _nugetPackageRoot; + private Muxer _muxer; + + public DepsJsonCommandResolver(string nugetPackageRoot) + : this(new Muxer(), nugetPackageRoot) { } + + public DepsJsonCommandResolver(Muxer muxer, string nugetPackageRoot) + { + _muxer = muxer; + _nugetPackageRoot = nugetPackageRoot; + } + + public CommandSpec Resolve(CommandResolverArguments commandResolverArguments) + { + if (commandResolverArguments.CommandName == null + || commandResolverArguments.DepsJsonFile == null) + { + return null; + } + + return ResolveFromDepsJsonFile( + commandResolverArguments.CommandName, + commandResolverArguments.CommandArguments.OrEmptyIfNull(), + commandResolverArguments.DepsJsonFile); + } + + private CommandSpec ResolveFromDepsJsonFile( + string commandName, + IEnumerable commandArgs, + string depsJsonFile) + { + var dependencyContext = LoadDependencyContextFromFile(depsJsonFile); + + var commandPath = GetCommandPathFromDependencyContext(commandName, dependencyContext); + if (commandPath == null) + { + return null; + } + + return CreateCommandSpecUsingMuxerIfPortable( + commandPath, + commandArgs, + depsJsonFile, + CommandResolutionStrategy.DepsFile, + _nugetPackageRoot, + IsPortableApp(commandPath)); + } + + public DependencyContext LoadDependencyContextFromFile(string depsJsonFile) + { + DependencyContext dependencyContext = null; + DependencyContextJsonReader contextReader = new DependencyContextJsonReader(); + + using (var contextStream = File.OpenRead(depsJsonFile)) + { + dependencyContext = contextReader.Read(contextStream); + } + + return dependencyContext; + } + + public string GetCommandPathFromDependencyContext(string commandName, DependencyContext dependencyContext) + { + var commandCandidates = new List(); + + var assemblyCommandCandidates = GetCommandCandidates( + commandName, + dependencyContext, + CommandCandidateType.RuntimeCommandCandidate); + var nativeCommandCandidates = GetCommandCandidates( + commandName, + dependencyContext, + CommandCandidateType.NativeCommandCandidate); + + commandCandidates.AddRange(assemblyCommandCandidates); + commandCandidates.AddRange(nativeCommandCandidates); + + var command = ChooseCommandCandidate(commandCandidates); + + return command?.GetAbsoluteCommandPath(_nugetPackageRoot); + } + + private IEnumerable GetCommandCandidates( + string commandName, + DependencyContext dependencyContext, + CommandCandidateType commandCandidateType) + { + var commandCandidates = new List(); + + foreach (var runtimeLibrary in dependencyContext.RuntimeLibraries) + { + IEnumerable runtimeAssetGroups = null; + + if (commandCandidateType == CommandCandidateType.NativeCommandCandidate) + { + runtimeAssetGroups = runtimeLibrary.NativeLibraryGroups; + } + else if (commandCandidateType == CommandCandidateType.RuntimeCommandCandidate) + { + runtimeAssetGroups = runtimeLibrary.RuntimeAssemblyGroups; + } + + commandCandidates.AddRange(GetCommandCandidatesFromRuntimeAssetGroups( + commandName, + runtimeAssetGroups, + runtimeLibrary.Name, + runtimeLibrary.Version)); + } + + return commandCandidates; + } + + private IEnumerable GetCommandCandidatesFromRuntimeAssetGroups( + string commandName, + IEnumerable runtimeAssetGroups, + string PackageName, + string PackageVersion) + { + var candidateAssetGroups = runtimeAssetGroups + .Where(r => r.Runtime == string.Empty) + .Where(a => + a.AssetPaths.Any(p => + Path.GetFileNameWithoutExtension(p).Equals(commandName, StringComparison.OrdinalIgnoreCase))); + + var commandCandidates = new List(); + foreach (var candidateAssetGroup in candidateAssetGroups) + { + var candidateAssetPaths = candidateAssetGroup.AssetPaths.Where( + p => Path.GetFileNameWithoutExtension(p) + .Equals(commandName, StringComparison.OrdinalIgnoreCase)); + + foreach (var candidateAssetPath in candidateAssetPaths) + { + commandCandidates.Add(new CommandCandidate + { + PackageName = PackageName, + PackageVersion = PackageVersion, + RelativeCommandPath = candidateAssetPath + }); + } + } + + return commandCandidates; + } + + private CommandCandidate ChooseCommandCandidate(IEnumerable commandCandidates) + { + foreach (var extension in s_extensionPreferenceOrder) + { + var candidate = commandCandidates + .FirstOrDefault(p => Path.GetExtension(p.RelativeCommandPath) + .Equals(extension, StringComparison.OrdinalIgnoreCase)); + + if (candidate != null) + { + return candidate; + } + } + + return null; + } + + private CommandSpec CreateCommandSpecUsingMuxerIfPortable( + string commandPath, + IEnumerable commandArgs, + string depsJsonFile, + CommandResolutionStrategy commandResolutionStrategy, + string nugetPackagesRoot, + bool isPortable) + { + var depsFileArguments = GetDepsFileArguments(depsJsonFile); + var additionalProbingPathArguments = GetAdditionalProbingPathArguments(); + + var muxerArgs = new List(); + muxerArgs.Add("exec"); + muxerArgs.AddRange(depsFileArguments); + muxerArgs.AddRange(additionalProbingPathArguments); + muxerArgs.Add(commandPath); + muxerArgs.AddRange(commandArgs); + + var escapedArgString = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(muxerArgs); + + return new CommandSpec(_muxer.MuxerPath, escapedArgString, commandResolutionStrategy); + } + + private bool IsPortableApp(string commandPath) + { + var commandDir = Path.GetDirectoryName(commandPath); + + var runtimeConfigPath = Directory.EnumerateFiles(commandDir) + .FirstOrDefault(x => x.EndsWith("runtimeconfig.json")); + + if (runtimeConfigPath == null) + { + return false; + } + + var runtimeConfig = new RuntimeConfig(runtimeConfigPath); + + return runtimeConfig.IsPortable; + } + + private IEnumerable GetDepsFileArguments(string depsJsonFile) + { + return new[] { "--depsfile", depsJsonFile }; + } + + private IEnumerable GetAdditionalProbingPathArguments() + { + return new[] { "--additionalProbingPath", _nugetPackageRoot }; + } + + private class CommandCandidate + { + public string PackageName { get; set; } + public string PackageVersion { get; set; } + public string RelativeCommandPath { get; set; } + + public string GetAbsoluteCommandPath(string nugetPackageRoot) + { + return Path.Combine( + nugetPackageRoot.Replace('/', Path.DirectorySeparatorChar), + PackageName.Replace('/', Path.DirectorySeparatorChar), + PackageVersion.Replace('/', Path.DirectorySeparatorChar), + RelativeCommandPath.Replace('/', Path.DirectorySeparatorChar)); + } + } + + private enum CommandCandidateType + { + NativeCommandCandidate, + RuntimeCommandCandidate + } + } +} diff --git a/src/Microsoft.DotNet.Cli.Utils/DepsJsonCommandFactory.cs b/src/Microsoft.DotNet.Cli.Utils/DepsJsonCommandFactory.cs new file mode 100644 index 000000000..55108f4f8 --- /dev/null +++ b/src/Microsoft.DotNet.Cli.Utils/DepsJsonCommandFactory.cs @@ -0,0 +1,50 @@ +// 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.Collections.Generic; +using NuGet.Frameworks; +using System.IO; +using System; +using Microsoft.DotNet.ProjectModel; + +namespace Microsoft.DotNet.Cli.Utils +{ + public class DepsJsonCommandFactory : ICommandFactory + { + private DepsJsonCommandResolver _depsJsonCommandResolver; + private string _temporaryDirectory; + private string _depsJsonFile; + private string _runtimeConfigFile; + + public DepsJsonCommandFactory( + string depsJsonFile, + string runtimeConfigFile, + string nugetPackagesRoot, + string temporaryDirectory) + { + _depsJsonCommandResolver = new DepsJsonCommandResolver(nugetPackagesRoot); + + _temporaryDirectory = temporaryDirectory; + _depsJsonFile = depsJsonFile; + _runtimeConfigFile = runtimeConfigFile; + } + + public ICommand Create( + string commandName, + IEnumerable args, + NuGetFramework framework = null, + string configuration = Constants.DefaultConfiguration) + { + var commandResolverArgs = new CommandResolverArguments() + { + CommandName = commandName, + CommandArguments = args, + DepsJsonFile = _depsJsonFile + }; + + var commandSpec = _depsJsonCommandResolver.Resolve(commandResolverArgs); + + return Command.Create(commandSpec); + } + } +} diff --git a/src/corehost/cli/fxr/fx_muxer.cpp b/src/corehost/cli/fxr/fx_muxer.cpp index 3a0ed9d51..d798f43d3 100644 --- a/src/corehost/cli/fxr/fx_muxer.cpp +++ b/src/corehost/cli/fxr/fx_muxer.cpp @@ -308,7 +308,7 @@ int fx_muxer_t::execute(const int argc, const pal::char_t* argv[]) trace::verbose(_X("Current argv is %s"), argv[cur_i]); pal::string_t app_or_deps = deps_file.empty() ? argv[cur_i] : deps_file; - pal::string_t no_json = deps_file.empty() ? app_or_deps : strip_file_ext(app_or_deps); + pal::string_t no_json = argv[cur_i]; auto config_file = get_runtime_config_from_file(no_json); runtime_config_t config(config_file); if (!config.is_valid()) diff --git a/src/corehost/cli/libhost.cpp b/src/corehost/cli/libhost.cpp index c68253f23..e238303ca 100644 --- a/src/corehost/cli/libhost.cpp +++ b/src/corehost/cli/libhost.cpp @@ -13,11 +13,8 @@ pal::string_t get_runtime_config_from_file(const pal::string_t& file) auto json_path = get_directory(file); append_path(&json_path, json_name.c_str()); - if (pal::file_exists(json_path)) - { - return json_path; - } - return pal::string_t(); + trace::verbose(_X("Runtime config is %s"), json_path.c_str()); + return json_path; } host_mode_t detect_operating_mode(const int argc, const pal::char_t* argv[], pal::string_t* p_own_dir) diff --git a/src/dotnet/commands/dotnet-compile-fsc/Program.cs b/src/dotnet-compile-fsc/Program.cs similarity index 70% rename from src/dotnet/commands/dotnet-compile-fsc/Program.cs rename to src/dotnet-compile-fsc/Program.cs index 6eb454330..070846b7a 100644 --- a/src/dotnet/commands/dotnet-compile-fsc/Program.cs +++ b/src/dotnet-compile-fsc/Program.cs @@ -12,15 +12,16 @@ using System.Text; using Microsoft.DotNet.Cli.Compiler.Common; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ProjectModel; +using Microsoft.DotNet.ProjectModel.Resolution; using NuGet.Frameworks; +using System.Reflection; namespace Microsoft.DotNet.Tools.Compiler.Fsc { public class CompileFscCommand { private const int ExitFailed = 1; - - public static int Run(string[] args) + public static int Main(string[] args) { DebugHelper.HandleDebugSwitch(ref args); @@ -80,19 +81,24 @@ namespace Microsoft.DotNet.Tools.Compiler.Fsc return returnCode; } - // TODO less hacky bool targetNetCore = commonOptions.Defines.Contains("DNXCORE50") || commonOptions.Defines.Where(d => d.StartsWith("NETSTANDARDAPP1_")).Any() || commonOptions.Defines.Where(d => d.StartsWith("NETSTANDARD1_")).Any(); + // Get FSC Path upfront to use it for win32manifest path + var fscCommandSpec = ResolveFsc(null, tempOutDir); + var fscExeFile = fscCommandSpec.FscExeFile; + var fscExeDir = fscCommandSpec.FscExeDir; + // FSC arguments var allArgs = new List(); //HACK fsc raise error FS0208 if target exe doesnt have extension .exe bool hackFS0208 = targetNetCore && commonOptions.EmitEntryPoint == true; - string originalOutputName = outputName; + + var originalOutputName = outputName; if (outputName != null) { @@ -168,11 +174,8 @@ namespace Microsoft.DotNet.Tools.Compiler.Fsc allArgs.Add("--target:exe"); //HACK we need default.win32manifest for exe - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - var win32manifestPath = Path.Combine(AppContext.BaseDirectory, "default.win32manifest"); - allArgs.Add($"--win32manifest:{win32manifestPath}"); - } + var win32manifestPath = Path.Combine(fscExeDir, "..", "..", "runtimes", "any", "native", "default.win32manifest"); + allArgs.Add($"--win32manifest:{win32manifestPath}"); } if (commonOptions.SuppressWarnings != null) @@ -227,13 +230,13 @@ namespace Microsoft.DotNet.Tools.Compiler.Fsc //source files + assemblyInfo allArgs.AddRange(GetSourceFiles(sources, assemblyInfo).ToArray()); - //TODO check the switch enabled in fsproj in RELEASE and DEBUG configuration + //TODO check the switch enabled in fsproj in RELEASE and DEBUG configuration var rsp = Path.Combine(tempOutDir, "dotnet-compile-fsc.rsp"); File.WriteAllLines(rsp, allArgs, Encoding.UTF8); // Execute FSC! - var result = RunFsc(new List { $"@{rsp}" }) + var result = RunFsc(new List { $"@{rsp}" }, tempOutDir) .ForwardStdErr() .ForwardStdOut() .Execute(); @@ -257,26 +260,6 @@ namespace Microsoft.DotNet.Tools.Compiler.Fsc return result.ExitCode; } - private static Command RunFsc(List fscArgs) - { - var fscExe = Environment.GetEnvironmentVariable("DOTNET_FSC_PATH") - ?? Path.Combine(AppContext.BaseDirectory, "fsc.exe"); - - var exec = Environment.GetEnvironmentVariable("DOTNET_FSC_EXEC")?.ToUpper() ?? "COREHOST"; - - switch (exec) - { - case "RUN": - return Command.Create(fscExe, fscArgs.ToArray()); - - case "COREHOST": - default: - var corehost = Path.Combine(AppContext.BaseDirectory, Constants.HostExecutableName); - return Command.Create(corehost, new[] { fscExe }.Concat(fscArgs).ToArray()); - } - - } - // The assembly info must be in the last minus 1 position because: // - assemblyInfo should be in the end to override attributes // - assemblyInfo cannot be in the last position, because last file contains the main @@ -295,5 +278,97 @@ namespace Microsoft.DotNet.Tools.Compiler.Fsc yield return sourceFiles.Last(); } + + private static Command RunFsc(List fscArgs, string temp) + { + var fscEnvExe = Environment.GetEnvironmentVariable("DOTNET_FSC_PATH"); + var exec = Environment.GetEnvironmentVariable("DOTNET_FSC_EXEC")?.ToUpper() ?? "COREHOST"; + + var muxer = new Muxer(); + + if (fscEnvExe != null) + { + switch (exec) + { + case "RUN": + return Command.Create(fscEnvExe, fscArgs.ToArray()); + + case "COREHOST": + default: + var host = muxer.MuxerPath; + return Command.Create(host, new[] { fscEnvExe }.Concat(fscArgs).ToArray()); + } + } + else + { + var fscCommandSpec = ResolveFsc(fscArgs, temp)?.Spec; + return Command.Create(fscCommandSpec); + } + } + + private static FscCommandSpec ResolveFsc(List fscArgs, string temp) + { + var nugetPackagesRoot = PackageDependencyProvider.ResolvePackagesPath(null, null); + var depsFile = Path.Combine(AppContext.BaseDirectory, "dotnet-compile-fsc" + FileNameSuffixes.DepsJson); + + var depsJsonCommandResolver = new DepsJsonCommandResolver(nugetPackagesRoot); + var dependencyContext = depsJsonCommandResolver.LoadDependencyContextFromFile(depsFile); + var fscPath = depsJsonCommandResolver.GetCommandPathFromDependencyContext("fsc", dependencyContext); + + + var commandResolverArgs = new CommandResolverArguments() + { + CommandName = "fsc", + CommandArguments = fscArgs, + DepsJsonFile = depsFile + }; + + var fscCommandSpec = depsJsonCommandResolver.Resolve(commandResolverArgs); + + var runtimeConfigFile = Path.Combine( + Path.GetDirectoryName(typeof(CompileFscCommand).GetTypeInfo().Assembly.Location) + , "dotnet-compile-fsc" + FileNameSuffixes.RuntimeConfigJson); + + + CopyRuntimeConfigForFscExe(runtimeConfigFile, "fsc", depsFile, nugetPackagesRoot, fscPath); + + return new FscCommandSpec + { + Spec = fscCommandSpec, + FscExeDir = Path.GetDirectoryName(fscPath), + FscExeFile = fscPath + }; + } + + private static void CopyRuntimeConfigForFscExe( + string runtimeConfigFile, + string commandName, + string depsJsonFile, + string nugetPackagesRoot, + string fscPath) + { + var newFscRuntimeConfigDir = Path.GetDirectoryName(fscPath); + var newFscRuntimeConfigFile = Path.Combine( + newFscRuntimeConfigDir, + Path.GetFileNameWithoutExtension(fscPath) + FileNameSuffixes.RuntimeConfigJson); + + try + { + File.Copy(runtimeConfigFile, newFscRuntimeConfigFile, true); + } + catch(Exception e) + { + Reporter.Error.WriteLine("Failed to copy fsc runtimeconfig.json"); + throw e; + } + } + + private class FscCommandSpec + { + public CommandSpec Spec { get; set; } + public string FscExeDir { get; set; } + public string FscExeFile { get; set; } + } } } + diff --git a/src/dotnet-compile-fsc/dotnet-compile-fsc.xproj b/src/dotnet-compile-fsc/dotnet-compile-fsc.xproj new file mode 100644 index 000000000..186b3d19a --- /dev/null +++ b/src/dotnet-compile-fsc/dotnet-compile-fsc.xproj @@ -0,0 +1,19 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 60cf7e6c-d6c8-439d-b7b7-d8a27e29be2c + Microsoft.DotNet.Tools.Compiler.Fsc + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin + + + + 2.0 + + + \ No newline at end of file diff --git a/src/dotnet-compile-fsc/project.json b/src/dotnet-compile-fsc/project.json new file mode 100644 index 000000000..59c39edee --- /dev/null +++ b/src/dotnet-compile-fsc/project.json @@ -0,0 +1,29 @@ +{ + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": true + }, + + "dependencies": { + "Microsoft.FSharp.Compiler.netcore": "1.0.0-alpha-160318", + "System.CommandLine": "0.1.0-e160323-1", + + "Microsoft.DotNet.ProjectModel": "1.0.0-*", + "Microsoft.DotNet.Compiler.Common": "1.0.0-*", + "Microsoft.DotNet.Cli.Utils": "1.0.0-*", + + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.0.0-rc2-23931" + } + }, + "frameworks": { + "netstandard1.5": { + "imports": [ + "dnxcore50", + "portable-net45+win81", + "netstandard1.3" + ] + } + } +} diff --git a/src/dotnet/Program.cs b/src/dotnet/Program.cs index 73f75b217..7d8e02cb3 100644 --- a/src/dotnet/Program.cs +++ b/src/dotnet/Program.cs @@ -13,7 +13,6 @@ using Microsoft.DotNet.ProjectModel.Server; using Microsoft.DotNet.Tools.Build; using Microsoft.DotNet.Tools.Compiler; using Microsoft.DotNet.Tools.Compiler.Csc; -using Microsoft.DotNet.Tools.Compiler.Fsc; using Microsoft.DotNet.Tools.Compiler.Native; using Microsoft.DotNet.Tools.Help; using Microsoft.DotNet.Tools.New; diff --git a/src/dotnet/commands/dotnet-new/FSharp_Console/NuGet.Config b/src/dotnet/commands/dotnet-new/FSharp_Console/NuGet.Config index 3f788a5d7..f1c321599 100644 --- a/src/dotnet/commands/dotnet-new/FSharp_Console/NuGet.Config +++ b/src/dotnet/commands/dotnet-new/FSharp_Console/NuGet.Config @@ -6,5 +6,8 @@ + + + diff --git a/src/dotnet/commands/dotnet-new/FSharp_Console/project.json.template b/src/dotnet/commands/dotnet-new/FSharp_Console/project.json.template index 7f2fc80c4..745dc0243 100644 --- a/src/dotnet/commands/dotnet-new/FSharp_Console/project.json.template +++ b/src/dotnet/commands/dotnet-new/FSharp_Console/project.json.template @@ -14,6 +14,11 @@ "version": "1.0.0-rc2-23931" } }, + + "tools": { + "dotnet-compile-fsc": "1.0.0-*" + }, + "frameworks": { "netstandard1.5": { "imports": [ diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Assertions/CommandResultAssertions.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Assertions/CommandResultAssertions.cs index 3fab175b5..c763ae5f3 100644 --- a/test/Microsoft.DotNet.Tools.Tests.Utilities/Assertions/CommandResultAssertions.cs +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Assertions/CommandResultAssertions.cs @@ -32,13 +32,6 @@ namespace Microsoft.DotNet.Tools.Test.Utilities return new AndConstraint(this); } - public AndConstraint NotPass() - { - Execute.Assertion.ForCondition(_commandResult.ExitCode != 0) - .FailWith(AppendDiagnosticsTo($"Expected command to fail but it did not.")); - return new AndConstraint(this); - } - public AndConstraint Fail() { Execute.Assertion.ForCondition(_commandResult.ExitCode != 0) diff --git a/test/dotnet-compile-fsc.Tests/GivenThatIWantToCompileFSharpPrograms.cs b/test/dotnet-compile-fsc.Tests/GivenThatIWantToCompileFSharpPrograms.cs new file mode 100644 index 000000000..a37b47064 --- /dev/null +++ b/test/dotnet-compile-fsc.Tests/GivenThatIWantToCompileFSharpPrograms.cs @@ -0,0 +1,66 @@ +// 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.IO; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.TestFramework; +using Microsoft.DotNet.Tools.Test.Utilities; +using FluentAssertions; +using Xunit; + +namespace Microsoft.DotNet.Tools.Compiler.Tests +{ + public class GivenThatIWantToCompileFSharpPrograms + { + private readonly static string s_testProjectsRoot = Path.Combine( + AppContext.BaseDirectory, + "TestAssets", + "TestProjects", + "FSharpTestProjects"); + + [Fact] + public void Compilation_of_app_with_invalid_source_should_fail() + { + var testProject = Path.Combine(s_testProjectsRoot, "CompileFailApp", "project.json"); + var buildCommand = new BuildCommand(testProject); + + var oldDirectory = Directory.GetCurrentDirectory(); + Directory.SetCurrentDirectory(Path.GetDirectoryName(testProject)); + + buildCommand.Execute().Should().Fail(); + + Directory.SetCurrentDirectory(oldDirectory); + } + + [Fact] + public void Compilation_of_valid_app_should_succeed() + { + var testProject = Path.Combine(s_testProjectsRoot, "TestAppWithArgs", "project.json"); + var buildCommand = new BuildCommand(testProject); + + var oldDirectory = Directory.GetCurrentDirectory(); + Directory.SetCurrentDirectory(Path.GetDirectoryName(testProject)); + + buildCommand.Execute().Should().Pass(); + + Directory.SetCurrentDirectory(oldDirectory); + } + + [Fact] + public void Compilation_of_app_with_P2P_reference_to_fsharp_library_should_be_runnable() + { + var testProject = Path.Combine(s_testProjectsRoot, "TestApp", "project.json"); + var runCommand = new RunCommand(testProject); + + var oldDirectory = Directory.GetCurrentDirectory(); + Directory.SetCurrentDirectory(Path.GetDirectoryName(testProject)); + + var result = runCommand.Execute(); + + result.Should().Pass(); + + Directory.SetCurrentDirectory(oldDirectory); + } + } +} diff --git a/test/dotnet-compile-fsc.Tests/dotnet-compile-fsc.Tests.xproj b/test/dotnet-compile-fsc.Tests/dotnet-compile-fsc.Tests.xproj new file mode 100644 index 000000000..109254497 --- /dev/null +++ b/test/dotnet-compile-fsc.Tests/dotnet-compile-fsc.Tests.xproj @@ -0,0 +1,21 @@ + + + + 14.0.23107 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 833ffee1-7eed-4f51-8dfd-946d48893d6e + Microsoft.DotNet.Tools.Compiler.Tests + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin + + + 2.0 + + + + + + \ No newline at end of file diff --git a/test/dotnet-compile-fsc.Tests/project.json b/test/dotnet-compile-fsc.Tests/project.json new file mode 100644 index 000000000..268f178df --- /dev/null +++ b/test/dotnet-compile-fsc.Tests/project.json @@ -0,0 +1,34 @@ +{ + "version": "1.0.0-*", + + "dependencies": { + "NETStandard.Library": "1.5.0-rc2-23931", + + "Microsoft.DotNet.Tools.Tests.Utilities": { "target": "project" }, + "Microsoft.DotNet.Cli.Utils": { + "target": "project" + }, + + "xunit": "2.1.0", + "dotnet-test-xunit": "1.0.0-dev-128011-22" + }, + + "frameworks": { + "netstandardapp1.5": { + "imports": [ + "dnxcore50", + "portable-net451+win8" + ] + } + }, + + "content": [ + "../../TestAssets/TestProjects/FSharpTestProjects/CompileFailApp/**/*", + "../../TestAssets/TestProjects/FSharpTestProjects/TestApp/**/*", + "../../TestAssets/TestProjects/FSharpTestProjects/TestAppWithArgs/**/*", + "../../TestAssets/TestProjects/FSharpTestProjects/TestLibrary/**/*", + "../../TestAssets/TestProjects/FSharpTestProjects/global.json" + ], + + "testRunner": "xunit" +} diff --git a/test/dotnet.Tests/PackagedCommandTests.cs b/test/dotnet.Tests/PackagedCommandTests.cs index 3fee9f023..cdda94343 100644 --- a/test/dotnet.Tests/PackagedCommandTests.cs +++ b/test/dotnet.Tests/PackagedCommandTests.cs @@ -88,7 +88,7 @@ namespace Microsoft.DotNet.Tests CommandResult result = new HelloCommand().ExecuteWithCapturedOutput(); result.StdOut.Should().Contain("No executable found matching command"); - result.Should().NotPass(); + result.Should().Fail(); } finally {