public async Task <IFileSet> CreateAsync(CancellationToken cancellationToken) { var watchList = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); try { var projectDir = Path.GetDirectoryName(_projectFile); while (true) { cancellationToken.ThrowIfCancellationRequested(); var capture = _outputSink.StartCapture(); // TODO adding files doesn't currently work. Need to provide a way to detect new files // find files var processSpec = new ProcessSpec { Executable = DotNetMuxer.MuxerPathOrDefault(), WorkingDirectory = projectDir, Arguments = new[] { "msbuild", _projectFile, $"/p:_DotNetWatchListFile={watchList}" }.Concat(_buildFlags), OutputCapture = capture }; _reporter.Verbose($"Running MSBuild target '{TargetName}' on '{_projectFile}'"); var exitCode = await _processRunner.RunAsync(processSpec, cancellationToken); if (exitCode == 0 && File.Exists(watchList)) { var fileset = new FileSet( File.ReadAllLines(watchList) .Select(l => l?.Trim()) .Where(l => !string.IsNullOrEmpty(l))); _reporter.Verbose($"Watching {fileset.Count} file(s) for changes"); #if DEBUG foreach (var file in fileset) { _reporter.Verbose($" -> {file}"); } Debug.Assert(fileset.All(Path.IsPathRooted), "All files should be rooted paths"); #endif return(fileset); } _reporter.Error($"Error(s) finding watch items project file '{Path.GetFileName(_projectFile)}'"); _reporter.Output($"MSBuild output from target '{TargetName}':"); _reporter.Output(string.Empty); foreach (var line in capture.Lines) { _reporter.Output($" {line}"); } _reporter.Output(string.Empty); if (!_waitOnError) { return(null); } else { _reporter.Warn("Fix the error to continue or press Ctrl+C to exit."); var fileSet = new FileSet(new[] { _projectFile }); using (var watcher = new FileSetWatcher(fileSet, _reporter)) { await watcher.GetChangedFileAsync(cancellationToken); _reporter.Output($"File changed: {_projectFile}"); } } } } finally { if (File.Exists(watchList)) { File.Delete(watchList); } } }
public async Task <IFileSet> CreateAsync(CancellationToken cancellationToken) { var watchList = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); try { var projectDir = Path.GetDirectoryName(_projectFile); while (true) { cancellationToken.ThrowIfCancellationRequested(); var args = new StringBuilder(); args.Append($"msbuild \"{_projectFile}\" /p:_DotNetWatchListFile=\"{watchList}\""); foreach (var flag in _buildFlags) { args.Append(" "); args.Append(flag); } var processSpec = new ProcessSpec { Executable = "dotnet", WorkingDirectory = projectDir !, Arguments = args.ToString() }; _logger.LogDebug($"Running MSBuild target '{TargetName}' on '{_projectFile}'"); var processResult = await ProcessUtil.RunAsync(processSpec, cancellationToken); if (processResult.ExitCode == 0 && File.Exists(watchList)) { var fileset = new FileSet( File.ReadAllLines(watchList) .Select(l => l?.Trim()) .Where(l => !string.IsNullOrEmpty(l)) !); _logger.LogDebug($"Watching {fileset.Count} file(s) for changes"); #if DEBUG foreach (var file in fileset) { _logger.LogDebug($" -> {file}"); } Debug.Assert(fileset.All(Path.IsPathRooted), "All files should be rooted paths"); #endif return(fileset); } _logger.LogError($"Error(s) finding watch items project file '{Path.GetFileName(_projectFile)}'"); _logger.LogInformation($"MSBuild output from target '{TargetName}':"); _logger.LogInformation(string.Empty); _logger.LogInformation(string.Empty); if (!_waitOnError) { return(null !); } else { _logger.LogWarning("Fix the error to continue or press Ctrl+C to exit."); var fileSet = new FileSet(new[] { _projectFile }); using (var watcher = new FileSetWatcher(fileSet, _logger)) { await watcher.GetChangedFileAsync(cancellationToken); _logger.LogInformation($"File changed: {_projectFile}"); } } } } finally { if (File.Exists(watchList)) { File.Delete(watchList); } } }
public async Task <FileSet> CreateAsync(CancellationToken cancellationToken) { var watchList = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); try { var projectDir = Path.GetDirectoryName(_projectFile); while (true) { cancellationToken.ThrowIfCancellationRequested(); var capture = _outputSink.StartCapture(); var arguments = new List <string> { "msbuild", "/nologo", _projectFile, $"/p:_DotNetWatchListFile={watchList}", }; if (_dotNetWatchOptions.SuppressHandlingStaticContentFiles) { arguments.Add("/p:DotNetWatchContentFiles=false"); } arguments.AddRange(_buildFlags); var processSpec = new ProcessSpec { Executable = _muxerPath, WorkingDirectory = projectDir, Arguments = arguments, OutputCapture = capture }; _reporter.Verbose($"Running MSBuild target '{TargetName}' on '{_projectFile}'"); var exitCode = await _processRunner.RunAsync(processSpec, cancellationToken); if (exitCode == 0 && File.Exists(watchList)) { using var watchFile = File.OpenRead(watchList); var result = await JsonSerializer.DeserializeAsync <MSBuildFileSetResult>(watchFile, cancellationToken : cancellationToken); var fileItems = new List <FileItem>(); foreach (var project in result.Projects) { var value = project.Value; var fileCount = value.Files.Count; for (var i = 0; i < fileCount; i++) { fileItems.Add(new FileItem { FilePath = value.Files[i], ProjectPath = project.Key, }); } var staticItemsCount = value.StaticFiles.Count; for (var i = 0; i < staticItemsCount; i++) { var item = value.StaticFiles[i]; fileItems.Add(new FileItem { FilePath = item.FilePath, ProjectPath = project.Key, IsStaticFile = true, StaticWebAssetPath = item.StaticWebAssetPath, }); } } _reporter.Verbose($"Watching {fileItems.Count} file(s) for changes"); #if DEBUG foreach (var file in fileItems) { _reporter.Verbose($" -> {file.FilePath} {(file.IsStaticFile ? file.StaticWebAssetPath : null)}"); } Debug.Assert(fileItems.All(f => Path.IsPathRooted(f.FilePath)), "All files should be rooted paths"); #endif // TargetFrameworkVersion appears as v6.0 in msbuild. Ignore the leading v var targetFrameworkVersion = !string.IsNullOrEmpty(result.TargetFrameworkVersion) ? Version.Parse(result.TargetFrameworkVersion.AsSpan(1)) : // Ignore leading v null; var projectInfo = new ProjectInfo( _projectFile, result.IsNetCoreApp, targetFrameworkVersion, result.RunCommand, result.RunArguments, result.RunWorkingDirectory); return(new FileSet(projectInfo, fileItems)); } _reporter.Error($"Error(s) finding watch items project file '{Path.GetFileName(_projectFile)}'"); _reporter.Output($"MSBuild output from target '{TargetName}':"); _reporter.Output(string.Empty); foreach (var line in capture.Lines) { _reporter.Output($" {line}"); } _reporter.Output(string.Empty); if (!_waitOnError) { return(null); } else { _reporter.Warn("Fix the error to continue or press Ctrl+C to exit."); var fileSet = new FileSet(null, new[] { new FileItem { FilePath = _projectFile } }); using (var watcher = new FileSetWatcher(fileSet, _reporter)) { await watcher.GetChangedFileAsync(cancellationToken); _reporter.Output($"File changed: {_projectFile}"); } } } } finally { if (File.Exists(watchList)) { File.Delete(watchList); } } }
public async Task <FileSet> CreateAsync(CancellationToken cancellationToken) { var watchList = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); try { var projectDir = Path.GetDirectoryName(_projectFile); while (true) { cancellationToken.ThrowIfCancellationRequested(); var capture = _outputSink.StartCapture(); // TODO adding files doesn't currently work. Need to provide a way to detect new files // find files var processSpec = new ProcessSpec { Executable = DotNetMuxer.MuxerPathOrDefault(), WorkingDirectory = projectDir, Arguments = new[] { "msbuild", "/nologo", _projectFile, $"/p:_DotNetWatchListFile={watchList}", _dotNetWatchOptions.SuppressHandlingStaticContentFiles ? "/p:DotNetWatchContentFiles=false" : "", }.Concat(_buildFlags), OutputCapture = capture }; _reporter.Verbose($"Running MSBuild target '{TargetName}' on '{_projectFile}'"); var exitCode = await _processRunner.RunAsync(processSpec, cancellationToken); if (exitCode == 0 && File.Exists(watchList)) { var lines = File.ReadAllLines(watchList); var staticFiles = new List <string>(); var commandLine = new CommandLineApplication(); var contentFiles = commandLine.Option("-c", "Content file", CommandOptionType.MultipleValue); var contentFilePaths = commandLine.Option("-s", "Static asset path", CommandOptionType.MultipleValue); var files = commandLine.Option("-f", "Watched files", CommandOptionType.MultipleValue); var isNetCoreApp31 = commandLine.Option("-isnetcoreapp31", "Is .NET Core 3.1 or newer?", CommandOptionType.NoValue); commandLine.Invoke = () => 0; commandLine.Execute(lines); var isNetCoreApp31OrNewer = isNetCoreApp31.Value(); var fileItems = new List <FileItem>(); foreach (var file in files.Values) { fileItems.Add(new FileItem(file)); } for (var i = 0; i < contentFiles.Values.Count; i++) { var contentFile = contentFiles.Values[i]; var staticWebAssetPath = contentFilePaths.Values[i].TrimStart('/'); fileItems.Add(new FileItem(contentFile, FileKind.StaticFile, staticWebAssetPath)); } var fileset = new FileSet(isNetCoreApp31.HasValue(), fileItems); _reporter.Verbose($"Watching {fileset.Count} file(s) for changes"); #if DEBUG foreach (var file in fileset) { _reporter.Verbose($" -> {file.FilePath} {file.FileKind} {file.StaticWebAssetPath}."); } Debug.Assert(fileset.All(f => Path.IsPathRooted(f.FilePath)), "All files should be rooted paths"); #endif return(fileset); } _reporter.Error($"Error(s) finding watch items project file '{Path.GetFileName(_projectFile)}'"); _reporter.Output($"MSBuild output from target '{TargetName}':"); _reporter.Output(string.Empty); foreach (var line in capture.Lines) { _reporter.Output($" {line}"); } _reporter.Output(string.Empty); if (!_waitOnError) { return(null); } else { _reporter.Warn("Fix the error to continue or press Ctrl+C to exit."); var fileSet = new FileSet(false, new[] { new FileItem(_projectFile) }); using (var watcher = new FileSetWatcher(fileSet, _reporter)) { await watcher.GetChangedFileAsync(cancellationToken); _reporter.Output($"File changed: {_projectFile}"); } } } } finally { if (File.Exists(watchList)) { File.Delete(watchList); } } }