|
| 1 | +// Licensed to the .NET Foundation under one or more agreements. |
| 2 | +// The .NET Foundation licenses this file to you under the MIT license. |
| 3 | + |
| 4 | +using Microsoft.Extensions.Logging; |
| 5 | + |
| 6 | +namespace Microsoft.DotNet.Watch; |
| 7 | + |
| 8 | +internal static class DotNetWatchLauncher |
| 9 | +{ |
| 10 | + public static async Task<bool> RunAsync(string workingDirectory, DotNetWatchOptions options) |
| 11 | + { |
| 12 | + var globalOptions = new GlobalOptions() |
| 13 | + { |
| 14 | + Quiet = options.IsQuiet, |
| 15 | + Verbose = options.IsVerbose, |
| 16 | + NoHotReload = false, |
| 17 | + NonInteractive = true, |
| 18 | + }; |
| 19 | + |
| 20 | + var commandArguments = new List<string>(); |
| 21 | + if (options.NoLaunchProfile) |
| 22 | + { |
| 23 | + commandArguments.Add("--no-launch-profile"); |
| 24 | + } |
| 25 | + |
| 26 | + commandArguments.AddRange(options.ApplicationArguments); |
| 27 | + |
| 28 | + var rootProjectOptions = new ProjectOptions() |
| 29 | + { |
| 30 | + IsRootProject = true, |
| 31 | + ProjectPath = options.ProjectPath, |
| 32 | + WorkingDirectory = workingDirectory, |
| 33 | + TargetFramework = null, |
| 34 | + BuildArguments = [], |
| 35 | + NoLaunchProfile = options.NoLaunchProfile, |
| 36 | + LaunchProfileName = null, |
| 37 | + Command = "run", |
| 38 | + CommandArguments = [.. commandArguments], |
| 39 | + LaunchEnvironmentVariables = [], |
| 40 | + }; |
| 41 | + |
| 42 | + var muxerPath = Path.GetFullPath(Path.Combine(options.SdkDirectory, "..", "..", "dotnet" + PathUtilities.ExecutableExtension)); |
| 43 | + |
| 44 | + var console = new PhysicalConsole(TestFlags.None); |
| 45 | + var reporter = new ConsoleReporter(console, globalOptions.Verbose, globalOptions.Quiet, suppressEmojis: false); |
| 46 | + var environmentOptions = EnvironmentOptions.FromEnvironment(muxerPath); |
| 47 | + var processRunner = new ProcessRunner(environmentOptions.GetProcessCleanupTimeout(isHotReloadEnabled: true)); |
| 48 | + var loggerFactory = new LoggerFactory(reporter); |
| 49 | + var logger = loggerFactory.CreateLogger(DotNetWatchContext.DefaultLogComponentName); |
| 50 | + |
| 51 | + using var context = new DotNetWatchContext() |
| 52 | + { |
| 53 | + ProcessOutputReporter = reporter, |
| 54 | + LoggerFactory = loggerFactory, |
| 55 | + Logger = logger, |
| 56 | + BuildLogger = loggerFactory.CreateLogger(DotNetWatchContext.BuildLogComponentName), |
| 57 | + ProcessRunner = processRunner, |
| 58 | + Options = globalOptions, |
| 59 | + EnvironmentOptions = environmentOptions, |
| 60 | + RootProjectOptions = rootProjectOptions, |
| 61 | + BrowserRefreshServerFactory = new BrowserRefreshServerFactory(), |
| 62 | + BrowserLauncher = new BrowserLauncher(logger, reporter, environmentOptions), |
| 63 | + }; |
| 64 | + |
| 65 | + using var shutdownHandler = new ShutdownHandler(console, logger); |
| 66 | + |
| 67 | + try |
| 68 | + { |
| 69 | + var watcher = new HotReloadDotNetWatcher(context, console, runtimeProcessLauncherFactory: null); |
| 70 | + await watcher.WatchAsync(shutdownHandler.CancellationToken); |
| 71 | + } |
| 72 | + catch (OperationCanceledException) when (shutdownHandler.CancellationToken.IsCancellationRequested) |
| 73 | + { |
| 74 | + // Ctrl+C forced an exit |
| 75 | + } |
| 76 | + catch (Exception e) |
| 77 | + { |
| 78 | + logger.LogError("An unexpected error occurred: {Exception}", e.ToString()); |
| 79 | + return false; |
| 80 | + } |
| 81 | + |
| 82 | + return true; |
| 83 | + } |
| 84 | +} |
0 commit comments