Exemplo n.º 1
0
    public static void Preview(Engine engine, NukeBuild build)
    {
        var _messageEvent = new AutoResetEvent(false);
        var _changedFiles = new ConcurrentQueue <string>();
        var _exit         = new InterlockedBool(false);
        // Start the preview server
        DirectoryPath previewPath = (NukeBuild.RootDirectory / "output").ToString();

        engine.Execute();
        var previewServer = PreviewServer.Start(previewPath, 5080, true, null, true, new Dictionary <string, string>());

        Trace.Information("Watching paths(s) {0}", string.Join(", ", engine.FileSystem.InputPaths));
        var inputFolderWatcher = new ActionFileSystemWatcher(
            engine.FileSystem.GetOutputDirectory().Path,
            engine.FileSystem.GetInputDirectories().Select(x => x.Path),
            true,
            "*.*",
            path =>
        {
            _changedFiles.Enqueue(path);
            _messageEvent.Set();
        });

        // Start the message pump if an async process is running
        ExitCode exitCode = ExitCode.Normal;

        // Only wait for a key if console input has not been redirected, otherwise it's on the caller to exit
        if (!Console.IsInputRedirected)
        {
            // Start the key listening thread
            Thread thread = new Thread(() =>
            {
                Trace.Information("Hit Ctrl-C to exit");
                Console.TreatControlCAsInput = true;
                while (true)
                {
                    // Would have prefered to use Console.CancelKeyPress, but that bubbles up to calling batch files
                    // The (ConsoleKey)3 check is to support a bug in VS Code: https://github.com/Microsoft/vscode/issues/9347
                    ConsoleKeyInfo consoleKey = Console.ReadKey(true);
                    if (consoleKey.Key == (ConsoleKey)3 || (consoleKey.Key == ConsoleKey.C && (consoleKey.Modifiers & ConsoleModifiers.Control) != 0))
                    {
                        _exit.Set();
                        _messageEvent.Set();
                        break;
                    }
                }
            })
            {
                IsBackground = true
            };
            thread.Start();
        }

        // Wait for activity
        while (true)
        {
            _messageEvent.WaitOne(); // Blocks the current thread until a signal
            if (_exit)
            {
                break;
            }

            // Execute if files have changed
            HashSet <string> changedFiles = new HashSet <string>();
            string           changedFile;
            while (_changedFiles.TryDequeue(out changedFile))
            {
                if (changedFiles.Add(changedFile))
                {
                    Trace.Verbose("{0} has changed", changedFile);
                }
            }
            if (changedFiles.Count > 0)
            {
                Trace.Information("{0} files have changed, re-executing", changedFiles.Count);
                engine.Execute();
                previewServer?.TriggerReloadAsync().GetAwaiter().GetResult();
            }

            // Check one more time for exit
            if (_exit)
            {
                break;
            }
            Trace.Information("Hit Ctrl-C to exit");
            _messageEvent.Reset();
        }

        // Shutdown
        Trace.Information("Shutting down");
        inputFolderWatcher?.Dispose();
        previewServer?.Dispose();
    }