Skip to content

Commit

Permalink
Enable per-workspace override of MSBuildExtensionsPath.
Browse files Browse the repository at this point in the history
  • Loading branch information
tintoy committed Nov 24, 2018
1 parent 612fd66 commit 8489b1c
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 8 deletions.
42 changes: 35 additions & 7 deletions src/LanguageServer.Common/Utilities/MSBuildHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,17 @@ public static class MSBuildHelper
/// <param name="solutionDirectory">
/// The base (i.e. solution) directory.
/// </param>
/// <param name="globalPropertyOverrides">
/// An optional dictionary containing property values to override.
/// </param>
/// <returns>
/// The project collection.
/// </returns>
public static ProjectCollection CreateProjectCollection(string solutionDirectory)
public static ProjectCollection CreateProjectCollection(string solutionDirectory, Dictionary<string, string> globalPropertyOverrides = null)
{
return CreateProjectCollection(solutionDirectory,
DotNetRuntimeInfo.GetCurrent(solutionDirectory)
DotNetRuntimeInfo.GetCurrent(solutionDirectory),
globalPropertyOverrides
);
}

Expand All @@ -56,10 +60,13 @@ public static ProjectCollection CreateProjectCollection(string solutionDirectory
/// <param name="runtimeInfo">
/// Information about the current .NET Core runtime.
/// </param>
/// <param name="globalPropertyOverrides">
/// An optional dictionary containing property values to override.
/// </param>
/// <returns>
/// The project collection.
/// </returns>
public static ProjectCollection CreateProjectCollection(string solutionDirectory, DotNetRuntimeInfo runtimeInfo)
public static ProjectCollection CreateProjectCollection(string solutionDirectory, DotNetRuntimeInfo runtimeInfo, Dictionary<string, string> globalPropertyOverrides = null)
{
if (String.IsNullOrWhiteSpace(solutionDirectory))
throw new ArgumentException("Argument cannot be null, empty, or entirely composed of whitespace: 'baseDir'.", nameof(solutionDirectory));
Expand All @@ -70,7 +77,7 @@ public static ProjectCollection CreateProjectCollection(string solutionDirectory
if (String.IsNullOrWhiteSpace(runtimeInfo.BaseDirectory))
throw new InvalidOperationException("Cannot determine base directory for .NET Core (check the output of 'dotnet --info').");

Dictionary<string, string> globalProperties = CreateGlobalMSBuildProperties(runtimeInfo, solutionDirectory);
Dictionary<string, string> globalProperties = CreateGlobalMSBuildProperties(runtimeInfo, solutionDirectory, globalPropertyOverrides);
EnsureMSBuildEnvironment(globalProperties);

ProjectCollection projectCollection = new ProjectCollection(globalProperties) { IsBuildEnabled = false };
Expand All @@ -79,7 +86,7 @@ public static ProjectCollection CreateProjectCollection(string solutionDirectory
Toolset toolset = projectCollection.GetToolset("15.0");
toolset = new Toolset(
toolsVersion: "15.0",
toolsPath: globalProperties["MSBuildExtensionsPath"],
toolsPath: runtimeInfo.BaseDirectory,
projectCollection: projectCollection,
msbuildOverrideTasksPath: ""
);
Expand All @@ -97,10 +104,13 @@ public static ProjectCollection CreateProjectCollection(string solutionDirectory
/// <param name="solutionDirectory">
/// The base (i.e. solution) directory.
/// </param>
/// <param name="globalPropertyOverrides">
/// An optional dictionary containing property values to override.
/// </param>
/// <returns>
/// A dictionary containing the global properties.
/// </returns>
public static Dictionary<string, string> CreateGlobalMSBuildProperties(DotNetRuntimeInfo runtimeInfo, string solutionDirectory)
public static Dictionary<string, string> CreateGlobalMSBuildProperties(DotNetRuntimeInfo runtimeInfo, string solutionDirectory, Dictionary<string, string> globalPropertyOverrides = null)
{
if (runtimeInfo == null)
throw new ArgumentNullException(nameof(runtimeInfo));
Expand All @@ -116,7 +126,7 @@ public static Dictionary<string, string> CreateGlobalMSBuildProperties(DotNetRun
if (String.IsNullOrWhiteSpace(sdksPath))
sdksPath = Path.Combine(runtimeInfo.BaseDirectory, "Sdks");

return new Dictionary<string, string>
var globalProperties = new Dictionary<string, string>
{
[WellKnownPropertyNames.DesignTimeBuild] = "true",
[WellKnownPropertyNames.BuildProjectReferences] = "false",
Expand All @@ -126,6 +136,14 @@ public static Dictionary<string, string> CreateGlobalMSBuildProperties(DotNetRun
[WellKnownPropertyNames.MSBuildSDKsPath] = sdksPath,
[WellKnownPropertyNames.RoslynTargetsPath] = Path.Combine(runtimeInfo.BaseDirectory, "Roslyn")
};

if (globalPropertyOverrides != null)
{
foreach (string propertyName in globalPropertyOverrides.Keys)
globalProperties[propertyName] = globalPropertyOverrides[propertyName];
}

return globalProperties;
}

/// <summary>
Expand Down Expand Up @@ -230,11 +248,21 @@ public static class WellKnownPropertyNames
/// </summary>
public static readonly string MSBuildExtensionsPath = "MSBuildExtensionsPath";

/// <summary>
/// The "MSBuildExtensionsPath32" property.
/// </summary>
public static readonly string MSBuildExtensionsPath32 = "MSBuildExtensionsPath32";

/// <summary>
/// The "MSBuildSDKsPath" property.
/// </summary>
public static readonly string MSBuildSDKsPath = "MSBuildSDKsPath";

/// <summary>
/// The "MSBuildToolsPath" property.
/// </summary>
public static readonly string MSBuildToolsPath = "MSBuildToolsPath";

/// <summary>
/// The "SolutionDir" property.
/// </summary>
Expand Down
31 changes: 31 additions & 0 deletions src/LanguageServer.Engine/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ public Configuration()
/// </summary>
[JsonProperty("language", ObjectCreationHandling = ObjectCreationHandling.Reuse)]
public LanguageConfiguration Language { get; } = new LanguageConfiguration();

/// <summary>
/// The MSBuild language service's MSBuild engine configuration.
/// </summary>
[JsonProperty("msbuild", ObjectCreationHandling = ObjectCreationHandling.Reuse)]
public MSBuildConfiguration MSBuild { get; } = new MSBuildConfiguration();

/// <summary>
/// The MSBuild language service's NuGet configuration.
Expand Down Expand Up @@ -162,6 +168,31 @@ public LanguageConfiguration()
public HashSet<CompletionSource> CompletionsFromProject { get; } = new HashSet<CompletionSource>();
}

/// <summary>
/// Configuration for the MSBuild engine.
/// </summary>
public class MSBuildConfiguration
{
/// <summary>
/// Create a new <see cref="MSBuildConfiguration"/>.
/// </summary>
public MSBuildConfiguration()
{
}

/// <summary>
/// Override the default value of MSBuildExtensionsPath.
/// </summary>
[JsonProperty("extensionsPath")]
public string ExtensionsPath { get; set; }

/// <summary>
/// Override the default value of MSBuildExtensionsPath32.
/// </summary>
[JsonProperty("extensionsPath32")]
public string ExtensionsPath32 { get; set; }
}

/// <summary>
/// Configuration for disabled language-service features.
/// </summary>
Expand Down
6 changes: 5 additions & 1 deletion src/LanguageServer.Engine/Documents/MasterProjectDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,11 @@ protected override bool TryLoadMSBuildProject()
return true;

if (MSBuildProjectCollection == null)
MSBuildProjectCollection = MSBuildHelper.CreateProjectCollection(ProjectFile.Directory.FullName);
{
MSBuildProjectCollection = MSBuildHelper.CreateProjectCollection(ProjectFile.Directory.FullName,
globalPropertyOverrides: GetMSBuildGlobalPropertyOverrides()
);
}

if (HasMSBuildProject && IsDirty)
{
Expand Down
14 changes: 14 additions & 0 deletions src/LanguageServer.Engine/Documents/ProjectDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,20 @@ public Range GetRange(ExpressionNode expression, Position relativeToPosition)
return metadata;
}

/// <summary>
/// Get overrides (if any) for MSBuild global properties.
/// </summary>
protected virtual Dictionary<string, string> GetMSBuildGlobalPropertyOverrides()
{
var propertyOverrides = new Dictionary<string, string>();
if (!String.IsNullOrWhiteSpace(Workspace.Configuration.MSBuild.ExtensionsPath))
propertyOverrides[MSBuildHelper.WellKnownPropertyNames.MSBuildExtensionsPath] = Workspace.Configuration.MSBuild.ExtensionsPath;
if (!String.IsNullOrWhiteSpace(Workspace.Configuration.MSBuild.ExtensionsPath32))
propertyOverrides[MSBuildHelper.WellKnownPropertyNames.MSBuildExtensionsPath32] = Workspace.Configuration.MSBuild.ExtensionsPath32;

return propertyOverrides;
}

/// <summary>
/// Attempt to load the underlying MSBuild project.
/// </summary>
Expand Down

0 comments on commit 8489b1c

Please sign in to comment.