Skip to content

Commit

Permalink
Port OmniSharp#1021 to master
Browse files Browse the repository at this point in the history
  • Loading branch information
DustinCampbell committed Nov 10, 2017
1 parent 2c2bcdc commit 00efa68
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 15 deletions.
38 changes: 25 additions & 13 deletions src/OmniSharp.MSBuild/ProjectLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ internal class ProjectLoader
private readonly ILogger _logger;
private readonly Dictionary<string, string> _globalProperties;
private readonly MSBuildOptions _options;
private readonly SdksPathResolver _sdksPathResolver;

public ProjectLoader(MSBuildOptions options, string solutionDirectory, ImmutableDictionary<string, string> propertyOverrides, ILoggerFactory loggerFactory)
public ProjectLoader(MSBuildOptions options, string solutionDirectory, ImmutableDictionary<string, string> propertyOverrides, ILoggerFactory loggerFactory, SdksPathResolver sdksPathResolver)
{
_logger = loggerFactory.CreateLogger<ProjectLoader>();
_options = options ?? new MSBuildOptions();

_sdksPathResolver = sdksPathResolver ?? throw new ArgumentNullException(nameof(sdksPathResolver));
_globalProperties = CreateGlobalProperties(_options, solutionDirectory, propertyOverrides, _logger);
}

