From 6b7ca1de785b667e1dfdc435b9639e78cd5ad5b1 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 12 Dec 2016 11:20:53 -0800 Subject: [PATCH 01/17] Make build script download and unzip Microsoft.Build.Windows directly --- .gitignore | 1 + NuGet.Config | 3 ++- build.cake | 65 ++++++++++++++++++++++++++++++++++++++------- build.json | 10 +++++++ scripts/nuget.cake | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 134 insertions(+), 11 deletions(-) create mode 100644 scripts/nuget.cake diff --git a/.gitignore b/.gitignore index 4a4b77e745..2e1bb5ab3a 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ buildlog *.lock.json /omnisharp*.tar.gz scripts/Omnisharp* +msbuild/ # NuGet *.nuget.targets diff --git a/NuGet.Config b/NuGet.Config index 36b0477907..ef10a62e57 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -1,7 +1,8 @@ - + + diff --git a/build.cake b/build.cake index dcc303a839..d43c963ec6 100644 --- a/build.cake +++ b/build.cake @@ -3,6 +3,7 @@ #load "scripts/runhelpers.cake" #load "scripts/archiving.cake" #load "scripts/artifacts.cake" +#load "scripts/nuget.cake" using System.ComponentModel; using System.Net; @@ -26,6 +27,15 @@ var shell = IsRunningOnWindows() ? "powershell" : "bash"; var shellArgument = IsRunningOnWindows() ? "-NoProfile /Command" : "-C"; var shellExtension = IsRunningOnWindows() ? "ps1" : "sh"; +public class NuGetPackage +{ + public string Name { get; set; } + public string Version { get; set; } + public string FeedURL { get; set; } + public string ContentPath { get; set; } + public string TargetFolder { get; set; } +} + /// /// Class representing build.json /// @@ -34,6 +44,8 @@ public class BuildPlan public IDictionary TestProjects { get; set; } public string BuildToolsFolder { get; set; } public string ArtifactsFolder { get; set; } + public string PackagesFolder { get; set; } + public NuGetPackage[] Packages { get; set; } public bool UseSystemDotNetPath { get; set; } public string DotNetFolder { get; set; } public string DotNetInstallScriptURL { get; set; } @@ -62,6 +74,8 @@ var logFolder = System.IO.Path.Combine(artifactFolder, "logs"); var packageFolder = System.IO.Path.Combine(artifactFolder, "package"); var scriptFolder = System.IO.Path.Combine(artifactFolder, "scripts"); +var packagesFolder = System.IO.Path.Combine(workingDirectory, buildPlan.PackagesFolder); + /// /// Clean artifacts. /// @@ -76,6 +90,7 @@ Task("Cleanup") System.IO.Directory.CreateDirectory(logFolder); System.IO.Directory.CreateDirectory(packageFolder); System.IO.Directory.CreateDirectory(scriptFolder); + System.IO.Directory.CreateDirectory(packagesFolder); }); /// @@ -84,10 +99,44 @@ Task("Cleanup") Task("Setup") .IsDependentOn("BuildEnvironment") .IsDependentOn("PopulateRuntimes") + .IsDependentOn("AcquirePackages") .Does(() => { }); +/// +/// Acquire additional NuGet packages included with OmniSharp (such as MSBuild). +/// +Task("AcquirePackages") + .IsDependentOn("BuildEnvironment") + .Does(() => +{ + foreach (var package in buildPlan.Packages) + { + Information($"Downloading {package.Name}..."); + + DownloadNuGetPackage( + packageID: package.Name, + version: package.Version, + outputDirectory: packagesFolder, + feedUrl: package.FeedURL); + + var contentFolder = System.IO.Path.Combine(packagesFolder, package.Name); + foreach (var part in package.ContentPath.Split('/')) + { + contentFolder = System.IO.Path.Combine(contentFolder, part); + } + + if (System.IO.Directory.Exists(contentFolder)) + { + var targetFolder = System.IO.Path.Combine(workingDirectory, package.TargetFolder); + + Information($"Copying content to {targetFolder}..."); + CopyDirectory(contentFolder, targetFolder); + } + } +}); + /// /// Populate the RIDs for the specific environment. /// Use default RID (+ win7-x86 on Windows) for now. @@ -177,16 +226,12 @@ Task("BuildEnvironment") System.IO.Directory.CreateDirectory(toolsFolder); - var nugetPath = Environment.GetEnvironmentVariable("NUGET_EXE"); - var arguments = $"install xunit.runner.console -ExcludeVersion -NoCache -Prerelease -OutputDirectory \"{toolsFolder}\""; - if (IsRunningOnWindows()) - { - Run(nugetPath, arguments); - } - else - { - Run("mono", $"\"{nugetPath}\" {arguments}"); - } + InstallNuGetPackage( + packageID: "xunit.runner.console", + excludeVersion: true, + noCache: true, + prerelease: true, + outputDirectory: $"\"{toolsFolder}\""); }); /// diff --git a/build.json b/build.json index 1b934b4ed0..6d11481748 100644 --- a/build.json +++ b/build.json @@ -6,6 +6,16 @@ "DotNetVersion": "1.0.0-preview2-003131", "BuildToolsFolder": ".tools", "ArtifactsFolder": "artifacts", + "PackagesFolder": "packages", + "Packages": [ + { + "Name": "Microsoft.Build.Runtime", + "Version": "15.1.0-preview-000454-01", + "FeedURL": "https://dotnet.myget.org/F/msbuild/api/v2/package", + "ContentPath": "contentFiles/any/net46", + "TargetFolder": "msbuild" + } + ], "TestProjects": { "OmniSharp.MSBuild.Tests": [ "netcoreapp1.0" diff --git a/scripts/nuget.cake b/scripts/nuget.cake new file mode 100644 index 0000000000..67ab11c4e9 --- /dev/null +++ b/scripts/nuget.cake @@ -0,0 +1,66 @@ +#load "runhelpers.cake" + +using System.Net; + +/// +/// Downloads and unzips a NuGet package directly without any dependencies. +/// +void DownloadNuGetPackage(string packageID, string version, string outputDirectory, string feedUrl) +{ + var outputFolder = System.IO.Path.Combine(outputDirectory, packageID); + var outputFileName = System.IO.Path.ChangeExtension(outputFolder, "nupkg"); + + if (DirectoryExists(outputFolder)) + { + DeleteDirectory(outputFolder, recursive: true); + } + + using (var client = new WebClient()) + { + client.DownloadFile( + address: $"{feedUrl}/{packageID}/{version}", + fileName: outputFileName); + } + + Unzip(outputFileName, outputFolder); +} + +ExitStatus InstallNuGetPackage(string packageID, string version = null, bool excludeVersion = false, bool noCache = false, bool prerelease = false, string outputDirectory = null) +{ + var nugetPath = Environment.GetEnvironmentVariable("NUGET_EXE"); + + var argList = new List { "install", packageID }; + + if (!string.IsNullOrWhiteSpace(version)) + { + argList.Add("-Version"); + argList.Add(version); + } + + if (excludeVersion) + { + argList.Add("-ExcludeVersion"); + } + + if (noCache) + { + argList.Add("-NoCache"); + } + + if (prerelease) + { + argList.Add("-Prerelease"); + } + + if (!string.IsNullOrWhiteSpace(outputDirectory)) + { + argList.Add("-OutputDirectory"); + argList.Add(outputDirectory); + } + + var arguments = string.Join(" ", argList); + + return IsRunningOnWindows() + ? Run(nugetPath, arguments) + : Run("mono", $"\"{nugetPath}\" {arguments}"); +} \ No newline at end of file From f45b408e01972df703392cb336c86e6996d33d9d Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 12 Dec 2016 11:41:15 -0800 Subject: [PATCH 02/17] Clean up build.cake a bit --- build.cake | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/build.cake b/build.cake index d43c963ec6..1c9733d25e 100644 --- a/build.cake +++ b/build.cake @@ -188,20 +188,25 @@ Task("BuildEnvironment") { client.DownloadFile($"{buildPlan.DotNetInstallScriptURL}/{installScript}", scriptPath); } + if (!IsRunningOnWindows()) { Run("chmod", $"+x '{scriptPath}'"); } + var installArgs = $"-Channel {buildPlan.DotNetChannel}"; if (!String.IsNullOrEmpty(buildPlan.DotNetVersion)) { installArgs = $"{installArgs} -Version {buildPlan.DotNetVersion}"; } + if (!buildPlan.UseSystemDotNetPath) { installArgs = $"{installArgs} -InstallDir {dotnetFolder}"; } + Run(shell, $"{shellArgument} {scriptPath} {installArgs}"); + try { Run(dotnetcli, "--info"); @@ -374,21 +379,36 @@ Task("OnlyPublish") foreach (var runtime in buildPlan.Rids) { var outputFolder = System.IO.Path.Combine(publishFolder, project, runtime, framework); - var publishArguments = "publish"; + var argList = new List { "publish" }; + if (!runtime.Equals("default")) { - publishArguments = $"{publishArguments} --runtime {runtime}"; + argList.Add("--runtime"); + argList.Add(runtime); } else if (buildPlan.CurrentRid == "osx.10.12-x64") { // This is a temporary hack to handle the macOS Sierra. At this point, // runtime == "default" but the current RID is macOS Sierra (10.12). // In that case, fall back to El Capitan (10.11). - publishArguments = $"{publishArguments} --runtime osx.10.11-x64"; + argList.Add("--runtime"); + argList.Add("osx.10.11-x64"); } - publishArguments = $"{publishArguments} --framework {framework} --configuration {configuration}"; - publishArguments = $"{publishArguments} --output \"{outputFolder}\" \"{projectFolder}\""; + argList.Add("--framework"); + argList.Add(framework); + + argList.Add("--configuration"); + argList.Add(configuration); + + argList.Add("--output"); + argList.Add($"\"{outputFolder}\""); + + argList.Add($"\"{projectFolder}\""); + + var publishArguments = string.Join(" ", argList); + Information($"publishArguments: {publishArguments}"); + Run(dotnetcli, publishArguments) .ExceptionOnError($"Failed to publish {project} / {framework}"); @@ -398,6 +418,7 @@ Task("OnlyPublish") } } } + CreateRunScript(System.IO.Path.Combine(publishFolder, project, "default"), scriptFolder); }); @@ -471,6 +492,7 @@ Task("CleanupInstall") { System.IO.Directory.Delete(installFolder, true); } + System.IO.Directory.CreateDirectory(installFolder); }); From 73b0a82fedcb06f4dd18e3ab4c6c39510b4eaa37 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 12 Dec 2016 12:21:36 -0800 Subject: [PATCH 03/17] Copy msbuild and targets to folder under OmniSharp during publishing --- build.cake | 26 ++++++++++++++++++++++++-- build.json | 10 ++++++++++ src/OmniSharp/project.json | 3 +-- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/build.cake b/build.cake index 1c9733d25e..9228601406 100644 --- a/build.cake +++ b/build.cake @@ -36,6 +36,12 @@ public class NuGetPackage public string TargetFolder { get; set; } } +public class CopyToOutput +{ + public string From { get; set; } + public string To { get; set; } +} + /// /// Class representing build.json /// @@ -46,6 +52,7 @@ public class BuildPlan public string ArtifactsFolder { get; set; } public string PackagesFolder { get; set; } public NuGetPackage[] Packages { get; set; } + public CopyToOutput[] CopyToOutput { get; set; } public bool UseSystemDotNetPath { get; set; } public string DotNetFolder { get; set; } public string DotNetInstallScriptURL { get; set; } @@ -127,7 +134,7 @@ Task("AcquirePackages") contentFolder = System.IO.Path.Combine(contentFolder, part); } - if (System.IO.Directory.Exists(contentFolder)) + if (DirectoryExists(contentFolder)) { var targetFolder = System.IO.Path.Combine(workingDirectory, package.TargetFolder); @@ -407,11 +414,26 @@ Task("OnlyPublish") argList.Add($"\"{projectFolder}\""); var publishArguments = string.Join(" ", argList); - Information($"publishArguments: {publishArguments}"); Run(dotnetcli, publishArguments) .ExceptionOnError($"Failed to publish {project} / {framework}"); + // Copy other output from build.json to output folder. + foreach (var copyToOuput in buildPlan.CopyToOutput) + { + var path = System.IO.Path.Combine(workingDirectory, copyToOuput.From); + var targetPath = System.IO.Path.Combine(outputFolder, copyToOuput.To); + + if (DirectoryExists(path)) + { + CopyDirectory(path, targetPath); + } + else if (FileExists(path)) + { + CopyFile(path, targetPath); + } + } + if (requireArchive) { Package(runtime, framework, outputFolder, packageFolder, buildPlan.MainProject.ToLower()); diff --git a/build.json b/build.json index 6d11481748..18531c1d9d 100644 --- a/build.json +++ b/build.json @@ -16,6 +16,16 @@ "TargetFolder": "msbuild" } ], + "CopyToOutput": [ + { + "From": "msbuild", + "To": "msbuild" + }, + { + "From": "Microsoft.CSharp.Core.targets", + "To": "msbuild/Microsoft.CSharp.Core.targets" + } + ], "TestProjects": { "OmniSharp.MSBuild.Tests": [ "netcoreapp1.0" diff --git a/src/OmniSharp/project.json b/src/OmniSharp/project.json index bfe7104401..86268a41a9 100644 --- a/src/OmniSharp/project.json +++ b/src/OmniSharp/project.json @@ -16,8 +16,7 @@ "OmniSharp.DotNet": "1.0.0", "OmniSharp.DotNetTest": "1.0.0", "OmniSharp.MSBuild": "1.0.0", - "OmniSharp.Script": "1.0.0", - "Microsoft.Build.Runtime": "15.1.0-preview-000454-01" + "OmniSharp.Script": "1.0.0" }, "frameworks": { "net46": {}, From 6b57e592c4797b272fa4d02e72c88c538cd86708 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 12 Dec 2016 12:23:01 -0800 Subject: [PATCH 04/17] Use a few Cake primitives --- build.cake | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/build.cake b/build.cake index 9228601406..53cb2f8a76 100644 --- a/build.cake +++ b/build.cake @@ -89,15 +89,16 @@ var packagesFolder = System.IO.Path.Combine(workingDirectory, buildPlan.Packages Task("Cleanup") .Does(() => { - if (System.IO.Directory.Exists(artifactFolder)) + if (DirectoryExists(artifactFolder)) { - System.IO.Directory.Delete(artifactFolder, true); + DeleteDirectory(artifactFolder, recursive: true); } - System.IO.Directory.CreateDirectory(artifactFolder); - System.IO.Directory.CreateDirectory(logFolder); - System.IO.Directory.CreateDirectory(packageFolder); - System.IO.Directory.CreateDirectory(scriptFolder); - System.IO.Directory.CreateDirectory(packagesFolder); + + CreateDirectory(artifactFolder); + CreateDirectory(logFolder); + CreateDirectory(packageFolder); + CreateDirectory(scriptFolder); + CreateDirectory(packagesFolder); }); /// From e32fd921342ac3acc1c185a875a000c4994e18b7 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 12 Dec 2016 12:45:23 -0800 Subject: [PATCH 05/17] Set MSBUILD_EXE_PATH environment variable in OmniSharp during MSBuildProjectSystem initialization --- src/OmniSharp.MSBuild/MSBuildProjectSystem.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs b/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs index f6d54101ae..7b90c8ff73 100644 --- a/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs +++ b/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs @@ -69,6 +69,9 @@ public MSBuildProjectSystem( public void Initalize(IConfiguration configuration) { + // Set MSBUILD_EXE_PATH to the path of the MSBuild toolset + Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", Path.Combine(AppContext.BaseDirectory, "msbuild")); + _options = new MSBuildOptions(); ConfigurationBinder.Bind(configuration, _options); From ea783ccd28bc577b3563a56154e25bd811403e06 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 12 Dec 2016 15:31:45 -0800 Subject: [PATCH 06/17] Install various SDK packages and copy MSBuild+SDKs on publish --- .gitignore | 4 +- NuGet.Config | 3 +- build.cake | 115 ++++++++++-------- build.json | 19 --- packages/packages.config | 10 ++ scripts/nuget.cake | 16 ++- src/OmniSharp.MSBuild/MSBuildProjectSystem.cs | 4 +- 7 files changed, 92 insertions(+), 79 deletions(-) create mode 100644 packages/packages.config diff --git a/.gitignore b/.gitignore index 2e1bb5ab3a..359cd693cd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ TestResults/ .nuget/ *.sln.ide/ _ReSharper.*/ -packages/ +packages/**/ artifacts/ PublishProfiles/ *.user @@ -31,7 +31,7 @@ buildlog *.lock.json /omnisharp*.tar.gz scripts/Omnisharp* -msbuild/ +.msbuild-*/ # NuGet *.nuget.targets diff --git a/NuGet.Config b/NuGet.Config index ef10a62e57..50c3e6837d 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -2,7 +2,8 @@ - + + diff --git a/build.cake b/build.cake index 53cb2f8a76..c921d49642 100644 --- a/build.cake +++ b/build.cake @@ -15,8 +15,8 @@ var target = Argument("target", "Default"); var configuration = Argument("configuration", "Release"); // Optional arguments var testConfiguration = Argument("test-configuration", "Debug"); -var installFolder = Argument("install-path", System.IO.Path.Combine(Environment.GetEnvironmentVariable(IsRunningOnWindows() ? "USERPROFILE" : "HOME"), - ".omnisharp", "local")); +var installFolder = Argument("install-path", + System.IO.Path.Combine(Environment.GetEnvironmentVariable(IsRunningOnWindows() ? "USERPROFILE" : "HOME"), ".omnisharp", "local")); var requireArchive = HasArgument("archive"); // Working directory @@ -27,21 +27,6 @@ var shell = IsRunningOnWindows() ? "powershell" : "bash"; var shellArgument = IsRunningOnWindows() ? "-NoProfile /Command" : "-C"; var shellExtension = IsRunningOnWindows() ? "ps1" : "sh"; -public class NuGetPackage -{ - public string Name { get; set; } - public string Version { get; set; } - public string FeedURL { get; set; } - public string ContentPath { get; set; } - public string TargetFolder { get; set; } -} - -public class CopyToOutput -{ - public string From { get; set; } - public string To { get; set; } -} - /// /// Class representing build.json /// @@ -51,8 +36,6 @@ public class BuildPlan public string BuildToolsFolder { get; set; } public string ArtifactsFolder { get; set; } public string PackagesFolder { get; set; } - public NuGetPackage[] Packages { get; set; } - public CopyToOutput[] CopyToOutput { get; set; } public bool UseSystemDotNetPath { get; set; } public string DotNetFolder { get; set; } public string DotNetInstallScriptURL { get; set; } @@ -82,6 +65,9 @@ var packageFolder = System.IO.Path.Combine(artifactFolder, "package"); var scriptFolder = System.IO.Path.Combine(artifactFolder, "scripts"); var packagesFolder = System.IO.Path.Combine(workingDirectory, buildPlan.PackagesFolder); +var msbuildBaseFolder = System.IO.Path.Combine(workingDirectory, ".msbuild"); +var msbuildNet46Folder = msbuildBaseFolder + "-net46"; +var msbuildNetCoreAppFolder = msbuildBaseFolder + "-netcoreapp1.0"; /// /// Clean artifacts. @@ -98,7 +84,6 @@ Task("Cleanup") CreateDirectory(logFolder); CreateDirectory(packageFolder); CreateDirectory(scriptFolder); - CreateDirectory(packagesFolder); }); /// @@ -119,30 +104,67 @@ Task("AcquirePackages") .IsDependentOn("BuildEnvironment") .Does(() => { - foreach (var package in buildPlan.Packages) + var configFilePath = System.IO.Path.Combine(packagesFolder, "packages.config"); + + InstallNuGetPackages( + configFilePath: configFilePath, + excludeVersion: true, + noCache: true, + outputDirectory: $"\"{packagesFolder}\""); + + if (DirectoryExists(msbuildNet46Folder)) { - Information($"Downloading {package.Name}..."); + DeleteDirectory(msbuildNet46Folder, recursive: true); + } - DownloadNuGetPackage( - packageID: package.Name, - version: package.Version, - outputDirectory: packagesFolder, - feedUrl: package.FeedURL); + if (DirectoryExists(msbuildNetCoreAppFolder)) + { + DeleteDirectory(msbuildNetCoreAppFolder, recursive: true); + } - var contentFolder = System.IO.Path.Combine(packagesFolder, package.Name); - foreach (var part in package.ContentPath.Split('/')) - { - contentFolder = System.IO.Path.Combine(contentFolder, part); - } + CreateDirectory(msbuildNet46Folder); + CreateDirectory(msbuildNetCoreAppFolder); - if (DirectoryExists(contentFolder)) - { - var targetFolder = System.IO.Path.Combine(workingDirectory, package.TargetFolder); + // Copy MSBuild and SDKs to appropriate locations + var msbuildInstallFolder = System.IO.Path.Combine(packagesFolder, "Microsoft.Build.Runtime", "contentFiles", "any"); + var msbuildNet46InstallFolder = System.IO.Path.Combine(msbuildInstallFolder, "net46"); + var msbuildNetCoreAppInstallFolder = System.IO.Path.Combine(msbuildInstallFolder, "netcoreapp1.0"); - Information($"Copying content to {targetFolder}..."); - CopyDirectory(contentFolder, targetFolder); - } + CopyDirectory(msbuildNet46InstallFolder, msbuildNet46Folder); + CopyDirectory(msbuildNetCoreAppInstallFolder, msbuildNetCoreAppFolder); + + var sdks = new [] + { + "Microsoft.NET.Sdk", + "Microsoft.NET.Sdk.Publish", + "Microsoft.NET.Sdk.Web", + "Microsoft.NET.Sdk.Web.ProjectSystem", + "NuGet.Build.Tasks.Pack" + }; + + var net46SdkFolder = System.IO.Path.Combine(msbuildNet46Folder, "Sdks"); + var netCoreAppSdkFolder = System.IO.Path.Combine(msbuildNetCoreAppFolder, "Sdks"); + + foreach (var sdk in sdks) + { + var sdkInstallFolder = System.IO.Path.Combine(packagesFolder, sdk); + var net46SdkTargetFolder = System.IO.Path.Combine(net46SdkFolder, sdk); + var netCoreAppSdkTargetFolder = System.IO.Path.Combine(netCoreAppSdkFolder, sdk); + + CopyDirectory(sdkInstallFolder, net46SdkTargetFolder); + CopyDirectory(sdkInstallFolder, netCoreAppSdkTargetFolder); + + // Ensure that we don't leave the .nupkg unnecessarily hanging around. + DeleteFiles(System.IO.Path.Combine(net46SdkTargetFolder, "*.nupkg")); + DeleteFiles(System.IO.Path.Combine(netCoreAppSdkTargetFolder, "*.nupkg")); } + + // Finally, copy Microsoft.CSharp.Core.targets from Microsoft.Net.Compilers + var targetsName = "Microsoft.CSharp.Core.targets"; + var csharpTargetsPath = System.IO.Path.Combine(packagesFolder, "Microsoft.Net.Compilers", "tools", targetsName); + + CopyFile(csharpTargetsPath, System.IO.Path.Combine(msbuildNet46Folder, targetsName)); + CopyFile(csharpTargetsPath, System.IO.Path.Combine(msbuildNetCoreAppFolder, targetsName)); }); /// @@ -419,21 +441,8 @@ Task("OnlyPublish") Run(dotnetcli, publishArguments) .ExceptionOnError($"Failed to publish {project} / {framework}"); - // Copy other output from build.json to output folder. - foreach (var copyToOuput in buildPlan.CopyToOutput) - { - var path = System.IO.Path.Combine(workingDirectory, copyToOuput.From); - var targetPath = System.IO.Path.Combine(outputFolder, copyToOuput.To); - - if (DirectoryExists(path)) - { - CopyDirectory(path, targetPath); - } - else if (FileExists(path)) - { - CopyFile(path, targetPath); - } - } + // Copy MSBuild and SDKs to output + CopyDirectory($"{msbuildBaseFolder}-{framework}", System.IO.Path.Combine(outputFolder, "msbuild")); if (requireArchive) { diff --git a/build.json b/build.json index 18531c1d9d..bfa0f91f5f 100644 --- a/build.json +++ b/build.json @@ -7,25 +7,6 @@ "BuildToolsFolder": ".tools", "ArtifactsFolder": "artifacts", "PackagesFolder": "packages", - "Packages": [ - { - "Name": "Microsoft.Build.Runtime", - "Version": "15.1.0-preview-000454-01", - "FeedURL": "https://dotnet.myget.org/F/msbuild/api/v2/package", - "ContentPath": "contentFiles/any/net46", - "TargetFolder": "msbuild" - } - ], - "CopyToOutput": [ - { - "From": "msbuild", - "To": "msbuild" - }, - { - "From": "Microsoft.CSharp.Core.targets", - "To": "msbuild/Microsoft.CSharp.Core.targets" - } - ], "TestProjects": { "OmniSharp.MSBuild.Tests": [ "netcoreapp1.0" diff --git a/packages/packages.config b/packages/packages.config new file mode 100644 index 0000000000..df8c627943 --- /dev/null +++ b/packages/packages.config @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/scripts/nuget.cake b/scripts/nuget.cake index 67ab11c4e9..de5c148ca2 100644 --- a/scripts/nuget.cake +++ b/scripts/nuget.cake @@ -25,11 +25,11 @@ void DownloadNuGetPackage(string packageID, string version, string outputDirecto Unzip(outputFileName, outputFolder); } -ExitStatus InstallNuGetPackage(string packageID, string version = null, bool excludeVersion = false, bool noCache = false, bool prerelease = false, string outputDirectory = null) +private ExitStatus RunNuGetInstall(string packageIdOConfigFilePath, string version, bool excludeVersion, bool noCache, bool prerelease, string outputDirectory) { var nugetPath = Environment.GetEnvironmentVariable("NUGET_EXE"); - var argList = new List { "install", packageID }; + var argList = new List { "install", packageIdOConfigFilePath }; if (!string.IsNullOrWhiteSpace(version)) { @@ -63,4 +63,14 @@ ExitStatus InstallNuGetPackage(string packageID, string version = null, bool exc return IsRunningOnWindows() ? Run(nugetPath, arguments) : Run("mono", $"\"{nugetPath}\" {arguments}"); -} \ No newline at end of file +} + +ExitStatus InstallNuGetPackage(string packageID, string version = null, bool excludeVersion = false, bool noCache = false, bool prerelease = false, string outputDirectory = null) +{ + return RunNuGetInstall(packageID, version, excludeVersion, noCache, prerelease, outputDirectory); +} + +ExitStatus InstallNuGetPackages(string configFilePath, bool excludeVersion = false, bool noCache = false, string outputDirectory = null) +{ + return RunNuGetInstall(configFilePath, null, excludeVersion, noCache, false, outputDirectory); +} diff --git a/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs b/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs index 7b90c8ff73..1a202cfaac 100644 --- a/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs +++ b/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs @@ -70,7 +70,9 @@ public MSBuildProjectSystem( public void Initalize(IConfiguration configuration) { // Set MSBUILD_EXE_PATH to the path of the MSBuild toolset - Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", Path.Combine(AppContext.BaseDirectory, "msbuild")); + var msbuildExePath = Path.Combine(AppContext.BaseDirectory, "msbuild"); + Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuildExePath); + _logger.LogInformation($"MSBUILD_EXE_PATH environment variable set to {msbuildExePath}"); _options = new MSBuildOptions(); ConfigurationBinder.Bind(configuration, _options); From c22949cc95a27413614de91c024e1e2522851c97 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 12 Dec 2016 15:33:57 -0800 Subject: [PATCH 07/17] Remove Microsoft.CSharp.Core.targets now that we copy it from the Microsoft.Net.Compilers package --- Microsoft.CSharp.Core.targets | 152 ---------------------------------- src/OmniSharp/project.json | 3 +- 2 files changed, 1 insertion(+), 154 deletions(-) delete mode 100644 Microsoft.CSharp.Core.targets diff --git a/Microsoft.CSharp.Core.targets b/Microsoft.CSharp.Core.targets deleted file mode 100644 index 14d100b653..0000000000 --- a/Microsoft.CSharp.Core.targets +++ /dev/null @@ -1,152 +0,0 @@ - - - - - $(NoWarn);1701;1702 - - - - - $(NoWarn);2008 - - - - - - - - - - - $(AppConfig) - - - $(IntermediateOutputPath)$(TargetName).compile.pdb - - - - - false - - - - - - - - - - true - - - - - - - - - <_CoreCompileResourceInputs Remove="@(_CoreCompileResourceInputs)" /> - - - - - diff --git a/src/OmniSharp/project.json b/src/OmniSharp/project.json index 86268a41a9..74daaaad7f 100644 --- a/src/OmniSharp/project.json +++ b/src/OmniSharp/project.json @@ -6,8 +6,7 @@ "preserveCompilationContext": true, "emitEntryPoint": true, "copyToOutput": [ - "config.json", - "../../Microsoft.CSharp.Core.targets" + "config.json" ] }, "dependencies": { From 5fd2bec7983b6486ea55899783b483e60ce6d949 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 12 Dec 2016 15:51:58 -0800 Subject: [PATCH 08/17] Properly set MSBuild_EXE_PATH and MSBuildSDKsPath environment variables --- src/OmniSharp.MSBuild/MSBuildProjectSystem.cs | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs b/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs index 1a202cfaac..ba3c07752f 100644 --- a/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs +++ b/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs @@ -69,14 +69,39 @@ public MSBuildProjectSystem( public void Initalize(IConfiguration configuration) { - // Set MSBUILD_EXE_PATH to the path of the MSBuild toolset - var msbuildExePath = Path.Combine(AppContext.BaseDirectory, "msbuild"); - Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuildExePath); - _logger.LogInformation($"MSBUILD_EXE_PATH environment variable set to {msbuildExePath}"); - _options = new MSBuildOptions(); ConfigurationBinder.Bind(configuration, _options); + // Set the MSBUILD_EXE_PATH and MSBuildSDKsPath environment variables + var msbuildFolder = Path.Combine(AppContext.BaseDirectory, "msbuild"); + + var msbuildExePath = Path.Combine(msbuildFolder, "MSBuild.exe"); + if (!File.Exists(msbuildExePath)) + { + msbuildExePath = Path.Combine(msbuildFolder, "MSBuild.dll"); + } + + if (File.Exists(msbuildExePath)) + { + Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuildExePath); + _logger.LogInformation($"MSBUILD_EXE_PATH environment variable set to {msbuildExePath}"); + } + else + { + _logger.LogError("Could not locate MSBuild to set MSBUILD_EXE_PATH");; + } + + var msbuildSdksFolder = Path.Combine(msbuildFolder, "Sdks"); + if (Directory.Exists(msbuildSdksFolder)) + { + Environment.SetEnvironmentVariable("MSBuildSDKsPath", msbuildSdksFolder); + _logger.LogInformation($"MSBuildSDKsPath environment variable set to {msbuildSdksFolder}"); + } + else + { + _logger.LogError("Could not locate MSBuild Sdks path to set MSBuildSDKsPath"); + } + if (_options.WaitForDebugger) { Console.WriteLine($"Attach to process {System.Diagnostics.Process.GetCurrentProcess().Id}"); From 969003b83b5d0a2c6af0f4c0b4491ea0eeda124a Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 12 Dec 2016 16:00:48 -0800 Subject: [PATCH 09/17] Set MSBuildExtensionsPath correctly now that MSBuild is moved to its own folder --- src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfo.cs b/src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfo.cs index d38b0585db..1d3e7f9ce9 100644 --- a/src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfo.cs +++ b/src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfo.cs @@ -124,7 +124,7 @@ public static ProjectFileInfo Create( } else { - globalProperties.Add(PropertyNames.MSBuildExtensionsPath, AppContext.BaseDirectory); + globalProperties.Add(PropertyNames.MSBuildExtensionsPath, Path.Combine(AppContext.BaseDirectory, "msbuild")); } if (PlatformHelper.IsMono) From eb78bd29054de83309fbf4c1bc58835f1608a0fb Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 12 Dec 2016 16:38:56 -0800 Subject: [PATCH 10/17] Remove dead code from nuget.cake --- scripts/nuget.cake | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/scripts/nuget.cake b/scripts/nuget.cake index de5c148ca2..4f4027f438 100644 --- a/scripts/nuget.cake +++ b/scripts/nuget.cake @@ -1,30 +1,5 @@ #load "runhelpers.cake" -using System.Net; - -/// -/// Downloads and unzips a NuGet package directly without any dependencies. -/// -void DownloadNuGetPackage(string packageID, string version, string outputDirectory, string feedUrl) -{ - var outputFolder = System.IO.Path.Combine(outputDirectory, packageID); - var outputFileName = System.IO.Path.ChangeExtension(outputFolder, "nupkg"); - - if (DirectoryExists(outputFolder)) - { - DeleteDirectory(outputFolder, recursive: true); - } - - using (var client = new WebClient()) - { - client.DownloadFile( - address: $"{feedUrl}/{packageID}/{version}", - fileName: outputFileName); - } - - Unzip(outputFileName, outputFolder); -} - private ExitStatus RunNuGetInstall(string packageIdOConfigFilePath, string version, bool excludeVersion, bool noCache, bool prerelease, string outputDirectory) { var nugetPath = Environment.GetEnvironmentVariable("NUGET_EXE"); From 4d5caedc453793ca8b2a5b0bf190d23c567cc602 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 12 Dec 2016 18:17:41 -0800 Subject: [PATCH 11/17] On OSX/Linux, acquire special build of Mono MSBuild for net46 builds --- build.cake | 33 ++++++++++++++++++++++++++++++++- build.json | 2 ++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/build.cake b/build.cake index c921d49642..ba12ed3a7d 100644 --- a/build.cake +++ b/build.cake @@ -41,6 +41,8 @@ public class BuildPlan public string DotNetInstallScriptURL { get; set; } public string DotNetChannel { get; set; } public string DotNetVersion { get; set; } + public string DownloadURL { get; set; } + public string MSBuildForMono { get; set; } public string[] Frameworks { get; set; } public string[] Rids { get; set; } public string MainProject { get; set; } @@ -112,6 +114,27 @@ Task("AcquirePackages") noCache: true, outputDirectory: $"\"{packagesFolder}\""); + var msbuildMonoInstallFolder = System.IO.Path.Combine(packagesFolder, "Microsoft.Build.Runtime.Mono"); + if (!IsRunningOnWindows()) + { + if (DirectoryExists(msbuildMonoInstallFolder)) + { + DeleteDirectory(msbuildMonoInstallFolder, recursive: true); + } + + CreateDirectory(msbuildMonoInstallFolder); + + var msbuildMonoZip = System.IO.Path.Combine(msbuildMonoInstallFolder, buildPlan.MSBuildForMono); + + using (var client = new WebClient()) + { + client.DownloadFile($"{buildPlan.DownloadURL}/{buildPlan.MSBuildForMono}", msbuildMonoZip); + } + + Unzip(msbuildMonoZip, msbuildMonoInstallFolder); + DeleteFile(msbuildMonoZip); + } + if (DirectoryExists(msbuildNet46Folder)) { DeleteDirectory(msbuildNet46Folder, recursive: true); @@ -130,7 +153,15 @@ Task("AcquirePackages") var msbuildNet46InstallFolder = System.IO.Path.Combine(msbuildInstallFolder, "net46"); var msbuildNetCoreAppInstallFolder = System.IO.Path.Combine(msbuildInstallFolder, "netcoreapp1.0"); - CopyDirectory(msbuildNet46InstallFolder, msbuildNet46Folder); + if (IsRunningOnWindows()) + { + CopyDirectory(msbuildNet46InstallFolder, msbuildNet46Folder); + } + else + { + CopyDirectory(msbuildMonoInstallFolder, msbuildNet46Folder); + } + CopyDirectory(msbuildNetCoreAppInstallFolder, msbuildNetCoreAppFolder); var sdks = new [] diff --git a/build.json b/build.json index bfa0f91f5f..d049f5c7b0 100644 --- a/build.json +++ b/build.json @@ -4,6 +4,8 @@ "DotNetInstallScriptURL": "https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0-preview2/scripts/obtain", "DotNetChannel": "preview", "DotNetVersion": "1.0.0-preview2-003131", + "DownloadURL": "https://omnisharpdownload.blob.core.windows.net/ext", + "MSBuildForMono": "Microsoft.Build.Runtime.Mono-alpha1.zip", "BuildToolsFolder": ".tools", "ArtifactsFolder": "artifacts", "PackagesFolder": "packages", From 9d2617fb4e99a764fa1083712c10be05ca5220da Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 12 Dec 2016 19:51:01 -0800 Subject: [PATCH 12/17] On OSX/Linux, copy over MSBuild libraries with special Mono MSBuild build for net46 --- build.cake | 39 +++++++++++++++++++++++++++++---------- build.json | 3 ++- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/build.cake b/build.cake index ba12ed3a7d..72868d0645 100644 --- a/build.cake +++ b/build.cake @@ -42,7 +42,8 @@ public class BuildPlan public string DotNetChannel { get; set; } public string DotNetVersion { get; set; } public string DownloadURL { get; set; } - public string MSBuildForMono { get; set; } + public string MSBuildRuntimeForMono { get; set; } + public string MSBuildLibForMono { get; set; } public string[] Frameworks { get; set; } public string[] Rids { get; set; } public string MainProject { get; set; } @@ -70,6 +71,8 @@ var packagesFolder = System.IO.Path.Combine(workingDirectory, buildPlan.Packages var msbuildBaseFolder = System.IO.Path.Combine(workingDirectory, ".msbuild"); var msbuildNet46Folder = msbuildBaseFolder + "-net46"; var msbuildNetCoreAppFolder = msbuildBaseFolder + "-netcoreapp1.0"; +var msbuildRuntimeForMonoInstallFolder = System.IO.Path.Combine(packagesFolder, "Microsoft.Build.Runtime.Mono"); +var msbuildLibForMonoInstallFolder = System.IO.Path.Combine(packagesFolder, "Microsoft.Build.Lib.Mono"); /// /// Clean artifacts. @@ -114,25 +117,35 @@ Task("AcquirePackages") noCache: true, outputDirectory: $"\"{packagesFolder}\""); - var msbuildMonoInstallFolder = System.IO.Path.Combine(packagesFolder, "Microsoft.Build.Runtime.Mono"); if (!IsRunningOnWindows()) { - if (DirectoryExists(msbuildMonoInstallFolder)) + if (DirectoryExists(msbuildRuntimeForMonoInstallFolder)) { - DeleteDirectory(msbuildMonoInstallFolder, recursive: true); + DeleteDirectory(msbuildRuntimeForMonoInstallFolder, recursive: true); } - CreateDirectory(msbuildMonoInstallFolder); + if (DirectoryExists(msbuildLibForMonoInstallFolder)) + { + DeleteDirectory(msbuildLibForMonoInstallFolder, recursive: true); + } - var msbuildMonoZip = System.IO.Path.Combine(msbuildMonoInstallFolder, buildPlan.MSBuildForMono); + CreateDirectory(msbuildRuntimeForMonoInstallFolder); + CreateDirectory(msbuildLibForMonoInstallFolder); + + var msbuildMonoRuntimeZip = System.IO.Path.Combine(msbuildRuntimeForMonoInstallFolder, buildPlan.MSBuildRuntimeForMono); + var msbuildMonoLibZip = System.IO.Path.Combine(msbuildLibForMonoInstallFolder, buildPlan.MSBuildLibForMono); using (var client = new WebClient()) { - client.DownloadFile($"{buildPlan.DownloadURL}/{buildPlan.MSBuildForMono}", msbuildMonoZip); + client.DownloadFile($"{buildPlan.DownloadURL}/{buildPlan.MSBuildRuntimeForMono}", msbuildMonoRuntimeZip); + client.DownloadFile($"{buildPlan.DownloadURL}/{buildPlan.MSBuildLibForMono}", msbuildMonoLibZip); } - Unzip(msbuildMonoZip, msbuildMonoInstallFolder); - DeleteFile(msbuildMonoZip); + Unzip(msbuildMonoRuntimeZip, msbuildRuntimeForMonoInstallFolder); + Unzip(msbuildMonoLibZip, msbuildLibForMonoInstallFolder); + + DeleteFile(msbuildMonoRuntimeZip); + DeleteFile(msbuildMonoLibZip); } if (DirectoryExists(msbuildNet46Folder)) @@ -159,7 +172,7 @@ Task("AcquirePackages") } else { - CopyDirectory(msbuildMonoInstallFolder, msbuildNet46Folder); + CopyDirectory(msbuildRuntimeForMonoInstallFolder, msbuildNet46Folder); } CopyDirectory(msbuildNetCoreAppInstallFolder, msbuildNetCoreAppFolder); @@ -475,6 +488,12 @@ Task("OnlyPublish") // Copy MSBuild and SDKs to output CopyDirectory($"{msbuildBaseFolder}-{framework}", System.IO.Path.Combine(outputFolder, "msbuild")); + // For OSX/Linux net46 builds, copy the MSBuild libraries built for Mono. + if (!IsRunningOnWindows() && framework == "net46") + { + CopyDirectory($"{msbuildLibForMonoInstallFolder}", outputFolder); + } + if (requireArchive) { Package(runtime, framework, outputFolder, packageFolder, buildPlan.MainProject.ToLower()); diff --git a/build.json b/build.json index d049f5c7b0..b42c252c93 100644 --- a/build.json +++ b/build.json @@ -5,7 +5,8 @@ "DotNetChannel": "preview", "DotNetVersion": "1.0.0-preview2-003131", "DownloadURL": "https://omnisharpdownload.blob.core.windows.net/ext", - "MSBuildForMono": "Microsoft.Build.Runtime.Mono-alpha1.zip", + "MSBuildRuntimeForMono": "Microsoft.Build.Runtime.Mono-alpha1.zip", + "MSBuildLibForMono": "Microsoft.Build.Lib.Mono-alpha1.zip", "BuildToolsFolder": ".tools", "ArtifactsFolder": "artifacts", "PackagesFolder": "packages", From 5071d3c757db860a0e1e44b8ddb40d03b2bd3968 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 12 Dec 2016 21:33:48 -0800 Subject: [PATCH 13/17] Delete a handful of binaries that aren't necessary (and sometimes harmful) on net46 builds targeting Mono --- build.cake | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/build.cake b/build.cake index 72868d0645..7a4d6c01a6 100644 --- a/build.cake +++ b/build.cake @@ -492,6 +492,20 @@ Task("OnlyPublish") if (!IsRunningOnWindows() && framework == "net46") { CopyDirectory($"{msbuildLibForMonoInstallFolder}", outputFolder); + + // Delete a handful of binaries that aren't necessary (and in some cases harmful) when running on Mono. + DeleteFile(System.IO.Path.Combine(outputFolder, "System.AppContext.dll")); + DeleteFile(System.IO.Path.Combine(outputFolder, "System.Numerics.Vectors.dll")); + DeleteFile(System.IO.Path.Combine(outputFolder, "System.Runtime.InteropServices.RuntimeInformation.dll")); + DeleteFile(System.IO.Path.Combine(outputFolder, "System.ComponentModel.Primitives.dll")); + DeleteFile(System.IO.Path.Combine(outputFolder, "System.ComponentModel.TypeConverter.dll")); + DeleteFile(System.IO.Path.Combine(outputFolder, "System.Console.dll")); + DeleteFile(System.IO.Path.Combine(outputFolder, "System.IO.FileSystem.Primitives.dll")); + DeleteFile(System.IO.Path.Combine(outputFolder, "System.IO.FileSystem.dll")); + DeleteFile(System.IO.Path.Combine(outputFolder, "System.Security.Cryptography.Encoding.dll")); + DeleteFile(System.IO.Path.Combine(outputFolder, "System.Security.Cryptography.Primitives.dll")); + DeleteFile(System.IO.Path.Combine(outputFolder, "System.Security.Cryptography.X509Certificates.dll")); + DeleteFile(System.IO.Path.Combine(outputFolder, "System.Threading.Thread.dll")); } if (requireArchive) From b4f6d6338cf45db10e6c31eab98892a4da5d0e25 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 13 Dec 2016 14:41:00 -0800 Subject: [PATCH 14/17] Expose public static method on MSBuildProjectSystem to set MSBuild environment variables --- src/OmniSharp.MSBuild/MSBuildProjectSystem.cs | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs b/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs index ba3c07752f..5d3132b19c 100644 --- a/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs +++ b/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs @@ -67,40 +67,51 @@ public MSBuildProjectSystem( _logger = loggerFactory.CreateLogger("OmniSharp#MSBuild"); } - public void Initalize(IConfiguration configuration) + public static void SetUpMSBuildEnvironment(string msbuildFolder, ILogger logger) { - _options = new MSBuildOptions(); - ConfigurationBinder.Bind(configuration, _options); - - // Set the MSBUILD_EXE_PATH and MSBuildSDKsPath environment variables - var msbuildFolder = Path.Combine(AppContext.BaseDirectory, "msbuild"); - + // Set the MSBUILD_EXE_PATH environment variable to the location of MSBuild.exe or MSBuild.dll. var msbuildExePath = Path.Combine(msbuildFolder, "MSBuild.exe"); if (!File.Exists(msbuildExePath)) { msbuildExePath = Path.Combine(msbuildFolder, "MSBuild.dll"); } + if (!File.Exists(msbuildExePath)) + { + logger.LogError("Could not locate MSBuild to set MSBUILD_EXE_PATH"); + return; + } + if (File.Exists(msbuildExePath)) { Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuildExePath); - _logger.LogInformation($"MSBUILD_EXE_PATH environment variable set to {msbuildExePath}"); + logger.LogInformation($"MSBUILD_EXE_PATH environment variable set to {msbuildExePath}"); } else { - _logger.LogError("Could not locate MSBuild to set MSBUILD_EXE_PATH");; + logger.LogError("Could not locate MSBuild to set MSBUILD_EXE_PATH"); ; } + // Set the MSBuildSDKsPath environment variable to the location of the SDKs. var msbuildSdksFolder = Path.Combine(msbuildFolder, "Sdks"); if (Directory.Exists(msbuildSdksFolder)) { Environment.SetEnvironmentVariable("MSBuildSDKsPath", msbuildSdksFolder); - _logger.LogInformation($"MSBuildSDKsPath environment variable set to {msbuildSdksFolder}"); + logger.LogInformation($"MSBuildSDKsPath environment variable set to {msbuildSdksFolder}"); } else { - _logger.LogError("Could not locate MSBuild Sdks path to set MSBuildSDKsPath"); + logger.LogError("Could not locate MSBuild Sdks path to set MSBuildSDKsPath"); } + } + + public void Initalize(IConfiguration configuration) + { + _options = new MSBuildOptions(); + ConfigurationBinder.Bind(configuration, _options); + + var msbuildFolder = Path.Combine(AppContext.BaseDirectory, "msbuild"); + SetUpMSBuildEnvironment(msbuildFolder, _logger); if (_options.WaitForDebugger) { From 15b8d855709add99aca42c2f8c9e178496301eb7 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 13 Dec 2016 15:05:33 -0800 Subject: [PATCH 15/17] Use .msbuild-* folder in MSBuild tests --- src/OmniSharp.MSBuild/MSBuildProjectSystem.cs | 4 +++ .../ProjectFile/ProjectFileInfo.cs | 4 --- .../ProjectFileInfoTests.cs | 32 ++++++------------- tests/OmniSharp.MSBuild.Tests/project.json | 1 - 4 files changed, 14 insertions(+), 27 deletions(-) diff --git a/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs b/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs index 5d3132b19c..e8275f78e4 100644 --- a/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs +++ b/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs @@ -69,6 +69,10 @@ public MSBuildProjectSystem( public static void SetUpMSBuildEnvironment(string msbuildFolder, ILogger logger) { + // Set the MSBuildExtensionsPath environment variable to the msbuild folder. + Environment.SetEnvironmentVariable("MSBuildExtensionsPath", msbuildFolder); + logger.LogInformation($"MSBuildExtensionsPath environment variable set to {msbuildFolder}"); + // Set the MSBUILD_EXE_PATH environment variable to the location of MSBuild.exe or MSBuild.dll. var msbuildExePath = Path.Combine(msbuildFolder, "MSBuild.exe"); if (!File.Exists(msbuildExePath)) diff --git a/src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfo.cs b/src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfo.cs index 1d3e7f9ce9..78eb750933 100644 --- a/src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfo.cs +++ b/src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfo.cs @@ -122,10 +122,6 @@ public static ProjectFileInfo Create( { globalProperties.Add(PropertyNames.MSBuildExtensionsPath, options.MSBuildExtensionsPath); } - else - { - globalProperties.Add(PropertyNames.MSBuildExtensionsPath, Path.Combine(AppContext.BaseDirectory, "msbuild")); - } if (PlatformHelper.IsMono) { diff --git a/tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs b/tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs index 8998cbfc35..9260adb0b0 100644 --- a/tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs +++ b/tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs @@ -1,5 +1,4 @@ -using System; -using System.IO; +using System.IO; using Microsoft.Extensions.Logging; using OmniSharp.MSBuild.ProjectFile; using TestUtility; @@ -8,15 +7,11 @@ namespace OmniSharp.MSBuild.Tests { - public class ProjectFileInfoTests : IDisposable + public class ProjectFileInfoTests { private readonly TestAssets _testAssets; private readonly ILogger _logger; - private const string MSBUILD_EXE_PATH = "MSBUILD_EXE_PATH"; - private readonly bool _isMSBuildExePathSet; - private readonly string _previousMSBuildExePath; - public ProjectFileInfoTests() { this._testAssets = TestAssets.Instance; @@ -24,24 +19,17 @@ public ProjectFileInfoTests() var loggerFactory = new FakeLoggerFactory(); this._logger = loggerFactory.CreateLogger("test"); - var msbuildExePath = Path.Combine(Directory.GetCurrentDirectory(), "msbuild.exe"); - if (File.Exists(msbuildExePath)) - { - this._previousMSBuildExePath = Environment.GetEnvironmentVariable(MSBUILD_EXE_PATH); - Environment.SetEnvironmentVariable(MSBUILD_EXE_PATH, msbuildExePath); - this._isMSBuildExePathSet = true; - } - } +#if NET46 + var folderName = ".msbuild-net46"; +#else + var folderName = ".msbuild-netcoreapp1.0"; +#endif - public void Dispose() - { - if (this._isMSBuildExePathSet) - { - Environment.SetEnvironmentVariable(MSBUILD_EXE_PATH, this._previousMSBuildExePath); - } + var msbuildFolder = Path.Combine(this._testAssets.SolutionFolder, folderName); + MSBuildProjectSystem.SetUpMSBuildEnvironment(msbuildFolder, this._logger); } - [Fact(Skip = "Doesn't run on OSX/Linux yet")] + [Fact] public void Hello_world_has_correct_property_values() { var projectFolder = _testAssets.GetTestProjectFolder("HelloWorld"); diff --git a/tests/OmniSharp.MSBuild.Tests/project.json b/tests/OmniSharp.MSBuild.Tests/project.json index ab6594cb1b..c8ddadf1fd 100644 --- a/tests/OmniSharp.MSBuild.Tests/project.json +++ b/tests/OmniSharp.MSBuild.Tests/project.json @@ -8,7 +8,6 @@ }, "dependencies": { "OmniSharp.MSBuild": "1.0.0", - "Microsoft.Build.Runtime": "15.1.0-preview-000454-01", "TestUtility": "1.0.0", "xunit": "2.1.0" }, From f1c9fde4d1277671bbd4f3c70c2a0cf3d9432dc4 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 13 Dec 2016 16:39:04 -0800 Subject: [PATCH 16/17] Add TestLogger utility for logging output to xUnit --- tests/TestUtility/TestLogger.cs | 34 +++++++++++++++++++++++++++++++++ tests/TestUtility/project.json | 3 ++- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 tests/TestUtility/TestLogger.cs diff --git a/tests/TestUtility/TestLogger.cs b/tests/TestUtility/TestLogger.cs new file mode 100644 index 0000000000..56213d6fe3 --- /dev/null +++ b/tests/TestUtility/TestLogger.cs @@ -0,0 +1,34 @@ +using System; +using Microsoft.Extensions.Logging; +using Xunit.Abstractions; + +namespace TestUtility +{ + public class TestLogger : ILogger + { + private readonly ITestOutputHelper _output; + + public TestLogger(ITestOutputHelper output) + { + this._output = output; + } + + public bool IsEnabled(LogLevel level) => true; + + public IDisposable BeginScope(TState state) => new NoopDisposable(); + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + var text = formatter(state, exception); + if (!string.IsNullOrEmpty(text) || exception != null) + { + _output.WriteLine(text); + } + } + + private class NoopDisposable : IDisposable + { + public void Dispose() { } + } + } +} diff --git a/tests/TestUtility/project.json b/tests/TestUtility/project.json index fa7f2d083f..9ae69141d1 100644 --- a/tests/TestUtility/project.json +++ b/tests/TestUtility/project.json @@ -8,7 +8,8 @@ "OmniSharp.Roslyn.CSharp": "1.0.0", "Microsoft.CodeAnalysis.CSharp.Workspaces": "2.0.0-rc", "Microsoft.DotNet.ProjectModel": "1.0.0-rc3-003121", - "Microsoft.DotNet.ProjectModel.Workspaces": "1.0.0-preview2-003121" + "Microsoft.DotNet.ProjectModel.Workspaces": "1.0.0-preview2-003121", + "xunit": "2.1.0" }, "frameworks": { "netstandard1.6": { From 386d3e325fa2b51b19313d3143af6c25dc1af975 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 13 Dec 2016 16:39:18 -0800 Subject: [PATCH 17/17] Skip unit test --- src/OmniSharp.MSBuild/MSBuildProjectSystem.cs | 51 +++++++++++++++++-- .../ProjectFileInfoTests.cs | 22 +++----- tests/OmniSharp.MSBuild.Tests/project.json | 5 +- 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs b/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs index e8275f78e4..5fdc10a57a 100644 --- a/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs +++ b/src/OmniSharp.MSBuild/MSBuildProjectSystem.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Composition; +using System.Diagnostics; using System.IO; using System.Linq; using System.Text; @@ -67,8 +68,49 @@ public MSBuildProjectSystem( _logger = loggerFactory.CreateLogger("OmniSharp#MSBuild"); } - public static void SetUpMSBuildEnvironment(string msbuildFolder, ILogger logger) + private static string FindMSBuildFolder() { + // Try to locate the appropriate build-time msbuild folder by searching for + // the OmniSharp solution relative to the current folder. + + var current = Directory.GetCurrentDirectory(); + while (!File.Exists(Path.Combine(current, "OmniSharp.sln"))) + { + current = Path.GetDirectoryName(current); + if (Path.GetPathRoot(current) == current) + { + break; + } + } + +#if NET46 + var folderName = ".msbuild-net46"; +#else + var folderName = ".msbuild-netcoreapp1.0"; +#endif + + var result = Path.Combine(current, folderName); + + return Directory.Exists(result) + ? result + : null; + } + + public static void SetUpMSBuildEnvironment(ILogger logger) + { + var msbuildFolder = Path.Combine(AppContext.BaseDirectory, "msbuild"); + + if (!Directory.Exists(msbuildFolder)) + { + msbuildFolder = FindMSBuildFolder(); + } + + if (msbuildFolder == null || !Directory.Exists(msbuildFolder)) + { + logger.LogError("Could not locate MSBuild path. MSBuildProjectSystem will not function properly."); + return; + } + // Set the MSBuildExtensionsPath environment variable to the msbuild folder. Environment.SetEnvironmentVariable("MSBuildExtensionsPath", msbuildFolder); logger.LogInformation($"MSBuildExtensionsPath environment variable set to {msbuildFolder}"); @@ -114,13 +156,12 @@ public void Initalize(IConfiguration configuration) _options = new MSBuildOptions(); ConfigurationBinder.Bind(configuration, _options); - var msbuildFolder = Path.Combine(AppContext.BaseDirectory, "msbuild"); - SetUpMSBuildEnvironment(msbuildFolder, _logger); + SetUpMSBuildEnvironment(_logger); if (_options.WaitForDebugger) { - Console.WriteLine($"Attach to process {System.Diagnostics.Process.GetCurrentProcess().Id}"); - while (!System.Diagnostics.Debugger.IsAttached) + Console.WriteLine($"Attach to process {Process.GetCurrentProcess().Id}"); + while (!Debugger.IsAttached) { System.Threading.Thread.Sleep(100); } diff --git a/tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs b/tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs index 9260adb0b0..f9231896e3 100644 --- a/tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs +++ b/tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs @@ -1,9 +1,11 @@ -using System.IO; +using System; +using System.IO; using Microsoft.Extensions.Logging; using OmniSharp.MSBuild.ProjectFile; using TestUtility; using TestUtility.Fake; using Xunit; +using Xunit.Abstractions; namespace OmniSharp.MSBuild.Tests { @@ -12,24 +14,15 @@ public class ProjectFileInfoTests private readonly TestAssets _testAssets; private readonly ILogger _logger; - public ProjectFileInfoTests() + public ProjectFileInfoTests(ITestOutputHelper output) { this._testAssets = TestAssets.Instance; + this._logger = new TestLogger(output); - var loggerFactory = new FakeLoggerFactory(); - this._logger = loggerFactory.CreateLogger("test"); - -#if NET46 - var folderName = ".msbuild-net46"; -#else - var folderName = ".msbuild-netcoreapp1.0"; -#endif - - var msbuildFolder = Path.Combine(this._testAssets.SolutionFolder, folderName); - MSBuildProjectSystem.SetUpMSBuildEnvironment(msbuildFolder, this._logger); + MSBuildProjectSystem.SetUpMSBuildEnvironment(this._logger); } - [Fact] + [Fact(Skip = "Won't work until we restore .NET Core .csproj projects")] public void Hello_world_has_correct_property_values() { var projectFolder = _testAssets.GetTestProjectFolder("HelloWorld"); @@ -37,6 +30,7 @@ public void Hello_world_has_correct_property_values() var projectFileInfo = ProjectFileInfo.Create(projectFilePath, projectFolder, this._logger); + Assert.NotNull(projectFileInfo); Assert.Equal(projectFilePath, projectFileInfo.ProjectFilePath); Assert.Equal(1, projectFileInfo.TargetFrameworks.Count); Assert.Equal(".NETCoreApp,Version=v1.0", projectFileInfo.TargetFrameworks[0].DotNetFrameworkName); diff --git a/tests/OmniSharp.MSBuild.Tests/project.json b/tests/OmniSharp.MSBuild.Tests/project.json index c8ddadf1fd..e05b197eca 100644 --- a/tests/OmniSharp.MSBuild.Tests/project.json +++ b/tests/OmniSharp.MSBuild.Tests/project.json @@ -1,10 +1,7 @@ { "version": "1.0.0-*", "buildOptions": { - "warningsAsErrors": true, - "copyToOutput": [ - "../../Microsoft.CSharp.Core.targets" - ] + "warningsAsErrors": true }, "dependencies": { "OmniSharp.MSBuild": "1.0.0",