public override async Task Run(IConsole console, CommandArguments arguments, CancellationToken token) { var siteName = arguments.Name ?? _envAppName; var sitePort = arguments.Port ?? _envPort; if (string.IsNullOrEmpty(siteName)) { throw new Exception("Argument 'name' is required."); } if (!sitePort.HasValue) { throw new Exception("Argument 'port' is required."); } var iisExpressPath = await IISExpressDiscovery.GetIISExpressPath(); var siteConfig = new SiteConfig(siteName, arguments.Path.FullName, sitePort.Value); var configPath = await siteConfig.Create(TempDirectory.Value); if (!arguments.NoBuild) { var buildRes = await _msBuild.BuildAndGetArtifactPath(arguments.Path.FullName, arguments.SolutionPath?.FullName); if (!buildRes.Success) { if (!string.IsNullOrEmpty(buildRes.Error)) { throw new Exception(buildRes.Error); } throw new Exception("Failed to build website"); } } var spec = new ProcessSpec { Executable = iisExpressPath, Arguments = $"/config:{configPath} /site:{siteName}", WorkingDirectory = arguments.Path.FullName, OutputData = data => console.Out.WriteLine(data), ErrorData = data => console.Error.WriteLine(data), OnStart = pid => console.Out.WriteLine($"IIS Express Started at PID {pid}"), OnStop = code => console.Out.WriteLine($"IIS Express Stopped with status code {code}"), CreateWindow = false }; await ProcessUtil.RunAsync(spec, token, throwOnError : false); }
public async Task ShouldBuildAndFindArtifact(bool provideSolutionPath) { await using var testSolution = await CopyTestAssets("democonsole"); var projectPath = Path.Join(testSolution.Value, "democonsole"); var msBuild = new MSBuild(); var buildRes = await msBuild.BuildAndGetArtifactPath(projectPath, provideSolutionPath?testSolution.Value : null); Assert.Equal(provideSolutionPath, buildRes.Success); if (buildRes.Success) { Assert.Equal($@"{projectPath}\bin\Debug", buildRes.Directory); Assert.Equal("democonsole.exe", buildRes.File); } }
public override async Task Run(IConsole console, CommandArguments arguments, CancellationToken token) { var buildRes = await _msBuild.BuildAndGetArtifactPath(arguments.Path.FullName, arguments.SolutionPath?.FullName); if (!buildRes.Success) { if (!string.IsNullOrEmpty(buildRes.Error)) { throw new Exception(buildRes.Error); } throw new Exception("Could not determine path of built artifacts"); } while (!token.IsCancellationRequested) { await using var buildDirectory = new TemporaryDirectory(TempDirectory.Value); console.Out.WriteLine($"Copying artifacts from '{buildRes.Directory}' to '{buildDirectory.Value}'"); buildDirectory.CopyFrom(buildRes.Directory !); using var cts = new CancellationTokenSource(); await using var _ = token.Register(() => cts.Cancel()); var watch = !arguments.NoRestart ? _watcher.WatchUntilRebuild(buildRes.Directory !, buildRes.File !, cts.Token) : Task.Delay(-1, cts.Token); var process = StartProcess(console, arguments, buildDirectory.Value, buildRes.File !, cts.Token); var firstTask = await Task.WhenAny(watch, process); cts.Cancel(); if (firstTask == process) { break; } else if (!token.IsCancellationRequested) { console.Out.WriteLine($"Restarting {buildRes.File!} due to rebuild"); } await process; } }
public async Task ShouldRestartUponRebuild(bool noRestart) { await using var testSolution = await CopyTestAssets("democonsole"); var projectPath = Path.Join(testSolution.Value, "democonsole"); var msBuild = new MSBuild(); await using var dnfHost = new DNFHost(); using var cancel = new CancellationTokenSource(); var finishedBuild = new TaskCompletionSource <int>(); var newMessageArrived = new TaskCompletionSource <int>(); int originalPid = 0; Action <bool, string> capture = (error, message) => { if (!error && message.Contains("Started at PID")) { originalPid = int.Parse(message.Split(" ").Last()); } else if (!error && message == "Message A") { var projectCs = Path.Join(projectPath, "Program.cs"); File.WriteAllText(projectCs, File.ReadAllText(projectCs).Replace("Message A", "Message B")); msBuild.BuildAndGetArtifactPath(projectPath, testSolution.Value) .ContinueWith(res => { if (!res.Result.Success) { _console.Error.WriteLine(res.Result.Error); } finishedBuild.TrySetResult(0); }); } else if (!error && message == "Message B") { newMessageArrived.TrySetResult(0); } }; var run = dnfHost.Run(new MultiplexerConsole(new[] { _console, new CaptureConsole(capture) }), new CommandArguments { Path = new DirectoryInfo(projectPath), SolutionPath = new DirectoryInfo(testSolution.Value), NoRestart = noRestart }, cancel.Token); try { await finishedBuild.Task; if (!noRestart) { await WaitOrTimeout(newMessageArrived.Task); } else { await ShouldTimeout(newMessageArrived.Task); } } finally { cancel.Cancel(); await run; } }