Add better errors, fix help output text, and add 'dotnet watch --list' to help us diagnose issues
Fixes #252 - help output shown twice in dotnet-watch Fixes #250 - add dotnet-watch --list. Prints a list of all files discovered Fixes #249 - better error message when GenerateWatchList fails
This commit is contained in:
parent
7ee45afed4
commit
e481df3d49
|
|
@ -0,0 +1,28 @@
|
|||
; EditorConfig to support per-solution formatting.
|
||||
; Use the EditorConfig VS add-in to make this work.
|
||||
; http://editorconfig.org/
|
||||
|
||||
; This is the default for the codeline.
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{cs}]
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
|
||||
; All XML-based file formats
|
||||
[*.{config,csproj,nuspec,props,resx,targets,xml}]
|
||||
indent_size = 2
|
||||
|
||||
[*.{json}]
|
||||
indent_size = 2
|
||||
|
||||
[*.{ps1}]
|
||||
indent_size = 4
|
||||
|
||||
[*.{sh}]
|
||||
indent_size = 4
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.25807.0
|
||||
VisualStudioVersion = 15.0.26020.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{66517987-2A5A-4330-B130-207039378FD4}"
|
||||
EndProject
|
||||
|
|
@ -8,6 +8,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.Watcher.To
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8321E0D1-9A47-4D2F-AED8-3AE636D44E35}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
NuGet.Config = NuGet.Config
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
|
@ -43,10 +44,6 @@ Global
|
|||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Release|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Release|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9295E811-FF0F-E40A-2F9A-0B2C4EBC22AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9295E811-FF0F-E40A-2F9A-0B2C4EBC22AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9295E811-FF0F-E40A-2F9A-0B2C4EBC22AD}.Release|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9295E811-FF0F-E40A-2F9A-0B2C4EBC22AD}.Release|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7B331122-83B1-4F08-A119-DC846959844C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7B331122-83B1-4F08-A119-DC846959844C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7B331122-83B1-4F08-A119-DC846959844C}.Release|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
|
|
@ -59,6 +56,10 @@ Global
|
|||
{53F3B53D-303A-4DAA-9C38-4F55195FA5B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{53F3B53D-303A-4DAA-9C38-4F55195FA5B9}.Release|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{53F3B53D-303A-4DAA-9C38-4F55195FA5B9}.Release|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9295E811-FF0F-E40A-2F9A-0B2C4EBC22AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9295E811-FF0F-E40A-2F9A-0B2C4EBC22AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9295E811-FF0F-E40A-2F9A-0B2C4EBC22AD}.Release|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9295E811-FF0F-E40A-2F9A-0B2C4EBC22AD}.Release|Any CPU.Build.0 = Debug|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -67,9 +68,9 @@ Global
|
|||
{8A8CEABC-AC47-43FF-A5DF-69224F7E1F46} = {66517987-2A5A-4330-B130-207039378FD4}
|
||||
{16BADE2F-1184-4518-8A70-B68A19D0805B} = {F5B382BC-258F-46E1-AC3D-10E5CCD55134}
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E} = {66517987-2A5A-4330-B130-207039378FD4}
|
||||
{9295E811-FF0F-E40A-2F9A-0B2C4EBC22AD} = {F5B382BC-258F-46E1-AC3D-10E5CCD55134}
|
||||
{7B331122-83B1-4F08-A119-DC846959844C} = {F5B382BC-258F-46E1-AC3D-10E5CCD55134}
|
||||
{8A2E6961-6B12-4A8E-8215-3E7301D52EAC} = {F5B382BC-258F-46E1-AC3D-10E5CCD55134}
|
||||
{53F3B53D-303A-4DAA-9C38-4F55195FA5B9} = {66517987-2A5A-4330-B130-207039378FD4}
|
||||
{9295E811-FF0F-E40A-2F9A-0B2C4EBC22AD} = {F5B382BC-258F-46E1-AC3D-10E5CCD55134}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ namespace Microsoft.DotNet.Watcher
|
|||
public bool IsQuiet { get; private set; }
|
||||
public bool IsVerbose { get; private set; }
|
||||
public IList<string> RemainingArguments { get; private set; }
|
||||
public bool ListFiles { get; private set; }
|
||||
|
||||
public static CommandLineOptions Parse(string[] args, IConsole console)
|
||||
{
|
||||
|
|
@ -63,6 +64,9 @@ Examples:
|
|||
CommandOptionType.NoValue);
|
||||
var optVerbose = app.VerboseOption();
|
||||
|
||||
var optList = app.Option("--list", "Lists all discovered files without starting the watcher",
|
||||
CommandOptionType.NoValue);
|
||||
|
||||
app.VersionOptionFromAssemblyAttributes(typeof(Program).GetTypeInfo().Assembly);
|
||||
|
||||
if (app.Execute(args) != 0)
|
||||
|
|
@ -75,7 +79,9 @@ Examples:
|
|||
throw new CommandParsingException(app, Resources.Error_QuietAndVerboseSpecified);
|
||||
}
|
||||
|
||||
if (app.RemainingArguments.Count == 0)
|
||||
if (app.RemainingArguments.Count == 0
|
||||
&& !app.IsShowingInformation
|
||||
&& !optList.HasValue())
|
||||
{
|
||||
app.ShowHelp();
|
||||
}
|
||||
|
|
@ -86,8 +92,9 @@ Examples:
|
|||
IsQuiet = optQuiet.HasValue(),
|
||||
IsVerbose = optVerbose.HasValue(),
|
||||
RemainingArguments = app.RemainingArguments,
|
||||
IsHelp = app.IsShowingInformation
|
||||
IsHelp = app.IsShowingInformation,
|
||||
ListFiles = optList.HasValue(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,13 @@ namespace Microsoft.DotNet.Watcher
|
|||
while (true)
|
||||
{
|
||||
var fileSet = await fileSetFactory.CreateAsync(cancellationToken);
|
||||
|
||||
if (fileSet == null)
|
||||
{
|
||||
_reporter.Error("Failed to find a list of files to watch");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return;
|
||||
|
|
@ -91,4 +98,4 @@ namespace Microsoft.DotNet.Watcher
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,17 +16,19 @@ namespace Microsoft.DotNet.Watcher.Internal
|
|||
public class MsBuildFileSetFactory : IFileSetFactory
|
||||
{
|
||||
private const string TargetName = "GenerateWatchList";
|
||||
private const string ProjectExtensionFileExtension = ".dotnetwatch.targets";
|
||||
private const string ProjectExtensionFileExtension = ".dotnetwatch.g.targets";
|
||||
private const string WatchTargetsFileName = "DotNetWatchCommon.targets";
|
||||
private readonly IReporter _reporter;
|
||||
private readonly string _projectFile;
|
||||
private readonly string _watchTargetsDir;
|
||||
private readonly OutputSink _outputSink;
|
||||
private readonly ProcessRunner _processRunner;
|
||||
private readonly bool _waitOnError;
|
||||
|
||||
public MsBuildFileSetFactory(IReporter reporter, string projectFile)
|
||||
public MsBuildFileSetFactory(IReporter reporter, string projectFile, bool waitOnError)
|
||||
: this(reporter, projectFile, new OutputSink())
|
||||
{
|
||||
_waitOnError = waitOnError;
|
||||
}
|
||||
|
||||
// output sink is for testing
|
||||
|
|
@ -86,7 +88,7 @@ namespace Microsoft.DotNet.Watcher.Internal
|
|||
|
||||
var exitCode = await _processRunner.RunAsync(processSpec, cancellationToken);
|
||||
|
||||
if (exitCode == 0)
|
||||
if (exitCode == 0 && File.Exists(watchList))
|
||||
{
|
||||
var fileset = new FileSet(
|
||||
File.ReadAllLines(watchList)
|
||||
|
|
@ -109,28 +111,41 @@ namespace Microsoft.DotNet.Watcher.Internal
|
|||
|
||||
_reporter.Error($"Error(s) finding watch items project file '{Path.GetFileName(_projectFile)}'");
|
||||
|
||||
_reporter.Output($"MSBuild output from target '{TargetName}'");
|
||||
_reporter.Output($"MSBuild output from target '{TargetName}':");
|
||||
_reporter.Output(string.Empty);
|
||||
|
||||
foreach (var line in capture.Lines)
|
||||
{
|
||||
_reporter.Output($" [MSBUILD] : {line}");
|
||||
_reporter.Output($" {line}");
|
||||
}
|
||||
|
||||
_reporter.Warn("Fix the error to continue or press Ctrl+C to exit.");
|
||||
_reporter.Output(string.Empty);
|
||||
|
||||
var fileSet = new FileSet(new[] {_projectFile});
|
||||
|
||||
using (var watcher = new FileSetWatcher(fileSet))
|
||||
if (!_waitOnError)
|
||||
{
|
||||
await watcher.GetChangedFileAsync(cancellationToken);
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
_reporter.Warn("Fix the error to continue or press Ctrl+C to exit.");
|
||||
|
||||
_reporter.Output($"File changed: {_projectFile}");
|
||||
var fileSet = new FileSet(new[] { _projectFile });
|
||||
|
||||
using (var watcher = new FileSetWatcher(fileSet))
|
||||
{
|
||||
await watcher.GetChangedFileAsync(cancellationToken);
|
||||
|
||||
_reporter.Output($"File changed: {_projectFile}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
File.Delete(watchList);
|
||||
if (File.Exists(watchList))
|
||||
{
|
||||
File.Delete(watchList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -173,4 +188,4 @@ namespace Microsoft.DotNet.Watcher.Internal
|
|||
return Path.GetDirectoryName(targetPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
|
@ -80,7 +80,20 @@ namespace Microsoft.DotNet.Watcher
|
|||
|
||||
try
|
||||
{
|
||||
return await MainInternalAsync(reporter, options.Project, options.RemainingArguments, ctrlCTokenSource.Token);
|
||||
if (options.ListFiles)
|
||||
{
|
||||
return await ListFilesAsync(reporter,
|
||||
options.Project,
|
||||
ctrlCTokenSource.Token);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
return await MainInternalAsync(reporter,
|
||||
options.Project,
|
||||
options.RemainingArguments,
|
||||
ctrlCTokenSource.Token);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -115,8 +128,7 @@ namespace Microsoft.DotNet.Watcher
|
|||
return 1;
|
||||
}
|
||||
|
||||
var fileSetFactory = new MsBuildFileSetFactory(reporter, projectFile);
|
||||
|
||||
var fileSetFactory = new MsBuildFileSetFactory(reporter, projectFile, waitOnError: true);
|
||||
var processInfo = new ProcessSpec
|
||||
{
|
||||
Executable = DotNetMuxer.MuxerPathOrDefault(),
|
||||
|
|
@ -130,6 +142,39 @@ namespace Microsoft.DotNet.Watcher
|
|||
return 0;
|
||||
}
|
||||
|
||||
private async Task<int> ListFilesAsync(
|
||||
IReporter reporter,
|
||||
string project,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO multiple projects should be easy enough to add here
|
||||
string projectFile;
|
||||
try
|
||||
{
|
||||
projectFile = MsBuildProjectFinder.FindMsBuildProject(_workingDir, project);
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
reporter.Error(ex.Message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
var fileSetFactory = new MsBuildFileSetFactory(reporter, projectFile, waitOnError: false);
|
||||
var files = await fileSetFactory.CreateAsync(cancellationToken);
|
||||
|
||||
if (files == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
_console.Out.WriteLine(file);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static IReporter CreateReporter(bool verbose, bool quiet, IConsole console)
|
||||
{
|
||||
const string prefix = "watch : ";
|
||||
|
|
@ -178,4 +223,4 @@ namespace Microsoft.DotNet.Watcher
|
|||
.Build();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
|
@ -98,9 +98,7 @@ namespace Microsoft.Extensions.SecretManager.Tools.Internal
|
|||
// running tool
|
||||
using (var resource = GetType().GetTypeInfo().Assembly.GetManifestResourceStream("ProjectIdResolverTargets.xml"))
|
||||
using (var stream = new FileStream(projectExtensionsPath, FileMode.Create))
|
||||
using (var writer = new StreamWriter(stream))
|
||||
{
|
||||
writer.WriteLine("<!-- Auto-generated by dotnet-user-secrets. This file can be deleted and should not be commited to source control. -->");
|
||||
resource.CopyTo(stream);
|
||||
}
|
||||
}
|
||||
|
|
@ -120,4 +118,4 @@ namespace Microsoft.Extensions.SecretManager.Tools.Internal
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
[Fact]
|
||||
public async Task ChangeFileInDependency()
|
||||
{
|
||||
await _app.StartWatcher().OrTimeout();
|
||||
await _app.StartWatcherAsync().OrTimeout();
|
||||
|
||||
var fileToChange = Path.Combine(_app.DependencyFolder, "Foo.cs");
|
||||
var programCs = File.ReadAllText(fileToChange);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
|
@ -9,8 +10,8 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks.Dataflow;
|
||||
using Microsoft.Extensions.Internal;
|
||||
using Xunit.Abstractions;
|
||||
using Microsoft.Extensions.Tools.Internal;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
||||
{
|
||||
|
|
@ -71,6 +72,21 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
return null;
|
||||
}
|
||||
|
||||
public async Task<IList<string>> GetAllOutputLines()
|
||||
{
|
||||
var lines = new List<string>();
|
||||
while (!_source.Completion.IsCompleted)
|
||||
{
|
||||
while (await _source.OutputAvailableAsync())
|
||||
{
|
||||
var next = await _source.ReceiveAsync();
|
||||
_logger.WriteLine($"{DateTime.Now}: recv: '{next}'");
|
||||
lines.Add(next);
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
private void StartProcessingOutput(StreamReader streamReader)
|
||||
{
|
||||
_source = _source ?? new BufferBlock<string>();
|
||||
|
|
@ -80,7 +96,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
string line;
|
||||
while ((line = streamReader.ReadLine()) != null)
|
||||
{
|
||||
_logger.WriteLine($"{DateTime.Now} post: {line}");
|
||||
_logger.WriteLine($"{DateTime.Now}: post: '{line}'");
|
||||
_source.Post(line);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.DotNet.Watcher.Tools.Tests;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
|
|
@ -24,7 +25,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
[InlineData(false)]
|
||||
public async Task ChangeCompiledFile(bool usePollingWatcher)
|
||||
{
|
||||
await _app.StartWatcher().OrTimeout();
|
||||
await _app.StartWatcherAsync().OrTimeout();
|
||||
|
||||
var types = await _app.GetCompiledAppDefinedTypes().OrTimeout();
|
||||
Assert.Equal(2, types);
|
||||
|
|
@ -41,7 +42,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
[Fact(Skip = "Broken. See https://github.com/aspnet/DotNetTools/issues/212")]
|
||||
public async Task AddCompiledFile()
|
||||
{
|
||||
await _app.StartWatcher().OrTimeout();
|
||||
await _app.StartWatcherAsync().OrTimeout();
|
||||
|
||||
var types = await _app.GetCompiledAppDefinedTypes().OrTimeout();
|
||||
Assert.Equal(2, types);
|
||||
|
|
@ -57,7 +58,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
[Fact]
|
||||
public async Task DeleteCompiledFile()
|
||||
{
|
||||
await _app.StartWatcher().OrTimeout();
|
||||
await _app.StartWatcherAsync().OrTimeout();
|
||||
|
||||
var types = await _app.GetCompiledAppDefinedTypes().OrTimeout();
|
||||
Assert.Equal(2, types);
|
||||
|
|
@ -73,7 +74,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
[Fact]
|
||||
public async Task DeleteSourceFolder()
|
||||
{
|
||||
await _app.StartWatcher().OrTimeout();
|
||||
await _app.StartWatcherAsync().OrTimeout();
|
||||
|
||||
var types = await _app.GetCompiledAppDefinedTypes().OrTimeout();
|
||||
Assert.Equal(2, types);
|
||||
|
|
@ -89,7 +90,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
[Fact]
|
||||
public async Task RenameCompiledFile()
|
||||
{
|
||||
await _app.StartWatcher().OrTimeout();
|
||||
await _app.StartWatcherAsync().OrTimeout();
|
||||
|
||||
var oldFile = Path.Combine(_app.SourceDirectory, "include", "Foo.cs");
|
||||
var newFile = Path.Combine(_app.SourceDirectory, "include", "Foo_new.cs");
|
||||
|
|
@ -101,7 +102,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
[Fact]
|
||||
public async Task ChangeExcludedFile()
|
||||
{
|
||||
await _app.StartWatcher().OrTimeout();
|
||||
await _app.StartWatcherAsync().OrTimeout();
|
||||
|
||||
var changedFile = Path.Combine(_app.SourceDirectory, "exclude", "Baz.cs");
|
||||
File.WriteAllText(changedFile, "");
|
||||
|
|
@ -111,6 +112,23 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
Assert.NotSame(restart, finished);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ListsFiles()
|
||||
{
|
||||
_app.Start(new [] { "--list" });
|
||||
var lines = await _app.Process.GetAllOutputLines();
|
||||
|
||||
AssertEx.EqualFileList(
|
||||
_app.Scenario.WorkFolder,
|
||||
new[]
|
||||
{
|
||||
"GlobbingApp/Program.cs",
|
||||
"GlobbingApp/include/Foo.cs",
|
||||
"GlobbingApp/GlobbingApp.csproj",
|
||||
},
|
||||
lines);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_app.Dispose();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
[Fact]
|
||||
public async Task RestartProcessOnFileChange()
|
||||
{
|
||||
await _app.StartWatcher(new[] { "--no-exit" }).OrTimeout();
|
||||
await _app.StartWatcherAsync(new[] { "--no-exit" }).OrTimeout();
|
||||
var pid = await _app.GetProcessId().OrTimeout();
|
||||
|
||||
// Then wait for it to restart when we change a file
|
||||
|
|
@ -42,7 +42,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
[Fact]
|
||||
public async Task RestartProcessThatTerminatesAfterFileChange()
|
||||
{
|
||||
await _app.StartWatcher().OrTimeout();
|
||||
await _app.StartWatcherAsync().OrTimeout();
|
||||
var pid = await _app.GetProcessId().OrTimeout();
|
||||
await _app.HasExited().OrTimeout(); // process should exit after run
|
||||
|
||||
|
|
|
|||
|
|
@ -118,17 +118,17 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
// this launches a new .NET Core process using the runtime of the current test app
|
||||
// and the version of dotnet-watch that this test app is compiled against
|
||||
var thisAssembly = Path.GetFileNameWithoutExtension(GetType().GetTypeInfo().Assembly.Location);
|
||||
var args = new List<string>();
|
||||
args.Add("exec");
|
||||
|
||||
args.Add("--depsfile");
|
||||
args.Add(Path.Combine(AppContext.BaseDirectory, thisAssembly + ".deps.json"));
|
||||
var args = new List<string>
|
||||
{
|
||||
"exec",
|
||||
"--depsfile",
|
||||
Path.Combine(AppContext.BaseDirectory, thisAssembly + ".deps.json"),
|
||||
"--runtimeconfig",
|
||||
Path.Combine(AppContext.BaseDirectory, thisAssembly + ".runtimeconfig.json")
|
||||
};
|
||||
|
||||
args.Add("--runtimeconfig");
|
||||
args.Add(Path.Combine(AppContext.BaseDirectory, thisAssembly + ".runtimeconfig.json"));
|
||||
|
||||
var currentFxVersion = AppContext.GetData("FX_DEPS_FILE") as string;
|
||||
if (currentFxVersion != null)
|
||||
if (AppContext.GetData("FX_DEPS_FILE") is string currentFxVersion)
|
||||
{
|
||||
// This overrides the version of shared fx in the runtimeconfig.json file.
|
||||
// Tests do this to ensure dotnet-watch is executing on the version of Microsoft.NETCore.App
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Extensions.Tools.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Tools.Internal;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
||||
|
|
@ -16,12 +17,11 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
private const string StartedMessage = "Started";
|
||||
private const string ExitingMessage = "Exiting";
|
||||
|
||||
protected ProjectToolScenario Scenario { get; }
|
||||
private readonly ITestOutputHelper _logger;
|
||||
protected AwaitableProcess Process { get; set; }
|
||||
private string _appName;
|
||||
private bool _prepared;
|
||||
|
||||
|
||||
public WatchableApp(string appName, ITestOutputHelper logger)
|
||||
{
|
||||
_logger = logger;
|
||||
|
|
@ -31,6 +31,10 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
SourceDirectory = Path.Combine(Scenario.WorkFolder, appName);
|
||||
}
|
||||
|
||||
public ProjectToolScenario Scenario { get; }
|
||||
|
||||
public AwaitableProcess Process { get; protected set; }
|
||||
|
||||
public string SourceDirectory { get; }
|
||||
|
||||
public Task HasRestarted()
|
||||
|
|
@ -41,9 +45,6 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
|
||||
public bool UsePollingWatcher { get; set; }
|
||||
|
||||
public Task StartWatcher([CallerMemberName] string name = null)
|
||||
=> StartWatcher(Array.Empty<string>(), name);
|
||||
|
||||
public async Task<int> GetProcessId()
|
||||
{
|
||||
var line = await Process.GetOutputLineAsync(l => l.StartsWith("PID ="));
|
||||
|
|
@ -58,7 +59,7 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
_prepared = true;
|
||||
}
|
||||
|
||||
public async Task StartWatcher(string[] arguments, [CallerMemberName] string name = null)
|
||||
public void Start(IEnumerable<string> arguments, [CallerMemberName] string name = null)
|
||||
{
|
||||
if (!_prepared)
|
||||
{
|
||||
|
|
@ -67,7 +68,6 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
|
||||
var args = Scenario
|
||||
.GetDotnetWatchArguments()
|
||||
.Concat(new[] { "run", "--" })
|
||||
.Concat(arguments);
|
||||
|
||||
var spec = new ProcessSpec
|
||||
|
|
@ -79,6 +79,15 @@ namespace Microsoft.DotNet.Watcher.Tools.FunctionalTests
|
|||
|
||||
Process = new AwaitableProcess(spec, _logger);
|
||||
Process.Start();
|
||||
}
|
||||
|
||||
public Task StartWatcherAsync([CallerMemberName] string name = null)
|
||||
=> StartWatcherAsync(Array.Empty<string>(), name);
|
||||
|
||||
public async Task StartWatcherAsync(string[] arguments, [CallerMemberName] string name = null)
|
||||
{
|
||||
var args = new[] { "run", "--" }.Concat(arguments);
|
||||
Start(args, name);
|
||||
await Process.GetOutputLineAsync(StartedMessage);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -297,7 +297,8 @@ namespace Microsoft.DotNet.Watcher.Tools.Tests
|
|||
}
|
||||
|
||||
private Task<IFileSet> GetFileSet(TemporaryCSharpProject target)
|
||||
=> GetFileSet(new MsBuildFileSetFactory(_reporter, target.Path));
|
||||
=> GetFileSet(new MsBuildFileSetFactory(_reporter, target.Path, waitOnError: false));
|
||||
|
||||
private async Task<IFileSet> GetFileSet(MsBuildFileSetFactory filesetFactory)
|
||||
{
|
||||
_tempDir.Create();
|
||||
|
|
@ -305,6 +306,7 @@ namespace Microsoft.DotNet.Watcher.Tools.Tests
|
|||
var finished = await Task.WhenAny(createTask, Task.Delay(TimeSpan.FromSeconds(10)));
|
||||
|
||||
Assert.Same(createTask, finished);
|
||||
Assert.NotNull(createTask.Result);
|
||||
return createTask.Result;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue