Build project before running
This commit is contained in:
@@ -120,7 +120,7 @@ public partial class RoslynAnalysis(ILogger<RoslynAnalysis> logger, BuildService
|
||||
using (var ___ = SharpIdeOtel.Source.StartActivity("RestoreSolution"))
|
||||
{
|
||||
// MsBuildProjectLoader doesn't do a restore which is absolutely required for resolving PackageReferences, if they have changed. I am guessing it just reads from project.assets.json
|
||||
await _buildService.MsBuildAsync(_sharpIdeSolutionModel.FilePath, BuildType.Restore, cancellationToken);
|
||||
await _buildService.MsBuildAsync(_sharpIdeSolutionModel.FilePath, BuildType.Restore, BuildStartedFlags.UserFacing, cancellationToken);
|
||||
}
|
||||
using (var ___ = SharpIdeOtel.Source.StartActivity("OpenSolution"))
|
||||
{
|
||||
@@ -187,7 +187,7 @@ public partial class RoslynAnalysis(ILogger<RoslynAnalysis> logger, BuildService
|
||||
Guard.Against.Null(_msBuildProjectLoader, nameof(_msBuildProjectLoader));
|
||||
|
||||
// It is important to note that a Workspace has no concept of MSBuild, nuget packages etc. It is just told about project references and "metadata" references, which are dlls. This is the what MSBuild does - it reads the csproj, and most importantly resolves nuget package references to dlls
|
||||
await _buildService.MsBuildAsync(_sharpIdeSolutionModel!.FilePath, BuildType.Restore, cancellationToken);
|
||||
await _buildService.MsBuildAsync(_sharpIdeSolutionModel!.FilePath, BuildType.Restore, BuildStartedFlags.UserFacing, cancellationToken);
|
||||
var __ = SharpIdeOtel.Source.StartActivity($"{nameof(RoslynAnalysis)}.MSBuildProjectLoader.LoadSolutionInfoAsync");
|
||||
// This call is the expensive part - MSBuild is slow. There doesn't seem to be any incrementalism for solutions.
|
||||
// The best we could do to speed it up is do .LoadProjectInfoAsync for the single project, and somehow munge that into the existing solution
|
||||
@@ -214,7 +214,7 @@ public partial class RoslynAnalysis(ILogger<RoslynAnalysis> logger, BuildService
|
||||
Guard.Against.Null(_workspace, nameof(_workspace));
|
||||
Guard.Against.Null(_msBuildProjectLoader, nameof(_msBuildProjectLoader));
|
||||
|
||||
await _buildService.MsBuildAsync(_sharpIdeSolutionModel!.FilePath, BuildType.Restore, cancellationToken);
|
||||
await _buildService.MsBuildAsync(_sharpIdeSolutionModel!.FilePath, BuildType.Restore, BuildStartedFlags.Internal, cancellationToken);
|
||||
var __ = SharpIdeOtel.Source.StartActivity($"{nameof(RoslynAnalysis)}.{nameof(CustomMsBuildProjectLoader)}.{nameof(CustomMsBuildProjectLoader.LoadProjectInfosAsync)}");
|
||||
|
||||
var thisProject = GetProjectForSharpIdeProjectModel(projectModel);
|
||||
|
||||
@@ -16,15 +16,16 @@ public enum BuildType
|
||||
Clean,
|
||||
Restore
|
||||
}
|
||||
public enum BuildStartedFlags { UserFacing = 0, Internal }
|
||||
public class BuildService(ILogger<BuildService> logger)
|
||||
{
|
||||
private readonly ILogger<BuildService> _logger = logger;
|
||||
|
||||
public EventWrapper<Task> BuildStarted { get; } = new(() => Task.CompletedTask);
|
||||
public EventWrapper<BuildStartedFlags, Task> BuildStarted { get; } = new(_ => Task.CompletedTask);
|
||||
public EventWrapper<Task> BuildFinished { get; } = new(() => Task.CompletedTask);
|
||||
public ChannelTextWriter BuildTextWriter { get; } = new ChannelTextWriter();
|
||||
private CancellationTokenSource? _cancellationTokenSource;
|
||||
public async Task MsBuildAsync(string solutionOrProjectFilePath, BuildType buildType = BuildType.Build, CancellationToken cancellationToken = default)
|
||||
public async Task MsBuildAsync(string solutionOrProjectFilePath, BuildType buildType = BuildType.Build, BuildStartedFlags buildStartedFlags = BuildStartedFlags.UserFacing, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (_cancellationTokenSource is not null) throw new InvalidOperationException("A build is already in progress.");
|
||||
_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
||||
@@ -55,7 +56,7 @@ public class BuildService(ILogger<BuildService> logger)
|
||||
hostServices: null,
|
||||
flags: BuildRequestDataFlags.None);
|
||||
|
||||
BuildStarted.InvokeParallelFireAndForget();
|
||||
BuildStarted.InvokeParallelFireAndForget(buildStartedFlags);
|
||||
var timer = Stopwatch.StartNew();
|
||||
var buildResult = await BuildManager.DefaultBuildManager.BuildAsync(buildParameters, buildRequest, _cancellationTokenSource.Token).ConfigureAwait(false);
|
||||
timer.Stop();
|
||||
|
||||
@@ -5,6 +5,7 @@ using AsyncReadProcess;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages;
|
||||
using SharpIDE.Application.Features.Analysis;
|
||||
using SharpIDE.Application.Features.Build;
|
||||
using SharpIDE.Application.Features.Debugging;
|
||||
using SharpIDE.Application.Features.Evaluation;
|
||||
using SharpIDE.Application.Features.Events;
|
||||
@@ -14,13 +15,14 @@ using Breakpoint = SharpIDE.Application.Features.Debugging.Breakpoint;
|
||||
|
||||
namespace SharpIDE.Application.Features.Run;
|
||||
|
||||
public partial class RunService(ILogger<RunService> logger, RoslynAnalysis roslynAnalysis)
|
||||
public partial class RunService(ILogger<RunService> logger, RoslynAnalysis roslynAnalysis, BuildService buildService)
|
||||
{
|
||||
private readonly ConcurrentDictionary<SharpIdeProjectModel, SemaphoreSlim> _projectLocks = [];
|
||||
private Debugger? _debugger; // TODO: Support multiple debuggers for multiple running projects
|
||||
|
||||
private readonly ILogger<RunService> _logger = logger;
|
||||
private readonly RoslynAnalysis _roslynAnalysis = roslynAnalysis;
|
||||
private readonly BuildService _buildService = buildService;
|
||||
|
||||
public async Task RunProject(SharpIdeProjectModel project, bool isDebug = false, DebuggerExecutableInfo? debuggerExecutableInfo = null)
|
||||
{
|
||||
@@ -32,8 +34,10 @@ public partial class RunService(ILogger<RunService> logger, RoslynAnalysis rosly
|
||||
var waitResult = await semaphoreSlim.WaitAsync(0).ConfigureAwait(false);
|
||||
if (waitResult is false) throw new InvalidOperationException($"Project {project.Name} is already running.");
|
||||
if (project.RunningCancellationTokenSource is not null) throw new InvalidOperationException($"Project {project.Name} is already running with a cancellation token source.");
|
||||
|
||||
project.RunningCancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
await _buildService.MsBuildAsync(project.FilePath);
|
||||
|
||||
var launchProfiles = await LaunchSettingsParser.GetLaunchSettingsProfiles(project);
|
||||
var launchProfile = launchProfiles.FirstOrDefault();
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user