Example #1
0
        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);
        }
Example #2
0
        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);
            }
        }
Example #3
0
        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;
            }
        }
Example #4
0
        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;
            }
        }