Expand Down Expand Up @@ -56,24 +57,35 @@ private static Dictionary<string, string> CreateGlobalProperties(

public (MSB.Execution.ProjectInstance projectInstance, ImmutableArray<MSBuildDiagnostic> diagnostics) BuildProject(string filePath)
{
var evaluatedProject = EvaluateProjectFile(filePath);
using (_sdksPathResolver.SetSdksPathEnvironmentVariable(filePath))
{
var evaluatedProject = EvaluateProjectFileCore(filePath);

SetTargetFrameworkIfNeeded(evaluatedProject);
SetTargetFrameworkIfNeeded(evaluatedProject);

var projectInstance = evaluatedProject.CreateProjectInstance();
var msbuildLogger = new MSBuildLogger(_logger);
var buildResult = projectInstance.Build(
targets: new string[] { TargetNames.Compile, TargetNames.CoreCompile },
loggers: new[] { msbuildLogger });
var projectInstance = evaluatedProject.CreateProjectInstance();
var msbuildLogger = new MSBuildLogger(_logger);
var buildResult = projectInstance.Build(
targets: new string[] { TargetNames.Compile, TargetNames.CoreCompile },
loggers: new[] { msbuildLogger });

var diagnostics = msbuildLogger.GetDiagnostics();
var diagnostics = msbuildLogger.GetDiagnostics();

return buildResult
? (projectInstance, diagnostics)
: (null, diagnostics);
return buildResult
? (projectInstance, diagnostics)
: (null, diagnostics);
}
}

public MSB.Evaluation.Project EvaluateProjectFile(string filePath)
{
using (_sdksPathResolver.SetSdksPathEnvironmentVariable(filePath))
{
return EvaluateProjectFileCore(filePath);
}
}

private MSB.Evaluation.Project EvaluateProjectFileCore(string filePath)
{
// Evaluate the MSBuild project
var projectCollection = new MSB.Evaluation.ProjectCollection(_globalProperties);
Expand Down
5 changes: 4 additions & 1 deletion src/OmniSharp.MSBuild/ProjectSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class ProjectSystem : IProjectSystem
private readonly OmniSharpWorkspace _workspace;
private readonly ImmutableDictionary<string, string> _propertyOverrides;
private readonly DotNetCliService _dotNetCli;
private readonly SdksPathResolver _sdksPathResolver;
private readonly MetadataFileReferenceCache _metadataFileReferenceCache;
private readonly IEventEmitter _eventEmitter;
private readonly IFileSystemWatcher _fileSystemWatcher;
Expand All @@ -51,6 +52,7 @@ public ProjectSystem(
OmniSharpWorkspace workspace,
IMSBuildLocator msbuildLocator,
DotNetCliService dotNetCliService,
SdksPathResolver sdksPathResolver,
MetadataFileReferenceCache metadataFileReferenceCache,
IEventEmitter eventEmitter,
IFileSystemWatcher fileSystemWatcher,
Expand All @@ -60,6 +62,7 @@ public ProjectSystem(
_workspace = workspace;
_propertyOverrides = msbuildLocator.RegisteredInstance.PropertyOverrides;
_dotNetCli = dotNetCliService;
_sdksPathResolver = sdksPathResolver;
_metadataFileReferenceCache = metadataFileReferenceCache;
_eventEmitter = eventEmitter;
_fileSystemWatcher = fileSystemWatcher;
Expand All @@ -81,7 +84,7 @@ public void Initalize(IConfiguration configuration)
}

_packageDependencyChecker = new PackageDependencyChecker(_loggerFactory, _eventEmitter, _dotNetCli, _options);
_loader = new ProjectLoader(_options, _environment.TargetDirectory, _propertyOverrides, _loggerFactory);
_loader = new ProjectLoader(_options, _environment.TargetDirectory, _propertyOverrides, _loggerFactory, _sdksPathResolver);
_manager = new ProjectManager(_loggerFactory, _eventEmitter, _fileSystemWatcher, _metadataFileReferenceCache, _packageDependencyChecker, _loader, _workspace);

var initialProjectPaths = GetInitialProjectPaths();
Expand Down
80 changes: 80 additions & 0 deletions src/OmniSharp.MSBuild/SdksPathResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System;
using System.Composition;
using System.IO;
using OmniSharp.Services;

namespace OmniSharp.MSBuild
{
[Export, Shared]
public class SdksPathResolver
{
private const string MSBuildSDKsPath = nameof(MSBuildSDKsPath);
private const string Sdks = nameof(Sdks);

private readonly DotNetCliService _dotNetCli;

[ImportingConstructor]
public SdksPathResolver(DotNetCliService dotNetCli)
{
_dotNetCli = dotNetCli;
}

public bool TryGetSdksPath(string projectFilePath, out string sdksPath)
{
var projectFileDirectory = Path.GetDirectoryName(projectFilePath);

var info = _dotNetCli.GetInfo(projectFileDirectory);

if (info.IsEmpty || string.IsNullOrWhiteSpace(info.BasePath))
{
sdksPath = null;
return false;
}

sdksPath = Path.Combine(info.BasePath, Sdks);

if (Directory.Exists(sdksPath))
{
return true;
}

sdksPath = null;
return false;
}

public IDisposable SetSdksPathEnvironmentVariable(string projectFilePath)
{
if (!TryGetSdksPath(projectFilePath, out var sdksPath))
{
return NullDisposable.Instance;
}

var oldMSBuildSDKsPath = Environment.GetEnvironmentVariable(MSBuildSDKsPath);
Environment.SetEnvironmentVariable(MSBuildSDKsPath, sdksPath);

return new ResetSdksPathEnvironmentVariable(oldMSBuildSDKsPath);
}

private class NullDisposable : IDisposable
{
public static IDisposable Instance { get; } = new NullDisposable();

public void Dispose() { }
}

private class ResetSdksPathEnvironmentVariable : IDisposable
{
private readonly string _oldValue;

public ResetSdksPathEnvironmentVariable(string oldValue)
{
_oldValue = oldValue;
}

public void Dispose()
{
Environment.SetEnvironmentVariable(MSBuildSDKsPath, _oldValue);
}
}
}
}
5 changes: 4 additions & 1 deletion tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ public ProjectFileInfoTests(ITestOutputHelper output)
private ProjectFileInfo CreateProjectFileInfo(OmniSharpTestHost host, ITestProject testProject, string projectFilePath)
{
var msbuildLocator = host.GetExport<IMSBuildLocator>();
var sdksPathResolver = host.GetExport<SdksPathResolver>();

var loader = new ProjectLoader(
options: new MSBuildOptions(),
solutionDirectory: testProject.Directory,
propertyOverrides: msbuildLocator.RegisteredInstance.PropertyOverrides,
loggerFactory: LoggerFactory);
loggerFactory: LoggerFactory,
sdksPathResolver: sdksPathResolver);

var (projectFileInfo, _) = ProjectFileInfo.Load(projectFilePath, loader);

Expand Down

0 comments on commit 00efa68

Please sign in to comment.