public DotNetWatcher(IReporter reporter, IFileSetFactory fileSetFactory) { Ensure.NotNull(reporter, nameof(reporter)); _reporter = reporter; _processRunner = new ProcessRunner(reporter); _filters = new IWatchFilter[] { new MSBuildEvaluationFilter(fileSetFactory), new NoRestoreFilter(), }; }
public HotReloadDotNetWatcher(IReporter reporter, IFileSetFactory fileSetFactory, DotNetWatchOptions dotNetWatchOptions) { Ensure.NotNull(reporter, nameof(reporter)); _reporter = reporter; _processRunner = new ProcessRunner(reporter); _dotNetWatchOptions = dotNetWatchOptions; _filters = new IWatchFilter[] { new MSBuildEvaluationFilter(fileSetFactory), new DotNetBuildFilter(_processRunner, _reporter), new LaunchBrowserFilter(_dotNetWatchOptions), }; }
public DotNetWatcher(IReporter reporter, IFileSetFactory fileSetFactory, DotNetWatchOptions dotNetWatchOptions) { Ensure.NotNull(reporter, nameof(reporter)); _reporter = reporter; _processRunner = new ProcessRunner(reporter); _dotnetWatchOptions = dotNetWatchOptions; _staticFileHandler = new StaticFileHandler(reporter); _filters = new IWatchFilter[] { new MSBuildEvaluationFilter(fileSetFactory), new NoRestoreFilter(), new LaunchBrowserFilter(dotNetWatchOptions), }; }
public HotReloadDotNetWatcher(IReporter reporter, IFileSetFactory fileSetFactory, DotNetWatchOptions dotNetWatchOptions, IConsole console) { Ensure.NotNull(reporter, nameof(reporter)); _reporter = reporter; _processRunner = new ProcessRunner(reporter); _dotNetWatchOptions = dotNetWatchOptions; _console = console; _filters = new IWatchFilter[] { new DotNetBuildFilter(fileSetFactory, _processRunner, _reporter), new LaunchBrowserFilter(dotNetWatchOptions), new BrowserRefreshFilter(dotNetWatchOptions, _reporter), }; _rudeEditDialog = new(reporter, _console); }
public HotReloadDotNetWatcher(IReporter reporter, IRequester requester, IFileSetFactory fileSetFactory, DotNetWatchOptions dotNetWatchOptions, IConsole console, string workingDirectory) { Ensure.NotNull(reporter, nameof(reporter)); Ensure.NotNull(requester, nameof(requester)); Ensure.NotNullOrEmpty(workingDirectory, nameof(workingDirectory)); _reporter = reporter; _processRunner = new ProcessRunner(reporter); _dotNetWatchOptions = dotNetWatchOptions; _console = console; _workingDirectory = workingDirectory; _filters = new IWatchFilter[] { new DotNetBuildFilter(fileSetFactory, _processRunner, _reporter), new LaunchBrowserFilter(dotNetWatchOptions), new BrowserRefreshFilter(dotNetWatchOptions, _reporter), }; if (!dotNetWatchOptions.NonInteractive) { _rudeEditDialog = new(reporter, requester, _console); } }
public TestableMSBuildEvaluationFilter(IFileSetFactory factory) : base(factory) { }
internal Directory(IFileSystemWrapper fileSystemWrapper, IFileSetFactory fileSetFactory, string path) { _fileSystemWrapper = fileSystemWrapper; _fileSetFactory = fileSetFactory; _path = path; }
public async Task WatchAsync(ProcessSpec processSpec, IFileSetFactory fileSetFactory, string replica, CancellationToken cancellationToken) { var cancelledTaskSource = new TaskCompletionSource <object>(); cancellationToken.Register(state => ((TaskCompletionSource <object>)state !).TrySetResult(null !), cancelledTaskSource); var iteration = 1; while (true) { if (cancellationToken.IsCancellationRequested) { return; } processSpec.EnvironmentVariables["DOTNET_WATCH_ITERATION"] = iteration.ToString(CultureInfo.InvariantCulture); iteration++; var fileSet = await fileSetFactory.CreateAsync(cancellationToken); if (fileSet == null) { _logger.LogError("watch: Failed to find a list of files to watch"); return; } using (var currentRunCancellationSource = new CancellationTokenSource()) using (var combinedCancellationSource = CancellationTokenSource.CreateLinkedTokenSource( cancellationToken, currentRunCancellationSource.Token)) using (var fileSetWatcher = new FileSetWatcher(fileSet, _logger)) { var fileSetTask = fileSetWatcher.GetChangedFileAsync(combinedCancellationSource.Token); var processTask = ProcessUtil.RunAsync(processSpec, combinedCancellationSource.Token, throwOnError: false); var args = processSpec.Arguments !; _logger.LogDebug($"Running {processSpec.ShortDisplayName()} with the following arguments: {args}"); _logger.LogInformation("watch: {Replica} Started", replica); var finishedTask = await Task.WhenAny(processTask, fileSetTask, cancelledTaskSource.Task); // Regardless of the which task finished first, make sure everything is cancelled // and wait for dotnet to exit. We don't want orphan processes currentRunCancellationSource.Cancel(); await Task.WhenAll(processTask, fileSetTask); if (processTask.Result.ExitCode != 0 && finishedTask == processTask && !cancellationToken.IsCancellationRequested) { // Only show this error message if the process exited non-zero due to a normal process exit. // Don't show this if dotnet-watch killed the inner process due to file change or CTRL+C by the user _logger.LogError($"watch: Exited with error code {processTask.Result}"); } else { _logger.LogInformation("watch: {Replica} Exited", replica); } if (finishedTask == cancelledTaskSource.Task || cancellationToken.IsCancellationRequested) { return; } if (finishedTask == processTask) { // Now wait for a file to change before restarting process await fileSetWatcher.GetChangedFileAsync(cancellationToken, () => _logger.LogWarning("Waiting for a file to change before restarting dotnet...")); } if (!string.IsNullOrEmpty(fileSetTask.Result)) { _logger.LogInformation($"watch: File changed: {fileSetTask.Result}"); } if (processSpec.Build != null) { while (true) { if (cancellationToken.IsCancellationRequested) { break; } var exitCode = await processSpec.Build(); if (exitCode == 0) { break; // Build failed, keep retrying builds until successful build. } await fileSetWatcher.GetChangedFileAsync(cancellationToken, () => _logger.LogWarning("Waiting for a file to change before restarting dotnet...")); } } } } }
public DotNetBuildFilter(IFileSetFactory fileSetFactory, ProcessRunner processRunner, IReporter reporter) { _fileSetFactory = fileSetFactory; _processRunner = processRunner; _reporter = reporter; }
internal Directory(IFileSystemWrapper fileSystemWrapper, IFileSetFactory fileSetFactory, string path) { _fileSystemWrapper = fileSystemWrapper; _fileSetFactory = fileSetFactory; _path = path; }
public async Task WatchAsync(ProcessSpec processSpec, IFileSetFactory fileSetFactory, CancellationToken cancellationToken) { Ensure.NotNull(processSpec, nameof(processSpec)); var cancelledTaskSource = new TaskCompletionSource <object>(); cancellationToken.Register(state => ((TaskCompletionSource <object>)state).TrySetResult(null), cancelledTaskSource); var iteration = 1; while (true) { processSpec.EnvironmentVariables["DOTNET_WATCH_ITERATION"] = iteration.ToString(CultureInfo.InvariantCulture); iteration++; var fileSet = await fileSetFactory.CreateAsync(cancellationToken); if (fileSet == null) { _reporter.Error("Failed to find a list of files to watch"); return; } if (cancellationToken.IsCancellationRequested) { return; } using (var currentRunCancellationSource = new CancellationTokenSource()) using (var combinedCancellationSource = CancellationTokenSource.CreateLinkedTokenSource( cancellationToken, currentRunCancellationSource.Token)) using (var fileSetWatcher = new FileSetWatcher(fileSet, _reporter)) { var fileSetTask = fileSetWatcher.GetChangedFileAsync(combinedCancellationSource.Token); var processTask = _processRunner.RunAsync(processSpec, combinedCancellationSource.Token); var args = ArgumentEscaper.EscapeAndConcatenate(processSpec.Arguments); _reporter.Verbose($"Running {processSpec.ShortDisplayName()} with the following arguments: {args}"); _reporter.Output("Started"); var finishedTask = await Task.WhenAny(processTask, fileSetTask, cancelledTaskSource.Task); // Regardless of the which task finished first, make sure everything is cancelled // and wait for dotnet to exit. We don't want orphan processes currentRunCancellationSource.Cancel(); await Task.WhenAll(processTask, fileSetTask); if (processTask.Result != 0 && finishedTask == processTask && !cancellationToken.IsCancellationRequested) { // Only show this error message if the process exited non-zero due to a normal process exit. // Don't show this if dotnet-watch killed the inner process due to file change or CTRL+C by the user _reporter.Error($"Exited with error code {processTask.Result}"); } else { _reporter.Output("Exited"); } if (finishedTask == cancelledTaskSource.Task || cancellationToken.IsCancellationRequested) { return; } if (finishedTask == processTask) { _reporter.Warn("Waiting for a file to change before restarting dotnet..."); // Now wait for a file to change before restarting process await fileSetWatcher.GetChangedFileAsync(cancellationToken); } if (!string.IsNullOrEmpty(fileSetTask.Result)) { _reporter.Output($"File changed: {fileSetTask.Result}"); } } } }